Claude Codeで歴史風フェイク通知を活用した作業空間演出の作り方

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

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

Claude Code を使った AI coding workflow では、リポジトリの理解や context の維持、path 管理にまつわる悩みが頻繁に発生します。特に monorepo での作業や長時間のセッションでは、思いがけない挙動に戸惑うことも少なくありません。さらに、ツールの堅実な動作に慣れてくると、時には「ちょっとした遊び心」や気分転換が欲しくなる瞬間もあるでしょう。

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

こうした「真面目な悩み」に加えて、作業が煮詰まった時のリフレッシュや、チームの onboarding 時に空気を和ませる演出が欲しいという声も。通知・演出・OS連携系の Skill で、作業空間にちょっとした非日常を持ち込みたいニーズが潜在しています。

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

一言サマリ: このスキルは、作業中に突如「謎の幕末カウントダウン通知」を炸裂させ、作業空間を時空の彼方へ誘うSkill。

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

  • AI coding workflow の合間に、毎回異なる日本史風フェイクアラートがデスクトップやターミナルに登場し、作業空間が一瞬で非日常化
  • monorepo や複雑な repository 構造でも、意味不明なカウントダウン演出により「context の切り替えタイミング」を遊び心で演出
  • onboarding や session 再開時の「堅苦しさ」を和らげ、チームや個人の気分転換に役立つ
  • 通知は完全に無害で、repository understanding や path management への影響ゼロ
  • Skill の導入・削除も path 指定だけで完結し、Claude Code の標準機能とシームレスに共存
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/claude-code/os-fake-bakumatsu-countdown-alert .claude/skills/os-fake-bakumatsu-countdown-alert

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

使う側がイメージしやすいよう、擬似 terminal で出力例を3パターン示します。

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


# /os-fake-bakumatsu-countdown-alert

【緊急幕末速報】
本リポジトリは現在「維新前夜」モードです。
黒船が浦賀沖に現れました。あと13分で開国交渉が自動開始されます。

対象ディレクトリ: ./src/
アラートID: BAKUMATSU-1867-001
(ご安心ください。この通知は実害ゼロです)

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


> パッケージ間で context を切り替えたい

【幕末アラート】
本日は「大政奉還」パッケージ切替日です。
packages/api から packages/ui への政権移譲まで残り8分。

本能寺リブート準備中...(影響: packages/common/utils)
(本通知はフィクションです)

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


> ちょっと気分転換したい

【幕末カウントダウン】
突然ですが、あなたの作業環境に「尊王攘夷モード」が発動しました。
あと5分で新選組巡回が開始されます。

対象: ./scripts/
(気にせず作業を続けてください)

before / after の違い

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

発動方式

明示呼び出し (/os-fake-bakumatsu-countdown-alert) と暗黙発動 (「幕末」「カウントダウン」「黒船」などの description マッチ) の両方に対応。

Skill の中身を全部見せる

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

.claude/skills/os-fake-bakumatsu-countdown-alert/
├── SKILL.md
├── scripts/
│   └── bakumatsu_countdown_alert.py
└── references/
    └── design_notes.md

各ファイルの役割

ファイル 役割
SKILL.md Skill本体。frontmatter (name/description) と指示本文。Claude Code がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/bakumatsu_countdown_alert.py 幕末カウントダウンアラート (os-fake-bakumatsu-countdown-alert)
references/design_notes.md 概要 をまとめた参考資料

SKILL.md

---
name: os-fake-bakumatsu-countdown-alert
description: 作業中やCLI操作時に『幕末風カウントダウン通知』で雰囲気を一変させたい場合、または“カウントダウン”“アラート”“歴史ネタ”などのキーワードを含む会話や明示的な /os-fake-bakumatsu-countdown-alert 呼び出し時に発動。
---

# 機能概要
このSkillは、作業中のCLIやデスクトップ環境に、幕末日本をモチーフにしたフェイクカウントダウンアラートを突如表示します。通知内容は毎回ランダム生成され、例えば「緊急:システムはあと13分で明治維新されます」「本日は黒船再来。本能寺リブートまで残り8分」など、歴史パロディ満載。実際のシステムには一切影響せず、作業空間にシュールな演出を加えます。歴史好きはもちろん、気分転換やネタ枠としても活用可能です。

# 使い方
- 明示呼び出し例: `/os-fake-bakumatsu-countdown-alert`
- 暗黙発動キーワード例: 「カウントダウン」「アラート」「幕末」「歴史パロ」「タイムリミット」「黒船」「明治維新」などを含む会話やスクリプト実行時。

# 出力例
```terminal
[幕末カウントダウン] 緊急:システムはあと13分で明治維新されます
残り時間: 00:12:59

[幕末カウントダウン] 本日は黒船再来。本能寺リブートまで残り8分
残り時間: 00:07:59

[幕末カウントダウン] 土佐藩アップデートまで残り5分
残り時間: 00:04:59
```

# 注意点
- 実際のシステムやファイルには一切影響を与えません。
- 通知内容・残り時間は完全ランダムです。
- ローカル保存や履歴記録は行いません。
- 一部環境では通知表示に制限がある場合があります。

# 参考資料
詳細な設計方針や通知生成ロジックは references/design_notes.md を参照してください。Python標準の通知APIやCLI出力例も記載しています。

scripts/bakumatsu_countdown_alert.py

import random
import time
import sys
import argparse
import threading
import platform
import subprocess

BAKUMATSU_EVENTS = [
    ("緊急:システムはあと{minutes}分で明治維新されます", "明治維新"),
    ("本日は黒船再来。本能寺リブートまで残り{minutes}分", "黒船再来"),
    ("土佐藩アップデートまで残り{minutes}分", "土佐藩アップデート"),
    ("会津藩セーフモード突入まで残り{minutes}分", "会津藩セーフモード"),
    ("西郷どんプロセスが終了するまで{minutes}分", "西郷プロセス終了"),
    ("坂本龍馬のバージョンアップまで残り{minutes}分", "龍馬バージョンアップ"),
    ("江戸幕府シャットダウンまで{minutes}分", "江戸幕府シャットダウン"),
    ("薩長連合ネットワーク再構築まで{minutes}分", "薩長連合再構築"),
    ("新選組アップデート適用まで{minutes}分", "新選組アップデート"),
    ("ペリー警告:黒船リセットまで{minutes}分", "ペリー警告")
]

TERMINAL_PREFIX = "[幕末カウントダウン]"


def random_event():
    event_tpl, event_name = random.choice(BAKUMATSU_EVENTS)
    minutes = random.randint(5, 30)
    message = event_tpl.format(minutes=minutes)
    return message, event_name, minutes


def notify_desktop(title, message):
    system = platform.system()
    try:
        if system == "Darwin":  # macOS
            subprocess.run([
                "osascript", "-e",
                f'display notification "{message}" with title "{title}"'
            ])
        elif system == "Linux":
            subprocess.run([
                "notify-send", title, message
            ])
        elif system == "Windows":
            # Use Toast notification via 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('os-fake-bakumatsu-countdown-alert');"
            ps_script += f"$notifier.Show($toast);"
            subprocess.run(["powershell", "-Command", ps_script], shell=True)
        else:
            print(f"{TERMINAL_PREFIX} {title}: {message}")
    except Exception as e:
        print(f"{TERMINAL_PREFIX} 通知失敗: {e}")


def print_terminal_alert(message, minutes):
    print(f"{TERMINAL_PREFIX} {message}")
    print(f"残り時間: {minutes:02d}:00\n")


def countdown(minutes, event_name, desktop=False):
    total_seconds = minutes * 60
    for remaining in range(total_seconds, 0, -1):
        mins, secs = divmod(remaining, 60)
        sys.stdout.write(f"\r{TERMINAL_PREFIX} {event_name} 残り時間: {mins:02d}:{secs:02d}")
        sys.stdout.flush()
        time.sleep(1)
    print(f"\n{TERMINAL_PREFIX} {event_name} タイムアップ!\n")
    if desktop:
        notify_desktop("幕末カウントダウン終了", f"{event_name}が完了しました")


def list_events():
    print("利用可能な幕末カウントダウンイベント:")
    for idx, (tpl, name) in enumerate(BAKUMATSU_EVENTS, 1):
        print(f"{idx}. {name}")


def summary():
    print("このスクリプトは、幕末日本をテーマにしたフェイクカウントダウンアラートをCLIまたはデスクトップ通知で表示します。実害ゼロ、歴史パロディ専用です。")


def main():
    parser = argparse.ArgumentParser(description="幕末カウントダウンアラート (os-fake-bakumatsu-countdown-alert)")
    subparsers = parser.add_subparsers(dest="command", help="サブコマンド")

    parser_log = subparsers.add_parser("log", help="ランダムな幕末アラートを表示")
    parser_log.add_argument("--desktop", action="store_true", help="デスクトップ通知も表示")
    parser_log.add_argument("--countdown", action="store_true", help="カウントダウン演出も実行")
    parser_log.add_argument("--minutes", type=int, default=None, help="カウントダウン分数を指定")

    parser_list = subparsers.add_parser("list", help="利用可能なイベント一覧を表示")
    parser_summary = subparsers.add_parser("summary", help="概要を表示")

    args = parser.parse_args()

    if args.command == "log":
        message, event_name, minutes = random_event()
        if args.minutes is not None and 1 <= args.minutes <= 60:
            minutes = args.minutes
            message = message.split("まで残り")[0] + f"まで残り{minutes}分"
        print_terminal_alert(message, minutes)
        if args.desktop:
            notify_desktop("幕末カウントダウン", message)
        if args.countdown:
            countdown(minutes, event_name, desktop=args.desktop)
    elif args.command == "list":
        list_events()
    elif args.command == "summary":
        summary()
    else:
        parser.print_help()

if __name__ == "__main__":
    main()

references/design_notes.md

# 概要
このSkillは、CLIやデスクトップ環境に幕末日本をテーマにしたパロディカウントダウンアラートを無害に表示することを目的としています。通知内容は毎回ランダム生成され、歴史的な出来事や人物をもじったテキストで演出を行います。

# 公式ドキュメント抜粋
- Python標準の `argparse` によるCLIサブコマンド設計
- macOS: `osascript`、Linux: `notify-send`、Windows: PowerShell経由のToast通知を利用
- すべての通知はユーザー空間のみで完結し、システム設定やファイルには一切影響しません

# 利用例
- `/os-fake-bakumatsu-countdown-alert` コマンドで即時発動
- CLIで `python bakumatsu_countdown_alert.py log --desktop --countdown` など
- 作業中の気分転換やイベント演出、ネタ枠として活用

# 注意点
- 通知内容や残り時間は完全ランダムです
- ログや履歴は保存されません
- 一部のLinux/Windows環境では通知APIが未インストールの場合があります

# 設計方針
「実害ゼロ」「歴史パロディ」「毎回異なる演出」を重視し、通知APIの標準的な実装のみを採用しています。

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/claude-code/os-fake-bakumatsu-countdown-alert .claude/skills/os-fake-bakumatsu-countdown-alert

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

3. ファイル配置確認

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

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

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

5. 動作確認

/os-fake-bakumatsu-countdown-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で謎の幕末カウントダウン通知を炸裂させてみた! にまとめる予定 (公開準備中の場合あり)。
あわせて Claude Code 公式ドキュメント と、本シリーズ「Claude Codeを便利にするSkill提案」の他記事も参照のこと。

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

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

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

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