Antigravity ユーザーが日常でぶつかる悩み
Antigravity を日々使っていると、AI coding workflow の中で思わず「またか…」と感じる瞬間が何度も訪れます。特に通知や演出、OS連携系の Skill が乏しい環境では、作業のリズムや集中力を保つのが意外と難しいものです。AI が repository 全体の context を見失ったり、path management の煩雑さに振り回されたりして、気づけば精神的な“緊張感”が高まることもしばしば。
- Antigravity が context を見失って違う場所のコードを参照する
- monorepo で package を跨いだ瞬間、Antigravity が repo 構造を忘れる
- session を再開すると、前回までの context や path 指定をまるごと再説明しないといけない
- 長時間 workflow で long context が膨らみすぎて、important な情報が薄まる (stale context)
- 「ここはこういう構造のリポジトリ」というあらすじを毎回チャットの冒頭で書く羽目になる
こうした悩みは、単なる技術的なストレスだけでなく、心理的にも「なぜかドキドキして落ち着かない」状態を生み出します。通知・演出・OS連携の工夫が足りないと、逆に無駄な緊張感が増幅されることも。Antigravity の repository understanding や memory 機能を活かしきれず、つい気を揉む場面が多いのが現状です。
この Skill が一言でいうと何を解決するか
一言サマリ: あなたのその緊張感Skill。
この Skill は、作業中にランダムなタイミングでデスクトップの画面端に「現在の緊張度」をテロップ表示します。commit数やタイピング速度など“根拠になりそうでならない”値をもとに、「平常心」「やや焦り」「極度緊張」などのラベルで演出。意味はないけれど、なぜか気になる通知が workflow にスパイスを加えます。
- Antigravity の AI coding workflow 中、無意味な緊張度ラベルが定期的に表示され、集中力や気分転換のトリガーになる
- repo や directory の path management のストレスを、遊び心ある通知で和らげる
- onboarding や session 再開時の緊張感・違和感を、ユーモラスな演出で“見える化”できる
- monorepo や長時間作業時の stale context 問題に、思わず笑ってリセットできる余白を作る
- Skill の存在自体が、Antigravity の repository understanding を意識するきっかけになる
GitHub から degit でコマンド1行、Antigravity の Skill ディレクトリに展開できます。Node.js があれば即時に動きます。
npx degit aazutaku/ai-note/antigravity/desktop-tension-meter .agent/skills/desktop-tension-meter実行したらこうなる (3つの利用シーン)
Skill を導入すると、どんなふうにデスクトップで“無意味な緊張感”が演出されるのか。実際の利用シーンを3パターン、擬似 terminal 出力でイメージできます。
シーン1: session 開始時 (プロジェクト初動で)
> 新しいプロジェクトで作業を開始
[desktop-tension-meter] 緊張度: 平常心 (commit数: 0, タイピング速度: 0cpm)
[INFO] Skill の中身を全部見せる
.agent/skills/desktop-tension-meter/ に配置するファイル一覧です。GitHub に push 済みなので、上記の degit コマンドで一発取得できます。
.agent/skills/desktop-tension-meter/
├── SKILL.md
├── scripts/
│ └── tension_meter.py
└── references/
└── design_notes.md
各ファイルの役割
ファイル
役割
SKILL.md
Skill本体。frontmatter (name/description) と指示本文。Antigravity がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/tension_meter.py
Desktop Tension Meter
references/design_notes.md
概要 をまとめた参考資料
SKILL.md
---
name: desktop-tension-meter
description: 作業中やコミット・タイピングなどのアクティビティを検知し、"緊張"や"焦り"などのキーワードを含む状況で、デスクトップにランダムな緊張度ラベルをテロップ表示します。
---
# 機能概要
このSkillは、作業中のユーザーに対して、デスクトップ画面端に「現在の緊張度」をテロップとして表示します。緊張度は完全なランダム値、またはコミット数やタイピング速度といった“根拠になりそうでならない”情報から算出され、「平常心」「やや焦り」「極度緊張」など謎めいたラベルを演出します。これにより、背後に上司がいないのに謎のプレッシャーを感じるという、無意味だけど気になる演出体験を提供します。通知・演出・OS連携カテゴリに属し、職場や自宅のPCでの作業時に、ちょっとした刺激や話題作りとして活用できます。
# 使い方
このSkillは常時バックグラウンドで動作し、明示的な呼び出しは不要です。"緊張" "焦り" "集中" "commit" "タイピング"などのキーワードや、作業アクティビティの検知時に自動で発動します。トリガーはsemantic-match-onlyで、ユーザーの操作状況に応じてランダムなタイミングでテロップが表示されます。
# 出力例
```
[デスクトップ右上]
現在の緊張度: 極度緊張 (推定値: 87)
[デスクトップ左下]
現在の緊張度: 平常心 (推定値: 12)
[デスクトップ右下]
現在の緊張度: やや焦り (推定値: 54)
```
# 注意点
本Skillは純粋な演出目的であり、実際の緊張度や生体情報は取得しません。データはローカルメモリのみで管理され、記録・送信は行いません。通知が鬱陶しい場合はスクリプトを停止してください。強制終了や誤作動によるデータ損失は発生しませんが、画面表示が一時的に残る場合があります。
# 参考資料
詳細な設計や利用例は references/design_notes.md を参照してください。公式ドキュメント: https://docs.python.org/3/library/tkinter.html
scripts/tension_meter.py
import tkinter as tk
import random
import threading
import time
import argparse
import sys
import os
from datetime import datetime
TENSION_LABELS = [
(0, 30, '平常心'),
(31, 60, 'やや焦り'),
(61, 80, '緊張'),
(81, 100, '極度緊張')
]
POSITIONS = ['top_right', 'bottom_left', 'bottom_right', 'top_left']
LOG_FILE = os.path.expanduser('~/.desktop_tension_meter.log')
def get_random_tension():
# 擬似的な根拠値: タイピング速度やコミット数を模倣
base = random.randint(0, 100)
# たまに"根拠あり"風の補正
if random.random() < 0.2:
base += random.randint(-10, 10)
return max(0, min(100, base))
def get_tension_label(value):
for low, high, label in TENSION_LABELS:
if low <= value <= high:
return label
return '未知'
def get_random_position(screen_w, screen_h, window_w, window_h):
pos = random.choice(POSITIONS)
if pos == 'top_right':
x = screen_w - window_w - 20
y = 20
elif pos == 'bottom_left':
x = 20
y = screen_h - window_h - 60
elif pos == 'bottom_right':
x = screen_w - window_w - 20
y = screen_h - window_h - 60
else: # top_left
x = 20
y = 20
return x, y
def show_tension_popup(label, value, duration=2):
root = tk.Tk()
root.overrideredirect(True)
root.attributes('-topmost', True)
root.withdraw()
screen_w = root.winfo_screenwidth()
screen_h = root.winfo_screenheight()
window_w = 350
window_h = 60
x, y = get_random_position(screen_w, screen_h, window_w, window_h)
root.geometry(f'{window_w}x{window_h}+{x}+{y}')
frame = tk.Frame(root, bg='#222', bd=2)
frame.pack(fill='both', expand=True)
label_widget = tk.Label(
frame,
text=f'現在の緊張度: {label} (推定値: {value})',
fg='white',
bg='#222',
font=('Meiryo', 16, 'bold')
)
label_widget.pack(expand=True)
root.deiconify()
root.after(int(duration * 1000), root.destroy)
root.mainloop()
def log_tension(label, value):
with open(LOG_FILE, 'a') as f:
f.write(f'{datetime.now().isoformat()}\t{label}\t{value}\n')
def tension_loop(interval_min=90, interval_max=300):
try:
while True:
value = get_random_tension()
label = get_tension_label(value)
log_tension(label, value)
show_tension_popup(label, value, duration=2.5)
sleep_time = random.randint(interval_min, interval_max)
time.sleep(sleep_time)
except KeyboardInterrupt:
print('Tension Meter stopped.')
def list_logs(count=10):
if not os.path.exists(LOG_FILE):
print('No log file found.')
return
with open(LOG_FILE, 'r') as f:
lines = f.readlines()[-count:]
for line in lines:
print(line.strip())
def summary_logs():
if not os.path.exists(LOG_FILE):
print('No log file found.')
return
counts = {label: 0 for _, _, label in TENSION_LABELS}
total = 0
with open(LOG_FILE, 'r') as f:
for line in f:
parts = line.strip().split('\t')
if len(parts) == 3:
label = parts[1]
if label in counts:
counts[label] += 1
total += 1
print('緊張度ラベル別出現回数:')
for label, cnt in counts.items():
print(f'{label}: {cnt}')
print(f'合計: {total}')
def clear_logs():
if os.path.exists(LOG_FILE):
os.remove(LOG_FILE)
print('Log file cleared.')
else:
print('No log file found.')
def main():
parser = argparse.ArgumentParser(description='Desktop Tension Meter')
subparsers = parser.add_subparsers(dest='command')
run_parser = subparsers.add_parser('run', help='Start the tension meter loop')
run_parser.add_argument('--interval-min', type=int, default=90, help='最小表示間隔(秒)')
run_parser.add_argument('--interval-max', type=int, default=300, help='最大表示間隔(秒)')
list_parser = subparsers.add_parser('list', help='Show recent tension logs')
list_parser.add_argument('--count', type=int, default=10, help='表示件数')
subparsers.add_parser('summary', help='Show summary of tension logs')
subparsers.add_parser('clear', help='Clear log file')
args = parser.parse_args()
if args.command == 'run':
tension_loop(interval_min=args.interval_min, interval_max=args.interval_max)
elif args.command == 'list':
list_logs(count=args.count)
elif args.command == 'summary':
summary_logs()
elif args.command == 'clear':
clear_logs()
else:
parser.print_help()
if __name__ == '__main__':
main()
references/design_notes.md
# 概要
このSkillは、ユーザーの作業中にデスクトップへ無意味な「緊張度」テロップを表示することで、遊び心ある演出体験を提供します。根拠のないラベルをあえて用いることで、仕事やPC作業に謎のプレッシャーを演出します。
# 公式ドキュメント抜粋
本SkillはPython標準のTkinterを利用し、ウィンドウの位置・表示・非表示制御を行います。詳細: https://docs.python.org/3/library/tkinter.html
# 利用例
- 長時間の作業に飽きたときの気分転換
- オフィスでの話題作り
- 意味のない演出で集中を妨げる(逆効果もあり)
# 注意点
生体情報や実際のストレス値は取得しません。通知が鬱陶しい場合はスクリプトを停止してください。ログはローカルにのみ保存され、外部送信はありません。
# 設計方針
シンプルな構成とし、OSやユーザー環境に依存しない設計を心がけています。今後はユーザーアクティビティの検知範囲拡張や、通知演出のカスタマイズも検討可能です。
導入手順
このSkillは GitHub で管理されているので、degit を使えば必要なフォルダだけを1コマンドで取得できます。Antigravity はファイル配置後に再起動するだけで自動認識します。
1. 前提
- Node.js v16 以上 (
degit 実行に必要)
- Antigravity がローカルで動いていること
2. degit でフォルダ取得
プロジェクトのルートで以下のコマンドを実行します。
npx degit aazutaku/ai-note/antigravity/desktop-tension-meter .agent/skills/desktop-tension-meter
.agent/skills/desktop-tension-meter の中に SKILL.md / scripts/ / references/ / README.md が展開されます。
3. ファイル配置確認
ls .agent/skills/desktop-tension-meter
# 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記事を探す
本記事に付いているタグから、気になるテーマの記事を探せます。タグページで関連記事をまとめて読めるので、ぜひチェックしてみてください!
