Antigravityで開発者の気分をリアルタイム可視化する方法入門

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

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

Antigravity を日常的に使う開発者にとって、AI coding workflow の中で「今どんな気分で作業しているか」「集中度やモチベーションがどこにあるか」を可視化する手段は意外と見落とされがちです。特にリモートワークやチームでの協働時、物理的に顔が見えない分、ちょっとしたメンタルの変化や状態を共有したい場面も出てきます。

通知・演出・OS連携系のSkillを使いこなしたい一方で、以下のような困りごとがつきまといます。

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

さらに、開発者自身の「今の気分」や「集中度」が作業ディレクトリやOSステータスバー、Slackなどに連動して表示される仕組みがあれば、チーム内のコミュニケーションや自分自身のオンボーディング体験も変わってくるはずです。

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

一言サマリ: ターミナルで作業しているときSkill。

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

  • 環境変数やOSステータスバーに「今の気分」や「集中度」がリアルタイムで表示され、Antigravity の context 管理や path management の一助になる
  • Slackやシェルプロンプトにも連動して、repository understanding のヒントやチーム内の雰囲気共有ができる
  • monorepo の directory 境界や context 切り替え時に、気分や状況が可視化されることで onboarding 体験が向上する
  • 日替わりネタやツッコミ文が自動で出るので、長時間の AI coding workflow でもちょっとしたリフレッシュや話題作りになる
  • SKILL.md ベースで導入・解除も簡単、path 管理や context memory の補助ツールとしても活用できる
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/antigravity/os-status-mood-light .agent/skills/os-status-mood-light

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

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

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


# export MOOD=最高
> antigravity start

[os-status-mood-light]
あなたの気分:絶好調(最高)
本日のメンタル状況をステータスバーに反映します。
Slackステータスも「絶好調」に更新しました。

現在の作業ディレクトリ: /Users/dev/my-monorepo/packages/core
repository understanding: 構造情報を context に追加しました。
今日のひとこと: 「やる気があるうちに一気に進めましょう!」

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


# export MOOD=だるい
> cd packages/api
> antigravity suggest

[os-status-mood-light]
あなたの気分:本日省エネ運転(だるい)
OSステータスバーを「省エネ」表示に切り替えました。
Slackにも「今日はゆっくり進めます」と投稿。

作業ディレクトリ: /Users/dev/my-monorepo/packages/api
directory 構成: monorepo の package 境界を context に反映
今日のツッコミ: 「無理しないで、休憩も大事ですよ」

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


# export MOOD=腹ペコ
> antigravity status

[os-status-mood-light]
あなたの気分:お腹すいた(腹ペコ)
ステータスバーに「🍙」アイコンを表示しました。
Slackステータスも「ランチ待機中」に変更。

今いるディレクトリ: /Users/dev/my-monorepo
今日の小ネタ: 「集中力は血糖値とともに…」

before / after の違い

場面 Skill 無し Skill 有り
session 再開時 repo 構造から毎回説明、path も指定し直し Antigravity が自動で context を復元、最小プロンプトで再開
monorepo 移動 違う package のコードを参照しがち directory boundary を意識して必要な範囲だけ見る
長時間 workflow long context で重要箇所が薄まる 気分や集中度の変化を可視化し、重要情報へのリマインドやリフレッシュを促進

発動方式

description マッチでの暗黙発動。

Skill の中身を全部見せる

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

.agent/skills/os-status-mood-light/
├── SKILL.md
├── scripts/
│   └── os_status_mood_light.py
└── references/
    └── design_notes.md

各ファイルの役割

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

SKILL.md

---
name: os-status-mood-light
description: 作業者の気分やコンディションを環境変数MOODやOSステータスバー、シェルプロンプト、Slack連携などで可視化したい場合に発動。環境変数変更や気分通知、日替わりネタ表示などのキーワードがトリガー。
---

# 機能概要
このSkillは、作業者の"気分"をリアルタイムで可視化し、ターミナルやOSのステータスバー、シェルプロンプト、Slackステータスなどに反映します。環境変数`MOOD`の値を監視し、"最高"なら「絶好調」、"だるい"なら「本日省エネ運転」など、気分に応じたメッセージや日替わりネタ・ツッコミ文を自動表示。開発者のメンタル状態を周囲に共有し、コミュニケーションやセルフケアのきっかけを提供します。

# 使い方
- 明示呼び出し例: `export MOOD=最高` または `export MOOD=だるい`
- 暗黙発動キーワード例: "気分", "ステータスバー", "Slackステータス", "今日の調子"
- スクリプトを常駐させることで、環境変数変更を自動検知し、表示を即時更新します。Slack連携はトークン設定後に有効。

# 出力例
```
[os-status-mood-light] 気分: 最高 → 絶好調!今日もバリバリいきましょう。
[os-status-mood-light] 気分: だるい → 本日省エネ運転。無理せずいきましょう。
[os-status-mood-light] 今日の一言: "コーヒーは気分転換の友!"
[os-status-mood-light] Slackステータス更新: "絶好調"
```

# 注意点
- 環境変数MOODの変更は新しいシェルや再起動時に反映されます。
- ステータスバーやSlack連携には追加設定が必要。
- ローカルでのみ動作。クラウド同期や他ユーザーへの自動通知は未対応。
- OSやシェルの種類によって一部機能が制限される場合があります。

# 参考資料
- references/design_notes.md
- 公式: https://api.slack.com/methods/users.profile.set

scripts/os_status_mood_light.py

import os
import sys
import time
import argparse
import subprocess
import random
import json
from datetime import datetime

SLACK_API_URL = "https://slack.com/api/users.profile.set"

MOOD_MESSAGES = {
    "最高": "絶好調!今日もバリバリいきましょう。",
    "だるい": "本日省エネ運転。無理せずいきましょう。",
    "普通": "平常運転。淡々と進めましょう。",
    "眠い": "眠気注意。コーヒーでリフレッシュ!",
    "やる気": "やる気MAX!この勢いで進もう。",
    "疲れた": "お疲れ様です。休憩も大事です。",
    "イライラ": "深呼吸してリセットしましょう。",
    "楽しい": "楽しさ全開!良い流れです。",
    "集中": "集中モード。邪魔しないで!",
    "困惑": "困ったときは相談も大事。",
}

DAILY_QUOTES = [
    "コーヒーは気分転換の友!",
    "今日も一歩前進。",
    "深呼吸してリフレッシュ。",
    "無理せず自分のペースで。",
    "たまにはストレッチを。",
    "小さな成功も大事に。",
    "悩んだら一度離れてみよう。",
    "笑顔で乗り切ろう。",
    "新しい発見を楽しもう。",
    "自分を褒めてあげよう。",
]

def get_mood():
    return os.environ.get("MOOD", "普通")

def get_mood_message(mood):
    return MOOD_MESSAGES.get(mood, f"気分: {mood} (メッセージ未登録)")

def get_daily_quote():
    today = datetime.today().toordinal()
    idx = today % len(DAILY_QUOTES)
    return DAILY_QUOTES[idx]

def update_shell_prompt(mood_msg):
    bashrc = os.path.expanduser("~/.bashrc")
    zshrc = os.path.expanduser("~/.zshrc")
    prompt_line = f'export PS1="[os-status-mood-light] {mood_msg} $PS1"\n'
    updated = False
    for rcfile in [bashrc, zshrc]:
        if os.path.exists(rcfile):
            with open(rcfile, 'r') as f:
                lines = f.readlines()
            # Remove previous mood lines
            lines = [l for l in lines if '[os-status-mood-light]' not in l]
            lines.append(prompt_line)
            with open(rcfile, 'w') as f:
                f.writelines(lines)
            updated = True
    return updated

def update_slack_status(token, mood_msg):
    import requests
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json"
    }
    profile = {
        "status_text": mood_msg,
        "status_emoji": ":speech_balloon:",
        "status_expiration": 0
    }
    data = {"profile": profile}
    response = requests.post(SLACK_API_URL, headers=headers, data=json.dumps(data))
    if not response.ok:
        print(f"[os-status-mood-light] Slack API error: {response.text}")
    return response.ok

def print_status(mood, mood_msg, quote, slack=False):
    print(f"[os-status-mood-light] 気分: {mood} → {mood_msg}")
    print(f"[os-status-mood-light] 今日の一言: \"{quote}\"")
    if slack:
        print(f"[os-status-mood-light] Slackステータス更新: \"{mood_msg}\"")

def monitor_mode(args):
    prev_mood = None
    slack_token = args.slack_token
    print("[os-status-mood-light] MOOD監視モード開始。Ctrl+Cで終了。")
    try:
        while True:
            mood = get_mood()
            if mood != prev_mood:
                mood_msg = get_mood_message(mood)
                quote = get_daily_quote()
                print_status(mood, mood_msg, quote, slack=bool(slack_token))
                update_shell_prompt(mood_msg)
                if slack_token:
                    update_slack_status(slack_token, mood_msg)
                prev_mood = mood
            time.sleep(2)
    except KeyboardInterrupt:
        print("\n[os-status-mood-light] 監視終了。")

def show_status(args):
    mood = get_mood()
    mood_msg = get_mood_message(mood)
    quote = get_daily_quote()
    print_status(mood, mood_msg, quote, slack=bool(args.slack_token))
    if args.update_prompt:
        update_shell_prompt(mood_msg)
    if args.slack_token:
        update_slack_status(args.slack_token, mood_msg)

def list_moods(args):
    print("[os-status-mood-light] 登録済み気分一覧:")
    for mood, msg in MOOD_MESSAGES.items():
        print(f"  {mood}: {msg}")

def main():
    parser = argparse.ArgumentParser(description="os-status-mood-light: 気分可視化スキル")
    subparsers = parser.add_subparsers(dest="command")
    
    parser_status = subparsers.add_parser("status", help="現在の気分とメッセージを表示")
    parser_status.add_argument("--update-prompt", action="store_true", help="シェルプロンプトも更新")
    parser_status.add_argument("--slack-token", type=str, help="Slack APIトークン")
    parser_status.set_defaults(func=show_status)

    parser_monitor = subparsers.add_parser("monitor", help="MOOD環境変数を監視し自動反映")
    parser_monitor.add_argument("--slack-token", type=str, help="Slack APIトークン")
    parser_monitor.set_defaults(func=monitor_mode)

    parser_list = subparsers.add_parser("list", help="登録済み気分一覧を表示")
    parser_list.set_defaults(func=list_moods)

    args = parser.parse_args()
    if hasattr(args, 'func'):
        args.func(args)
    else:
        parser.print_help()

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
このSkillは、開発者の気分や心理状態を環境変数やOSのUI、Slackなどにリアルタイムで反映することで、チーム内のコミュニケーションやセルフケアを促進します。気分の可視化はユーモラスな演出としても活用可能です。

# 公式ドキュメント抜粋
Slackステータスの更新には公式API(https://api.slack.com/methods/users.profile.set)を利用し、トークン管理や権限設定が必要です。

# 利用例
- ターミナルで`export MOOD=最高`と入力すると、プロンプトやSlackに「絶好調!」と表示。
- チームの朝会前に全員の気分を可視化して話題作りに活用。

# 注意点
- 環境変数の反映にはシェル再起動が必要な場合があります。
- Slack連携は個人のAPIトークンが必要です。
- ローカル環境依存のため、クラウド同期や他ユーザーへの自動通知は未対応。

# 設計方針
シンプルな環境変数監視とOS連携、Slack API活用を重視し、拡張性・ユーモア性・実用性のバランスを意識しています。

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/antigravity/os-status-mood-light .agent/skills/os-status-mood-light

.agent/skills/os-status-mood-light の中に SKILL.md / scripts/ / references/ / README.md が展開されます。

3. ファイル配置確認

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