Antigravityでコミット失敗時の俳句自動生成を楽しむ方法

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

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

Antigravity を日々の AI coding workflow に活用していると、思いがけないところで小さなストレスが積み重なります。特に repository understanding や path management が絡む作業では、context のズレや directory 境界の誤認識も起こりがちです。そんな中、git commit 操作で失敗したときの空気感は独特です。単なるエラー表示が並ぶだけでは、気持ちの切り替えもうまくいきません。

  • Antigravity が context を見失って違う場所のコードを参照する
  • monorepo で package を跨いだ瞬間、Antigravity が repo 構造を忘れる
  • session を再開すると、前回までの context や path 指定をまるごと再説明しないといけない
  • 長時間 workflow で long context が膨らみすぎて、important な情報が薄まる (stale context)
  • コミット失敗時、ただエラーが流れるだけで場が重くなりがち。ちょっとした和み要素が欲しい

特に、エラー時に気まずい沈黙が流れる瞬間は、ジョークやパロディ系 Skill の出番です。

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

一言サマリ: コミットが失敗したときSkill。

この Skill を入れることで、コミット失敗時の「ただエラーが流れるだけ」の空気が一変します。具体的には:

  • git commit 失敗時、エラー内容や状況をもとに Antigravity が自動で俳句を生成し、ターミナルに表示
  • 毎回異なる五・七・五の一句が出るので、単調なエラー体験にバリエーションとユーモアが生まれる
  • エラーの内容や repository の directory 構造を俳句に織り込むことで、context を自然に振り返るきっかけになる
  • 長い session や monorepo 作業で workflow が煮詰まったときも、気持ちを切り替えやすい
  • onboarding やチーム作業でも、エラー時の重苦しさを和らげて場を和ませる
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/antigravity/commit-failure-haikuizer .agent/skills/commit-failure-haikuizer

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

この Skill はコミット失敗時に自動で発動し、状況に応じた俳句を表示します。以下はその出力例です。

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


> git commit -m "init: add base structure"

error: path 'src/config.js' does not exist in the working directory

俳句:
初 commit
見つからぬ道
src の奥

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


> git commit -m "fix: update utils in packages/core"

error: Your branch is behind 'origin/main' by 2 commits, and can be fast-forwarded.

一句:
monorepo
追いつけぬまま
core さみし

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


> git commit -m "chore: clean up"

error: commit message missing required ticket number

五七五:
チケットなし
流れる汗と
空 push

before / after の違い

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

発動方式

description マッチでの暗黙発動。

Skill の中身を全部見せる

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

.agent/skills/commit-failure-haikuizer/
├── SKILL.md
├── scripts/
│   └── commit_failure_haikuizer.py
└── references/
    └── design_notes.md

各ファイルの役割

ファイル 役割
SKILL.md Skill本体。frontmatter (name/description) と指示本文。Antigravity がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/commit_failure_haikuizer.py commit-failure-haikuizer: gitエラー時に俳句を生成
references/design_notes.md 概要 をまとめた参考資料

SKILL.md

---
name: commit-failure-haikuizer
description: git commitやpushなどのバージョン管理操作でエラーや失敗が発生した際に、エラーメッセージをもとに五・七・五の俳句へ自動変換し、ターミナルに表示するSkillです。エラー発生時に自動で発動します。
---

# 機能概要
commit-failure-haikuizerは、gitのcommitやpush等でエラーが発生した際、単なるエラーメッセージの表示だけでなく、その内容や状況をもとに五・七・五形式の俳句を自動生成し、ターミナルへ出力します。これにより、繰り返される失敗やトラブルの瞬間にも、ユーモアや哀愁が漂う一句で場の空気を和ませ、開発者の気持ちを少し軽くします。毎回異なる俳句が生成されるため、飽きずに楽しめます。

# 使い方
このSkillは、git commit/push/pullなどの失敗時に自動で発動します(明示的な呼び出しは不要)。エラー発生時、エラーメッセージや状況をもとに俳句が生成され、標準出力に表示されます。

**暗黙発動キーワード例:**
- commit failed
- push rejected
- merge conflict
- authentication error

# 出力例
```
$ git push origin main
error: failed to push some refs to 'origin/main'

俳句:
遠いリモート
拒まれしpush
明日こそは

$ git commit -m 'fix bug'
error: pathspec 'fix bug' did not match any file(s) known to git

俳句:
ファイルなし
静かなリポジトリ
手が止まる
```

# 注意点
- 俳句の品質はエラーメッセージ内容や自動生成ロジックに依存します。
- 日本語エラー以外もサポートしますが、意味不明な句になる場合があります。
- 生成された俳句はローカルに保存されません。
- 一部の特殊なエラーは正しく俳句化できない場合があります。

# 参考資料
- [Git公式ドキュメント](https://git-scm.com/doc)
- references/design_notes.md を参照してください。

scripts/commit_failure_haikuizer.py

import sys
import subprocess
import random
import re
import argparse
from datetime import datetime

HAIKU_TEMPLATES = [
    ["{error_short}", "{context}", "{hope}"],
    ["{context}", "{error_short}", "{advice}"],
    ["{emotion}", "{error_short}", "{next_time}"],
    ["{error_short}", "{advice}", "{emotion}"],
    ["{context}", "{emotion}", "{hope}"],
]

ERROR_SHORT_LIST = [
    "pushできず",
    "競合あり",
    "認証失敗",
    "ファイルなし",
    "拒まれる",
    "エラーなり",
    "差分なし",
    "リモート遠し",
    "HEAD迷子",
    "権限なし",
]

CONTEXT_LIST = [
    "静かな夜",
    "遠いリモート",
    "手が止まる",
    "誰もいない",
    "branch違い",
    "静かなrepo",
    "深夜のcommit",
    "朝焼けの中",
    "黙るターミナル",
    "一人きり",
]

HOPE_LIST = [
    "明日こそは",
    "またtry",
    "次は成功",
    "やり直そう",
    "もう一度",
    "希望持つ",
    "心静かに",
    "再挑戦",
    "歩み出す",
    "次のpush",
]

ADVICE_LIST = [
    "pullしてから",
    "addを忘れず",
    "status見て",
    "fetchしよう",
    "resetしよう",
    "branch確認",
    "rebase注意",
    "commitまとめて",
    "stash活用",
    "メッセージ丁寧に",
]

EMOTION_LIST = [
    "ため息を",
    "苦笑い",
    "哀しみよ",
    "焦りつつ",
    "静かな怒り",
    "戸惑いも",
    "孤独な夜",
    "諦めず",
    "涙ひとつ",
    "心折れず",
]

NEXT_TIME_LIST = [
    "次こそは",
    "また明日",
    "歩み続け",
    "希望抱き",
    "もう一度",
    "再び挑む",
    "明日は晴れ",
    "前を向く",
    "リトライを",
    "進みゆく",
]

def extract_error_short(msg):
    for key in ["push", "merge", "auth", "file", "HEAD", "permission", "remote", "branch", "conflict", "error"]:
        if key in msg.lower():
            for phrase in ERROR_SHORT_LIST:
                if key in phrase:
                    return phrase
    return random.choice(ERROR_SHORT_LIST)

def extract_context(msg):
    if "remote" in msg.lower():
        return "遠いリモート"
    if "branch" in msg.lower():
        return "branch違い"
    if "file" in msg.lower():
        return "ファイルなし"
    if "conflict" in msg.lower():
        return "競合あり"
    return random.choice(CONTEXT_LIST)

def extract_hope(msg):
    return random.choice(HOPE_LIST)

def extract_advice(msg):
    return random.choice(ADVICE_LIST)

def extract_emotion(msg):
    return random.choice(EMOTION_LIST)

def extract_next_time(msg):
    return random.choice(NEXT_TIME_LIST)

def generate_haiku(error_msg):
    template = random.choice(HAIKU_TEMPLATES)
    mapping = {
        "error_short": extract_error_short(error_msg),
        "context": extract_context(error_msg),
        "hope": extract_hope(error_msg),
        "advice": extract_advice(error_msg),
        "emotion": extract_emotion(error_msg),
        "next_time": extract_next_time(error_msg),
    }
    lines = [t.format(**mapping) for t in template]
    return lines

def print_haiku(haiku_lines):
    print("\n俳句:")
    for line in haiku_lines:
        print(line)

def run_git_command(args):
    try:
        completed = subprocess.run(["git"] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        if completed.returncode != 0:
            error_msg = completed.stderr.strip() or completed.stdout.strip()
            print(completed.stderr)
            haiku_lines = generate_haiku(error_msg)
            print_haiku(haiku_lines)
            sys.exit(completed.returncode)
        else:
            print(completed.stdout)
    except Exception as e:
        print(f"Unexpected error: {e}")
        haiku_lines = generate_haiku(str(e))
        print_haiku(haiku_lines)
        sys.exit(1)

def log_haiku(error_msg, haiku_lines):
    with open(".commit_failure_haiku.log", "a", encoding="utf-8") as f:
        f.write(f"[{datetime.now()}] {error_msg}\n")
        for l in haiku_lines:
            f.write(l + "\n")
        f.write("\n")

def list_haiku_logs():
    try:
        with open(".commit_failure_haiku.log", "r", encoding="utf-8") as f:
            print(f.read())
    except FileNotFoundError:
        print("No haiku logs found.")

def summary_haiku_logs():
    try:
        with open(".commit_failure_haiku.log", "r", encoding="utf-8") as f:
            logs = f.read().split("\n\n")
            print(f"Total haiku entries: {len([l for l in logs if l.strip()])}")
    except FileNotFoundError:
        print("No haiku logs found.")

def main():
    parser = argparse.ArgumentParser(description="commit-failure-haikuizer: gitエラー時に俳句を生成")
    subparsers = parser.add_subparsers(dest="command")

    parser_run = subparsers.add_parser("run", help="gitコマンドをラップして実行")
    parser_run.add_argument("git_args", nargs=argparse.REMAINDER, help="gitコマンド引数")

    parser_list = subparsers.add_parser("list", help="生成された俳句ログを表示")
    parser_summary = subparsers.add_parser("summary", help="俳句ログのサマリー表示")

    args = parser.parse_args()
    if args.command == "run":
        run_git_command(args.git_args)
    elif args.command == "list":
        list_haiku_logs()
    elif args.command == "summary":
        summary_haiku_logs()
    else:
        parser.print_help()

if __name__ == "__main__":
    main()

references/design_notes.md

# 概要
commit-failure-haikuizerは、git操作の失敗時にエラーメッセージをもとに俳句を自動生成し、開発現場にユーモアと癒しをもたらすためのSkillです。

# 公式ドキュメント抜粋
- Git公式: https://git-scm.com/doc
- Python subprocess: https://docs.python.org/3/library/subprocess.html

# 利用例
- pushやcommit失敗時、即座に五・七・五の俳句が表示され、エラーの重さを和らげます。
- チーム開発での小ネタや、ペアプロ・レビュー時のアイスブレイクにも活用可能です。

# 注意点
- 俳句の内容はエラー文脈から自動生成されるため、必ずしも文意が正確とは限りません。
- ログは .commit_failure_haiku.log に追記されますが、容量肥大に注意してください。

# 設計方針
- テンプレートとランダム選択を組み合わせ、毎回異なる句を生成。
- サブコマンド(run/list/summary)で操作性を確保。
- 日本語エラー・英語エラー双方に対応し、汎用性を重視しています。

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/antigravity/commit-failure-haikuizer .agent/skills/commit-failure-haikuizer

.agent/skills/commit-failure-haikuizer の中に SKILL.md / scripts/ / references/ / README.md が展開されます。

3. ファイル配置確認

ls .agent/skills/commit-failure-haikuizer
# SKILL.md, scripts/, references/, README.md があればOK

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

新しいSkillが自動で認識されます。リスト確認したい場合は Antigravity に「使えるSkill一覧を見せて」と聞く と Skill 名で出てきます。

5. 動作確認

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

こんな瞬間に便利

  • session 開始時: 前回までの repo 把握を Antigravity に一発で復元させたい
  • monorepo 移動時: packages を跨いだ瞬間に context を切り替えたい
  • onboarding 時: 新しい repo を Antigravity に把握させ、こちらが 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 コードを拾ってしまう可能性
  • Antigravity 固有の引っかかり: description のセマンティックマッチ精度が要件次第
  • 発動しないケース: description が漠然 / 他の Skill が優先 / git管理外 directory
  • 俳句生成の品質: 五・七・五のフォーマットが崩れる場合や、内容がワンパターンになる可能性

試す前に確かめたいこと

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

  • 実 repo での token 消費は許容範囲か?
  • monorepo (packages 多数) で安定して動くか?
  • stale context にならず、長時間 workflow でも有効か?
  • プロジェクト指示との連携をどう組み立てるか?
  • コミット失敗時に必ず一句が出るか、五・七・五が守られているか?
  • 毎回異なる俳句が生成され、飽きずに使い続けられるか?

実際に Antigravity で試した検証ログは Antigravityでコミット失敗時に俳句を表示してみた!笑えるエラー体験 にまとめる予定 (公開準備中の場合あり)。
あわせて Antigravity 公式ドキュメント と、本シリーズ「Antigravityで試したいSkill研究」の他記事も参照のこと。

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

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

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

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