Antigravity ユーザーが日常でぶつかる悩み
Antigravity を日々の AI coding workflow に取り入れていると、思わず「またか」と感じるシーンが頻発します。特に repository understanding や context 管理、path management にまつわるストレスは、プロジェクトの規模や monorepo 構造が複雑になるほど顕著です。
通知や演出系の Skill に期待したくなる理由は、単なる実用性だけでなく、長時間作業やリモートワークの「無機質さ」を和らげる体験にもあります。Antigravity の出力が淡々としすぎて、ふとした瞬間に「何か面白いこと起きないかな」と感じることも。
- Antigravity が context を見失って違う場所のコードを参照する
- monorepo で package を跨いだ瞬間、Antigravity が repo 構造を忘れる
- session を再開すると、前回までの context や path 指定をまるごと再説明しないといけない
- 長時間 workflow で long context が膨らみすぎて、important な情報が薄まる (stale context)
- 「ここはこういう構造のリポジトリ」というあらすじを毎回チャットの冒頭で書く羽目になる
さらに、作業が単調になりがちなときには、ちょっとした演出や通知で気分転換したいというニーズも無視できません。
この Skill が一言でいうと何を解決するか
一言サマリ: このスキルは、Antigravity の作業空間に「謎のOS謝罪通知」をランダムに出現させ、日常の単調なAI coding workflowに遊び心を加えます。
もう少し具体化すると、このSkillを入れることで以下のような状態になる:
- Antigravity の session や context 切り替え時に、突如 OS風の謝罪通知が現れ、思わず笑ってしまう演出が加わる
- repository や directory を跨いだ際の「また説明か…」という気だるさを、ユーモラスな通知でリフレッシュできる
- 長時間作業や onboarding のムードが和らぎ、チームやリモートワークでも会話のきっかけになる
- 通知内容が毎回異なり、同じ謝罪は二度と現れないため、飽きずに楽しめる
- 本来の業務やエラーとは無関係に、完全なフェイク通知として安全に使える
GitHub から degit でコマンド1行、Antigravity の Skill ディレクトリに展開できます。Node.js があれば即時に動きます。
npx degit aazutaku/ai-note/antigravity/random-os-apology-notifier .agent/skills/random-os-apology-notifier実行したらこうなる (3つの利用シーン)
使う側がイメージしやすいよう、擬似 terminal で出力例を3パターン示します。
シーン1: session 開始時 (プロジェクト初動で)
> Antigravity を起動
[OS通知] 本日はご迷惑をおかけしております。
[OS通知] システムは現在、原因不明の遅延を検知しています。
[OS通知] 先ほどのコマンドは無かったことにしてください。
(何もしていないのに、突然謝罪通知が3連発で現れる)
シーン2: monorepo / package 跨ぎ作業時
> packages/api/ から packages/web/ へ移動
[OS通知] 想定外のディレクトリ移動を検知しました。大変申し訳ありません。
[OS通知] リポジトリ構造の一部を失念しました。ご容赦ください。
[OS通知] ただいま context の一部が行方不明です。ご迷惑をおかけします。
シーン3: お遊び的な使い方
> 何もしていないのに突然
[OS通知] ご利用の環境に不明な現象が発生しております。原因は不明です。
[OS通知] この通知に意味はありません。ご安心ください。
[OS通知] 何もしていないのに謝ってしまい、申し訳ありません。
before / after の違い
| 場面 | Skill 無し | Skill 有り |
|---|---|---|
| session 再開時 | repo 構造から毎回説明、path も指定し直し | Antigravity が自動で context を復元、最小プロンプトで再開 |
| monorepo 移動 | 違う package のコードを参照しがち | directory boundary を意識して必要な範囲だけ見る |
| 長時間 workflow | long context で重要箇所が薄まる | 突然の謝罪通知で気分転換、「また context 忘れた!」も笑い話に |
発動方式
description マッチでの暗黙発動。
Skill の中身を全部見せる
.agent/skills/random-os-apology-notifier/ に配置するファイル一覧です。GitHub に push 済みなので、上記の degit コマンドで一発取得できます。
.agent/skills/random-os-apology-notifier/
├── SKILL.md
├── scripts/
│ └── random_os_apology_notifier.py
└── references/
└── design_notes.md
各ファイルの役割
| ファイル | 役割 |
|---|---|
SKILL.md |
Skill本体。frontmatter (name/description) と指示本文。Antigravity がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します |
scripts/random_os_apology_notifier.py |
random-os-apology-notifier: OS風のフェイク謝罪通知をランダム表示 |
references/design_notes.md |
概要 をまとめた参考資料 |
SKILL.md
---
name: random-os-apology-notifier
description: 作業中やコマンド実行時など、通常の進行に影響を与えず、ランダムなタイミングやキーワード(例:通知, OS, 謝罪, 演出, フェイク, ユーモア)にマッチした際に、OSの通知領域へフェイク謝罪メッセージを表示します。
---
# 機能概要
random-os-apology-notifierは、作業中に突然OS風の謝罪通知をデスクトップへ表示するスキルです。実際のエラーや業務進行には一切影響せず、完全なフェイク通知として、OSが「原因不明の遅延」「謎の障害」「無責任な謝罪」などを繰り返します。職場やリモートワークの雰囲気を和らげたり、ユーモラスな演出を加えたい場合に最適です。
# 使い方
このスキルはAntigravityのsemantic-match-onlyトリガーにより、明示的な呼び出しは不要です。通知, OS, 謝罪, 演出, フェイク, ユーモアなどのキーワードや、作業進行中の任意タイミングで自動的に発動します。スクリプトはローカル環境で直接実行も可能です。
# 出力例
```
[通知] 本日はご迷惑をおかけしております。詳細は不明ですが、引き続きご理解ください。
[通知] 謎の遅延が発生しましたが、原因不明です。ご不便をおかけします。
[通知] 大変申し訳ありませんが、さっきのコマンドは無かったことにしてください。
[通知] 予期せぬ問題が発生しましたが、何も対応しません。
[通知] システムは正常ですが、念のためお詫び申し上げます。
```
# 注意点
- 本スキルは完全なフェイク通知であり、実際のエラーや業務進行には一切干渉しません。
- 通知はローカル環境のOS通知API(Windows: Toast, macOS: AppleScript, Linux: notify-send等)を利用します。
- 通知履歴やログはローカルにのみ保存されます。
- セキュリティや業務規定により、通知機能が制限されている場合は動作しません。
# 参考資料
詳細仕様や設計方針、各OSの通知API利用例は references/design_notes.md を参照してください。公式ドキュメント:
- Windows Toast Notifications: https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/
- macOS AppleScript: https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/
- Linux notify-send: https://specifications.freedesktop.org/notification-spec/latest/
scripts/random_os_apology_notifier.py
import sys
import os
import platform
import random
import time
import argparse
import subprocess
from datetime import datetime
APOLOGY_MESSAGES = [
"本日はご迷惑をおかけしております。詳細は不明ですが、引き続きご理解ください。",
"謎の遅延が発生しましたが、原因不明です。ご不便をおかけします。",
"大変申し訳ありませんが、さっきのコマンドは無かったことにしてください。",
"予期せぬ問題が発生しましたが、何も対応しません。",
"システムは正常ですが、念のためお詫び申し上げます。",
"原因不明のエラーが発生した可能性があります。詳細は不明です。",
"本件については調査中ですが、特に何もしていません。ご容赦ください。",
"ご迷惑をおかけしておりますが、特に問題はありません。",
"システムは正常に動作していますが、お詫び申し上げます。",
"本日のご利用に感謝しつつ、無責任に謝罪いたします。"
]
LOG_FILE = os.path.expanduser("~/.random_os_apology_notifier.log")
def send_notification(message):
system = platform.system()
if system == "Darwin":
# macOS: use AppleScript
script = f'display notification "{message}" with title "通知"'
try:
subprocess.run(["osascript", "-e", script], check=True)
except Exception as e:
print(f"[ERROR] macOS通知失敗: {e}")
elif system == "Linux":
# Linux: use notify-send
try:
subprocess.run(["notify-send", "通知", message], check=True)
except Exception as e:
print(f"[ERROR] Linux通知失敗: {e}")
elif system == "Windows":
# Windows: use Toast notification
try:
import win10toast
toaster = win10toast.ToastNotifier()
toaster.show_toast("通知", message, duration=5, threaded=True)
except ImportError:
# Fallback: powershell
try:
script = f'[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null;'
script += f'$template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02);'
script += f'$toastXml = $template;'
script += f'$toastXml.GetElementsByTagName("text")[0].AppendChild($toastXml.CreateTextNode("通知")) > $null;'
script += f'$toastXml.GetElementsByTagName("text")[1].AppendChild($toastXml.CreateTextNode("{message}")) > $null;'
script += f'$toast = [Windows.UI.Notifications.ToastNotification]::new($toastXml);'
script += f'$notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("random-os-apology-notifier");'
script += f'$notifier.Show($toast);'
subprocess.run(["powershell", "-Command", script], check=True)
except Exception as e2:
print(f"[ERROR] Windows通知失敗: {e2}")
else:
print(f"[通知] {message}")
def log_message(message):
try:
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(f"{datetime.now().isoformat()}\t{message}\n")
except Exception as e:
print(f"[ERROR] ログ保存失敗: {e}")
def list_logs(limit=20):
try:
if not os.path.exists(LOG_FILE):
print("ログファイルが存在しません。")
return
with open(LOG_FILE, "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines[-limit:]:
print(line.strip())
except Exception as e:
print(f"[ERROR] ログ読み込み失敗: {e}")
def summary_logs():
try:
if not os.path.exists(LOG_FILE):
print("ログファイルが存在しません。")
return
with open(LOG_FILE, "r", encoding="utf-8") as f:
lines = f.readlines()
print(f"総通知回数: {len(lines)}")
counts = {}
for line in lines:
msg = line.strip().split("\t", 1)[-1]
counts[msg] = counts.get(msg, 0) + 1
print("頻出メッセージ:")
for msg, cnt in sorted(counts.items(), key=lambda x: -x[1])[:5]:
print(f" {msg} : {cnt}回")
except Exception as e:
print(f"[ERROR] サマリー取得失敗: {e}")
def notify_once():
message = random.choice(APOLOGY_MESSAGES)
send_notification(message)
log_message(message)
print(f"[通知] {message}")
def notify_loop(interval_min=600, interval_max=1800):
print(f"ランダム謝罪通知を開始します (間隔: {interval_min//60}-{interval_max//60}分)。Ctrl+Cで終了。")
try:
while True:
delay = random.randint(interval_min, interval_max)
time.sleep(delay)
notify_once()
except KeyboardInterrupt:
print("\n[INFO] 通知ループを終了しました。")
def main():
parser = argparse.ArgumentParser(description="random-os-apology-notifier: OS風のフェイク謝罪通知をランダム表示")
subparsers = parser.add_subparsers(dest="command")
parser_notify = subparsers.add_parser("notify", help="1回だけ謝罪通知を表示")
parser_loop = subparsers.add_parser("loop", help="ランダム間隔で謝罪通知を繰り返し表示")
parser_loop.add_argument("--min", type=int, default=600, help="最短通知間隔(秒)")
parser_loop.add_argument("--max", type=int, default=1800, help="最長通知間隔(秒)")
parser_list = subparsers.add_parser("list", help="通知ログを最新20件表示")
parser_list.add_argument("--limit", type=int, default=20, help="表示件数")
parser_summary = subparsers.add_parser("summary", help="通知履歴のサマリーを表示")
args = parser.parse_args()
if args.command == "notify":
notify_once()
elif args.command == "loop":
notify_loop(interval_min=args.min, interval_max=args.max)
elif args.command == "list":
list_logs(limit=args.limit)
elif args.command == "summary":
summary_logs()
else:
parser.print_help()
if __name__ == '__main__':
main()
references/design_notes.md
# 概要
random-os-apology-notifierは、ユーザー体験を損なうことなく、デスクトップ通知APIを活用して完全なフェイク謝罪メッセージを表示する演出スキルです。実際のエラーや業務進行と無関係に、ユーモアや和みを提供します。
# 公式ドキュメント抜粋
- Windows: Toast通知API(https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/)
- macOS: AppleScript通知(https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/)
- Linux: notify-send(https://specifications.freedesktop.org/notification-spec/latest/)
# 利用例
- リモートワークやオフィスでのアイスブレイク
- 業務進行中の息抜きや話題作り
- フェイク障害訓練やユーモア演出
# 注意点
- 通知APIが利用不可な環境や、通知がポップアップしない設定では効果がありません。
- ログはユーザーのホームディレクトリにのみ保存され、外部送信はありません。
- 実際のエラーやシステム障害とは一切関係ありません。
# 設計方針
- OSごとに実在する通知APIのみを利用し、追加ライブラリが不要な範囲は極力標準機能で実装。
- ログ・サマリー機能で利用状況を可視化。
- ユーザーの混乱を避けるため、通知タイトルやメッセージ文面でフェイク性を明示。
導入手順
このSkillは GitHub で管理されているので、degit を使えば必要なフォルダだけを1コマンドで取得できます。Antigravity はファイル配置後に再起動するだけで自動認識します。
1. 前提
- Node.js v16 以上 (
degit実行に必要) - Antigravity がローカルで動いていること
2. degit でフォルダ取得
プロジェクトのルートで以下のコマンドを実行します。
npx degit aazutaku/ai-note/antigravity/random-os-apology-notifier .agent/skills/random-os-apology-notifier
.agent/skills/random-os-apology-notifier の中に SKILL.md / scripts/ / references/ / README.md が展開されます。
3. ファイル配置確認
ls .agent/skills/random-os-apology-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 でも有効か?
- プロジェクト指示との連携をどう組み立てるか?
- 通知内容のランダム性は十分か? 毎回異なる謝罪文が生成されるか?
- 本物のエラーや業務進行には一切干渉しないか?
実際に Antigravity で試した検証ログは Antigravityの謎謝罪通知を使ってみた!突然の無責任謝罪で盛り上がる にまとめる予定 (公開準備中の場合あり)。
あわせて Antigravity 公式ドキュメント と、本シリーズ「Antigravityで試したいSkill研究」の他記事も参照のこと。
関連タグで他のSkill記事を探す
本記事に付いているタグから、気になるテーマの記事を探せます。タグページで関連記事をまとめて読めるので、ぜひチェックしてみてください!
