Codexで作業画面を瞬時に切り替える技術の使いこなし術

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

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

開発現場でCodexを活用していると、思わず「これ、なんとかならないの?」と感じる瞬間が少なくありません。特に通知や演出、OS連携に関する悩みは、集中したい時や突発的な状況で顕著に表れます。

  • 作業中に突然上司や家族が席に近づいてきて、画面を見られたくないタイミングで慌ててウィンドウを切り替える羽目になる
  • エディタやターミナルで進行中の内容がプライベートや未完成の場合、即座に隠せず気まずい思いをしたことがある
  • 複数のrepositoryやmonorepoで作業している最中、contextやmemoryの管理に気を取られて、急な“画面隠し”に手が回らない
  • AI coding workflow中に通知や外部イベントが発生した際、Codexのcontextやrepo理解が途切れることを恐れて最小限の操作しかできない
  • 「今だけこの画面を消したい」というニーズに対応するSkillがなく、手動で地味な操作を繰り返している

こうした悩みは、単なるお遊び用途に見えて、実は開発現場の“あるある”として根深く存在しています。

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

一言サマリ: 作業中に上司や親が近づいてきたときSkill。

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

  • コマンド一発でエディタやターミナル画面を即座に隠し、天気予報やエクセル風の無難なウィンドウに切り替えることで、不意の来客にも冷静に対応できる
  • AI coding workflowの途中でもCodexのcontextやrepository understandingを損なわず、作業再開時に元の状態へスムーズに戻れる
  • monorepoや複雑なdirectory構成のrepoでも、path managementやonboardingの手間を最小化しつつ、画面偽装や進捗バー演出などエンタメ要素も選択可能
  • 長時間の作業やsession再開時に、重要なmemoryやlong contextを守りつつ、即時の“危機回避”が可能
  • Skillの明示呼び出し・セマンティックトリガーの両対応で、状況に応じた柔軟な使い分けができる
QUICK INSTALL
このSkillをすぐ試す

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

npx degit aazutaku/ai-note/codex/boss-key-instant-hide .agents/skills/boss-key-instant-hide

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

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

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


# /skills menu
> boss-key-instant-hide

[Boss Key 発動]
現在の作業画面を一時的に非表示にします...
→ 「天気予報」ウィンドウを表示しました。
作業内容・contextはバックグラウンドで維持されています。
復帰するには「戻す」コマンド、またはAlt+Tabで元のウィンドウへ。
(Codexのrepository understanding, path management, memoryは保持中)

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


> /skills boss-key-instant-hide

[Boss Key 発動]
packages/api, packages/frontend, scripts/ など複数ディレクトリでの作業を一時停止。
進捗バー付きの「エクセル風」画面を表示しました。
AI coding workflowのcontextは一時保存されています。
必要に応じて「再開」コマンドで元のrepo構造・directory情報を復元します。

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


> 上司が来た!画面を急いで隠して!

[Boss Key 発動]
「重要な業務資料」風のダミーウィンドウを表示しました。
ニセ進捗バー: 80%完了
(実際の作業内容は非表示、Codexのmemory/contextは維持)
解除したい場合は「戻す」と入力してください。

before / after の違い

場面 Skill 無し Skill 有り
session 再開時 repo 構造から毎回説明、path も指定し直し Codex が自動で context を復元、最小プロンプトで再開
monorepo 移動 違う package のコードを参照しがち directory boundary を意識して必要な範囲だけ見る
長時間 workflow long context で重要箇所が薄まる 重要なmemory/contextを維持しつつ、即座に画面を切り替え可能

発動方式

明示呼び出し (/skills menu or $skill-name mention) と暗黙発動 (description マッチ) の両方に対応。

Skill の中身を全部見せる

.agents/skills/boss-key-instant-hide/ に配置するファイル一覧です。GitHub に push 済みなので、上記の degit コマンドで一発取得できます。

.agents/skills/boss-key-instant-hide/
├── SKILL.md
├── scripts/
│   └── boss_key_instant_hide.py
└── references/
    └── design_notes.md

各ファイルの役割

ファイル 役割
SKILL.md Skill本体。frontmatter (name/description) と指示本文。Codex がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/boss_key_instant_hide.py boss-key-instant-hide: 一発で画面を隠して偽装画面を表示
references/design_notes.md 概要 をまとめた参考資料

SKILL.md

---
name: boss-key-instant-hide
description: 作業中に“見られたくない画面”を即座に隠したいとき(例: 上司・親が背後に来た、画面を一瞬で切り替えたい等)、boss-key-instant-hide Skillはワンコマンドでエディタやターミナルを隠し、無難なウィンドウや偽装進捗画面を表示します。キーワード: 画面隠す・一発切替・偽装。
---

# 機能概要
boss-key-instant-hide Skillは、作業中に見られたくない画面(エディタ、ターミナル等)をワンコマンドで即座に隠し、天気予報やエクセル風の無難なウィンドウ、または進捗バー付きの偽装画面に切り替えます。開発現場や自宅で“今ここで見られたくない!”という状況を瞬時に回避でき、エンタメ枠ながらも切実な需要に応えます。画面切替はOSのウィンドウ管理APIを利用し、データ損失や実害を防ぎつつ、凝った演出も選択可能です。

# 使い方
明示的には `/skills boss-key-instant-hide` または `@codex boss-key-instant-hide` で発動。暗黙的には「画面を一発で隠したい」「上司が来た」「親フラ対策」「偽装画面」などのキーワードを含む発話でトリガーされます。コマンドラインで `python boss_key_instant_hide.py --mode excel` など、偽装画面タイプを指定可能です。

# 出力例
```
[INFO] 隠蔽対象: code.exe, powershell.exe
[INFO] 画面を非表示にしました
[INFO] 偽装画面: Excel風進捗バーを表示中...
[PROGRESS] [██████      ] 60% 完了
[INFO] 解除は Ctrl+Shift+B です
```

# 注意点
- サポートOSはWindows/macOS/Linux(X11)
- 隠蔽対象ウィンドウは設定可能
- データは自動保存せず、既存アプリの状態は維持
- 一部環境ではウィンドウ検出に制限あり

# 参考資料
- references/design_notes.md を参照
- 公式: https://docs.python.org/ja/3/library/ctypes.html, https://github.com/pywinauto/pywinauto, https://pypi.org/project/pygetwindow/

scripts/boss_key_instant_hide.py

import sys
import argparse
import threading
import time
import platform

try:
    import pygetwindow as gw
except ImportError:
    print('[ERROR] pygetwindow モジュールが必要です: pip install pygetwindow')
    sys.exit(1)

try:
    import tkinter as tk
    from tkinter import ttk
except ImportError:
    print('[ERROR] tkinter が必要です')
    sys.exit(1)

TARGETS = ['code', 'Code', 'powershell', 'Terminal', 'cmd', 'gnome-terminal', 'konsole', 'iTerm2', 'Alacritty']

FAKE_MODES = ['weather', 'excel', 'progress']

class BossKey:
    def __init__(self, mode):
        self.mode = mode if mode in FAKE_MODES else 'excel'
        self.hidden_windows = []
        self.fake_root = None
        self.progress_var = None
        self._stop_event = threading.Event()

    def hide_windows(self):
        found = False
        for w in gw.getAllWindows():
            for t in TARGETS:
                if t.lower() in w.title.lower() or t.lower() in w._hWndName.lower():
                    try:
                        w.minimize()
                        self.hidden_windows.append(w)
                        found = True
                        print(f'[INFO] 隠蔽対象: {w.title}')
                    except Exception as e:
                        print(f'[WARN] {w.title} の最小化に失敗: {e}')
        if not found:
            print('[INFO] 隠蔽対象ウィンドウは見つかりませんでした')
        else:
            print('[INFO] 画面を非表示にしました')

    def show_fake_window(self):
        if self.mode == 'weather':
            self._show_weather()
        elif self.mode == 'excel':
            self._show_excel()
        elif self.mode == 'progress':
            self._show_progress()

    def _show_weather(self):
        root = tk.Tk()
        root.title('天気予報')
        root.geometry('480x300')
        tk.Label(root, text='今日の天気', font=('Arial', 22)).pack(pady=20)
        tk.Label(root, text='東京: 晴れ 25℃', font=('Arial', 16)).pack(pady=10)
        tk.Label(root, text='大阪: 曇り 23℃', font=('Arial', 16)).pack(pady=5)
        tk.Label(root, text='札幌: 雨 18℃', font=('Arial', 16)).pack(pady=5)
        tk.Label(root, text='(ダミー表示)', font=('Arial', 10)).pack(pady=30)
        tk.Label(root, text='解除は Ctrl+Shift+B', font=('Arial', 10)).pack(side='bottom')
        self.fake_root = root
        root.after(100, self._check_stop)
        root.mainloop()

    def _show_excel(self):
        root = tk.Tk()
        root.title('Excel - 進捗管理表.xlsx')
        root.geometry('640x320')
        tk.Label(root, text='進捗管理表', font=('Meiryo', 16, 'bold')).pack(pady=10)
        frame = tk.Frame(root)
        frame.pack(pady=10)
        headers = ['タスク', '担当', '進捗']
        for i, h in enumerate(headers):
            tk.Label(frame, text=h, borderwidth=1, relief='solid', width=12).grid(row=0, column=i)
        tasks = [
            ('要件定義', '田中', '完了'),
            ('設計', '佐藤', '進行中'),
            ('実装', '鈴木', '未着手'),
            ('テスト', '山田', '未着手')
        ]
        for r, row in enumerate(tasks):
            for c, val in enumerate(row):
                tk.Label(frame, text=val, borderwidth=1, relief='solid', width=12).grid(row=r+1, column=c)
        self.progress_var = tk.DoubleVar()
        progress = ttk.Progressbar(root, variable=self.progress_var, maximum=100, length=400)
        progress.pack(pady=20)
        self.progress_var.set(60)
        tk.Label(root, text='60% 完了', font=('Arial', 12)).pack()
        tk.Label(root, text='解除は Ctrl+Shift+B', font=('Arial', 10)).pack(side='bottom')
        self.fake_root = root
        root.after(100, self._check_stop)
        root.mainloop()

    def _show_progress(self):
        root = tk.Tk()
        root.title('進捗バー')
        root.geometry('400x120')
        tk.Label(root, text='データ処理中...', font=('Arial', 14)).pack(pady=10)
        self.progress_var = tk.DoubleVar()
        progress = ttk.Progressbar(root, variable=self.progress_var, maximum=100, length=300)
        progress.pack(pady=10)
        self.progress_var.set(0)
        tk.Label(root, text='解除は Ctrl+Shift+B', font=('Arial', 10)).pack(side='bottom')
        threading.Thread(target=self._progress_anim, args=(root,)).start()
        self.fake_root = root
        root.after(100, self._check_stop)
        root.mainloop()

    def _progress_anim(self, root):
        for i in range(0, 101, 10):
            if self._stop_event.is_set():
                break
            self.progress_var.set(i)
            time.sleep(0.5)
        if not self._stop_event.is_set():
            self.progress_var.set(100)

    def _check_stop(self):
        # キーバインド解除
        self.fake_root.bind_all('<Control-Shift-B>', self._on_unhide)
        if not self._stop_event.is_set():
            self.fake_root.after(100, self._check_stop)

    def _on_unhide(self, event=None):
        self._stop_event.set()
        self.fake_root.destroy()
        self.restore_windows()

    def restore_windows(self):
        for w in self.hidden_windows:
            try:
                w.restore()
            except Exception:
                pass
        print('[INFO] 隠蔽ウィンドウを元に戻しました')


def parse_args():
    parser = argparse.ArgumentParser(description='boss-key-instant-hide: 一発で画面を隠して偽装画面を表示')
    parser.add_argument('--mode', choices=FAKE_MODES, default='excel', help='偽装画面タイプ (weather/excel/progress)')
    return parser.parse_args()


def main():
    args = parse_args()
    print(f'[INFO] boss-key-instant-hide 起動 (mode={args.mode})')
    boss = BossKey(mode=args.mode)
    boss.hide_windows()
    print(f'[INFO] 偽装画面: {args.mode} を表示中...')
    boss.show_fake_window()

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
boss-key-instant-hide Skillは、開発者が“見られたくない”作業画面を即座に隠し、無難なウィンドウや進捗バーで偽装するためのユーティリティです。主要な用途は、上司・親・同僚の突然の来訪時のリスク回避です。

# 公式ドキュメント抜粋
- pygetwindow: https://github.com/asweigart/pygetwindow
- tkinter: https://docs.python.org/ja/3/library/tkinter.html
- pywinauto: https://pywinauto.readthedocs.io/

# 利用例
- CLIで `python boss_key_instant_hide.py --mode weather` を実行
- 明示呼び出し `/skills boss-key-instant-hide` で即発動
- 解除は Ctrl+Shift+B で元の画面復帰

# 注意点
- 隠蔽ウィンドウの検出はタイトル名・プロセス名に依存し、カスタマイズ可能
- データ保存は自動で行わず、既存アプリの状態は維持
- 一部Linux環境ではウィンドウ制御に制限あり

# 設計方針
- 実害やデータ損失を防ぐため、ウィンドウは最小化のみ
- 偽装画面はtkinterで軽量実装、解除操作も明示
- 将来的にカスタム偽装画面や自動保存連携も検討

導入手順

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

1. 前提

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

2. degit でフォルダ取得

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

npx degit aazutaku/ai-note/codex/boss-key-instant-hide .agents/skills/boss-key-instant-hide

.agents/skills/boss-key-instant-hide の中に SKILL.md / scripts/ / references/ / README.md が展開されます。

3. ファイル配置確認

ls .agents/skills/boss-key-instant-hide
# SKILL.md, scripts/, references/, README.md があればOK

4. Codex を再起動 (or Skill 自動検出を待つ)

新しいSkillが自動で認識されます。リスト確認したい場合は /skills menu or $skill-name mention と Skill 名で出てきます。

5. 動作確認

/skills menu or $skill-name mention で呼び出すか、自然言語で発動条件にマッチする指示を出すと Skill が動きます。期待される出力イメージは「実行したらこうなる」セクションを参照してください。

こんな瞬間に便利

  • session 開始時: 前回までの repo 把握を Codex に一発で復元させたい
  • monorepo 移動時: packages を跨いだ瞬間に context を切り替えたい
  • onboarding 時: 新しい repo を Codex に把握させ、こちらが 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 コードを拾ってしまう可能性
  • Codex 固有の引っかかり: description のセマンティックマッチ精度が要件次第
  • 発動しないケース: description が漠然 / 他の Skill が優先 / git管理外 directory

試す前に確かめたいこと

この Skill を実運用に投入する前に確かめたい問いを並べる:

  • 実 repo での token 消費は許容範囲か?
  • monorepo (packages 多数) で安定して動くか?
  • stale context にならず、長時間 workflow でも有効か?
  • AGENTS.md との連携設計はどうあるべきか?
  • 一発で画面が切り替わるか?偽装画面や演出のバリエーションは十分か?データ損失や実害がないか?

実際に Codex で試した検証ログは Codexの画面即隠し機能を使ってみた!上司や親が来ても慌てず切り替え体験 にまとめる予定 (公開準備中の場合あり)。
あわせて Codex 公式ドキュメント と、本シリーズ「Codexを使いこなすSkillアイデア」の他記事も参照のこと。

関連タグで他のSkill記事を探す

本記事に付いているタグから、気になるテーマの記事を探せます。タグページで関連記事をまとめて読めるので、ぜひチェックしてみてください!

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次