Codexで謎のOSペット乱入を演出して集中力をリセットする方法

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

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

Codex を日々の AI coding workflow に活用していると、集中しすぎて思わぬ落とし穴にハマる瞬間がしばしば訪れます。repository understanding や path management の精度を高めるために、context の維持や directory 構造の把握に気を配る一方、作業がルーティン化して気分転換のタイミングを見失いがちです。特に monorepo での作業や長時間 session では、AI とユーザー双方の「メモリ疲労」が蓄積し、オンボーディングのたびに同じ説明を繰り返すことも珍しくありません。

  • Codex が context を見失って違う場所のコードを参照する
  • monorepo で package を跨いだ瞬間、Codex が repo 構造を忘れる
  • session を再開すると、前回までの context や path 指定をまるごと再説明しないといけない
  • 長時間 workflow で long context が膨らみすぎて、important な情報が薄まる (stale context)
  • 「ここはこういう構造のリポジトリ」というあらすじを毎回チャットの冒頭で書く羽目になる

こういった悩みに加えて、作業に没頭しすぎてリフレッシュのきっかけを失い、気づけば効率が下がっていることも。通知・演出・OS連携の工夫で、適度に集中をリセットする仕掛けが求められています。

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

一言サマリ: このスキルは、Codex の作業フローに「謎のOSペット乱入イベント」を完全ランダムで挟み込み、集中しすぎた状態を強制リセットするSkill。

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

  • AI coding workflow の中に予期せぬ癒しや混乱が入り、長時間 session の stale context を強制的にリフレッシュできる
  • repository understanding の合間に、気分転換のきっかけを自動生成し、単調な path management 作業から意識を切り替えられる
  • onboarding や session 再開時に、ペットイベントが context の切り替え合図となり、次の作業フェーズへスムーズに移行できる
  • monorepo の directory 移動や package 跨ぎの瞬間に、ユーモラスな演出で「今いる場所」を直感的に再認識できる
  • 長時間の repository 作業でも、AI とユーザー双方の「メモリ疲労」を和らげ、会話に余白を生み出す
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/codex/random-os-fake-system-pet-interruption .agents/skills/random-os-fake-system-pet-interruption

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

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

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


# /skills menu or random-os-fake-system-pet-interruption

[Codex Notification]
🐾 OS公式ペット「バーチャル柴犬」があなたのデスクトップを横切りました。
何もなかったかのように消えていきます...

リポジトリ構造:
- src/
- tests/
- docs/

(作業を続けてください)

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


> packages/payment/README.md を編集

[Codex Notification]
🐱 仮想猫が packages/payment ディレクトリでマウスカーソルを追いかけています。
「/packages/user/」にも何か気配が...

現在の作業パス: packages/payment/
関連パッケージ: user, billing

(引き続き編集できます)

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


> 今日は集中できないので何か面白いことして

[Codex Notification]
🦦 デジタルカワウソが repository の README.md 上で昼寝を始めました。
ファイルを開くたびに起きたり寝たりします。

(何の役にも立ちませんが癒されます)

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-fake-system-pet-interruption/ に配置するファイル一覧です。GitHub に push 済みなので、上記の degit コマンドで一発取得できます。

.agents/skills/random-os-fake-system-pet-interruption/
├── SKILL.md
├── scripts/
│   └── os_pet_interruption.py
└── references/
    └── design_notes.md

各ファイルの役割

ファイル 役割
SKILL.md Skill本体。frontmatter (name/description) と指示本文。Codex がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/os_pet_interruption.py interval_min: イベント間隔(分), stop_after: 最大稼働時間(分)
references/design_notes.md 概要 をまとめた参考資料

SKILL.md

---
name: random-os-fake-system-pet-interruption
description: Codexはユーザーの作業が一定時間継続している、または明示的な呼び出し(/skills menuやrandom-os-fake-system-pet-interruptionへの言及)があった場合にこのSkillを発動してください。キーワード: 通知, OSペット, 乱入, リフレッシュ。
---

# 機能概要
このSkillは、作業中のユーザーに対して完全ランダムなタイミングで“OSペット乱入イベント”を発生させる演出ツールです。ペットは仮想的な猫や犬、鳥などがデスクトップ上を横切ったり、ファイルの上で寝たり、マウスカーソルを追いかけたりします。通知や端末出力を通じて、何の役にも立たない癒しと混乱を提供し、集中しすぎた状態を一瞬リセットします。OSがペットを飼い始めたような不思議な体験が得られます。

# 使い方
- 明示呼び出し例: `/skills menu` から `random-os-fake-system-pet-interruption` を選択、または `$random-os-fake-system-pet-interruption` への直接言及。
- 暗黙発動: 作業が一定時間継続している、または「疲れ」「集中しすぎ」「癒し」などのキーワードが会話やログに現れた場合に自動発動します。

# 出力例
```
[OSペット通知] デジタル柴犬がファイル「report.docx」の上で昼寝を始めました。
[OSペット通知] 仮想猫がマウスカーソルを追いかけています!
[OSペット通知] OS公式ペンギンが画面を横切りました。
[OSペット通知] デジタルインコがウィンドウの隅で羽を休めています。
[OSペット通知] バーチャルハムスターがタスクバーでおやつを探しています。
```

# 注意点
- このSkillは実用的な機能はありません。通知内容は完全に架空です。
- ローカルファイルの変更や実際のデスクトップ操作は行いません。
- 出力は端末または通知API経由のみ。実際のペット画像やアニメーションは含みません。
- 連続発動を避けるため、一定のクールタイムを設けています。

# 参考資料
- references/design_notes.md に設計方針や利用例を記載
- 公式通知API: https://docs.python.org/ja/3/library/notify2.html
- OS通知の一般仕様: https://developer.gnome.org/notification-spec/

scripts/os_pet_interruption.py

import argparse
import random
import time
import sys
import os
import threading
try:
    import notify2
except ImportError:
    notify2 = None

PET_EVENTS = [
    '{pet}がファイル「{file}」の上で昼寝を始めました。',
    '{pet}がマウスカーソルを追いかけています!',
    'OS公式{pet}が画面を横切りました。',
    '{pet}がウィンドウの隅で羽を休めています。',
    '{pet}がタスクバーでおやつを探しています。',
    '{pet}が通知領域で丸くなっています。',
    '{pet}が仮想デスクトップを移動しています。',
    '{pet}が設定画面で遊んでいます。',
    '{pet}がコマンド履歴を眺めています。',
    '{pet}がスクリーンショットを撮ろうとしています。',
]

PETS = [
    'デジタル柴犬',
    '仮想猫',
    'OS公式ペンギン',
    'デジタルインコ',
    'バーチャルハムスター',
    'サイバーうさぎ',
    'ピクセルリス',
    'デジタルカメ',
    'バーチャルフクロウ',
    '仮想フェレット'
]

FILES = [
    'report.docx',
    'main.py',
    'presentation.pptx',
    'budget.xlsx',
    'notes.txt',
    'README.md',
    'archive.zip',
    'photo.jpg',
    'tasks.csv',
    'music.mp3'
]

HISTORY_LOG = os.path.expanduser('~/.os_pet_interruptions.log')
COOLTIME_SEC = 600  # 10分


def random_event():
    pet = random.choice(PETS)
    file = random.choice(FILES)
    event = random.choice(PET_EVENTS)
    msg = event.format(pet=pet, file=file)
    return msg


def notify(msg):
    if notify2 is not None:
        try:
            notify2.init('OSペット通知')
            n = notify2.Notification('OSペット通知', msg)
            n.set_timeout(5000)
            n.show()
            return True
        except Exception:
            pass
    # Fallback: print to terminal
    print(f'[OSペット通知] {msg}')
    return False


def log_event(msg):
    ts = time.strftime('%Y-%m-%d %H:%M:%S')
    with open(HISTORY_LOG, 'a', encoding='utf-8') as f:
        f.write(f'{ts}\t{msg}\n')


def list_events(limit=10):
    if not os.path.exists(HISTORY_LOG):
        print('まだイベント履歴がありません。')
        return
    with open(HISTORY_LOG, 'r', encoding='utf-8') as f:
        lines = f.readlines()[-limit:]
    for line in lines:
        print(line.strip())


def summary():
    if not os.path.exists(HISTORY_LOG):
        print('まだイベント履歴がありません。')
        return
    pet_count = {pet: 0 for pet in PETS}
    with open(HISTORY_LOG, 'r', encoding='utf-8') as f:
        for line in f:
            for pet in PETS:
                if pet in line:
                    pet_count[pet] += 1
    print('ペット別乱入回数:')
    for pet, count in pet_count.items():
        print(f'  {pet}: {count}回')


def can_trigger():
    if not os.path.exists(HISTORY_LOG):
        return True
    with open(HISTORY_LOG, 'r', encoding='utf-8') as f:
        lines = f.readlines()
        if not lines:
            return True
        last = lines[-1]
        ts_str = last.split('\t')[0]
        try:
            last_time = time.mktime(time.strptime(ts_str, '%Y-%m-%d %H:%M:%S'))
            now = time.time()
            return (now - last_time) > COOLTIME_SEC
        except Exception:
            return True


def trigger_event():
    if not can_trigger():
        print('クールタイム中のため、まだ乱入できません。')
        return
    msg = random_event()
    notify(msg)
    log_event(msg)


def auto_mode(interval_min=20, stop_after=120):
    """interval_min: イベント間隔(分), stop_after: 最大稼働時間(分)"""
    start = time.time()
    while (time.time() - start) < stop_after * 60:
        sleep_time = random.randint(int(interval_min*0.5), int(interval_min*1.5)) * 60
        time.sleep(sleep_time)
        trigger_event()
    print('自動乱入モード終了')


def main():
    parser = argparse.ArgumentParser(description='random-os-fake-system-pet-interruption')
    subparsers = parser.add_subparsers(dest='command')

    parser_trigger = subparsers.add_parser('trigger', help='手動で乱入イベントを発生')
    parser_auto = subparsers.add_parser('auto', help='自動乱入モード')
    parser_auto.add_argument('--interval', type=int, default=20, help='イベント間隔(分)')
    parser_auto.add_argument('--duration', type=int, default=120, help='最大稼働時間(分)')
    parser_list = subparsers.add_parser('list', help='履歴を表示')
    parser_list.add_argument('--limit', type=int, default=10, help='表示件数')
    parser_summary = subparsers.add_parser('summary', help='ペット別乱入回数')

    args = parser.parse_args()

    if args.command == 'trigger':
        trigger_event()
    elif args.command == 'auto':
        auto_mode(interval_min=args.interval, stop_after=args.duration)
    elif args.command == 'list':
        list_events(limit=args.limit)
    elif args.command == 'summary':
        summary()
    else:
        parser.print_help()

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
本Skillは、ユーザーの作業中に完全ランダムなタイミングで“OSペット乱入”という非生産的な癒しイベントを発生させるものです。現実のデスクトップやファイルには一切影響を与えず、通知APIや端末出力のみを利用します。

# 公式ドキュメント抜粋
- Python通知API: https://docs.python.org/ja/3/library/notify2.html
- Linux通知仕様: https://developer.gnome.org/notification-spec/

# 利用例
- 長時間作業中に「trigger」コマンドで強制乱入
- 「auto」モードで20分〜30分毎に自動発動
- 履歴やペット別回数の集計も可能

# 注意点
- 実際のペット画像やアニメーション表示は行いません
- ログはホームディレクトリ配下に保存
- クールタイム制御あり

# 設計方針
- 完全ランダム性と多様なメッセージで飽きさせない
- 実在APIのみ使用し、環境依存を最小化
- ログや履歴で“癒しイベント”の振り返りも可能に

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/codex/random-os-fake-system-pet-interruption .agents/skills/random-os-fake-system-pet-interruption

.agents/skills/random-os-fake-system-pet-interruption の中に SKILL.md / scripts/ / references/ / README.md が展開されます。

3. ファイル配置確認

ls .agents/skills/random-os-fake-system-pet-interruption
# 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で謎のOSペットが突然乱入してくる演出を試してみた! にまとめる予定 (公開準備中の場合あり)。
あわせて Codex 公式ドキュメント と、本シリーズ「Codexを使いこなすSkillアイデア」の他記事も参照のこと。

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

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

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

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