Antigravity ユーザーが日常でぶつかる悩み
Antigravity を日々使う開発者なら、コマンド実行時の「失敗」体験がどこか味気なく感じたことがあるはずです。AI coding workflow の中で、エラーが出るたびに淡々としたエラーメッセージだけが表示され、気持ちが沈みがちになる瞬間も少なくありません。特に monorepo や大規模 repository で作業していると、context や path management の煩雑さも相まって、コマンド失敗時の雰囲気がさらに重くなりがちです。
Antigravity の通知・演出系 Skill を活用することで、こうした「冷たい」開発体験を少しでも柔らかくしたい、というニーズは高まっています。日々の開発現場でよく遭遇する困りごとは以下の通りです。
- コマンド失敗時、無機質なエラーメッセージしか出ず、気分が落ち込む
- 長時間 workflow でエラーが続くと、自己肯定感が下がりやすい
- onboarding や session 再開時に、失敗理由をうまく説明できず雰囲気が重くなる
- repository understanding や path management でつまずいた時、ただ「失敗」とだけ出て流れが止まる
- AI coding workflow の中で、エラー時の context が薄く「何が起きたか」より「なぜ失敗したか」に目が行きがち
こうした状況を、もう少し楽しく前向きなものに変えられたらと思う方も多いのではないでしょうか。
この Skill が一言でいうと何を解決するか
一言サマリ: コマンド実行でエラーが出た時Skill。
この Skill を導入すると、Antigravity でコマンド実行に失敗した際、ただエラーメッセージを出すのではなく、OS の通知領域に“謎の言い訳”を自動で表示するようになります。これにより、開発現場の空気が一気に和らぎ、自己肯定感の維持やチーム内コミュニケーションにもプラス効果が期待できます。
- コマンド失敗時に毎回違うユーモラスな言い訳が自動表示され、開発 workflow の雰囲気が明るくなる
- repository や directory 構造が複雑な場面でも、失敗体験をポジティブに転換できる
- onboarding や session 再開時も、エラーに対する心理的ハードルが下がる
- 長時間の AI coding workflow でも、失敗を自己否定ではなく「運命」や「猫」のせいにできる
- 本来のエラーメッセージも参照できるため、問題解決の context は維持される
GitHub から degit でコマンド1行、Antigravity の Skill ディレクトリに展開できます。Node.js があれば即時に動きます。
npx degit aazutaku/ai-note/antigravity/command-failure-excuse-notifier .agent/skills/command-failure-excuse-notifier実行したらこうなる (3つの利用シーン)
この Skill の導入により、コマンド失敗時の体験がどのように変わるのか、具体的な利用シーン別にイメージしやすい出力例をまとめます。
シーン1: session 開始時 (プロジェクト初動で)
> npm run setup
[Antigravity] コマンド 'npm run setup' の実行に失敗しました。
Error: Cannot find module 'setup.js' in current directory.
【言い訳通知】「猫がキーボードを踏みました。今度はうまくいくかも?」
(通知領域にポップアップ表示)
ヒント: Skill の中身を全部見せる
.agent/skills/command-failure-excuse-notifier/ に配置するファイル一覧です。GitHub に push 済みなので、上記の degit コマンドで一発取得できます。
.agent/skills/command-failure-excuse-notifier/
├── SKILL.md
├── scripts/
│ └── command_failure_excuse_notifier.py
└── references/
└── reference.md
各ファイルの役割
ファイル
役割
SKILL.md
Skill本体。frontmatter (name/description) と指示本文。Antigravity がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/command_failure_excuse_notifier.py
指定コマンドを実行し、失敗時に言い訳通知を送る
references/reference.md
概要 をまとめた参考資料
SKILL.md
---
name: command-failure-excuse-notifier
description: コマンド実行やスクリプト動作時にエラーや失敗メッセージが発生した場合、このSkillは自動的にOSの通知領域へ“言い訳”メッセージを表示します。失敗・エラー・例外・command not found・exit code!=0 などのキーワードが検知された際に発動します。
---
# 機能概要
コマンド実行やスクリプト動作時、ただエラーメッセージを表示するだけでは味気ないもの。このSkillは、実行失敗時にOSの通知領域へ“全力の言い訳”を自動表示します。例えば「猫がキーボードを踏みました」「宇宙線の影響です」など、毎回異なるユーモラスなメッセージで、失敗体験を楽しく演出。自己肯定感を損なわず、開発作業のストレスを軽減します。
# 使い方
このSkillは明示的な呼び出しを必要とせず、Antigravityがコマンド失敗・例外・exit code!=0・command not found・エラー発生などを検知した際に自動発動します。スクリプトやCLIツールの実行時、失敗検知時に自動で通知が表示されます。
# 出力例
```
$ python build.py
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
[通知] 言い訳: 猫がキーボードを踏みました
$ make deploy
make: *** [deploy] Error 2
[通知] 言い訳: 宇宙線がビットをひっくり返しました
```
# 注意点
- OS通知はWindows/macOS/Linuxの主要デスクトップ環境でサポートされますが、サーバやWSL等では通知が表示されない場合があります。
- 言い訳メッセージはランダム生成され、同じ失敗でも毎回異なります。
- 本来のエラーメッセージは失われず、通知とは別に標準出力/標準エラーに出力されます。
- ローカルに通知履歴は保存されません。
# 参考資料
詳細設計や言い訳メッセージ例、OSごとの通知API利用例は references/ 以下および https://docs.python.org/ja/3/library/subprocess.html, https://pypi.org/project/plyer/ などを参照してください。
scripts/command_failure_excuse_notifier.py
import argparse
import subprocess
import sys
import random
import platform
import threading
import time
try:
from plyer import notification
except ImportError:
notification = None
EXCUSES = [
'猫がキーボードを踏みました',
'宇宙線がビットをひっくり返しました',
'運命のせいです',
'今日は水星逆行です',
'AIの気まぐれです',
'ネットワークの妖精が悪さをしました',
'コーヒーが足りません',
'コードの神様が休暇中です',
'机の上のホコリが原因です',
'月の引力の影響です',
'時間軸がずれました',
'サーバの気分が乗りません',
'開発者のせいではありません',
'電子の流れが逆でした',
'世界線が違いました'
]
HISTORY = []
def send_notification(title, message):
if notification is not None:
try:
notification.notify(title=title, message=message, timeout=5)
except Exception as e:
print(f'[通知失敗] {e}', file=sys.stderr)
else:
# Fallback: print to stderr
print(f'[通知] {title}: {message}', file=sys.stderr)
def run_command(cmd_args):
"""指定コマンドを実行し、失敗時に言い訳通知を送る"""
try:
proc = subprocess.run(cmd_args, capture_output=True, text=True)
stdout, stderr = proc.stdout, proc.stderr
if proc.returncode != 0:
excuse = random.choice(EXCUSES)
send_notification('言い訳', excuse)
HISTORY.append({'cmd': ' '.join(cmd_args), 'excuse': excuse, 'rc': proc.returncode, 'stderr': stderr.strip(), 'time': time.time()})
sys.stderr.write(stderr)
sys.exit(proc.returncode)
else:
sys.stdout.write(stdout)
except FileNotFoundError as e:
excuse = random.choice(EXCUSES)
send_notification('言い訳', excuse)
HISTORY.append({'cmd': ' '.join(cmd_args), 'excuse': excuse, 'rc': 127, 'stderr': str(e), 'time': time.time()})
print(f'command not found: {cmd_args[0]}', file=sys.stderr)
sys.exit(127)
except Exception as e:
excuse = random.choice(EXCUSES)
send_notification('言い訳', excuse)
HISTORY.append({'cmd': ' '.join(cmd_args), 'excuse': excuse, 'rc': 1, 'stderr': str(e), 'time': time.time()})
print(f'error: {e}', file=sys.stderr)
sys.exit(1)
def list_history():
if not HISTORY:
print('通知履歴はありません')
return
for idx, item in enumerate(HISTORY):
t = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(item['time']))
print(f"[{idx+1}] {t} コマンド: {item['cmd']} | 言い訳: {item['excuse']} | RC: {item['rc']}")
if item['stderr']:
print(f" エラー: {item['stderr']}")
def summary():
print(f'通知回数: {len(HISTORY)}')
if HISTORY:
reasons = {}
for h in HISTORY:
reasons[h['excuse']] = reasons.get(h['excuse'], 0) + 1
print('言い訳ランキング:')
for excuse, count in sorted(reasons.items(), key=lambda x: -x[1]):
print(f' {excuse}: {count}回')
def main():
parser = argparse.ArgumentParser(description='コマンド失敗時に言い訳を通知するツール')
subparsers = parser.add_subparsers(dest='command')
parser_run = subparsers.add_parser('run', help='コマンドを実行し、失敗時に言い訳通知')
parser_run.add_argument('cmd', nargs=argparse.REMAINDER, help='実行するコマンド')
parser_list = subparsers.add_parser('list', help='通知履歴を表示')
parser_summary = subparsers.add_parser('summary', help='通知履歴のサマリー')
args = parser.parse_args()
if args.command == 'run':
if not args.cmd:
print('コマンドを指定してください', file=sys.stderr)
sys.exit(2)
run_command(args.cmd)
elif args.command == 'list':
list_history()
elif args.command == 'summary':
summary()
else:
parser.print_help()
if __name__ == '__main__':
main()
references/reference.md
# 概要
このSkillは、コマンド失敗時にOS通知領域へ“全力の言い訳”を表示し、失敗体験を前向きに変えることを目的としています。Pythonのsubprocessとplyerライブラリを組み合わせ、クロスプラットフォームで動作します。
# 公式ドキュメント抜粋
- subprocess: https://docs.python.org/ja/3/library/subprocess.html
- plyer (OS通知): https://plyer.readthedocs.io/en/latest/
# 利用例
- `python command_failure_excuse_notifier.py run ls /notfound`
- `python command_failure_excuse_notifier.py list`
- `python command_failure_excuse_notifier.py summary`
# 注意点
- plyerが未インストールの場合、通知は標準エラー出力にフォールバックします。
- サーバやCUI専用環境では通知が表示されない場合があります。
- 通知履歴はプロセスごとに保持され、永続保存はされません。
# 設計方針
- 言い訳メッセージは毎回ランダム生成。
- 本来のエラー出力は失われず、標準出力/標準エラーにそのまま出力。
- 複数サブコマンド(run/list/summary)で柔軟な利用を実現。
導入手順
このSkillは GitHub で管理されているので、degit を使えば必要なフォルダだけを1コマンドで取得できます。Antigravity はファイル配置後に再起動するだけで自動認識します。
1. 前提
- Node.js v16 以上 (
degit 実行に必要)
- Antigravity がローカルで動いていること
2. degit でフォルダ取得
プロジェクトのルートで以下のコマンドを実行します。
npx degit aazutaku/ai-note/antigravity/command-failure-excuse-notifier .agent/skills/command-failure-excuse-notifier
.agent/skills/command-failure-excuse-notifier の中に SKILL.md / scripts/ / references/ / README.md が展開されます。
3. ファイル配置確認
ls .agent/skills/command-failure-excuse-notifier
# 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 でも有効か?
- プロジェクト指示との連携をどう組み立てるか?
- OSごとの通知表示が正常に機能するか?
- 言い訳メッセージが毎回違う内容になるか?
- 本来のエラーメッセージは失われず参照できるか?
実際に Antigravity で試した検証ログは Antigravityの通知機能でコマンド失敗時に面白言い訳を表示してみた にまとめる予定 (公開準備中の場合あり)。
あわせて Antigravity 公式ドキュメント と、本シリーズ「Antigravityで試したいSkill研究」の他記事も参照のこと。
関連タグで他のSkill記事を探す
本記事に付いているタグから、気になるテーマの記事を探せます。タグページで関連記事をまとめて読めるので、ぜひチェックしてみてください!
