Antigravityで楽しむ謎の謝罪通知を自動演出する方法

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

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 のムードが和らぎ、チームやリモートワークでも会話のきっかけになる
  • 通知内容が毎回異なり、同じ謝罪は二度と現れないため、飽きずに楽しめる
  • 本来の業務やエラーとは無関係に、完全なフェイク通知として安全に使える
QUICK INSTALL
このSkillをすぐ試す

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記事を探す

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

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

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