Antigravityで朝礼通知を自動化して作業モードを切り替える方法

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

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

Antigravity を日々のAI coding workflowに組み込んでいると、プロジェクトやリポジトリの context 管理や path management で予想外の「つまずき」を感じる瞬間が多い。特に monorepo や複数 directory をまたぐ大規模 repository では、AIエージェントの context や memory の扱いに独特のクセが現れる。

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

また、通知や演出・OS連携のカテゴリにありがちな問題として、作業開始時の「気分転換」や「リズム作り」が難しい、単調な開発ルーチンになりがち、という悩みも根強い。

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

一言サマリ: このスキルは、Antigravity の session 開始時に“謎のOS朝礼通知”を自動表示し、作業のマンネリを一瞬でリセットするSkill。

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

  • AI coding workflow の起点で、ランダムな朝礼通知が context と共に現れ、気分も repository understanding も一新できる
  • monorepo や複雑な directory 構造でも、session 開始時に「本日の作業目標」や「点呼」などの演出で onboarding 体験が向上
  • 毎回異なる通知内容が出るため、長時間の作業や stale context への対策にも遊び心が加わる
  • 通知は既存ファイルや path management には一切干渉せず、純粋な演出として安全に導入できる
  • Antigravity の description マッチで自動発動するため、手動操作不要で自然に使える
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/antigravity/os-fake-morning-assembly-alert .agent/skills/os-fake-morning-assembly-alert

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

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

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


# ターミナルやエディタを開くと自動で…
[OS朝礼通知] 本日のスローガン: 「安全第一、コードレビューは念入りに!」
[点呼開始] src/, tests/, docs/ の担当者は応答してください。
[公式体操のご案内] 1分間ストレッチを推奨します。

[本日の作業目標] 新規APIの repository understanding を深めること。

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


# packages/core/ から packages/utils/ へ移動した瞬間…
[OS朝礼通知] monorepo点呼: core, utils, shared, app の各packageは準備OKですか?
[本日のスローガン] 「directoryごとの責任範囲を明確に!」
[作業目標] utils/ の path management を見直しましょう。

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


# 何気なく session を開いたとき
[OS朝礼通知] 謎の点呼開始:「main.py、README.md、あなたは生きていますか?」
[公式体操] 指を動かしてキーボード体操をしましょう。
[本日の作業目標] memory overflow を防ぐため、long context の整理を!

before / after の違い

場面 Skill 無し Skill 有り
session 再開時 repo 構造から毎回説明、path も指定し直し Antigravity が自動で context を復元、最小プロンプトで再開
monorepo 移動 違う package のコードを参照しがち directory boundary を意識して必要な範囲だけ見る
長時間 workflow long context で重要箇所が薄まる 朝礼通知で context リセットや作業目標を明示できる

発動方式

description マッチでの暗黙発動。

Skill の中身を全部見せる

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

.agent/skills/os-fake-morning-assembly-alert/
├── SKILL.md
├── scripts/
│   └── morning_assembly_alert.py
└── references/
    └── design_notes.md

各ファイルの役割

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

SKILL.md

---
name: os-fake-morning-assembly-alert
description: ターミナルやエディタ起動時、または作業開始直後のセッションで、'朝礼'や'点呼'などのキーワードが含まれる状況下で自動的に発動し、OS風のランダムな朝礼通知を画面端やデスクトップに表示します。
---

# 機能概要
このSkillは、開発者がターミナルやエディタを初めて開いたタイミングで、架空の“OS朝礼通知”を自動表示します。通知内容は「本日のスローガン発表」「点呼」「OS体操案内」など毎回ランダムで、作業開始時に一瞬で職場や学園の朝礼ムードを演出します。通知後には「本日の作業目標」も自動で宣言されることがあり、日常の開発作業にユーモアと非日常感を加えます。既存の作業やファイルには一切影響を与えません。

# 使い方
このSkillは明示的なコマンド呼び出しは不要です。ターミナルやエディタを初回起動した際、または「朝礼」「点呼」「スローガン」などのキーワードを含むセッション開始時に自動発動します。明示呼び出しはサポートしていません。

# 出力例
```
[OS朝礼通知] 2024-06-30 09:00
本日のスローガン: 「バグは朝のうちに退治せよ」
点呼開始: 1番から順にお名前をどうぞ。
OS公式体操のご案内: 10:05より画面端でストレッチ動画を再生します。
本日の作業目標: 「コミットは小まめに、レビューは丁寧に」
```

# 注意点
- 通知は初回起動時のみ表示され、既存ファイルや作業内容には変更を加えません。
- 通知内容は毎回ランダム生成されますが、ネタ度を優先しています。
- ローカル環境の通知API(例: notify-send, osascript, PowerShell)を利用します。通知が表示されない場合は環境設定をご確認ください。
- 除外パスや特定ディレクトリでは発動しません(例: /tmp, /var, システムディレクトリ)。

# 参考資料
詳細な設計方針や通知APIの利用例は references/design_notes.md をご参照ください。Linux/macOS/Windows の公式通知API仕様も参照しています。

scripts/morning_assembly_alert.py

import os
import sys
import random
import platform
import subprocess
import argparse
import datetime
import json

SLOGANS = [
    'バグは朝のうちに退治せよ',
    '今日も安全第一で開発を',
    'レビューは丁寧に、コミットは小まめに',
    'OS体操でリフレッシュ',
    '朝の一歩が一日を決める',
    '新しい発想は朝礼から',
    'エラーは怖くない、仲間がいる',
    '本日のキーワード: 継続は力なり',
    'コードは人のために書こう',
    '健康第一、バグ第二'
]

CHECKINS = [
    '点呼開始: 1番から順にお名前をどうぞ。',
    '点呼: みなさん、今日も元気ですか?',
    '出席確認: 返事は「はい!」でお願いします。',
    '点呼: 欠席者はいませんか?',
    '点呼: チーム全員の準備OK?'
]

EXERCISES = [
    'OS公式体操のご案内: 10:05より画面端でストレッチ動画を再生します。',
    '体操タイム: 1分間のストレッチを推奨します。',
    'OS体操: みんなで肩回しをしましょう。',
    '体操案内: 立ち上がって深呼吸を3回。',
    '公式体操: 指のストレッチも忘れずに。'
]

GOALS = [
    '本日の作業目標: 「コミットは小まめに、レビューは丁寧に」',
    '本日の作業目標: 「バグゼロを目指しましょう」',
    '本日の作業目標: 「健康第一、無理せず進めよう」',
    '本日の作業目標: 「新しい技術にチャレンジ」',
    '本日の作業目標: 「コードレビューを積極的に」'
]

EXCLUDE_PATHS = ['/tmp', '/var', '/etc', '/bin', '/sbin']

STATE_FILE = os.path.expanduser('~/.os_fake_morning_assembly_state.json')


def already_shown_today():
    today = datetime.date.today().isoformat()
    if os.path.exists(STATE_FILE):
        try:
            with open(STATE_FILE, 'r') as f:
                data = json.load(f)
                if data.get('date') == today:
                    return True
        except Exception:
            pass
    return False

def mark_shown_today():
    today = datetime.date.today().isoformat()
    data = {'date': today}
    try:
        with open(STATE_FILE, 'w') as f:
            json.dump(data, f)
    except Exception:
        pass

def in_exclude_path():
    cwd = os.path.abspath(os.getcwd())
    for path in EXCLUDE_PATHS:
        if cwd.startswith(path):
            return True
    return False

def random_message():
    slogan = random.choice(SLOGANS)
    checkin = random.choice(CHECKINS)
    exercise = random.choice(EXERCISES)
    goal = random.choice(GOALS)
    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M')
    lines = [
        f'[OS朝礼通知] {now}',
        f'本日のスローガン: 「{slogan}」',
        checkin,
        exercise,
        goal
    ]
    return '\n'.join(lines)

def send_notification(message):
    system = platform.system()
    title = 'OS朝礼通知'
    try:
        if system == 'Linux':
            # Use notify-send
            subprocess.run(['notify-send', title, message], check=False)
        elif system == 'Darwin':
            # macOS: use osascript
            script = f'display notification "{message}" with title "{title}"'
            subprocess.run(['osascript', '-e', script], check=False)
        elif system == 'Windows':
            # Windows: use PowerShell
            ps_script = f'[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null;'
            ps_script += f'$template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02);'
            ps_script += f'$textNodes = $template.GetElementsByTagName("text");'
            ps_script += f'$textNodes.Item(0).AppendChild($template.CreateTextNode("{title}")) > $null;'
            ps_script += f'$textNodes.Item(1).AppendChild($template.CreateTextNode("{message}")) > $null;'
            ps_script += f'$toast = [Windows.UI.Notifications.ToastNotification]::new($template);'
            ps_script += f'$notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("FakeMorningAssembly");'
            ps_script += f'$notifier.Show($toast);'
            subprocess.run(['powershell', '-Command', ps_script], check=False)
        else:
            # Fallback: print to stdout
            print(message)
    except Exception as e:
        print(f'通知送信エラー: {e}\n{message}', file=sys.stderr)

def cli_show(args):
    if in_exclude_path():
        return
    if already_shown_today():
        return
    msg = random_message()
    send_notification(msg)
    mark_shown_today()
    if args.print:
        print(msg)

def cli_reset(args):
    if os.path.exists(STATE_FILE):
        try:
            os.remove(STATE_FILE)
            print('朝礼通知状態をリセットしました。')
        except Exception as e:
            print(f'リセット失敗: {e}')
    else:
        print('リセット不要: 状態ファイルは存在しません。')

def cli_status(args):
    if already_shown_today():
        print('本日すでに朝礼通知を表示済みです。')
    else:
        print('本日はまだ朝礼通知を表示していません。')

def main():
    parser = argparse.ArgumentParser(description='OS Fake Morning Assembly Alert')
    subparsers = parser.add_subparsers(dest='command')

    show_parser = subparsers.add_parser('show', help='朝礼通知を表示(通常は自動発動)')
    show_parser.add_argument('--print', action='store_true', help='通知内容を標準出力にも表示')
    show_parser.set_defaults(func=cli_show)

    reset_parser = subparsers.add_parser('reset', help='通知状態をリセット')
    reset_parser.set_defaults(func=cli_reset)

    status_parser = subparsers.add_parser('status', help='本日の通知状態を表示')
    status_parser.set_defaults(func=cli_status)

    args = parser.parse_args()
    if not args.command:
        # デフォルトはshow
        args = parser.parse_args(['show'])
    args.func(args)

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
このSkillは、開発者が作業を始める際に“OS朝礼”という非日常的な演出を自動的に提供し、日々のルーチンにユーモアやリフレッシュ感を加えることを目的としています。通知内容は毎回ランダム生成され、作業内容や既存ファイルには一切影響を与えません。

# 公式ドキュメント抜粋
- Linux: `notify-send` コマンドを利用したデスクトップ通知
- macOS: `osascript` 経由のネイティブ通知
- Windows: PowerShellによるトースト通知
各OSの標準APIを用いることで、追加ライブラリ不要・高い互換性を実現しています。

# 利用例
- ターミナルやエディタを朝イチで開いた瞬間に、謎の朝礼通知が画面端に表示される
- 朝礼通知後、今日の「作業目標」や「点呼」案内が自動で表示される

# 注意点
- 通知は1日1回のみ表示(状態ファイルで管理)
- システムディレクトリや一時ディレクトリでは発動しません
- 通知APIが無効な環境では標準出力にフォールバックします

# 設計方針
- ユーザーの作業を妨げず、非破壊的・安全な設計
- OSごとに最適な通知手段を自動選択
- ネタ度・演出重視のメッセージ生成ロジック

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/antigravity/os-fake-morning-assembly-alert .agent/skills/os-fake-morning-assembly-alert

.agent/skills/os-fake-morning-assembly-alert の中に SKILL.md / scripts/ / references/ / README.md が展開されます。

3. ファイル配置確認

ls .agent/skills/os-fake-morning-assembly-alert
# 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をコピーしました!
目次