name: panorama description: "Obsidian Kanban ダッシュボードのタスク管理。サブコマンド: /panorama init, /panorama new, /panorama update, /panorama done, /panorama block, /panorama unblock"
panorama — Obsidian Kanban タスク管理
サブコマンドで操作する。引数でサブコマンドを判別:
| コマンド | 動作 |
|---|---|
/panorama init |
ghostty の現在ウィンドウを 2×4 grid に分割 |
/panorama new [名前] |
既存タスク完了 → 新タスク作成 → 🟢 対応中 |
/panorama update |
タスク名・セッションID更新、コンテキスト70%超で compact |
/panorama done |
タスクをアーカイブして削除 |
/panorama block |
🔴 ブロック中に移動 |
/panorama unblock |
🟢 対応中に戻す |
引数なしの /panorama は /panorama new として扱う。
前提
- Vault:
~/Documents/Obsidian/work-dashboard - Dashboard:
$VAULT/Dashboard.md - プロジェクトノート:
$VAULT/projects/<name>.md - auto マーカー: 行末
<!-- auto -->は絶対に手で書かない - セッションID:
<!-- session: {id} -->としてHTMLコメントで埋め込み - PC名 (
pcフィールド): 複数PCから接続することを想定し、カード作成/更新時に現在のマシン名を記録する - tmux セッション名 (
tmuxフィールド): tmux 配下で作業している場合のみ記録する。tmux 外では省略(フィールドごと書かない)
セッションID取得
PROJECT_DIR="$HOME/.claude/projects/$(pwd | sed 's|/|-|g')"
SESSION_ID=$(ls -t "$PROJECT_DIR"/*.jsonl 2>/dev/null | head -1 | xargs basename | sed 's/\.jsonl$//')
PC名取得
PC_NAME=$(scutil --get ComputerName 2>/dev/null || hostname -s)
tmux セッション名取得
TMUX_SESSION=$(tmux display-message -p '#S' 2>/dev/null || echo "")
TMUX_SESSION が空文字の場合は tmux 外で実行されているので、カード/履歴への tmux フィールド追記を丸ごとスキップする。
/panorama init
現在の ghostty ウィンドウを 2×4 grid(横 4・縦 2、合計 8 pane)に分割する。
scripts/init_ghostty.shを実行:
bash "$HOME/.claude/skills/panorama/scripts/init_ghostty.sh"
スクリプトは AppleScript 経由で以下を実行(binary split で各分割を 50/50 に保つ):
- Phase 1: 横方向に 4 等分(A|C|B|D)
cmd+dで右分割(A|B、focus=B)cmd+opt+leftで A へ戻るcmd+dで A を分割(A|C|B、focus=C)cmd+opt+rightで B へcmd+dで B を分割(A|C|B|D、focus=D)
- Phase 2: 各列を下方向に分割(右端 D から左へ順に)
cmd+shift+dで D を下分割cmd+opt+leftで B 列へ、cmd+shift+dcmd+opt+leftで C 列へ、cmd+shift+dcmd+opt+leftで A 列へ、cmd+shift+d
- Phase 3:
cmd+ctrl+=でequalize_splitsを呼び、端数丸めの誤差を解消して全 pane を均等化
- Phase 1: 横方向に 4 等分(A|C|B|D)
注意:
- ghostty が起動済みであること(起動していなければスクリプトはエラーで終了)
- 初回は「システム設定 → アクセシビリティ」で osascript/ターミナルに権限付与が必要
- ghostty の keybind がデフォルトであること(カスタマイズしている場合は動作しない)
/panorama new [名前]
- コンテキスト取得:
pwd
git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "(n/a)"
- セッションID・PC名・tmux セッション名を取得:
PROJECT_DIR="$HOME/.claude/projects/$(pwd | sed 's|/|-|g')"
SESSION_ID=$(ls -t "$PROJECT_DIR"/*.jsonl 2>/dev/null | head -1 | xargs basename | sed 's/\.jsonl$//')
PC_NAME=$(scutil --get ComputerName 2>/dev/null || hostname -s)
TMUX_SESSION=$(tmux display-message -p '#S' 2>/dev/null || echo "")
$VAULT/Dashboard.mdを読み、現在のセッションID と一致する<!-- session: {id} -->または<!-- session: {id} | blocked -->を持つカードを 🟢/🟡/🔴 から検索。見つかれば/panorama doneのステップ2〜6を全て実行して自動完了する(アーカイブ+✅完了へ移動)。セッションIDで見つからない場合は、同じpathのカードを 🟢/🟡/🔴 からフォールバック検索する。タスク名を決定。引数があればそのまま使用。なければ会話履歴から提案して確認。
tmux 配下の場合、ウィンドウ名を変更:
tmux rename-window "{task}"
## 🟢 対応中の直下にカードを挿入。TMUX_SESSIONが空文字なら**tmux:**行は省略する:
- **{project} / {task}**
- **path:** {absolute-path}
- **pc:** {pc-name}
- **tmux:** {tmux-session}
- → [[projects/{project}]]
<!-- session: {session-id} -->
- ユーザに完了を通知。
/panorama update
セッションIDを取得し、Dashboard.md から
<!-- session: {id} -->が一致するカードを特定。見つからなければpwdのpath:フィールドでフォールバック検索。それでも見つからなければユーザに通知して終了。会話履歴からタスク名を再提案し、ユーザー確認後にカードのタイトル行を更新。
カード内の
<!-- session: ... -->を現在のセッションIDに更新。存在しなければ追加。カード内の
**pc:** {old}を現在の PC名(前提セクション「PC名取得」のPC_NAMEに従う)に更新。pcフィールドが存在しない場合は**path:**行の直後に- **pc:** {pc-name}を追加する。tmux セッション名の更新(前提セクション「tmux セッション名取得」の
TMUX_SESSIONに従う):TMUX_SESSIONが空文字(tmux 外)の場合、カードに**tmux:**行があっても削除しない・追加もしない(no-op)。TMUX_SESSIONが空でない場合、カード内の**tmux:** {old}を更新。tmuxフィールドが存在しない場合は**pc:**行の直後に- **tmux:** {tmux-session}を追加する。
tmux 配下の場合、ウィンドウ名を新タスク名に更新:
tmux rename-window "{task}"
- コンテキスト使用量を確認。ステータスバーの使用率が 70% 以上なら
/compactを実行。
/panorama done
重要: 全ステップを順番通りに実行すること。ステップのスキップ禁止。ステップ7の /clear 実行は必須。
セッションIDで Dashboard.md から該当カードを特定(🟢/🟡/🔴 全てを検索し、
<!-- session: {id} -->または<!-- session: {id} | blocked -->で突合)。見つからなければpwdのpath:フィールドで 🟢/🟡/🔴 全列をフォールバック検索。見つからなければユーザに通知して終了。カードからプロジェクト名とタスク名を抽出(タイトル行
**{project} / {task}**をパース)。$VAULT/projects/{project}.mdが存在しなければ作成:
# {project}
## 概要
## リンク
## 履歴
$VAULT/projects/{project}.mdの## 履歴セクションに追記。tmux行はカードから抽出し、無ければ省略(tmux 外で作業したタスク):
### YYYY-MM-DD {task}
- session: {session-id}
- branch: {branch}
- path: {path}
- pc: {pc-name}
- tmux: {tmux-session}
※ pc はカードから抽出。無ければ前提セクション「PC名取得」の PC_NAME を使って補う (scutil --get ComputerName 2>/dev/null || hostname -s)。tmux もカードから抽出し、無ければその行ごと省略する。
Dashboard.md でカードを
## ✅ 完了列に移動する(削除しない)。カードのテキストブロック全体(タイトル行〜<!-- session: ... -->行を含む)を現在の列から切り取り、## ✅ 完了の直下に挿入する。ユーザに以下の形式で完了を通知:
panorama done 完了
- タスク: {project} / {task}
- 履歴: projects/{project}.md に追記済み
- セッション: {session-id}
- カードを ✅完了 に移動済み
- 必ず
/clearを実行してコンテキストをリセットする。スキップ禁止。
/panorama block
セッションIDで Dashboard.md から該当カードを特定(
<!-- session: {id} -->で突合)。見つからなければpwdのpath:フィールドでフォールバック検索。見つからなければユーザに通知して終了。カードのテキストブロック(タイトル・フィールド・セッションコメント全て)を現在の列から切り取り、🔴 で始まる列の直下に挿入する。カードのタイトルは変更しない。
tmux ウィンドウ名の先頭に
[BLOCK]を追加(元のウィンドウ名はそのまま残す):
CURRENT=$(tmux display-message -p '#W')
tmux rename-window "[BLOCK] $CURRENT"
カード内の
<!-- session: {id} -->を<!-- session: {id} | blocked -->に更新。ユーザに通知。
/panorama unblock
セッションIDで Dashboard.md からブロック中のカードを特定(🔴 列の
<!-- session: {id} | blocked -->で突合)。見つからなければpwdのpath:フィールドで🔴列をフォールバック検索。見つからなければユーザに通知して終了。カードのテキストブロックを 🔴 列から切り取り、
## 🟢 対応中の直下に挿入する。tmux ウィンドウ名から
[BLOCK]を除去:
CURRENT=$(tmux display-message -p '#W')
tmux rename-window "${CURRENT#\[BLOCK\] }"
カード内の
<!-- session: {id} | blocked -->から| blockedを除去。セッションIDを現在のセッションに更新。
カード内の
**pc:**を現在の PC名(前提セクション「PC名取得」のPC_NAME)に更新。別PCで unblock したときに追跡できるようにするため。pcフィールドが無ければ**path:**行の直後に追加する。tmux セッション名を現在の値(前提セクション「tmux セッション名取得」の
TMUX_SESSION)で更新。空文字なら既存のtmux行には触れず追加もしない。空でなければ**tmux:** {old}を新しい値に置換、存在しなければ**pc:**行の直後に- **tmux:** {tmux-session}を追加する。ユーザに通知。
プロジェクトノート作成
/panorama done で projects ノートが必要になった場合に自動実行。手動トリガ: 「プロジェクトノート作って」
- プロジェクト名を引数で受け取る(無ければカレントディレクトリの basename)
$VAULT/projects/{name}.mdが既に存在するなら上書きしない- 存在しない場合はテンプレートで作成
禁止事項
<!-- auto -->マーカー付き行の値を手で書き換えない- Kanban の列見出しを編集・移動しない
- updater が動いていなくてもスキル操作は完結する
<!-- session: ... -->はスキルのみが管理する