Claude Codeでエラーメッセージを詩に変換するSkillの作り方解説

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

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

Claude Code を使ったコーディングやリポジトリ管理の作業中、思いがけないエラーや警告が突然現れて作業の流れが止まることは日常茶飯事です。特にターミナルやエディタ上でコマンドを実行した際、無機質で味気ないエラーメッセージが並ぶと、緊張感が一気に高まったり、疲れがどっと押し寄せることも少なくありません。
また、ジョークやパロディ要素がほしい場面でも、Claude Code は基本的に真面目な出力が中心。少し肩の力を抜きたいときや、チームの雰囲気を和らげたいときに「遊び心」を感じさせる仕掛けがほしいという声もあります。
Claude Code 固有の context や path management の悩みとあわせて、こんな「あるある」を感じているユーザーも多いはずです。

  • エラーが出るたびに、無機質なメッセージばかりで気分が沈みがち
  • 長時間のAI coding workflowで集中力が切れたとき、ふとした息抜きがほしい
  • onboarding や session 再開時、context がリフレッシュされず単調なやり取りになりやすい
  • monorepo で directory や repository 構造を説明し直す場面が続くと、会話が堅苦しくなりがち
  • 「また同じエラーか…」と感じた瞬間、少しでもユーモアや変化がほしい

こうした「エラーの瞬間に、ちょっとした遊び心を感じたい」「作業の合間に脳をほぐしたい」というニーズに応える Skill が求められています。

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

一言サマリ: ターミナルやエディタでコマンド実行時にエラーが発生したらSkill。

この Skill を導入することで、日々の Claude Code 利用体験が次のように変化します:

  • エラーメッセージが唐突に詩的な表現へと変換され、作業中に思わず笑ってしまうユーモアが生まれる
  • 長時間の repository understanding や path management の合間に、脳をリフレッシュできる
  • onboarding や session 再開時の堅苦しい雰囲気を和らげ、チームメンバーとの会話のきっかけにもなる
  • monorepo や複雑な directory 構造で発生するエラーも、壮大なポエムで彩られ印象に残る
  • AI coding workflow の中で「エラー=嫌なもの」というイメージを転換し、前向きな気持ちで作業を継続できる
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/claude-code/random-os-error-poetry .claude/skills/random-os-error-poetry

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

Skill を導入すると、普段見慣れたエラーメッセージが「壮大な詩」へと変換されます。以下はその利用シーン例です。

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


# /random-os-error-poetry
> poetry install

Oh、許されぬ権限よ、我が手にパーミッションを  
root の門は固く閉ざされ、  
鍵なき旅人は彷徨うのみ  
「Permission denied」  
この行は詩の一節、  
再び sudo の名を唱えよ  
原文: [Errno 13] Permission denied: 'pyproject.toml'

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


> cd packages/auth && poetry run pytest

見つからぬ道、404の黄昏  
auth の彼方、test の光は遠く  
「No module named 'tests'」  
package の狭間で名を呼ぶ  
repo の記憶よ、今一度  
原文: ModuleNotFoundError: No module named 'tests'

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


> poetry run python main.py

Syntax の海に沈む我が願い  
閉じぬ括弧、流れる涙  
「SyntaxError: unexpected EOF while parsing」  
コードの詩人よ、構文を閉じて  
明日へと続く物語  
原文: SyntaxError: unexpected EOF while parsing

before / after の違い

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

発動方式

明示呼び出し (/random-os-error-poetry) と暗黙発動 (エラーメッセージ検出時に自動) の両方に対応。

Skill の中身を全部見せる

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

.claude/skills/random-os-error-poetry/
├── SKILL.md
├── scripts/
│   └── random_os_error_poetry.py
└── references/
    └── design_notes.md

各ファイルの役割

ファイル 役割
SKILL.md Skill本体。frontmatter (name/description) と指示本文。Claude Code がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/random_os_error_poetry.py エラーメッセージから例外名とパス(あれば)を抽出する
references/design_notes.md 概要 をまとめた参考資料

SKILL.md

---
name: random-os-error-poetry
description: コマンド実行やファイル操作などで発生したOSエラー(例: PermissionError, FileNotFoundError, OSError)を検知した際、自動的に詩的なエラーメッセージへ変換して表示します。エラー発生時や'/random-os-error-poetry'明示呼び出しで発動します。
---

# 機能概要
`random-os-error-poetry`は、ターミナルやエディタ上でコマンド実行時に発生する各種OSエラー(ファイル未発見、パーミッション拒否、I/Oエラーなど)を検知し、その内容を重厚な詩へと即興変換して表示するスキルです。従来の味気ないエラーメッセージを、思わず笑ってしまう壮大なポエムに変換することで、作業中のストレスや疲労を和らげます。真面目な開発現場にユーモアと創造性をもたらし、エラー内容の本質も詩的に伝達します。

# 使い方
- 明示呼び出し例: `/random-os-error-poetry "PermissionError: [Errno 13] Permission denied: '/etc/passwd'"`
- 暗黙発動キーワード例: `PermissionError`, `FileNotFoundError`, `OSError`, `No such file or directory`, `IsADirectoryError` などのエラー発生時に自動発動します。

# 出力例
```
$ python script.py
許されぬ権限よ、我が手にパーミッションを。
閉ざされた門の向こうに、/etc/passwdの夢。
[原文: PermissionError: [Errno 13] Permission denied: '/etc/passwd']

$ cat missing.txt
見つからぬ道、404の黄昏。
失われしファイル、missing.txtは幻。
[原文: FileNotFoundError: [Errno 2] No such file or directory: 'missing.txt']
```

# 注意点
- 本SkillはOSエラー例外のみを対象とし、SyntaxErrorやネットワーク系エラー等は詩化しません。
- 原文エラーメッセージも併記されるため、実際のトラブルシュートを妨げません。
- 詩の生成はランダム性を含むため、同じエラーでも毎回異なる表現になる場合があります。
- ローカルファイル等への自動保存は行いません。

# 参考資料
本SkillはPythonの組み込み例外クラス([OSError](https://docs.python.org/ja/3/library/exceptions.html#OSError)等)を対象としています。詩的変換ロジックや設計方針の詳細は`references/design_notes.md`を参照してください。

scripts/random_os_error_poetry.py

import sys
import argparse
import traceback
import random
import os
from typing import Optional, Tuple, List

POETIC_TEMPLATES = [
    (
        'PermissionError',
        [
            '許されぬ権限よ、我が手にパーミッションを。',
            '閉ざされた門の向こうに、{path}の夢。',
            '鉄の扉は静かに拒む、我が願いを。',
            'この道は選ばれし者のみが歩む。',
        ]
    ),
    (
        'FileNotFoundError',
        [
            '見つからぬ道、404の黄昏。',
            '失われしファイル、{path}は幻。',
            '探し求めし{path}、風の中に消ゆ。',
            '存在しないページに、我は問いかける。',
        ]
    ),
    (
        'IsADirectoryError',
        [
            '{path}はディレクトリなり、ファイルの仮面を脱ぎ捨てて。',
            '道を誤りし者よ、ディレクトリの深淵へ。',
            'ファイルと思いし{path}、実は広き箱庭。',
        ]
    ),
    (
        'NotADirectoryError',
        [
            '{path}は道にあらず、行き止まりの石壁。',
            'ディレクトリたらんとした{path}、しかし叶わず。',
        ]
    ),
    (
        'OSError',
        [
            'OSの叫び、見えざる力が我を阻む。',
            '予期せぬ障壁、システムの深奥より。',
            '機械仕掛けの運命に翻弄される我が手。',
        ]
    ),
]

def parse_error_message(msg: str) -> Tuple[str, Optional[str]]:
    """
    エラーメッセージから例外名とパス(あれば)を抽出する。
    """
    for exc, _ in POETIC_TEMPLATES:
        if exc in msg:
            # パス抽出(簡易)
            parts = msg.split(":")
            path = None
            for part in parts:
                if "'" in part:
                    path = part.split("'")[1]
                    break
            return exc, path
    # OSError系以外
    return 'OSError', None

def poeticize_error(msg: str) -> str:
    exc, path = parse_error_message(msg)
    for template_exc, templates in POETIC_TEMPLATES:
        if exc == template_exc:
            lines = []
            for tmpl in random.sample(templates, min(2, len(templates))):
                if '{path}' in tmpl and path:
                    lines.append(tmpl.format(path=path))
                else:
                    lines.append(tmpl)
            poetic = "\n".join(lines)
            return f"{poetic}\n[原文: {msg}]"
    # fallback
    return f"OSの詩情: {msg}"

def run_cli():
    parser = argparse.ArgumentParser(
        description='OSエラーを詩的に変換して表示します。')
    parser.add_argument('error', nargs='?', help='エラーメッセージ文字列(省略時は標準入力)')
    parser.add_argument('--log', action='store_true', help='詩化したメッセージをエラー履歴として保存')
    parser.add_argument('--list', action='store_true', help='詩化エラーログを一覧表示')
    parser.add_argument('--summary', action='store_true', help='詩化エラーの種類統計を表示')
    args = parser.parse_args()

    log_path = os.path.expanduser('~/.random_os_error_poetry.log')

    if args.list:
        if os.path.exists(log_path):
            with open(log_path, 'r', encoding='utf-8') as f:
                print(f.read())
        else:
            print('まだエラーログはありません。')
        return
    if args.summary:
        if os.path.exists(log_path):
            counts = {}
            with open(log_path, 'r', encoding='utf-8') as f:
                for line in f:
                    for exc, _ in POETIC_TEMPLATES:
                        if exc in line:
                            counts[exc] = counts.get(exc, 0) + 1
            if counts:
                print('エラー詩の種類統計:')
                for k, v in counts.items():
                    print(f'  {k}: {v}件')
            else:
                print('統計情報がありません。')
        else:
            print('まだエラーログはありません。')
        return

    if args.error:
        msg = args.error
    else:
        msg = sys.stdin.read().strip()
    poetic = poeticize_error(msg)
    print(poetic)
    if args.log:
        with open(log_path, 'a', encoding='utf-8') as f:
            f.write(poetic.replace('\n', ' ') + '\n')

def main():
    try:
        run_cli()
    except Exception as e:
        tb = traceback.format_exc()
        print(poeticize_error(f"OSError: {e}\n{tb}"))

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
`random-os-error-poetry`は、OSエラーを詩的かつユーモラスに変換することで、開発現場の雰囲気を和らげることを目的としています。主にPythonの標準例外(PermissionError, FileNotFoundError, OSError等)を対象にしています。

# 公式ドキュメント抜粋
- [Python 組み込み例外](https://docs.python.org/ja/3/library/exceptions.html)
- [OSError](https://docs.python.org/ja/3/library/exceptions.html#OSError)

# 利用例
- ターミナルやエディタでコマンド失敗時の出力を詩化。
- `/random-os-error-poetry "FileNotFoundError: [Errno 2] No such file or directory: 'foo.txt'"` のように明示呼び出し。
- `--log`で履歴保存、`--list`で詩化エラー一覧、`--summary`で統計表示。

# 注意点
- エラー原文も必ず併記されるため、詩化による情報損失はありません。
- 詩のテンプレートはランダム選択され、同じエラーでも多様な表現が楽しめます。
- ネットワークエラーや構文エラー等、OS例外以外は対象外です。

# 設計方針
例外ごとに複数の詩的テンプレートを用意し、エラー発生時にパス等の情報を埋め込んで即興詩を生成します。CLIサブコマンドで履歴や統計も管理でき、日々の開発に遊び心を提供します。

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/claude-code/random-os-error-poetry .claude/skills/random-os-error-poetry

.claude/skills/random-os-error-poetry の中に SKILL.md / scripts/ / references/ / README.md が展開されます。

3. ファイル配置確認

ls .claude/skills/random-os-error-poetry
# SKILL.md, scripts/, references/, README.md があればOK

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

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

5. 動作確認

/random-os-error-poetry で呼び出すか、自然言語で発動条件にマッチする指示を出すと 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をコピーしました!
目次