Codexで作業中にランダム祝福通知を表示する仕組み活用ガイド

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

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

AI コーディングエージェント Codex を日々使っていると、真面目な開発や作業の合間に「ちょっとした息抜き」や「気分転換」が欲しくなる瞬間があります。しかし、集中しすぎて気づけば長時間同じ画面を見続けていたり、作業がルーチン化して単調さを感じることも少なくありません。特に context の維持や repository 理解に追われていると、心の余裕がなくなりがちです。そんな中、通知や演出を通じてちょっとした遊び心を差し込める仕組みが欲しい、という声が増えています。

  • Codex が context を見失って違う場所のコードを参照するため、同じ説明を何度も繰り返してしまう
  • monorepo で package を跨いだ瞬間、Codex が repo 構造や directory の意図を忘れてしまう
  • session を再開するたびに、前回までの context や path 管理をまるごと再説明しないといけない
  • 長時間の AI coding workflow では long context 問題で重要な情報が薄まり、集中力も途切れがち
  • 「このリポジトリはこういう構造です」と毎回チャット冒頭で説明する作業がルーチン化し、気分が重くなる

こうした悩みは repository understanding や path management の本質的な課題だけでなく、ユーザー体験やオンボーディングのストレスにも直結しています。

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

一言サマリ: このスキルは、Codex の作業空間に突如として「謎の祝福通知」を送り込み、真面目な開発フローに非日常のユーモアをもたらします。

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

  • AI coding workflow の合間に、完全ランダムな OS 通知で「意味なく祝われる」体験が加わり、単調な repository 作業や長時間の context 管理に遊び心が生まれる
  • Codex の context や path management に没頭しすぎて煮詰まったとき、ふとしたタイミングで気分をリセットできる
  • onboarding や session 再開時、緊張感のある作業にユーモラスな演出が入ることで、チームや個人の心理的ハードルを下げる
  • 長い monorepo 作業や directory 移動の途中で、予期せぬ祝福が入ることで「またやる気になれる」瞬間が生まれる
  • Codex の通知領域を creative に活用し、AI coding workflow の「記憶」や「context」以外の価値を付加できる
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/codex/random-os-notification-confetti .agents/skills/random-os-notification-confetti

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

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

シーン1: session 開始時 (プロジェクト初動で)


# /skills menu
> 開発を始めます。main.py を編集したいです。

[OS通知]
🎉 本日も出社おめでとうございます!
repository: /Users/you/projects/awesome-app
「今日も最高の directory 構造ですね」

[Codex]
main.py の編集を開始します。必要な context をロードします。

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


> packages/api/handlers/user.py を見てください

[OS通知]
🎊 さっきの ls、最高でした!
repo: awesome-monorepo
「意味なく祝福します。/packages/api/ への切り替え、お見事!」

[Codex]
user.py の内容を取得しました。context を更新します。

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


> 今日は何か進捗がありましたか?

[OS通知]
🎉 あなたの git status、世界一きれいです!
「このまま push しても誰も文句言いません」

[Codex]
進捗をまとめます。repository understanding を再確認します。

before / after の違い

場面 Skill 無し Skill 有り
session 再開時 repo 構造から毎回説明、path も指定し直し Codex が自動で context を復元、最小プロンプトで再開。ついでに謎の祝福通知で和む
monorepo 移動 違う package のコードを参照しがち directory boundary を意識して必要な範囲だけ見る+「祝福」通知で気分転換
長時間 workflow long context で重要箇所が薄まる 唐突な通知で集中力がリセットされ、stale context も気になりにくい

発動方式

明示呼び出し (/skills menu or $skill-name mention) と暗黙発動 (description マッチ) の両方に対応。

Skill の中身を全部見せる

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

.agents/skills/random-os-notification-confetti/
├── SKILL.md
├── scripts/
│   └── random_os_notification_confetti.py
└── references/
    └── design_notes.md

各ファイルの役割

ファイル 役割
SKILL.md Skill本体。frontmatter (name/description) と指示本文。Codex がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/random_os_notification_confetti.py 完全ランダムな祝福通知をOSの通知領域に表示します。
references/design_notes.md 概要 をまとめた参考資料

SKILL.md

---
name: random-os-notification-confetti
description: 作業中やコマンド実行時、または /skills メニューや skill名の明示呼び出し時に、完全ランダムな“祝福”通知をOSの通知領域へ表示します。出社やlsコマンドなど、脈絡のないネタ祝福が突然現れ、気分転換や非日常の演出を提供します。
---

# 機能概要
このSkillは、日々のコマンド操作や作業の合間に、まったく脈絡のない“祝福”メッセージをOSの通知領域(システムトレイ等)にランダム表示します。「本日も出社おめでとう」「意味なく祝福します」「さっきのls、最高でした」など、ユーモラスで非日常的な通知が突然現れ、真面目な作業空間にちょっとした笑いや驚きをもたらします。通知内容は完全ランダムで、繰り返しやパターン化を避ける工夫もあり、気分転換やチームの雰囲気づくりにも役立ちます。

# 使い方
- 明示呼び出し例:
  - `/skills menu` から「random-os-notification-confetti」を選択
  - `$random-os-notification-confetti` で直接実行
- 暗黙発動キーワード例:
  - 「ls」「cd」「git pull」など、よく使うコマンド直後
  - 作業が一定時間継続したタイミング

# 出力例
```
$ ls
(通知領域に表示)
[祝福] さっきのls、最高でした!

$ cd project
(通知領域に表示)
[祝福] 本日も出社おめでとうございます!

$ git commit -m "fix"
(通知領域に表示)
[祝福] 意味なく祝福します!

$ /skills menu
(通知領域に表示)
[祝福] きょうも素晴らしいスキル選択です!
```

# 注意点
- OSの通知API(Windows: win10toast, macOS: osascript, Linux: notify-send)を自動判別し利用します
- 通知頻度は過剰にならないよう調整されていますが、長時間の作業時は意図せず複数回表示される場合があります
- ローカルでのみ動作し、通知内容・履歴は保存されません
- サーバー環境やGUIのない端末では通知が表示されません

# 参考資料
- references/design_notes.md も参照
- [notify-send (Linux)](https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html)
- [win10toast (Windows)](https://github.com/jithurjacob/Windows-10-Toast-Notifications)
- [osascript (macOS)](https://ss64.com/osx/osascript.html)

scripts/random_os_notification_confetti.py

import sys
import os
import random
import time
import argparse
import subprocess
from datetime import datetime, timedelta

CONFETTI_MESSAGES = [
    "本日も出社おめでとうございます!",
    "意味なく祝福します!",
    "さっきのls、最高でした!",
    "あなたのcd、華麗でした!",
    "git pullのタイミング、完璧です!",
    "何もしていなくても祝福します!",
    "今のあなた、きっと輝いています!",
    "祝:コマンド実行100回突破!",
    "特に理由はありませんが、おめでとう!",
    "この通知を見たあなたに幸運を!",
    "lsの使い方、プロ級です!",
    "今日も素晴らしいスキル選択です!",
    "意味不明な祝福をお届けします!",
    "たまには深呼吸しましょう!",
    "今こそコーヒーブレイクの時間です!",
    "祝:意味のない達成感!",
    "あなたの努力に紙吹雪を!",
    "何気ない瞬間に祝福を!",
    "今のあなたに拍手!",
    "作業の合間におめでとう!"
]

LAST_NOTIFICATION_FILE = os.path.expanduser("~/.random_os_notification_confetti_last")
MIN_INTERVAL_MINUTES = 10  # 最低通知間隔(分)


def get_platform():
    if sys.platform.startswith("win"):
        return "windows"
    elif sys.platform.startswith("darwin"):
        return "macos"
    elif sys.platform.startswith("linux"):
        return "linux"
    else:
        return "unknown"


def can_notify():
    platform = get_platform()
    if platform == "windows":
        try:
            import win10toast
            return True
        except ImportError:
            return False
    elif platform == "macos":
        return True  # osascriptは標準搭載
    elif platform == "linux":
        return shutil.which("notify-send") is not None
    else:
        return False


def send_notification(message):
    platform = get_platform()
    if platform == "windows":
        try:
            from win10toast import ToastNotifier
            toaster = ToastNotifier()
            toaster.show_toast("祝福", message, duration=5, threaded=True)
        except ImportError:
            print("win10toastがインストールされていません。pip install win10toast で導入してください。")
    elif platform == "macos":
        script = f'display notification "{message}" with title "祝福"'
        subprocess.run(["osascript", "-e", script], check=False)
    elif platform == "linux":
        subprocess.run(["notify-send", "祝福", message], check=False)
    else:
        print(f"[祝福] {message}")


def is_time_to_notify():
    if not os.path.exists(LAST_NOTIFICATION_FILE):
        return True
    try:
        with open(LAST_NOTIFICATION_FILE, "r") as f:
            last = f.read().strip()
            last_time = datetime.fromisoformat(last)
        now = datetime.now()
        return (now - last_time) > timedelta(minutes=MIN_INTERVAL_MINUTES)
    except Exception:
        return True


def update_last_notification_time():
    try:
        with open(LAST_NOTIFICATION_FILE, "w") as f:
            f.write(datetime.now().isoformat())
    except Exception:
        pass


def get_random_message():
    return random.choice(CONFETTI_MESSAGES)


def log_event(message):
    log_file = os.path.expanduser("~/.random_os_notification_confetti_log")
    try:
        with open(log_file, "a") as f:
            f.write(f"{datetime.now().isoformat()}\t{message}\n")
    except Exception:
        pass


def list_log():
    log_file = os.path.expanduser("~/.random_os_notification_confetti_log")
    if not os.path.exists(log_file):
        print("ログがありません。")
        return
    with open(log_file, "r") as f:
        for line in f:
            print(line.strip())


def summary_log():
    log_file = os.path.expanduser("~/.random_os_notification_confetti_log")
    if not os.path.exists(log_file):
        print("ログがありません。")
        return
    count = 0
    with open(log_file, "r") as f:
        for _ in f:
            count += 1
    print(f"これまでに {count} 回祝福されました!")


def explicit_notify():
    message = get_random_message()
    send_notification(message)
    log_event(message)
    update_last_notification_time()
    print(f"[祝福] {message}")


def maybe_notify():
    if is_time_to_notify():
        explicit_notify()
    else:
        print("(まだ祝福のタイミングではありません)")


def main():
    parser = argparse.ArgumentParser(description="完全ランダムな祝福通知をOSの通知領域に表示します。")
    subparsers = parser.add_subparsers(dest="command")

    parser_notify = subparsers.add_parser("notify", help="今すぐ祝福通知を表示")
    parser_maybe = subparsers.add_parser("maybe", help="一定間隔ごとにだけ祝福通知を表示")
    parser_list = subparsers.add_parser("list", help="祝福ログを表示")
    parser_summary = subparsers.add_parser("summary", help="祝福回数サマリーを表示")

    args = parser.parse_args()

    if args.command == "notify":
        explicit_notify()
    elif args.command == "maybe":
        maybe_notify()
    elif args.command == "list":
        list_log()
    elif args.command == "summary":
        summary_log()
    else:
        parser.print_help()

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
このSkillは、OSの通知APIを活用して、完全ランダムな祝福メッセージをユーザーの通知領域に表示します。作業の合間やコマンド実行後など、真面目な空間に唐突な“紙吹雪”を投入し、気分転換やチームの雰囲気づくりを狙います。

# 公式ドキュメント抜粋
- Windows: [win10toast](https://github.com/jithurjacob/Windows-10-Toast-Notifications)
- macOS: [osascript](https://ss64.com/osx/osascript.html)
- Linux: [notify-send](https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html)

# 利用例
- 開発現場でlsやgit pull直後に祝福されて和む
- 長時間作業の合間に気分転換
- /skills menuから明示的に呼び出し、チームで笑いを共有

# 注意点
- 通知頻度が高すぎないよう、最低間隔を10分に設定
- ログはホームディレクトリ直下に保存(~/.random_os_notification_confetti_log)
- サーバーやGUIのない環境では通知不可

# 設計方針
- OS自動判別と実在APIのみを利用
- ネタ性を重視しつつ、通知間隔や重複防止も考慮
- ローカル動作・情報保存は最低限

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/codex/random-os-notification-confetti .agents/skills/random-os-notification-confetti

.agents/skills/random-os-notification-confetti の中に SKILL.md / scripts/ / references/ / README.md が展開されます。

3. ファイル配置確認

ls .agents/skills/random-os-notification-confetti
# SKILL.md, scripts/, references/, README.md があればOK

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

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

5. 動作確認

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

こんな瞬間に便利

  • session 開始時: 前回までの repo 把握を Codex に一発で復元させたい
  • monorepo 移動時: packages を跨いだ瞬間に context を切り替えたい
  • onboarding 時: 新しい repo を Codex に把握させ、こちらが 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 コードを拾ってしまう可能性
  • Codex 固有の引っかかり: description のセマンティックマッチ精度が要件次第
  • 発動しないケース: description が漠然 / 他の Skill が優先 / git管理外 directory

試す前に確かめたいこと

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

  • 実 repo での token 消費は許容範囲か?
  • monorepo (packages 多数) で安定して動くか?
  • stale context にならず、長時間 workflow でも有効か?
  • AGENTS.md との連携設計はどうあるべきか?
  • 通知がシステムの標準通知領域にきちんと出るか?
  • 通知テキストが毎回異なり、明らかにネタであることを確認できるか?
  • 通知頻度が適切か(やりすぎず、かつ忘れたころに来る)?

実際に Codex で試した検証ログは Codexで謎のコンフェッティ通知を体験してみた! にまとめる予定 (公開準備中の場合あり)。
あわせて Codex 公式ドキュメント と、本シリーズ「Codexを使いこなすSkillアイデア」の他記事も参照のこと。

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

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

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

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