Skip to content

v0.43.0

Choose a tag to compare

@Kewton Kewton released this 30 Sep 13:58
· 13 commits to main since this release
496c67c

[0.43.0] - 2026-09-30

Highlight: OpenCode V2(opencode-v2)をエージェントとして正式に登録し、起動・状態表示・承認と質問への応答・スラッシュコマンド・スケジュール・Skill の互換表まで v1 と同じ場所で使えるようにした(#2934 ほか 20 件以上)。あわせて、委任まわりの CLI を強化した — 新しい commandmate reply でワーカーの最新の返答を台帳から読め(#3039)、ask は文脈の上限で止まった依頼を exit 11(id=context-limit)で返し(#3011)、起動直後の Command Code への送信は 503 SESSION_STARTING で「起動中」と区別できる(#3006)。

Added

  • feat(cli): commandmate reply でセッションの最新の返答を転写の台帳から読めるようにした (#3039): commandmate reply <worktree-id> [--instance <id>] [--agent <tool>] [--since <iso8601>] [--json]。ask と同じ規則(転写リーダーが書いた <tool>-turn:<id> 行だけを返答とみなし、relay-sys: / model-changed: を除き、ANSI・制御文字を落とす)で読み、読み取りは src/cli/utils/reply-ledger.ts に切り出して ask と共有する(ask の挙動は不変)。画面へのフォールバックはしない。返答が無いときは stdout 空・stderr 1 行・exit 0、--json は { worktreeId, instanceId, cliToolId, reply, requestId, at } で reply: null。Command Code のワーカーの「止めて報告」も転写ファイルの場所を知らずに読める。

  • feat(opencode-v2): チャット面のダイアログカードに OpenCode V2 のモデル切り替えキー(ctrl+t / ctrl+x m / ctrl+p)を出す (#2983): v1 では #2297 からカードに出していた variant 切り替え・モデル選択・コマンドパレットの 3 キーを、OpenCode V2(opencode-v2)のモデル選択・variant 選択・コマンドパレットなどのダイアログが開いているときのカードにも出す。キー定義はターミナル下のクイックキー(#2966)と同じ v2 の表から引く。opencode2 2.0.18 の実測で、ダイアログが開いたままではこの 3 キーが効かない(Commands の中の ctrl+x m は絞り込み欄に m が入る)ため、v2 のキーは Escape でダイアログを閉じてから送る。承認(Allow once / Always allow / Reject)と質問フォームのカードには Escape が回答になるため出さない。v1 のカードの表示とキーは変わらない。

  • feat(opencode-v2): CMATE.md のスケジュールで OpenCode V2 にもモデル・エージェントなどの実行オプションを渡せるようにする (#2982): CLI Tool 列の opencode-v2 に v1(#2044)と同じ --model <provider/model> / --agent <name> / --variant <name> / --continue(-c)/ --title <text> を書けるようにした(TOOLS_WITH_MODEL_SUPPORT / TOOLS_WITH_RUN_OPTIONS に opencode-v2 を追加)。opencode2 run には --variant フラグが無い(2.0.18 で Unrecognized flag)ため、列の --variant は実行時に -m <provider/model>#<variant> として渡し、モデル無しの --variant は黙って捨てずに構文エラー(行はスキップ、画面・API からの保存も拒否)にする。例: opencode-v2 --model anthropic/claude-sonnet-4-5 --agent plan → opencode2 run --standalone --format json -m anthropic/claude-sonnet-4-5 --agent plan -- <message>。エラーメッセージの文法は v2 用(OPENCODE_V2_COLUMN_SYNTAX)を出し、v1・copilot の文法とエラーメッセージは変えていない。スケジュール編集画面でも OpenCode V2 で Model / Agent / Variant / Title / Continue を入力でき、ja / en の手引きに渡せるオプションを追記した。

  • feat(opencode-v2): OpenCode V2 のセッションの使用量(トークン・費用・コンテキストの埋まり具合)を v1 と同じ場所に表示する (#2981): Epic #2370 Phase 5。opencode-v2 の SSE に session.usage.updated かターン終了(session.execution.succeeded / failed / interrupted)が流れるたびに、そのインスタンス自身のサーバ(v2 のポートとパスワード)へ GET /api/session/{id}(セッション累計の cost / tokens・タイトル・エージェント・モデル)、GET /api/session/{id}/message(最新の assistant メッセージ=コンテキスト)、GET /api/model(limit.context)を問い合わせ、v1 と同じ記録(structuredEvents.session / sessionContext)に書く。2.0.18 の実測で、セッション累計(2 ターン後 5925 / 34 / 128 / 13312)と TUI の footer 6.3K (1%)(最後のターン 6,341 トークン / 1,000,000)が別の量であることを確かめ、v1 と同じ意味で分けて記録する。サブエージェントのセッション(parentID あり)は記録しない。購読を閉じたとき・購読が自ら終わったときに記録を消す。v1 の挙動は不変。

  • feat(opencode-v2): Skill の探索・呼び出しを実測し互換表の v2 の行を埋めた (#2975): opencode2 2.0.18 を実機で測り、Skill の互換表の v2 の行を「未計測」から実測の値にした。.agents/skills と .claude/skills を project・global とも発見し、/<name> で呼び出せる(v2 自身の / 補完には出ないが @ 補完には出る)。稼働中に足した Skill も再起動なしで拾う。詳細は docs/reference/skill-agent-compatibility.md §10。

  • feat(opencode-v2): スケジュールの CLI Tool に指定できるようにした (#2974): opencode2 run --standalone --format json を実機で測り、v2 をスケジュールの CLI Tool として選べるようにした。Permission は default(フラグなし。ask ルールに当たると失敗として記録)と auto(--auto)。詳細はコミットメッセージ本文を参照。

  • feat(opencode-v2): クイックキー(エージェント切り替え・コマンドパレットなど)を出すようにした (#2966): 実機(opencode2 2.0.18)で実測した v2 のキー割り当て(shift+tab でエージェント切り替え、ctrl+p パレット、ctrl+t バリアント、ctrl+x a/l/n/m、スクロール)に基づき、OpencodeQuickKeys の定義表をツール ID で切り替えて v2 用の定義を追加し、OpenCodeV2Tool.navigationKeys() でそのキーを送れるようにした。詳細はコミットメッセージ本文を参照。

  • feat(opencode-v2): 実際に返答したモデル名を画面と capture に出すようにした (#2964): OpenCode V2 の各ターン終了時に読む GET /api/session/{id}/message から直近の assistant の model.id(providerID を足さない素のモデル名、v1 と同じ表記)を読み、v1 と同じ hook のモデル latch に載せるようにした。current-output / capture --json の .model に出て、2 ターン目で別モデルになれば #2357 のモデル変更通知が出る。

  • feat(opencode-v2): OpenCode V2 の承認(permission)と質問(form)に CommandMate の画面・スマホ・CLI・Auto-Yes から答えられるようにする (#2945): Epic #2370 Phase 2。SSE の permission.asked から承認を差分つきで作り(アクション・対象・metadata.files[].patch を承認カードに表示、Always allow が保存する save も表示)、回答を POST /api/session/{sessionID}/permission/{requestID}/reply に {"decision":"once"|"always"|"reject"} で送る。form.created(実測で form は data.form に入る。無いときは GET /api/session/{id}/form)から選択肢つきの質問を作り、回答を POST …/form/{formID}/reply に {"answer":{"<key>":<value>}} で送る(ラベルを選択肢の value に戻す。custom: true のフィールドだけ自由入力を通す。boolean は Yes/No。選択肢の無いフィールドを含む form は TUI で答える)。eventIdentity を permission-id(per_… / frm_…)にし、listPending はサーバーの GET /api/permission/request と GET /api/form を読むので、PC の PromptPanel・スマホの MobilePromptSheet(承認ボタンと質問の選択肢を新たに描画し、/respond に decision id で送る)・commandmate respond <wt> <番号> --instance opencode-v2・Auto-Yes(v1 と同じ規則で到着時に once を返す。無効時は答えない)がすべて v1 と同じ経路で答えられる。承認ボタンの文言は v2 の TUI に合わせ Allow once / Always allow / Reject(番号と送る値は不変)。質問は v1 と同じく Web Push で通知する。

  • feat(opencode-v2): OpenCode V2 のチャット入力欄の / にスラッシュコマンドの候補を出す (#2944): 実物の opencode2 2.0.18 の palette を端から端まで読んだ組み込みコマンド 37 件を attestation(slash-commands-attestations.json)と catalog に足し(v1 の行はそのまま、v2 用の行を別に持つ)、.opencode/skill(s)・.claude/skills・.agents/skills(project)と ~/.config/opencode/skill(s)・~/.claude/skills・~/.agents/skills(home)の Skills を読む。稼働中の v2 インスタンスの自前サーバーの GET /api/command / GET /api/skill(Basic 認証)から project の markdown コマンドと Skills を v1(#2036)と同じくキャッシュから答え、更新は待たずに足す。起動直後の空のコマンド一覧は「未読込」として次に開いたとき読み直し、インスタンスが無いときは毎回ポート記録を見直すので、起動後すぐ候補に出る。

  • feat(agent-health): 日次確認の対象に OpenCode V2(opencode-v2)を加え、本番と同じ launch.sh 経路での起動と自前 serve の SSE を確かめる (#2937): AGENT_HEALTH_TOOLS と TOOL_PROBE_SPECS に 6 ツール目として opencode-v2(実行ファイル opencode2、画面 80x200)を追加。probe は reserveOpencodeV2Server() でポートとパスワードを用意してから prepareLaunch を呼び、起動行が scripts/opencode-v2/launch.sh を通ることを確かめる(--standalone に落ちたら起動せず version 以外の check を fail)。パスワードとポートの記録は実行の一時ディレクトリ(CM_OPENCODE_V2_DIR)、TUI の状態は XDG_STATE_HOME を一時ディレクトリへ向けて、利用者の ~/.commandmate/opencode-v2/ と ~/.local/state/opencode/(背景サービスの service.json を含む)に書かない。hook-correlation の枠では自前 serve の /api/event を購読し、sleep 20 のターンの間に session.execution.started と session.execution.succeeded が届けば pass、受け取った type の一覧を summary に残す。セッション終了後に serve のプロセスかポートが残れば fail。承認ダイアログは既定で出ないため skip。v1(opencode)の hook-correlation は skip のまま。

  • feat(cli-tools): OpenCode V2(opencode-v2)をエージェントとして登録し、自前 serve と TUI を 1 ペインで起動・終了、SSE で状態を表示する (#2934): Epic #2370 Phase 1。OpenCode 2.0(実行ファイル opencode2、npm @opencode/cli、検証済み 2.0.18)を v1(opencode)とは別のツール ID opencode-v2(表示名 OpenCode V2)として追加(v1 の実装・テスト・fixture・挙動は不変)。起動は新しいラッパー scripts/opencode-v2/launch.sh(bash 3.2 互換)で、opencode2 serve --hostname 127.0.0.1 --port <N> を立てて GET /openapi.json の 200 を最大 15 秒待ち、TUI(opencode2 --server <url> <worktree>)を動かし、trap で EXIT / HUP / INT / TERM のどれでも serve を止めるので /exit・TUI の終了・tmux kill-session のいずれでもポートが空く。ポートは v1(4200–4299)と重ならない 4300–4399、状態は ~/.commandmate/opencode-v2/(ディレクトリ 0700)の ports.json とインスタンスごとのパスワードファイル <複合キー>.pw(0600、起動ごとに 32 バイトの乱数を生成)。パスワードは環境変数 OPENCODE_SERVER_PASSWORD にだけ渡し、起動行(AgentLaunchPlan.env / command)・tmux の画面・ログには出さない。状態は自前サーバの SSE(GET /api/event、Basic 認証)を購読し、session.execution.started → running、succeeded / failed / interrupted → ready(failed はエラーとして記録)、permission.asked / form.created → waiting、permission.replied / form.replied / form.cancelled → waiting 解除で表示する(1 インスタンス = 1 サーバなので location.directory の無いイベントも同じインスタンスに振り分ける)。CommandMate の起動時に、tmux セッションが生きているインスタンスは保存したポートとパスワードファイルから購読し直し、生きていないインスタンスのパスワードファイルとポートの記録は消す(起動後にペインを調べた時点でも購読し直す)。launch.sh は npm パッケージに同梱される(files に scripts/opencode-v2/)。送信は TUI の入力欄へ tmux 経由(入力欄の ┃ Ask anything… か footer の ctrl+p commands を確認してから)。Schedule(CMATE.md)の CLI Tool には未対応で、検証エラーになる。承認・質問への回答・History は Phase 2、画面検出の充実・クイックキーは Phase 3。

Changed

  • feat(opencode-v2): Build ⇄ Plan のエージェント切替を入力欄の横のモードボタンに移し、今のエージェントを表示する (#3038): OpenCode V2(opencode-v2)をモードボタン(AgentModeControl、#2592)の対象に加え、shift+tab(BTab)で Build ⇄ Plan を切り替えられるようにした(チャット画面・ターミナル画面・スマホ)。今のエージェントは入力欄の下の行(┃ Build · <model> / ┃ Plan · <model>、2.0.18 実測)から読み、チップに build / plan と出す(完了行 Build · <model> · 4.9s や利用者の発言は読まない。承認・質問のダイアログで入力欄が消えている間は unknown)。モード語彙に build を追加(default に読み替えない)。ボタンには「OpenCode V2 では Build(編集あり)と Plan(読み取りのみ)のエージェントが切り替わります」の注記(opencodeAgentSwitch)が付く。同じキーにボタンが 2 つ付かないよう、V2 のクイックキーから agentNext(shift+tab)を外した(11 キー → 10 キー)。v1 の opencode は不変。

  • docs(orchestrate): 送信ループが stdin を読み尽くす問題・起票前の重複確認・module-reference の親ディレクトリ行を手順に反映 (#3036): 3-1 の雛形で assign.tsv を stdin から読んでいたため、ループの中の commandmatedev が残りの行を消費して 1 件目の send の前で止まり、ワーカーが起動していないのに送信中と報告した(2026-09-30 実測)。雛形を fd 3 から読む形に変え、送信後に GET /api/worktrees/<WT>/tasks で task ができたことを確かめる行(task ok / task MISSING)を足した。8-3 に、起票の前に agent-health ラベルと本文検索で同じ不具合の開いている Issue を探す手順を足した(同じ日に #3024・#3031 を重複して起票したため)。2-4-1 の転記ブロックに、module-reference でファイルの行が 0 件なら親ディレクトリの行も探す、を足した。

  • test(detection): Claude 2.1.285 の effort が medium と表示されるのは実際の値であることを fixture で固定 (#3023): ~/.claude/settings.json のトップレベル effortLevel は claude 2.1.285 では legacy 扱いで、Opus 5.5 / Sonnet 5.5 には適用されずモデル既定の medium になることを隔離セッションで実測した(CommandMate の起動は effort を上書きしていない)。xhigh にするには modelSettings.<model>.effortLevel を使う。バナーは既定以外の effort のときだけ with <effort> effort を出し、右寄せの · /effort 行は最初のフレームだけに描かれることも実画面 3 本で固定した。検出の挙動は変えていない。

  • docs(orchestrate): Sonnet 5.5 に合わせて Claude の担当の振り分けを改定 (#3015): 「中」(sonnet)を「危険な領域・依存だけ」から「選択肢か手順が本文で閉じている判断・設計」まで広げ、原因未特定・実機で結論が変わるもの・新規 export などは opus に残した。根拠は Sonnet 5 の「中」17 件でワーカー起因の再指示 0・格上げ 0、2026-09-29 の run で opus に回した閉じた判断・設計 4 件がすべて初回合格だったこと。{"model":"sonnet"} が claude 2.1.284 で claude-sonnet-5-5 に解決することも記載。

  • docs(skills): cmate-verify の SKILL.md で実行例の起点を <skills-root> にし、Command Code も .agents/skills を読むと明記 (#3012): commandmate-skills#276(cmate-verify 0.6.0)の変更を .claude/skills/cmate-verify/SKILL.md と mirror の .agents/skills/cmate-verify/SKILL.md に移植。install 先の説明を「Claude は .claude/skills、Codex と Command Code は .agents/skills」に直し、手順 2 の実行例を <skills-root>/cmate-verify/scripts/verify-run.sh にして、.agents/skills と .claude/skills のうち cmate-verify/SKILL.md が在る方を指すと書いた。sync-map の sha256 pin を更新。

  • test(detection): Claude・Codex の返答本文の番号リストが実機では「応答待ち」にならないことを fixture で固定 (#2997): #2991 と同じ事象が Claude・Codex で起きるかを実機(claude 2.1.284 / codex 0.157.1、私設 tmux)で確かめ、返答の下に入力欄が必ず描かれるため番号リストが prompt と読まれないことを確認した。再現しないので requireVouchedPrompt は claude / codex では有効にせず、実機の画面 8 本を fixture に残して ready / 送信可を固定し、codex の画面を verdict corpus に登録した。検出の挙動は変えていない。

  • docs(opencode-v2): V2 ガイドから #2991 の「未修正」の記述を削除 (#2994): #2991(返答本文中の選択肢行で送信不能になる不具合)が develop にマージ・UAT 合格済みとなったため、OpenCode V2 ガイド(docs/user-guide/opencode-v2.md および docs/en/user-guide/opencode-v2.md)の「まだできないこと・既知の不具合」セクションから該当項目を削除。

  • fix(skills): Skill 互換表で OpenCode V2 の「Skill を足したあとにすること」を「開始し直し不要(次の送信から見つかる)」にする (#2985): #2975 の実測(docs/reference/skill-agent-compatibility.md §10.5)では opencode2 2.0.18 は稼働中に足した Skill を数秒で拾い、同じセッションのまま呼べたため、AGENT_RELOAD_MESSAGE_KEYS に PICKED_UP_LIVE(skills.compatibility.reload.pickedUpLive、ja / en)を足して opencode-v2 の行をそれに差し替えた。他のツールの行と、v2 の slash コマンド非対応(noSlashCommand)の表示は変えていない。

  • docs(opencode-v2): README・LP・公開面の文言と利用者向け docs(ja / en)で OpenCode V2 を対応ツールとして案内する (#2976): 公開面の数は 8 のまま(案 A)。docs/design/public-messaging.md §3c・§11 に「v1 と v2 は 1 種と数える」を明記し、README・LP・§4 の「Which agent」の列挙を「OpenCode (1.x and V2)」に揃えた(lede の「OpenCode」は両方の版を指す)。新しい docs/user-guide/opencode-v2.md(ja / en)に、導入と 1.x との共存・起動のしくみ・できること(送信・SSE の状態・転写・承認と質問・ダイアログ中の送信拒否・モデル表示・使用量・クイックキー・スラッシュコマンド候補・Skill・スケジュール・日次確認)・1.x との違い(shift+tab・Always allow・opencode2)・まだできないこと(#2991 ほか)を実測の範囲で書いた。cmate-schedules-guide(ja / en)に「常に許可」が同じリポジトリの全 worktree のスケジュールに効く注意、skills.md(ja / en)に V2 の行と「開始し直し不要」、agent-event-hooks(ja / en)の V2 の裁定欄を #2945 の結果に更新。

  • docs(orchestrate): 2026-09-28 の run の振り分けの改善案を /orchestrate の手順に反映 (#2956): 実機でエージェント CLI / サーバーを動かす Issue の隔離の雛形(別ポート・一時 DB と lsof での確認、XDG_* / CM_OPENCODE_V2_DIR を一時ディレクトリへ向けて ps eww で効いていることを確認、tmux の -L、後始末、利用者の状態の前後比較)を 2-6 として新設。$HOME 配下に新しい置き場所を足す Issue では tests/setup.ts の隔離の既定を受入基準に入れる(2-4)、Antigravity の雛形に「既存の it / describe を消さない」を追加(2-4-2)し PR 前に削除行数 0 を機械的に確認(6-4)、確定 diff は対象のコードを読んでから書く(1-2b)、並行ワーカーのテストが作る ~/.commandmate-demo-vitest-<pid> による env-clean の違反は再実行で消えれば合格扱い(3-4)。

Fixed

  • fix(agent-health): codex の config.toml を TOML として比べ、確認の一時パスの表だけが増えた場合は元に戻す (#3031): 日次確認(scripts/agent-health/run.ts --tools codex)の後始末で、codex の $CODEX_HOME/config.toml(TOML)を trust-state として JSON.parse で読んでいたため、中身が変わった回は必ず restore …: NOT restored (… is not valid JSON) になり、実行中の変更がそのまま残っていた。restoreTrustState() に比較方式を選ぶ引数(TrustStateComparator、既定は従来の JSON 比較で antigravity・command-code の挙動は不変)を足し、codex の config.toml は確認の一時パス(cm-agent-health-)を含む [projects."<dir>"] の表(ヘッダ行から次のヘッダ行または EOF まで)と空行を行単位で除いた残りが前後で一致するときだけ保存したバイト列を書き戻す。それ以外の変更(codex 0.159.1 が起動ごとに 4 まで 1 ずつ増やす [tui.model_availability_nux] など)が混ざっていれば従来どおり書き込まず「実行中に別の変更が入ったため触っていない」と報告する。

  • fix(test): env-scripts テストが $HOME に残した一時ディレクトリを次回実行時に回収 (#3025): beforeAll で $HOME 直下の .commandmate-demo-vitest-<pid> のうち pid が生きていないものだけを削除する(生きている pid・名前が違うものは対象外)。

  • fix(agent-health): v1 OpenCode の日次確認が利用者のモデル選択を引き継がず、既定モデル(未ロードの LM Studio)で全ターンが失敗していた問題を修正 (#3021): #2953 で XDG_STATE_HOME を一時ディレクトリへ向けた結果、モデル選択(opencode/model.json)も空になり、opencode 1.18.33 が組み込みの既定モデル(この環境では LM Studio の Qwen3 Coder 30B)で起動して毎ターン「No models loaded」を返していた(TUI の表示変更ではない)。起動前に利用者の model.json だけを隔離した状態ディレクトリへ複製するようにし(入力履歴は引き継がない。元ファイルは読むだけ)、screen-running に加えて同じ原因で時間切れになっていた screen-quoted-dialog(#3022)も pass に戻した。あわせて、起動直後の空のペイン(負荷時に opencode の描画が 5 秒ほど遅れる)を起動画面と取り違えて依頼を空打ちしないよう、waitForStartup は何か描かれた画面だけを起動画面として扱う。モデルがエラーを返した画面は完了印も実行中表示も無いので unknown_frame(evidence=none)のままであることを fixture で固定。

  • fix(agent-health): codex の新しい版が出た日に screen-idle が起動時の更新ダイアログを撮って fail する問題を修正 (#3020): codex は $CODEX_HOME/version.json に自分より新しい版が載っていると composer の代わりに更新ダイアログ(Update available · 0.157.1 → 0.159.1 / 1. Update now / 2. Skip / 3. Skip until next version)で起動するため、日次確認がこれを起動画面として判定していた(検出の waiting は正しい)。確認の codex 起動行に -c check_for_update_on_startup=false を足してダイアログを出さず、利用者の version.json の取り直しもしないようにし、それでも出たときは起動時のダイアログとして 2. Skip を選ぶ(Skip until next version は dismissed_version を書くので選ばない)。codex のダイアログのフッタの既知の文言に 0.157.1 の enter continue · esc skip を追加(フッタ変化の警告ログが出なくなる)。0.157.1 の実物の画面を tests/fixtures/codex-update-dialog-3020/ に置いてテストで固定。

  • fix(cli): ask now fails with exit 11 when the model's context limit ends the turn (#3011): a Command Code session over its context window (maximum context length is N tokens) used to finish ask as Completed with exit 0 and no reply; UPSTREAM_FAULTS gains context-limit, ask always treats an upstream fault as a failure, and stderr / --json name id=context-limit with the advice to start a fresh session.

  • fix(cli-tools): 起動直後の Command Code で composer が間に合わない送信を 503 SESSION_STARTING で返す (#3006): dispatch で新しく起動した Command Code への最初の送信が、composer が送信前の待ち(起動後 3 秒 + 起動待ち 30 秒 + 送信前 15 秒)に間に合わないと prompt not ready(500、commandmate send は exit 99)で失敗していた。CommandCodeTool が自分で起動してからまだ composer を一度も見ていないセッション(起動から 120 秒以内)では SessionStartTimeoutError を投げ、sendUserMessage がその code を結果に載せ、send ルートが Claude の起動中と同じ 503 { error, code: 'SESSION_STARTING' } を返す(CLI の exit code・文言も Claude と同じ)。composer を一度でも見たセッション・このサーバが起動していないセッション・起動から 120 秒を過ぎたセッションは従来どおり prompt not ready。サーバ側で自動再送はしない。Codex・Antigravity の挙動は変えない。

  • docs(docs): 日本語 README のスマホ通知リンク切れを修正 (#2996): docs/ja/README.md の「Webアプリ基本操作ガイド → スマホ通知」リンクを ../user-guide/webapp-guide.md#スマホ通知プッシュ通知 に直し(docs/ja/ 基準では user-guide/ が存在しない)、README.md と docs/ja/README.md の相対リンクが置き場所基準で実在ファイルを指すことをテストで固定。

  • fix(auto-yes): Auto-Yes が答えずに飛ばした画面の WARN を、同じ画面が続く間は 1 回だけにする (#2995): エージェントの返答に 1. Yes / 2. No のような番号リストが残った静止画面で、poller:auto-yes-skipped-unclassified-frame の WARN が 2 秒ごとのポーリングのたびに出続けていた(UAT で 69 秒に 35 行)。同じポーラーで同じ画面(prompt の種類・質問・選択肢の並びとカーソル位置・承認対象、と各理由の詳細)に対する 2 回目以降は debug に落とし、別の prompt に変わった・prompt の無い tick を挟んだ・応答を送った後は再び WARN を出す。auto-yes-skipped-launch-dialog・auto-yes-suppressed-by-policy・auto-yes-skipped-foreign-session も同じ仕組みで抑える。recordPolicySuppression() の記録(capture --json / wait が読む)は毎 tick 従来どおりで、Auto-Yes が何も送らない挙動も変わらない。

  • fix(opencode-v2): 返答の本文に ❯ 1. Yes / 2. No のような番号リストがあっても「応答待ち」にならず、次のメッセージを送れる (#2991): OpenCode V2 の状態判定が、Auto-Yes(#2984)と History(#2457)が既に使っている evaluateDialogPresence() を通すようにした(ToolDetectorSpec.requireVouchedPrompt を v2 で有効化し、detectSessionStatus が ToolDetectionContext.isPromptVouched を渡す)。v2 の detectDialog が認めない番号リストは waiting / prompt_detected にならず(isPromptWaiting: false・promptData なし)、送信の拒否(prompt_waiting の 409、CLI の send exit 2、Timer / Schedule)も wait の exit 10 も起きない。v2 の承認・質問・パレットは従来どおり waiting で、承認中の送信拒否(#1708 / #1737)も不変。claude / codex / copilot / opencode(v1)と legacy のツールの判定は変えていない。

  • fix(opencode-v2): Auto-Yes が、応答本文に書かれた番号付きの選択肢(❯ 1. Yes / 2. No など)に答えて番号を入力欄へ送ってしまわないようにした (#2984): OpenCode V2(opencode-v2)でも Auto-Yes の画面読み取り(汎用の番号リスト推定)は動いており、実機 2.0.18 でダイアログを引用した応答が multiple_choice と読まれ、ダイアログの確認ゲート(#1928)が legacy だったため 1 + Enter がユーザーの発言として送られうる状態だった(v1 の #1896 と同じ形)。v2 の画面判定に detectDialog を追加し(承認の Allow once / Always allow / Reject 行と一覧のキー操作ヒント・ダイアログのタイトル行。承認とダイアログは数字を受け付けず、質問フォームは数字だけで確定することを実機で確認)、ゲートを enforce にした。v2 の承認・質問は画面読み取りの候補にならず、これまでどおりサーバー API 経由で答えるため、Auto-Yes が答えていたものは減らない。CM_AUTOYES_DIALOG_GATE=opencode-v2=legacy で従来の動作に戻せる。

  • fix(opencode-v2): スケジュール実行が worktree で動くようにした (#2979): opencode2 はプロジェクトを cwd ではなく環境変数 PWD から決めるため、execFile の cwd が worktree でもサーバーの PWD(本体のチェックアウト)で動き、worktree の opencode.json(ask など)も読まれなかった。v2 の子プロセスにだけ PWD を cwd に合わせて渡す(v1・他ツールは不変)。

  • fix(opencode-v2): ダイアログが開いたまま送信すると本文が消える問題を修正 (#2971): モデル選択・variant・Commands・Sessions・エージェント選択などのダイアログが開いているあいだは、v2 の送信が本文を入力せず「"<タイトル>" dialog is open」の失敗で返るようにした(以前はダイアログの絞り込み欄に入り、送信は成功扱いだった)。ダイアログは閉じず(Escape は利用者の選択を捨てるため)、閉じてから送り直せば今までどおり届く。画面判定もダイアログ中は ready にせず waiting(opencode_modal_overlay)とし、wait が画面だけで完了と読まないようにした。詳細はコミットメッセージ本文を参照。

  • fix(test): opencode.test.ts が未処理の reject で不安定に落ちる問題を修正 (#2970): 前のテストが残したログファイルと、戻り値を受け取らない起動呼び出しが重なると未処理の reject が発生する不具合を直した。詳細はコミットメッセージ本文を参照。

  • fix(opencode-v2): 承認・質問待ち中の注意文がチャットに記録される問題を修正 (#2965): 構造化した承認・質問(#2945)が id で答えられる状態で保留中のあいだは recordUnclassifiedFrame と structured-prompt の注意文をチャットに記録しないようにし(opencode v1 の承認も同じ判定に乗る)、OpenCode V2 の画面判定に承認ダイアログ・質問・完了行を追加した。詳細はコミットメッセージ本文を参照。

  • fix(tmux): 新しいセッションの起動で、ペインのシェルが起動コマンドを約 61 秒実行せず送信が exit 99 になることがある問題を修正 (#2958): 原因は createSession が new-session で作ったウィンドウ 0 のログインシェルを、数ミリ秒後の new-window -k(Issue #1624 の history-limit 反映のための作り直し)で殺していたこと。rc ファイルの途中で殺されたシェルは pyenv の pyenv init -(command pyenv rehash)のロックファイル $PYENV_ROOT/shims/.pyenv-shim を残すことがあり、作り直した側のシェルが pyenv rehash のロック待ち(既定 60 秒)で止まり、CommandMate の起動待ち(60 秒)に間に合わなかった(ペインには pyenv: cannot rehash: … exists が出る。タイムアウトした rehash が終了時にロックを消すので次の起動は速い)。tmux 3.5a / pyenv 2.6.0 の隔離ソケットで、従来の手順は 40 回中 7 回ロックを残し、次のシェルの最初のコマンドが 61 秒後に実行された。ウィンドウ 0 をシェルではなくプレースホルダー(sleep 2147483647、2 語なので tmux がシェルを介さず直接 exec)で作るようにし、同じ手順で 40 回中 0 回になった。作り直しに失敗したときは、プレースホルダーのままにせず default-shell をログインシェルとして respawn-pane -k で入れ直す(それも失敗したらセッション作成の失敗として返す)。

  • fix(opencode-v2): OpenCode V2 を起動するとプロジェクトの package.json に packageManager が書き込まれる問題を修正 (#2957): opencode2 は起動時の更新確認で npm/pnpm/yarn/bun の list -g を起動ディレクトリで実行し、corepack の shim の pnpm/yarn が最寄りの package.json に "packageManager" を自動で書き込んでいた(auto-pin)。scripts/opencode-v2/launch.sh が serve と TUI の両方に OPENCODE_DISABLE_AUTOUPDATE=1(更新確認そのものを止める。opencode2 v2.0.18 で効果を実測)と COREPACK_ENABLE_AUTO_PIN=0(corepack が書き込まない)を渡す。OpenCode 1.x(1.18.33)は起動時にパッケージマネージャーを実行しないため変更しない。

  • fix(session): 起動直後の Claude セッションで capture --json の .model が null になる不具合を修正 (#2955): claude 2.1.284 の SessionStart は model(例 claude-sonnet-5-5)を運んでいるが、SessionStart を中継する scripts/hooks/cmate-agent-event.sh が POST 本文を固定キーで組み立て直して model を捨てていたため、hook 経由でモデルが届いていなかった。session_start のときだけ payload の model を本文に載せる(無いときは付けない)。あわせて、画面からの読み取りも 2.1.28x のバナー(Sonnet 5.5 · Claude Max の形。effort は右寄せ行 ◐ medium · /effort に移った)を読めるようにした(旧形式 … with <effort> effort も引き続き読む。新形式は · Claude <プラン> を必須にして、表の行などを誤読しない)。

  • fix(verify): env-clean が別 worktree のテスト実行中の ~/.commandmate-demo-vitest-<pid> を自分の違反に数えないようにする (#2954): 検証ゲート env-clean の home-entries で、名前が .commandmate-demo-vitest-<pid> の項目に限り pid で持ち主を判定する。pid のプロセスが生きていて、その作業ディレクトリ(Linux は /proc/<pid>/cwd、macOS は lsof -a -d cwd -p <pid>)が判定対象の worktree の兄弟ディレクトリ(別の worktree)なら other として除外し、tmux-sessions と同じく (N addition(s) attributed to another worktree) と表示する。判定対象の worktree の中の pid・生きていない pid・作業ディレクトリが読めない pid・名前が一致しない項目は従来どおり違反として数える。

  • fix(agent-health): v1 OpenCode の日次確認を利用者の入力履歴から隔離 (#2953): scripts/agent-health/tool-table.ts の opencode(v1)のプローブ定義に launchEnv を追加し、XDG_STATE_HOME を一時ディレクトリへ向けることで、日次確認の実行時に利用者の ~/.local/state/opencode/prompt-history.jsonl へ確認依頼が追記されないようにした。

  • fix(opencode-v2): OpenCode V2 を opencode の名前でしか入れていない環境でも、自前サーバーつきで起動する (#2952): 起動ラッパー scripts/opencode-v2/launch.sh に --executable <path> を追加し(省略時は従来どおり PATH の opencode2。存在しない・実行できないパスは exit 64)、serve と TUI の両方をその実行ファイルで起動する。CommandMate は --version で OpenCode V2 と判定した実行ファイルの絶対パスをこの引数で渡すので、opencode が opencode v2.x を返すだけの環境でも --standalone に落ちず、SSE による状態表示・返答の記録・承認と質問への応答・スラッシュコマンド候補が効く。opencode2 がある環境でも、ペインのシェルの PATH ではなく判定に使った実体を起動する。--standalone に落ちるのはポートかパスワードファイルを用意できないとき(とラッパーが無いとき)だけになった。

  • fix(opencode-v2): 承認の文言・保留中の承認への Auto-Yes・質問の自由記述を v2 に合わせて修正 (#2951): capture --json の decisionOptions と respond のラベル照合を v2 の語(Allow once / Always allow / Reject、structuredDecisionOptionsFor)に揃え、respond "Always allow" --instance opencode-v2 が通るように(v1 の Allow always と番号・送る値は不変)。v2 の resync を pending-list とし、Auto-Yes を有効にしたときと再接続したときに GET /api/permission/request・GET /api/form から保留中の承認・質問を再判定・再生。form の custom: true を画面まで渡し、PC パネルとスマホシートに自由記述の入力欄を追加(数字だけの入力は番号として解釈されるため送らない)。

  • fix(opencode-v2): 引数なしのスラッシュコマンドが OpenCode V2 で実行されない問題を修正し、組み込みコマンドの古さ判定に V2 を追加 (#2950): 送信経路が本文を trim するため、パレットが入れた /<name> の末尾空白が失われ、v2 の TUI の候補欄が閉じずに Enter が飲まれていた。OpenCodeV2Tool.sendMessage で本文が空白を含まない /<name> 1 語のときだけ末尾に空白を 1 つ足して送る(引数付き・通常の文章は変えない)。あわせて slash-command-catalog.ts の VERSION_PROBES に opencode-v2(resolveOpencodeV2Executable へ委譲)を追加し、インストール済み opencode2 が attestation より新しいとき catalogStaleness に古いと出るようにした。

  • fix(test): テスト実行が利用者の ~/.commandmate/opencode-v2/ を消す問題を修正 (#2948): tests/setup.ts で CM_OPENCODE_V2_DIR の既定値をプロセス別の一時ディレクトリ($TMPDIR/commandmate-test-opencode-v2/<pid>)に向け、起動時スイープ(server.ts の reattachOpencodeV2EventStreams())が稼働中 OpenCode V2 インスタンスのパスワードファイルとポート記録(ports.json)を消すのを防止。ガードテスト tests/unit/config/opencode-v2-test-isolation.test.ts を追加。

  • fix(opencode-v2): OpenCode V2 の返答がチャット(History)に記録されない問題を修正 (#2940): 画面の読み取り(scraper)は完了の目印をホーム画面にしか出ない見本文 Ask anything… に頼っていたため v2 の返答を 1 件も保存できなかった。購読中の SSE が session.execution.succeeded / failed / interrupted を受けたら、v2 のサーバーの GET /api/session/{id}/message から終わったターンを読み、user → assistant(ステップごと)→ idle の並びで 1 ターン 1 行の assistant 行(oc-turn:<user メッセージ id>、本文は v1 と同じ描画で text、reasoning は折りたたみ、tool は 1 行)として記録する。同じターンは二度書かず、取得に失敗しても状態表示と購読は止まらない。transcriptHistory を 'push' にし、購読が live の間は scraper の行を書かない(structured-history-gate に v2 の live 判定を追加)。チャット面と relay の 'opencode-v2' も転写ありに揃えた。

  • fix(cli-tools): opencode が OpenCode V2 を指していても OpenCode(1.x)と OpenCode V2 を取り違えない (#2939): npm @opencode/cli(V2)は opencode2 と並んで opencode も登録するため、PATH の順だけで opencode が V2 になり、OpenCode(1.x)が「入っている」と判定されて V2 に --port / --hostname を渡して起動に失敗していた。判定を名前(which opencode)から --version の出力に変え、OpenCode は PATH 上の opencode のうち 1.x を返すもの、OpenCode V2 は opencode2(無ければ opencode v2.x を返す opencode)だけを「入っている」とする。判定で見つけた実行ファイルの絶対パスを起動行に使う(サーバーとペインの PATH の食い違いでも別物を起動しない)。opencode が V2 しか指していないときの OpenCode の起動エラーには理由(opencode が OpenCode V2 であること)を出す。V2 を opencode の名前でしか入れていない場合は、opencode2 を名前で呼ぶラッパーを使わず --standalone で起動する。capture --json / commandmate status の版表示も同じ判定に揃えた(V2 の opencode v2.x を OpenCode の版として読まない)。両者が共有する ~/.local/share/opencode/opencode.db を V2 が作り替えたことで OpenCode(1.x)が no such column で起動できなかったときは、opencode のログ(起動時刻以降の行、末尾 256 KiB まで)から原因を読み取り、起動エラーとして「V2 との共有データの食い違い」と対処(V2 だけを使う/1.x のデータを分ける)を表示する。両方が入っている環境では More 画面の「Default agents for new branches」に注意を 1 行出す(ja/en)。docs/user-guide/cli-setup-guide.md(ja/en)に共存の注意と分け方を追記。

  • fix(schedule): OpenCode V2(opencode-v2)のスケジュールを画面・API から作れてしまう問題を修正 (#2936): 書き込み側の検証(validateScheduleInput)で isScheduleSupportedCliTool() による拒否を追加し、スケジュール作成・編集ダイアログ(ScheduleEditDialog)の選択肢からも未対応の CLI ツールを除外。