Antigravityで重大コマンド実行前の緊張感を自動演出する方法

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

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

Antigravity を日々の AI coding workflow に組み込んでいると、ちょっとした操作が思いがけず大きなインパクトを持つことがあります。特に通知や演出、OS連携まわりの体験では「もう少し緊張感が欲しい」「重要な操作に気づきたい」と感じる瞬間が意外と多いものです。

  • うっかり git pushrm などの重大コマンドを実行してしまい、取り返しのつかない変更をしてしまう
  • Antigravity が context を見失い、違う repository や directory のコードに影響を与えそうになる
  • monorepo で package を跨いだタイミングで「本当にこのコマンドをここで叩いて大丈夫か?」と不安になる
  • 長時間 session で集中力が切れ、重要な操作を routine work の一部として流してしまう
  • AI の repository understanding が進化した反面、ヒューマン側の緊張感や注意喚起が薄れやすい

「ちょっとした演出や通知があれば、うっかりミスや無意識な操作を減らせるのに…」という声は、Antigravity ユーザーなら一度は感じたことがあるはずです。

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

一言サマリ: このスキルは、重大コマンド実行の瞬間を“壮大なイベント”に変え、エンジニアの注意を最大化するSkill。

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

  • 重要な OS コマンド(git push、rm、npm publish など)の直前に、OS風ドラムロール+デスクトップ通知で「今から本当にやるのか?」と強制的に意識をリセットできる
  • repository や directory の path management を伴う操作時、Antigravity の context をまたいだ“運命の選択”をしっかり自覚できる
  • monorepo など複雑な repo 構造でも、パッケージ跨ぎのタイミングで緊張感を演出し、メンタルな区切りをサポート
  • AI coding workflow の中で「何気ないコマンド入力が一大イベントに昇華」することで、onboarding や session 再開時の注意喚起にも役立つ
  • 毎回異なるパターンの通知・サウンドがランダム再生されるので、飽きずに“本番”感を味わえる
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/antigravity/os-command-drumroll-alert .agent/skills/os-command-drumroll-alert

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

使う側がイメージしやすいよう、擬似 terminal で出力例を3パターン示す。Skill が返す出力は推測だが、現実的なフォーマット・現実的な長さで書く。

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


> git push origin main

[ドラムロール音が鳴る...]
[デスクトップ通知] 
「運命の選択が迫る!本当に main に push しますか?」

[Antigravity] 
重大コマンド検出: git push
この操作は repository: /Users/you/my-monorepo (package: core) に影響します。
続行する場合は y を押してください。

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


> npm publish --workspace=packages/api

[ドラムロール音(パターンB)が鳴る...]
[デスクトップ通知]
「この package(api) の公開は不可逆です。本当に進めますか?」

[Antigravity]
重要なコマンド: npm publish
directory: packages/api
monorepo context をまたいでいます。慎重にご確認ください。

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


> rm -rf ./tmp/test/

[ドラムロール音(パターンC)が鳴る...]
[デスクトップ通知]
「消去は一瞬、後悔は永遠。rm 実行、よろしいですか?」

[Antigravity]
重大コマンド: rm -rf
directory: ./tmp/test/
重要ファイルの削除操作です。最終確認をお願いします。

before / after の違い

場面 Skill 無し Skill 有り
session 再開時 repo 構造から毎回説明、path も指定し直し Antigravity が自動で context を復元、最小プロンプトで再開
monorepo 移動 違う package のコードを参照しがち directory boundary を意識して必要な範囲だけ見る
長時間 workflow long context で重要箇所が薄まる 重大コマンド実行時に注意喚起を挟み、重要な操作を見失わない

発動方式

description マッチでの暗黙発動。

Skill の中身を全部見せる

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

.agent/skills/os-command-drumroll-alert/
├── SKILL.md
├── scripts/
│   └── os_command_drumroll_alert.py
└── references/
    └── design_notes.md

各ファイルの役割

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

SKILL.md

---
name: os-command-drumroll-alert
description: git push、rm、npm publish などの重大コマンドを実行する直前に、Antigravity が自動でドラムロール音とOS通知を発動。コマンド実行前の緊張感を演出し、操作ミスや事故を防止するための演出系スキル。trigger: semantic-match-only。
---

# 機能概要
このSkillは、エンジニアがターミナルやエディタで重大なコマンド(例: `git push`, `rm`, `npm publish` など)を実行しようとした際、直前に“OS風ドラムロール”サウンドを鳴らし、さらにデスクトップ通知で「運命の選択が迫る!」「本当に実行しますか?」などの演出メッセージを表示します。普段の作業フローに緊張感とユーモアを加え、重大操作の前に注意を促すことで、ミスの抑止や気分転換にも役立ちます。

# 使い方
このSkillは明示的な呼び出しを必要とせず、`git push`, `rm -rf`, `npm publish`, `docker system prune` などのコマンドを実行しようとした際に自動発動します。Antigravityがコマンド内容をセマンティックに解析し、該当する場合にのみ演出を挿入します。

## 暗黙発動キーワード例
- git push
- rm -rf
- npm publish
- docker system prune
- systemctl restart

# 出力例
```
[ドラムロール音が鳴る]
[デスクトップ通知] 運命の選択が迫る!本当に git push を実行しますか?
[ターミナル出力] Drumroll... Are you sure you want to proceed with 'rm -rf ./build'?
[選択肢] Yes / No
```

# 注意点
- サウンド再生・通知機能はOS依存(Linux: notify-send, aplay / macOS: osascript, afplay / Windows: powershell通知)
- コマンド実行の遅延や割り込みを最小限に抑えますが、演出が不要な場合はSkillを無効化してください
- 通知・サウンドは複数パターンをランダム表示
- ローカル環境に一時的なサウンドファイルを保存します

# 参考資料
- [Python: subprocess, os, random, platform, plyer, playsound](https://docs.python.org/3/library/)
- references/design_notes.md を参照

scripts/os_command_drumroll_alert.py

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

try:
    from plyer import notification
except ImportError:
    notification = None

DRUMROLL_SOUNDS = [
    'https://cdn.pixabay.com/audio/2022/10/16/audio_12b5c8c7e8.mp3',
    'https://cdn.pixabay.com/audio/2022/10/16/audio_120d7a3b83.mp3',
    'https://cdn.pixabay.com/audio/2022/10/16/audio_12b5c8c7e8.mp3'
]

ALERT_MESSAGES = [
    '運命の選択が迫る!本当に実行しますか?',
    '今から本当にやるのか?',
    '重大操作直前!覚悟はできていますか?',
    'Drumroll... Are you sure you want to proceed?',
    'このコマンド、後戻りできません!'
]

TRIGGER_KEYWORDS = [
    'git push',
    'rm -rf',
    'npm publish',
    'docker system prune',
    'systemctl restart',
    'kubectl delete',
    'gcloud compute instances delete',
    'terraform apply',
    'aws s3 rm',
    'chmod 777',
    'chown',
    'shutdown',
    'reboot',
    'dd if=',
    'mkfs',
    'diskutil eraseDisk'
]

def download_sound(url):
    import urllib.request
    fd, path = tempfile.mkstemp(suffix='.mp3')
    os.close(fd)
    urllib.request.urlretrieve(url, path)
    return path

def play_sound(path):
    sysname = platform.system()
    if sysname == 'Darwin':
        subprocess.Popen(['afplay', path])
    elif sysname == 'Linux':
        subprocess.Popen(['mpg123', path])
    elif sysname == 'Windows':
        subprocess.Popen(['powershell', '-c', f'(New-Object Media.SoundPlayer "{path}").PlaySync();'])
    else:
        print('サウンド再生未対応OSです')

def show_notification(title, message):
    sysname = platform.system()
    if notification:
        notification.notify(title=title, message=message, timeout=5)
    elif sysname == 'Darwin':
        subprocess.Popen(['osascript', '-e', f'display notification "{message}" with title "{title}"'])
    elif sysname == 'Linux':
        subprocess.Popen(['notify-send', title, message])
    elif sysname == 'Windows':
        subprocess.Popen(['powershell', '-Command', f'[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null; $template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02); $textNodes = $template.GetElementsByTagName("text"); $textNodes.Item(0).AppendChild($template.CreateTextNode("{title}")) > $null; $textNodes.Item(1).AppendChild($template.CreateTextNode("{message}")) > $null; $toast = [Windows.UI.Notifications.ToastNotification]::new($template); [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("os-command-drumroll-alert").Show($toast);'])
    else:
        print(f'通知未対応OS: {title} {message}')

def drumroll_alert(command):
    msg = random.choice(ALERT_MESSAGES)
    sound_url = random.choice(DRUMROLL_SOUNDS)
    print(f'[ドラムロール音が鳴る]')
    print(f'[デスクトップ通知] {msg} {command}')
    print(f'[ターミナル出力] Drumroll... Are you sure you want to proceed with "{command}"?')
    # Download and play sound in background
    path = download_sound(sound_url)
    t = threading.Thread(target=play_sound, args=(path,))
    t.start()
    show_notification('重大コマンド警告', f'{msg} {command}')
    # 簡易的なYes/Noプロンプト
    while True:
        ans = input('実行しますか? [y/N]: ')
        if ans.lower() in ['y', 'yes']:
            return True
        elif ans.lower() in ['', 'n', 'no']:
            print('キャンセルされました')
            return False
        else:
            print('y または n を入力してください')

def is_major_command(cmd):
    for kw in TRIGGER_KEYWORDS:
        if kw in cmd:
            return True
    return False

def run_command(cmd):
    try:
        subprocess.run(cmd, shell=True, check=True)
    except subprocess.CalledProcessError as e:
        print(f'コマンド失敗: {e}')

def main():
    parser = argparse.ArgumentParser(description='os-command-drumroll-alert')
    parser.add_argument('command', nargs=argparse.REMAINDER, help='実行するコマンド')
    parser.add_argument('--list-keywords', action='store_true', help='重大コマンドキーワード一覧を表示')
    args = parser.parse_args()

    if args.list_keywords:
        print('重大コマンドキーワード:')
        for kw in TRIGGER_KEYWORDS:
            print(f'- {kw}')
        sys.exit(0)

    if not args.command:
        print('コマンドを指定してください')
        sys.exit(1)

    cmd_str = ' '.join(args.command)
    if is_major_command(cmd_str):
        proceed = drumroll_alert(cmd_str)
        if not proceed:
            sys.exit(0)
    run_command(cmd_str)

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
os-command-drumroll-alertは、エンジニアが重大なコマンド(git push, rm, npm publish等)を実行する直前に、ドラムロール音とOS通知で演出を加えるSkillです。操作ミスや事故を抑止しつつ、日常作業に遊び心を提供します。

# 公式ドキュメント抜粋
- [Python subprocess](https://docs.python.org/3/library/subprocess.html)
- [plyer notification](https://plyer.readthedocs.io/en/latest/)
- [notify-send (Linux)](https://specifications.freedesktop.org/notification-spec/)
- [osascript (macOS)](https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html)

# 利用例
- git pushやrm -rfなどの前に、緊張感を演出し注意喚起
- チーム内での運用で、誤操作防止やジョークとして活用

# 注意点
- サウンド再生や通知表示はOS依存。Linuxはmpg123/notify-send、macOSはafplay/osascript、Windowsはpowershellに依存
- サウンドファイルは一時保存されますが、定期的なクリーニングを推奨
- 重大コマンド検出は単純なキーワード一致のため、カスタマイズが必要な場合はTRIGGER_KEYWORDSを編集してください

# 設計方針
- コマンド実行の邪魔になりすぎないよう、演出は5秒以内に収める
- サウンド・通知パターンはランダム化し、繰り返しの作業でも飽きない工夫
- CLIラッパー形式で、既存のワークフローに容易に組み込める設計

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/antigravity/os-command-drumroll-alert .agent/skills/os-command-drumroll-alert

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

3. ファイル配置確認

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