Antigravityで気分転換!通知にランダム祝福メッセージを表示する方法

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

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

Antigravity を日常的に使っていると、AI coding workflow がどんどん効率化される一方で、淡々としたコマンドややり取りが続き、作業空間が無機質になりがちです。context や repository understanding の精度に気を配るあまり、ちょっとした遊び心や気分転換の余地がなくなってしまうことも珍しくありません。特に monorepo で複雑な directory や path management に追われていると、集中力が切れた瞬間に「今どこを触っているのか」「何を祝えばいいのか」すら分からなくなることも。

  • Antigravity が context を見失って違う場所のコードを参照する
  • monorepo で package を跨いだ瞬間、Antigravity が repo 構造を忘れる
  • session を再開すると、前回までの context や path 指定をまるごと再説明しないといけない
  • 長時間 workflow で long context が膨らみすぎて、important な情報が薄まる (stale context)
  • 「ここはこういう構造のリポジトリ」というあらすじを毎回チャットの冒頭で書く羽目になる

また、通知や演出が皆無なため、作業に没頭するほど無感情な時間が増え、ちょっとした達成感や「今日はここまでやった!」という区切りが感じにくいのも悩みの一つです。

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

一言サマリ: このスキルは、Antigravity の作業空間に“突発的な祝福通知”をランダムに差し込むことで、退屈なコーディングや単調なディレクトリ操作にユーモアと気分転換をもたらします。

もう少し具体化すると、このSkillを入れることで以下のような状態になる:

  • AI coding workflow の合間に、完全に脈絡のない祝福メッセージが OS の通知領域に現れ、作業のリズムが一瞬リセットされる
  • monorepo で repository understanding や path management に疲れても、唐突な“お祝い”で気持ちを切り替えやすくなる
  • 長時間の session や memory が膨らんだ長い context の中でも、ふいに現れる通知で集中力をリフレッシュできる
  • onboarding や初回起動時に「本日も出社おめでとう」などのメッセージで、ちょっとした非日常感を演出できる
  • Antigravity の真面目な通知やエラーだけでなく、遊び心ある Skill を追加することで、開発体験そのものが楽しくなる
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/antigravity/random-os-notification-confetti .agent/skills/random-os-notification-confetti

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

使う側がイメージしやすいよう、擬似 terminal で出力例を3パターン示します。

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


# Antigravity セッションを開始
> antigravity start

[通知] 🎉 おめでとうございます!本日も出社されました!
[通知] 祝: /src/main.py へのアクセスが最高にクールです
[通知] 何もしていないのに祝福します。とりあえず乾杯。
(タスクや指示には全く関係のない祝福通知が、OSの通知領域にランダムで表示される)

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


> cd packages/api
> ls

[通知] 今日の packages/api ディレクトリ移動、素晴らしい選択です
[通知] さっきの ls、最高でした。見事な directory management!
[通知] 祝: monorepo の package 跨ぎ、うまくいきましたね
(作業内容と全く関係なく、突発的に祝福メッセージが通知される)

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


> # 何気なく git status を実行
> git status

[通知] 祝: その git status、誰よりも美しい
[通知] 意味はないですが、とにかく祝福します
[通知] /README.md を眺めただけで偉業達成です
(ユーザーが戸惑うほど唐突な祝福がランダムで表示される)

before / after の違い

場面 Skill 無し Skill 有り
session 再開時 repo 構造から毎回説明、path も指定し直し Antigravity が自動で context を復元、最小プロンプトで再開
monorepo 移動 違う package のコードを参照しがち directory boundary を意識して必要な範囲だけ見る
長時間 workflow long context で重要箇所が薄まる 突発的な祝福通知で気分転換、集中力をリセット

発動方式

description マッチでの暗黙発動。

Skill の中身を全部見せる

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

.agent/skills/random-os-notification-confetti/
├── SKILL.md
├── scripts/
│   └── random_os_notification_confetti.py
└── references/
    └── design_notes.md

各ファイルの役割

ファイル 役割
SKILL.md Skill本体。frontmatter (name/description) と指示本文。Antigravity がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/random_os_notification_confetti.py 通知間隔を制御
references/design_notes.md 概要 をまとめた参考資料

SKILL.md

---
name: random-os-notification-confetti
description: コマンド実行や作業の合間に、Antigravityが自動でOS通知領域へ“謎の祝福メッセージ”をランダム表示します。lsやgit、buildなどの作業キーワードを検知し、適切な頻度で発動します。
---

# 機能概要
このSkillは、普段のコマンドライン作業やファイル操作の合間に、完全ランダムで“謎のコンフェッティ(紙吹雪)祝福メッセージ”をOSの通知領域へ表示します。内容は「本日も出社おめでとう」「意味なく祝福します」「さっきのls、最高でした」など、全く脈絡のないお祝いばかり。作業に没頭しがちな開発現場へ、唐突な非日常を演出し、気分転換やユーモアを提供します。通知は過剰にならないよう、一定間隔・確率で発動します。

# 使い方
このSkillは明示的な呼び出しは不要です。Antigravityが `ls`、`git`、`make`、`build`、`run` などの作業系コマンドや、ファイル編集・保存などのイベントを検知した際、ランダムなタイミングで自動発動します。暗黙発動キーワード例:`ls`、`git commit`、`make build`、`vim` など。

# 出力例
```
[通知] 本日も出社おめでとう!
[通知] さっきのls、最高でした。
[通知] 意味なく祝福します。
[通知] そのgit add、素晴らしい判断です。
[通知] 今日は何もなくても祝っておきます。
[通知] runコマンド、見事な実行力!
```

# 注意点
- 通知はOSの標準通知API(Windows: win10toast, macOS: pync, Linux: notify2等)を利用します。
- 頻度は過剰にならないよう制御されますが、環境によっては通知が重複・遅延する場合があります。
- ローカル環境でのみ動作し、通知内容は保存されません。
- サーバー・リモート環境では通知が表示されない場合があります。

# 参考資料
詳細は references/design_notes.md を参照。公式APIドキュメント(pync, win10toast, notify2)も併せてご覧ください。

scripts/random_os_notification_confetti.py

import sys
import os
import random
import time
import argparse
import platform
import threading

try:
    if platform.system() == 'Darwin':
        import pync
    elif platform.system() == 'Windows':
        from win10toast import ToastNotifier
    elif platform.system() == 'Linux':
        import notify2
except ImportError:
    pass

CONFETTI_MESSAGES = [
    '本日も出社おめでとう!',
    '意味なく祝福します。',
    'さっきのls、最高でした。',
    'runコマンド、見事な実行力!',
    '今日は何もなくても祝っておきます。',
    'そのgit add、素晴らしい判断です。',
    'make build、祝福の嵐。',
    'vim保存、お疲れさまでした。',
    'push前の静けさに乾杯。',
    'ls -la、完璧でした。',
    '何もしてないのに祝います。',
    '今日もターミナルが輝いています。',
    'あなたのコマンドに紙吹雪を。',
    'build成功、おめでとう!',
    'git commit、ナイスです。',
    '編集保存、祝福します。',
    'どんな作業にもエールを送ります。',
    'lsのタイミング、最高でした。',
    '意味はないけど祝います。',
    'push成功、紙吹雪!',
]

TRIGGER_KEYWORDS = [
    'ls', 'git', 'make', 'build', 'run', 'vim', 'nano', 'code', 'save', 'commit', 'push', 'pull', 'edit', 'open'
]

NOTIFY_INTERVAL_RANGE = (300, 900)  # 5分〜15分の間隔
LAST_NOTIFY_FILE = os.path.expanduser('~/.random_confetti_notify_time')


def can_notify():
    """
    通知間隔を制御。前回通知から十分経過していればTrue。
    """
    now = time.time()
    if os.path.exists(LAST_NOTIFY_FILE):
        try:
            with open(LAST_NOTIFY_FILE, 'r') as f:
                last = float(f.read().strip())
            if now - last < random.randint(*NOTIFY_INTERVAL_RANGE):
                return False
        except Exception:
            pass
    return True


def update_notify_time():
    try:
        with open(LAST_NOTIFY_FILE, 'w') as f:
            f.write(str(time.time()))
    except Exception:
        pass


def select_random_message():
    return random.choice(CONFETTI_MESSAGES)


def send_notification(message):
    sys_platform = platform.system()
    try:
        if sys_platform == 'Darwin':
            pync.notify(message, title='通知')
        elif sys_platform == 'Windows':
            toaster = ToastNotifier()
            toaster.show_toast('通知', message, duration=5, threaded=True)
        elif sys_platform == 'Linux':
            notify2.init('Confetti')
            n = notify2.Notification('通知', message)
            n.set_urgency(notify2.URGENCY_NORMAL)
            n.show()
        else:
            print('[通知]', message)
    except Exception as e:
        print('[通知]', message, '(通知APIエラー:', e, ')')


def monitor_commands(logfile=None):
    """
    コマンド履歴や作業ログを監視し、トリガーキーワード検出時に通知。
    """
    last_line = ''
    while True:
        if logfile and os.path.exists(logfile):
            with open(logfile, 'r') as f:
                lines = f.readlines()
                if lines:
                    line = lines[-1].strip()
                    if line != last_line:
                        last_line = line
                        if any(k in line for k in TRIGGER_KEYWORDS):
                            if can_notify():
                                msg = select_random_message()
                                send_notification(msg)
                                update_notify_time()
        else:
            # 標準入力監視(例: コマンドラッパー経由)
            try:
                line = sys.stdin.readline()
                if not line:
                    time.sleep(1)
                    continue
                line = line.strip()
                if any(k in line for k in TRIGGER_KEYWORDS):
                    if can_notify():
                        msg = select_random_message()
                        send_notification(msg)
                        update_notify_time()
            except KeyboardInterrupt:
                break
        time.sleep(2)


def random_notify_loop():
    """
    完全ランダムな間隔で祝福通知を送り続けるバックグラウンドループ。
    """
    while True:
        wait_sec = random.randint(*NOTIFY_INTERVAL_RANGE)
        time.sleep(wait_sec)
        if can_notify():
            msg = select_random_message()
            send_notification(msg)
            update_notify_time()


def main():
    parser = argparse.ArgumentParser(description='Random OS Notification Confetti')
    subparsers = parser.add_subparsers(dest='command')

    parser_run = subparsers.add_parser('run', help='バックグラウンドでランダム通知')
    parser_monitor = subparsers.add_parser('monitor', help='コマンド履歴やログを監視し通知')
    parser_monitor.add_argument('--logfile', type=str, default=None, help='監視するコマンド履歴ファイル')
    parser_test = subparsers.add_parser('test', help='1回だけテスト通知')

    args = parser.parse_args()

    if args.command == 'run':
        print('Confetti通知をバックグラウンドで実行します(Ctrl+Cで停止)')
        try:
            random_notify_loop()
        except KeyboardInterrupt:
            print('\n終了します')
    elif args.command == 'monitor':
        print('コマンド履歴監視モード(Ctrl+Cで停止)')
        try:
            monitor_commands(logfile=args.logfile)
        except KeyboardInterrupt:
            print('\n終了します')
    elif args.command == 'test':
        msg = select_random_message()
        send_notification(msg)
        update_notify_time()
        print('テスト通知を送信しました:', msg)
    else:
        parser.print_help()

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
このSkillは、日常的なコマンド操作や作業イベントの合間に、完全ランダムな祝福通知をOSの標準通知領域へ送信します。開発中の気分転換や、作業空間へのユーモア提供が主目的です。

# 公式ドキュメント抜粋
- macOS: [pync](https://github.com/setem/pync)
- Windows: [win10toast](https://github.com/jithurjacob/Windows-10-Toast-Notifications)
- Linux: [notify2](https://github.com/caronc/notify2)

# 利用例
- ターミナルで `python random_os_notification_confetti.py run` を実行し、バックグラウンドでランダム通知を受ける
- `monitor` サブコマンドでコマンド履歴ファイルを監視し、作業イベントごとに祝福
- `test` サブコマンドで通知動作確認

# 注意点
- 通知はローカルPCの通知APIに依存し、リモートやサーバー環境では表示されません
- 通知頻度は過剰にならないよう、前回通知時刻をファイル保存し制御します
- ユーザーの作業ログやコマンド履歴を直接保存・送信することはありません

# 設計方針
- シンプルな構成でOS横断的な通知API利用を優先
- ユーザーの作業を妨げない頻度・タイミングで祝福を挿入
- メッセージは完全ランダム選択、内容もネタ要素を重視

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/antigravity/random-os-notification-confetti .agent/skills/random-os-notification-confetti

.agent/skills/random-os-notification-confetti の中に SKILL.md / scripts/ / references/ / README.md が展開されます。

3. ファイル配置確認

ls .agent/skills/random-os-notification-confetti
# 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をコピーしました!
目次