feat: スラッシュコマンド機能 - #13
Merged
Merged
Conversation
入力欄の先頭が `/` のとき、通常の指示ではなくコマンドとして扱う土台を追加。 コマンドは `core/commands.ts` の `COMMANDS` レジストリに 1 エントリ足すだけで 増やせる設計にした(解析・照合は純粋関数に閉じ込め、副作用は UI が `CommandAction` を解釈して実行)。 - core/commands.ts: レジストリ + parseCommand / matchCommands / runCommand(純粋) - ui/command-palette.tsx: 入力中に前方一致コマンドを表示するパレット - session-list.tsx: composer の Enter でコマンド分岐、/help オーバーレイ - 初期コマンド: /help(別名 ?)・/quit(別名 exit / q)。未知は操作エラー - i18n: command グループを ja/en 両カタログに追加 テスト: commands.spec.ts(純粋・100% cov)+ tests/commands.test.tsx(UI 配線)。 全 383 テスト緑 / lint / typecheck / build 緑。
takecchi
added a commit
that referenced
this pull request
Aug 6, 2026
## 背景 セッションが自分で別ブランチを切って `gh pr create` すると、1 セッションに複数の PR が紐づきます。しかし一覧の PR セルは**セッションブランチ(`codiva/<slug>`)の PR しか出せず**、2 本目以降はどこにも表示されませんでした。 ## 変更内容 ### 検知(`core/pr-detect.ts` 新規・純粋) - `gh pr create` を実行した **tool_use の結果**に出る PR URL を拾う(`sdk-parse` が tool_use id を控えて tool_result と突き合わせる)。 - ログ全体から URL を拾わないのは誤検出を避けるため — `gh pr list` の出力や、`gh pr view` / WebFetch で覗いただけの他人の PR まで「このセッションの PR」になってしまう。 - MCP の `create_pull_request` 系ツールもツール名で拾う。 - 参照の追加・除去は**変化が無ければ同じ配列参照を返す**(`state.json` を無駄に書き直さない / 再描画を増やさない)。 ### 状態・永続化 - `SessionState.extraPrs`(識別のみ・**永続**)と `prCreateToolIds`(結果待ちの対応付け・transient)を追加。 - `state.json` に保存・復元(壊れた要素は 1 件ずつ落とす)。reducer はブランチの PR と重複したら畳む。 ### 表示 | 画面 | 表記 | |---|---| | 一覧 | `✓ #12 +2`(代表 + 残り件数)。PR 列は複数 PR の行があるときだけ 10 → 14 桁に広げる | | 詳細 | `PR 3 件: ✓ #12 · #13 · #14`(複数 PR のときだけ 1 行。1 本ならログの縦幅を 1 行も譲らない) | - **代表はセッションブランチの PR**。`prStatus`(グリフ)を持つ唯一の PR で、クリック / `p` で開く先でもあるため、見えている番号と開く先とグリフの意味を一致させた。 - セッションが自分で作った PR は codiva が追跡・操作しない(別ブランチのものを勝手に ready 化・マージしない)ので**番号のみ・グリフなし**。状態を知らないのに緑や赤で嘘をつかない。 - **`gh` の追加呼び出しはゼロ**(API クォータを増やさない)。 - 描画とクリック当たり判定は必ず同じ列幅(`core/list-hit.ts` の `prCellWidth`)を使う。 - `PrCell` / `prStatusBadge` は `ui/pr-cell.tsx` に共通化(一覧と詳細で同じグリフ・同じ色)。 ### ドキュメント `README.md`(利用者向けの表記説明)/ `docs/ARCHITECTURE.md`(状態フィールド・設計判断)/ `docs/TASKS.md`(Phase 27)/ `CLAUDE.md`(コードの地図)。 ## テスト - `src/core/pr-detect.spec.ts`(新規・テーブルドリブン): コマンド判定 / URL 抽出(GHE ホスト・サブパス・重複・issues リンク)/ 参照同一性 / 上限 / 表示ヘルパ。 - `src/core/sdk-parse.spec.ts`: 実フィクスチャと同じメッセージ形で tool_use → tool_result の対応、`gh pr list` を数えないこと、ブランチ PR と判明したら畳むこと。 - `src/core/persistence.spec.ts`: 往復と壊れた JSON の扱い。 - `src/core/list-hit.spec.ts`: 列幅の切替。 - `tests/app.test.tsx`: 一覧に `✓ #42 +2` が出て `#43` は出ないこと、詳細に全件が並ぶこと、1 本のときは詳細に PR 行を出さないこと。 ### 動作確認 - [x] `npm run lint` / `npm run typecheck` / `npm test`(2,232 件)/ `npm run build` - [ ] 実 TTY + Claude 認証での手動確認(非対話セッションでは実行できないため未実施)。確認観点: 複数 PR を出したセッションの行が `#12 +2` になり、PR セルのクリックで代表の PR が開く / 詳細ビューに全件が並ぶ / 再起動しても `+n` が残る。 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
入力欄の先頭に
/を打つとコマンドとして扱えるようにしました。今後どんどんコマンドを増やせるよう、レジストリ駆動 + 純粋関数で拡張しやすい土台にしています。コマンドの増やし方(設計の肝)
src/core/commands.tsのCOMMANDS配列に 1 エントリ足すだけです。新しい動作を足すときは
CommandActionに種類を追加し、UI 側(session-list.tsxのrunCommandInput)の switch で受けるだけ。解析・照合(parseCommand/matchCommands/runCommand)は純粋関数に閉じ込め、副作用(終了・ヘルプ表示など)は UI 層がCommandActionを解釈して実行します(core は Ink/React 非依存の規約を維持)。UX
ui/command-palette.tsx)。/q→/quitに絞り込み。/help(別名?): 全コマンドのヘルプ一覧をオーバーレイ表示(任意キーで閉じる)。/quit(別名exit/q): codiva を終了。useInputの原則は維持(コマンドは composer の Enter 分岐で処理)。i18n
commandグループを ja/en 両カタログに追加(説明文はカタログに集約、規約どおり UI に直書きしない)。テスト
src/core/commands.spec.ts: 純粋ロジックをテーブル駆動でテスト(commands.tsは 100% カバレッジ)。tests/commands.test.tsx: App 経由の UI 配線(パレット表示・前方一致・/helpオーバーレイ・/quitでdispose・未知エラー)。確認
npm test(383 件全緑、core/utils カバレッジ 80% 維持)npm run lintnpm run typechecknpm run buildTest plan
/入力時のパレット表示・/helpオーバーレイ・/quit終了を手動確認(TTY 必要)