Skip to content

feat: Claude Code 風 TUI と shift+tab パーミッションモード - #2

Merged
takecchi merged 1 commit into
mainfrom
feat/claude-code-ui
Jul 18, 2026
Merged

feat: Claude Code 風 TUI と shift+tab パーミッションモード#2
takecchi merged 1 commit into
mainfrom
feat/claude-code-ui

Conversation

@takecchi

Copy link
Copy Markdown
Owner

概要

Claude Code の実画面に寄せて TUI を刷新しました。あわせて、main に取り込まれた i18n(ja/en)機能へ統合しています(新規文字列も ja/en 両カタログに追加)。

主な変更

見た目(Claude Code 風)

  • 入力欄: 角丸ボックス → 上下の全幅横罫線 + キャレット(Claude Code の実画面準拠)
  • モード行: 下部に ⏵⏵ auto mode on (shift+tab to cycle) 形式のモード行を追加
  • 起動ヘッダ: 枠なしのバナー(マスコット + ワードマーク + 副題 + cwd)。マスコットは banner.tsxpaint(ch,row,col)1文字単位に色付け可能
  • 詳細ログ: (ツール)/ (結果)/ >(ユーザー)グリフで転記

shift+tab パーミッションモード(実トグル)

  • SessionManagerRunModeauto | confirm)+ cycleMode() + modePolicy を追加
  • tool 実行時に mode を読むため、切替は稼働中セッションにも即反映
  • auto = AskUserQuestion 以外は自動承認 / confirm = 毎回 allow/deny を要求(→ awaiting_permission / 一覧で「許可待ち」)
  • useRunMode() で購読、両ビューで shift+tabcycleMode()

i18n 統合

  • 新規文字列(banner.subtitle, footer.autoMode / confirmMode / cycleHint)を core/i18n.tsja/en 両方に追加
  • 新規/変更コンポーネントは useMessages() 経由に統一(ハードコード文字列なし)
  • i18n.spec.ts の ja/en キー一致テストが番人として通過

テスト

  • npm run typecheck / npm run lint / npm test すべてグリーン(131 tests
  • 追加テスト:
    • SessionManager: getMode / cycleMode / 通知(スナップショット非再構築)
    • 統合: shift+tab → confirm モードで tool が「許可待ち」にエスカレート
  • ja/en 双方のレンダリングを ink-testing-library で目視確認

手動確認 TODO

  • npm run dev(要 claude ログイン + 対象リポジトリ)で実機表示を確認
  • 実端末で shift+tab の auto ⇄ confirm 切替を確認
  • CODIVA_LANG=en で英語表示を確認

補足

  • 参考にした流出ソースは一切コピーしていません(実画面の外観のみ再現)。
  • 既知の軽微点: 英語ロケールで badge「Awaiting permission」がバッジ幅(12)で2行に折り返す。別 PR で幅調整可。

🤖 Generated with Claude Code

Claude Code の実画面に寄せて TUI を刷新する。

- 入力欄を上下の全幅横罫線 + ❯ キャレットに(角丸枠を廃止)
- 下部に ⏵⏵ auto / ⏸ confirm モード行を追加し、shift+tab で切替
  - SessionManager に RunMode(auto|confirm) / cycleMode() / modePolicy を追加。
    tool 実行時に mode を読むので稼働中セッションにも即反映される
  - confirm は AskUserQuestion 以外も allow/deny を要求(→ 許可待ち)
  - useRunMode() で購読
- 起動ヘッダをマスコット付きの枠なしバナーに(1文字単位で塗れる paint())
- 詳細ログを ⏺ / ⎿ / > グリフで転記
- 追加文字列は i18n カタログ(banner / footer グループ)に ja/en で追加
@takecchi
takecchi merged commit 0403540 into main Jul 18, 2026
1 check passed
@takecchi
takecchi deleted the feat/claude-code-ui branch July 18, 2026 15:34
takecchi added a commit that referenced this pull request Jul 18, 2026
## 概要

Phase 6(MVP後バックログ)のうち **4項目** を実装しました(`includePartialMessages`
によるストリーミング表示は今回対象外)。純粋ロジックは `core/`、副作用は `utils/`/合成ルートという既存の分離を踏襲しています。

着手項目はユーザーと相談のうえ決定(TASKS.md の「着手前にユーザーと相談」に従う)。

## 実装内容

### 1. 設定ファイル拡張 (#2)
- `CodivaConfig` に `model` / `effort` / `permissionMode` /
`maxBudgetUsd` / `notifications` を追加
- 検証は `toConfig()` に集約(不正値は静かに既定へフォールバック、TUI をクラッシュさせない)
- `SessionOptions` に束ね、`SessionManager → Session → SDK Options` へ注入
- `permissionMode` 未指定時は従来どおり `acceptEdits`

### 2. コスト表示 (#3)
- 純粋な `core/cost.ts`(`totalCostUsd()` / `formatUsd()`)を追加
- 一覧のバナーに合計コスト、詳細に各セッションのコスト行
- reducer は既に `result.total_cost_usd` を `state.totalCostUsd`
に保持していたため、導出のみ追加

### 3. デスクトップ通知 (#5)
- 発火判定は純粋な `core/notify.ts` の `notificationFor(prev, next, messages)` —
**状態遷移時のみ**発火(連続更新で鳴り続けない)
- 実 I/O は `utils/notify.ts`(darwin=`osascript` /
linux=`notify-send`、文字列は **argv 渡し**で注入防止、missing binary 等は握り潰す
best-effort)
- `SessionManager.onTransition` に配線、`config.notifications: false` で無効化

### 4. セッション復元 (#1)
- 永続スナップショットの型・変換・検証は純粋な `core/persistence.ts`(`toPersistedSession` /
`restoredSessionState` / `fromPersistedJson`)
- ファイル I/O は
`utils/state-store.ts`(`<repo>/.codiva/state.json`、破損時は空へフォールバック、起動時に存在しない
worktree を prune)
- `Session` は `resume`(SDK session id)/ `restored`(復元済み
state)を受け、**復元セッションは起動時にサブプロセスを立てず、最初の追加指示で遅延 resume**(起動時のサブプロセス乱立を回避)
- 終了時は `stop()`(quiet 停止)で実行中セッションも resumable のまま保存(`abort()` = failed 化
と区別)
- `SessionManager.restore()` / `persistableState()` を追加。id/slug
を予約して新規セッションとの衝突を回避

## テスト計画

- [x] `npm test` — **234件全緑**(旧131 → +103)
- [x] coverage — Statements 95.5% / Branches 85% / Functions 89.6% /
Lines 96.5%(core・utils とも 80% 閾値超)
- [x] `npm run typecheck` — 緑
- [x] `npm run lint` — 緑(既存の banner.tsx `paint` 未使用引数 warning のみ、本PR無関係)
- [x] `npm run build` — 緑
- 新規 spec: `config`(拡張) / `cost` / `notify`(core+utils) / `persistence`
/ `state-store`
- 統合テスト `tests/restore.test.tsx`: run → persist → 新 manager restore →
追加指示で `resume` が query options に載る、までを実 `Session` で通し検証
- [ ] **手動受け入れ(未実施)**: 実 Claude セッションでの resume 挙動・OS 通知の実表示は TTY +
認証が要るため未確認。仕組みは統合テストで検証済み

## ドキュメント

`TASKS.md`(チェック更新+実績メモ)、`ARCHITECTURE.md`(新モジュール・責務・「Phase 6
機能」節・決定表)、`TECH_NOTES.md`(Options の resume/model/effort/maxBudgetUsd
を実装済みに更新)を同期済み。

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant