Repository navigation
v0.43.0
[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 への送信は 503SESSION_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 の footer6.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)とは別のツール IDopencode-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):
asknow 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 finishaskasCompletedwith exit 0 and no reply;UPSTREAM_FAULTSgainscontext-limit,askalways treats an upstream fault as a failure, and stderr /--jsonnameid=context-limitwith 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 のsendexit 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 ツールを除外。