Codexで謎のプリンタ警告を再現し作業環境を楽しく混乱させる方法

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

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

日々 Codex を使っていると、便利さの裏で「あるある」と感じる小さなストレスや混乱が積み重なります。特に通知や演出、OS連携まわりでは、次のような悩みがよく挙がります。

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

さらに、作業に集中しているときに「何もしていないのに謎の警告が飛んでくる」ようなシュールな演出が欲しい、という声も。通知・演出系 Skill を活用することで、ちょっとした気分転換や、意図的な混乱を楽しむユーモアも求められています。

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

一言サマリ: このスキルは、完全に理不尽な“OS公式プリンタ紙詰まり警告”をランダムに炸裂させ、作業中のあなたを絶妙に混乱させるSkill。

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

  • 作業やAI coding workflowの最中に、現実には絶対起きない「プリンタ紙詰まり」通知が context 無視で現れ、ちょっとした笑いと混乱を演出できる
  • repoやdirectory構造、path管理とは全く無関係なタイミングでOS通知が発生し、長時間の集中や stale context を意図的にリフレッシュ
  • randomな通知内容・タイミングで、Codex の sessionやmemoryに依存せず、毎回ユニークな体験を提供
  • onboardingやチームでの導入時、話題やアイスブレイクのきっかけになる
  • 通知・演出・OS連携Skillのサンプルとして、CodexのSkill拡張性や遊び心を体感できる
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/codex/random-os-fake-printer-jam-alert .agents/skills/random-os-fake-printer-jam-alert

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

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

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


# /skills menu

[OS通知] 重要: プリンタ「OfficePrinter-02」で paperjam が発生しました。
対象ファイル: README.md
対処: 紙を手で給紙してください。トナーが謎に不足しています。

[OS通知] 警告: 印刷ジョブ queue.txt が詰まっています。
詳細: プリンタのカバーを閉じてください。エラーコード: 0xF00D

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


> cd packages/api && ls

[OS通知] 重大: プリンタ「api-printer」で main.py の印刷に失敗しました。
理由: 紙詰まり。プリンタの右側に謎の紙が挟まっています。
対処: 不明なトナーを補充してください。

[OS通知] 注意: 印刷待ちジョブが渋滞中です。
対象: packages/ui/App.tsx
ヒント: プリンタの電源を一度切ってみてください。

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


> echo "hello world" > test.txt

[OS通知] お知らせ: プリンタ「test-printer」で test.txt の印刷が途中で止まりました。
原因: 謎の紙詰まり。紙を逆さにセットしてください。
エラー: トナー残量がマイナスです。サポートに連絡してください。

before / after の違い

場面 Skill 無し Skill 有り
session 再開時 repo 構造から毎回説明、path も指定し直し Codex が自動で context を復元、最小プロンプトで再開
monorepo 移動 違う package のコードを参照しがち directory boundary を意識して必要な範囲だけ見る
長時間 workflow long context で重要箇所が薄まる 突発的な通知で workflow にリズムや変化を付与、集中しすぎを防ぐ

発動方式

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

Skill の中身を全部見せる

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

.agents/skills/random-os-fake-printer-jam-alert/
├── SKILL.md
├── scripts/
│   └── fake_printer_jam_alert.py
└── references/
    └── design_notes.md

各ファイルの役割

ファイル 役割
SKILL.md Skill本体。frontmatter (name/description) と指示本文。Codex がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/fake_printer_jam_alert.py duration: ループを続ける秒数
references/design_notes.md 概要 をまとめた参考資料

SKILL.md

---
name: random-os-fake-printer-jam-alert
description: このSkillは、コマンド実行や作業中に“プリンタ紙詰まり”などの理不尽なOS通知を完全ランダムに発生させます。通知・演出・OS連携系Skillとして、明示呼び出しや特定ワード(プリンタ/印刷/紙詰まり/エラー等)を含む操作で発動します。
---

# 機能概要
このSkillは、現実にはプリンタを使っていなくても、OSやターミナル上で“プリンタ紙詰まり”や“印刷エラー”などの理不尽な警告通知を完全ランダムに発生させます。通知内容は毎回異なり、「重要:プリンタで“main.py”が詰まりました」「警告:印刷待ちジョブが渋滞中」など、無関係なファイル名や不可解な指示が混じります。作業中のユーザーに小さな混乱や笑いを提供し、OS通知の演出やテストにも活用できます。

# 使い方
- 明示呼び出し例: `/skills random-os-fake-printer-jam-alert` または Skillメニューから選択
- 暗黙発動例: 「プリンタ」「印刷」「紙詰まり」「エラー」「ジョブ」などのワードを含むコマンドや会話中に自動発動
- semantic-or-explicit トリガー対応

# 出力例
```
[OS通知] 重要:プリンタで“README.md”が紙詰まりを検出しました。
[OS通知] 警告:印刷ジョブが渋滞中です。トナー補充を試してください。
[OS通知] エラー:プリンタが“main.py”を処理中に謎のジャムが発生。
[OS通知] 指示:紙を手で給紙してください。
[OS通知] 注意:プリンタに未知のエラーコード #E42。
```

# 注意点
- 実際のプリンタや印刷処理とは無関係です
- 通知は完全ランダムに生成され、内容も毎回異なります
- ローカル保存や履歴機能はありません
- OS通知API(notify-send等)が必要です(Linux/macOS推奨)

# 参考資料
詳細な設計方針・利用例は references/design_notes.md を参照。OS通知APIの詳細は [notify-send](https://specifications.freedesktop.org/notification-spec/latest/) 公式ドキュメントを参照してください。

scripts/fake_printer_jam_alert.py

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

# 通知メッセージのテンプレート
MESSAGE_TEMPLATES = [
    '重要:プリンタで“{filename}”が紙詰まりを検出しました。',
    '警告:印刷ジョブが渋滞中です。トナー補充を試してください。',
    'エラー:プリンタが“{filename}”を処理中に謎のジャムが発生。',
    '指示:紙を手で給紙してください。',
    '注意:プリンタに未知のエラーコード #{error_code}。',
    '警告:印刷待ちジョブが多すぎます。',
    'エラー:プリンタが“{filename}”を印刷中にヒーター異常。',
    '重要:プリンタの用紙トレイが空です。',
    '指示:謎のトナーを補充してください。',
    '注意:プリンタが“{filename}”を認識できません。',
    'エラー:プリンタの出力トレイが詰まっています。',
    '警告:プリンタが休憩中です。しばらくお待ちください。',
    '重要:プリンタが“{filename}”で紙詰まり(第3給紙カセット)。',
    '注意:プリンタのネットワークが不安定です。',
    'エラー:印刷ジョブがタイムアウトしました。',
    '指示:プリンタのカバーを一度閉じてください。',
    '警告:プリンタが“{filename}”で不明な問題を検出。',
    '重要:プリンタのメモリが不足しています。',
    '注意:プリンタのIPアドレスが迷子です。',
    'エラー:プリンタが“{filename}”の印刷を拒否しました。',
]

# サンプルファイル名リスト
SAMPLE_FILENAMES = [
    'main.py', 'README.md', 'report.docx', 'data.csv', 'script.sh', 'notes.txt',
    'diagram.png', 'invoice.pdf', 'presentation.pptx', 'summary.xlsx', 'draft.tex',
    'archive.zip', 'config.yaml', 'logfile.log', 'thesis.doc', 'manual.pdf',
]

# エラーコード生成
ERROR_CODES = ['E42', 'JAM99', 'PAPER404', 'TNR-7', 'ERR-PRT', 'E-PRNTR', 'XJAM', 'CODE13']

# OS通知コマンド
NOTIFY_COMMANDS = [
    ['notify-send', '{title}', '{message}'],  # Linux
    ['osascript', '-e', 'display notification "{message}" with title "{title}"'],  # macOS
]

HISTORY = []


def random_filename():
    return random.choice(SAMPLE_FILENAMES)

def random_error_code():
    return random.choice(ERROR_CODES)

def random_message():
    template = random.choice(MESSAGE_TEMPLATES)
    msg = template.format(
        filename=random_filename(),
        error_code=random_error_code()
    )
    return msg

def send_notification(message, title='OS通知'):
    sent = False
    for cmd_tpl in NOTIFY_COMMANDS:
        try:
            cmd = [part.format(title=title, message=message) for part in cmd_tpl]
            # macOSのosascriptは全体を-eで渡す
            if cmd[0] == 'osascript':
                subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            else:
                subprocess.run(cmd, check=True)
            sent = True
            break
        except Exception:
            continue
    if not sent:
        print(f'[OS通知] {message}')


def log_event(message):
    now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    HISTORY.append({'timestamp': now, 'message': message})

def list_history():
    if not HISTORY:
        print('通知履歴はありません。')
        return
    for event in HISTORY:
        print(f"[{event['timestamp']}] {event['message']}")

def summary():
    print(f'通知履歴件数: {len(HISTORY)}')
    if HISTORY:
        print(f'最新: {HISTORY[-1]["timestamp"]} - {HISTORY[-1]["message"]}')


def random_interval(min_sec=30, max_sec=180):
    return random.randint(min_sec, max_sec)

def run_alert_loop(duration=None, max_count=None):
    """
    duration: ループを続ける秒数
    max_count: 最大通知回数
    """
    start = datetime.now()
    count = 0
    while True:
        if duration and (datetime.now() - start).total_seconds() > duration:
            break
        if max_count and count >= max_count:
            break
        interval = random_interval()
        time.sleep(interval)
        msg = random_message()
        send_notification(msg)
        log_event(msg)
        count += 1


def explicit_trigger():
    msg = random_message()
    send_notification(msg)
    log_event(msg)


def parse_args():
    parser = argparse.ArgumentParser(description='Fake Printer Jam Alert Skill')
    subparsers = parser.add_subparsers(dest='command')

    parser_run = subparsers.add_parser('run', help='ランダムなタイミングでプリンタ紙詰まり通知を発生させる')
    parser_run.add_argument('--duration', type=int, default=None, help='動作秒数(省略時は無限)')
    parser_run.add_argument('--max-count', type=int, default=None, help='最大通知回数')

    parser_explicit = subparsers.add_parser('alert', help='即座に1件通知を発生させる')

    parser_list = subparsers.add_parser('list', help='通知履歴を表示')
    parser_summary = subparsers.add_parser('summary', help='通知履歴の要約')

    return parser.parse_args()


def main():
    args = parse_args()
    if args.command == 'run':
        print('プリンタ紙詰まり通知ループを開始します...')
        try:
            run_alert_loop(duration=args.duration, max_count=args.max_count)
        except KeyboardInterrupt:
            print('\n中断されました。')
    elif args.command == 'alert':
        explicit_trigger()
    elif args.command == 'list':
        list_history()
    elif args.command == 'summary':
        summary()
    else:
        print('コマンドを指定してください (run/alert/list/summary)')

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
このSkillは、ユーザーの作業中に現実には発生しない“プリンタ紙詰まり”警告をOS通知として再現し、理不尽な演出や混乱を意図的に発生させるために設計されました。通知内容は完全ランダムで、毎回異なるファイル名やエラーコード、指示が含まれます。

# 公式ドキュメント抜粋
Linuxでは `notify-send`、macOSでは `osascript` を利用してOS通知を実現しています。仕様詳細は [Freedesktop Notification Spec](https://specifications.freedesktop.org/notification-spec/latest/) を参照。

# 利用例
- `/skills random-os-fake-printer-jam-alert alert` で即時通知
- `/skills random-os-fake-printer-jam-alert run --duration 600` で10分間ランダム通知

# 注意点
実際のプリンタや印刷処理には一切影響を与えません。通知APIが利用できない環境では標準出力に代替表示されます。

# 設計方針
理不尽さ・無関係さ・バリエーションを重視し、現実には起こりえない状況も積極的に演出します。履歴機能はセッション内のみ(永続化なし)で簡易実装。

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/codex/random-os-fake-printer-jam-alert .agents/skills/random-os-fake-printer-jam-alert

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

3. ファイル配置確認

ls .agents/skills/random-os-fake-printer-jam-alert
# 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連携Skillを試してみた結果 にまとめる予定 (公開準備中の場合あり)。
あわせて Codex 公式ドキュメント と、本シリーズ「Codexを使いこなすSkillアイデア」の他記事も参照のこと。

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

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

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

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