Skip to content

feat: スラッシュコマンド機能 - #13

Merged
takecchi merged 1 commit into
mainfrom
feat/slash-commands
Jul 19, 2026
Merged

feat: スラッシュコマンド機能#13
takecchi merged 1 commit into
mainfrom
feat/slash-commands

Conversation

@takecchi

Copy link
Copy Markdown
Owner

概要

入力欄の先頭に / を打つとコマンドとして扱えるようにしました。今後どんどんコマンドを増やせるよう、レジストリ駆動 + 純粋関数で拡張しやすい土台にしています。

コマンドの増やし方(設計の肝)

src/core/commands.tsCOMMANDS 配列に 1 エントリ足すだけです。

export const COMMANDS: readonly CommandSpec[] = [
  { name: 'help', aliases: ['?'],          action: 'help', describe: (m) => m.command.help },
  { name: 'quit', aliases: ['exit', 'q'],  action: 'quit', describe: (m) => m.command.quit },
];

新しい動作を足すときは CommandAction に種類を追加し、UI 側(session-list.tsxrunCommandInput)の 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.ts100% カバレッジ)。
  • tests/commands.test.tsx: App 経由の UI 配線(パレット表示・前方一致・/help オーバーレイ・/quitdispose・未知エラー)。

確認

  • npm test383 件全緑、core/utils カバレッジ 80% 維持)
  • npm run lint
  • npm run typecheck
  • npm run build

Test plan

  • 実端末で / 入力時のパレット表示・/help オーバーレイ・/quit 終了を手動確認(TTY 必要)

入力欄の先頭が `/` のとき、通常の指示ではなくコマンドとして扱う土台を追加。
コマンドは `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
takecchi merged commit 17494a9 into main Jul 19, 2026
1 check passed
@takecchi
takecchi deleted the feat/slash-commands branch July 19, 2026 07:45
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)
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