環境変数で戻すのはやめた。Claude Code 2.1.233 で Todo・タスク追跡ツールの5つが新しいモデルから外れ、CLAUDE_CODE_ENABLE_TODO_TOOLS=1 を置けば従来どおり戻せる。戻す前に手元のセッションを覗いたら、常用している Opus 5 でも5つとも消えていた。運用スキルに書いてある「チェックリスト項目ごとに todo を作る」という1行は、ツールが消えたあともエラーひとつ出さずに素通りしていたことになる。直すのはその1行のほうだと判断した。
目次
2.1.233 で外れた5つのツール
changelog の該当行はこれ1行だけで、条件も戻し方も全部ここに書いてある。
Todo/task-tracking tools (TaskCreate/Get/Update/List, TodoWrite) are no longer available on Opus 4.8, Sonnet 5, Fable 5, Mythos 5, and newer models; set
CLAUDE_CODE_ENABLE_TODO_TOOLS=1to bring them back出典: Claude Code changelog 2.1.233(2026年8月14日)
原文が TaskCreate/Get/Update/List と圧縮して書いているので、展開すると TaskCreate・TaskGet・TaskUpdate・TaskList の4つ、これに TodoWrite を足して5つになる。
版番号について1つ注意がある。筆者の週次収集はこの変更を「v2.1.235 の更新」として拾ってきた。実際には changelog に 2.1.235 も 2.1.234 も存在しない。見出しの最上位は 2.1.233 で、日付は 2026年8月14日。手元で claude --version を叩いても同じ番号が返る。
PS> claude --version
2.1.233 (Claude Code)
存在しない版番号を根拠に「まだ来ていないから関係ない」と判断すると、すでに降ってきている変更を見送ることになる。版番号は changelog の見出しと手元の出力の2箇所で合わせたほうがいい。
Opus 5 は「and newer models」に入っていた
changelog が名指ししているのは Opus 4.8・Sonnet 5・Fable 5・Mythos 5 の4つで、あとは「and newer models」(より新しいモデル)とだけ書いてある。筆者が常用している Opus 5 の名前は出てこない。ここで困るのが、名指しが無いことは対象外の証明にならない点だ。「and newer models」がリリース順で後のものを指すのか、系列ごとの世代で見るのかは changelog に書かれていない。
読むだけで決まらないなら、動いているセッションに聞くほうが早い。
ツール名を指定して検索し、返ってくるかどうかを見た。返ってこないことを結論にする前に、「返ってくるはずのもの」を同じ検索に混ぜておく。全部返ってこないなら、検索そのものが死んでいるだけかもしれない。今回は SendMessage を対照として一緒に投げた。
| 検索したツール名 | 役割 | 結果 |
|---|---|---|
SendMessage |
対照(Todo とは無関係のツール) | 定義が返った |
TodoWrite |
todo リストの書き込み | 返らない |
TaskCreate |
タスク作成 | 返らない |
TaskGet |
タスク取得 | 返らない |
TaskUpdate |
タスク更新 | 返らない |
TaskList |
タスク一覧 | 返らない |
環境変数 CLAUDE_CODE_ENABLE_TODO_TOOLS は未設定であることを事前に確認済み(設定されていると結果が反転するため) |
||
対照の SendMessage が返ってきたので、検索の側は生きている。そのうえで Todo 系の5つが揃って返らない。Opus 5 は「and newer models」の側に入っている、というのが手元での結論になった。changelog を読んだだけでは確定しなかったものが、セッションに1回聞くだけで決まる。
# 交絡を先に潰しておく(値が入っていると「消えていない」ように見える)
PS> $env:CLAUDE_CODE_ENABLE_TODO_TOOLS
(何も出力されない=未設定)
ここまでで分かるのは「ツールが無い」ことだけだ。「スキルの指示が空振りしている」かどうかは別の話で、そこはまだ確かめていない。ツールが無くても、モデルが文章でチェックリストを並べて代替する可能性は残る。それなら実害は小さい。ツール一覧を見ただけで空振りを結論にすると、この可能性を見落とす。
環境変数で戻すか、スキルの記述を直すか
選択肢は2つある。どちらを採るかは、その todo が何のために書いてあったかで変わる。
| 選択肢 | 向いている場面 | 引き受けるもの |
|---|---|---|
(a) CLAUDE_CODE_ENABLE_TODO_TOOLS=1 で戻す |
todo の一覧を人間が実際に画面で見ている。スキルの本数が多く、書き換えの工数が読めない | 公式が既定から外したものを使い続ける。将来のリリースで環境変数ごと消える可能性が残る |
| (b) スキル側の記述を直す 採用 | todo が「作業を分解させる」ための指示で、一覧の表示自体は見ていない | スキルの書き換えと動作確認の工数。書き換えた文面がツール無しで意図どおり効くかを見る必要がある |
筆者は (b) を採った。理由は消極的なもので、todo の一覧を画面で追う運用を最初からしていなかったからだ。書いてあったのは「チェックリスト項目ごとに todo を作れ」で、狙いは作業を分解させることにあった。分解はツールが無くても指示できる。表示のためではない指示を、表示の道具ごと復活させて満たすのは筋が悪い。
似た形の変更を /verify と /code-review が自動で走らなくなった回でも扱った。あのときも機能自体は残っていて、既定から外れただけだった。設定で元に戻すより、何のためにその手順を置いていたかを1回言語化するほうが後で効く。
todo を「作業の記録」として使っていたのか、「モデルに作業を分解させる引き金」として使っていたのか。スクリーンリーダーモードを機械処理に流用しようとして間違えた回と同じで、想定用途から外れた使い方をしていた場合はツールを戻しても目的が満たされない。
戻すなら、置く場所で効く範囲が変わる
(a) を選ぶ読者向けに、置き場所だけ書いておく。ユーザー環境変数なら新しいセッション全部、シェルのプロファイルならそのシェルだけに効く。
# ユーザー環境変数として恒久設定する(新しいセッションから有効)
[Environment]::SetEnvironmentVariable("CLAUDE_CODE_ENABLE_TODO_TOOLS", "1", "User")
# その場のセッションだけで試す
$env:CLAUDE_CODE_ENABLE_TODO_TOOLS = "1"
無人ジョブを別経路で走らせているなら、その経路にも同じ変数が渡るかを見ておく。筆者の週次ジョブはタスクスケジューラから .cmd 経由で起動していて、ユーザー環境変数を引き継ぐかは未検証だ。対話セッションだけ戻して無人側は戻さない、という置き方も選べる。無人実行で todo の一覧を見る人間が居ない以上、そちらのほうが筋は通る。
同じ 2.1.233 に入った、スキル自作者に効く修正2件
2.1.233 には、スキルとコマンドを自作している人に効く修正が2つ入っている。todo とは別系統だが、棚卸しのついでに見ておきたい。
1つ目は、引数の値がテンプレートマーカーとして再展開されるのを防ぐ修正だ。コマンドに渡した引数の中にマーカーと同じ形の文字列が入っていると、そこがもう一度展開されてしまう。引数にユーザー入力やファイル内容を流し込む作りのコマンドで効いてくる。
2つ目のほうが実害を見つけにくい。同梱スキルのエイリアス、たとえば /checkup や /review が「Unknown command」を返す不具合の修正で、原文はこう書いている。
Fixed bundled skill aliases like
/checkupand/reviewreporting “Unknown command” in-pmode or with plugins/MCP loaded when a user or project skill shadows the bundled skill出典: Claude Code changelog 2.1.233
読み落としやすいのは or with plugins/MCP loaded のほうだ。-p はヘッドレス実行の経路なので、そこだけ見ると「無人ジョブの話で、対話セッションには関係ない」と読める。実際にはプラグインや MCP サーバーを積んでいる対話セッションでも踏む。プラグインを常用しているなら、影響外だと決めつけないほうがいい。名前が衝突しているスキルがあるかどうかは自分で数えられるが、素直に書くと外れる。先に外し方から書く。
最初に書いたのは、こういう2行だった。
# これは壊れている(実行した場所で答えが変わる)
$user = Get-ChildItem "$env:USERPROFILE\.claude\skills" -Directory -ErrorAction SilentlyContinue
$user | Where-Object { Test-Path ".\.claude\skills\$($_.Name)" } | Select-Object Name
当サイトのリポジトリで走らせたら「0件」と出たので、衝突は無いと書きかけた。実際にはこのリポジトリに .claude\skills ディレクトリ自体が無い(あるのは agents と commands だけ)。比較先が存在しないので、この 0 は「何とも比較していない」という意味でしかなかった。
もっと悪いのが、同じ2行をホームディレクトリで走らせたときになる。.\.claude\skills\ の .\ がホームを指すので、比較先がユーザー側スキルそのものになる。全部が自分自身とマッチして、筆者の環境では40件が「衝突」として出た。実行場所によって、偽の0と偽の40の間で答えが振れる。
0 を信じるなという話をしているのに、その根拠に使ったコードが 0 を作っていた。直すなら、比較する2つを明示して、成立しない条件を先に潰す。
# 比較する2つを明示し、成立しない条件を先に切り分ける
$userDir = Join-Path $env:USERPROFILE '.claude\skills'
$projectDir = Join-Path (Get-Location).Path '.claude\skills'
if ($projectDir -eq $userDir) {
"ホームで実行している(プロジェクト側とユーザー側が同じ場所)。比較にならない"
} elseif (-not (Test-Path $userDir)) {
"ユーザー側に .claude\skills が無い(判定対象なし)"
} elseif (-not (Test-Path $projectDir)) {
"プロジェクト側に .claude\skills が無い(判定対象なし)"
} else {
$hit = @(Get-ChildItem $userDir -Directory | Where-Object { Test-Path (Join-Path $projectDir $_.Name) })
"衝突 $($hit.Count) 件"
$hit | Select-Object -ExpandProperty Name
}
3か所から走らせて挙動を確かめた。リポジトリ直下では「プロジェクト側に .claude\skills が無い(判定対象なし)」、ホームでは「比較にならない」、無関係な作業ディレクトリでも「判定対象なし」。0件という数字はどこでも出ないので、衝突が無いのか比較していないのかを取り違えずに済む。
当サイトのリポジトリはプロジェクト側スキルを持たないので、この経路では踏みようがない。同梱スキルとの衝突は別の話で、このコードでは出てこない。棚卸しをリポジトリ横断でやるなら、8月に並んだ5つの廃止期限を grep 2本で監査した回と同じやり方が使える。
一次ソース
- Claude Code changelog(公式) — 2.1.233(2026年8月14日)の項
関連記事
まとめ
最初にやるのは、changelog で版番号を合わせて、自分のセッションにツールが残っているかを聞くことだ。設定に手を入れるのはそのあとで足りる。
読者への一手も同じ順序になる。CLAUDE.md とスキルを開いて「todo」「TodoWrite」で検索し、何行あるかを数える。0行なら今回の変更は関係ない。行があるなら、その行が何のために書いてあったかを思い出してから、戻すか書き直すかを選ぶ。書いた本人が理由を思い出せない指示は、たいてい消しても困らない。
未検証のまま残したこと。スキルの記述が実際に空振りしているかどうかは、ツール一覧を見ただけでは決まらないので確かめていない。タスクスケジューラ経由の無人ジョブにユーザー環境変数が渡るかどうかも未確認。同梱スキルの一覧を手元で列挙する方法も把握していない。(b) の書き換えはこれから着手するもので、ツール無しでも意図どおり作業を分解させられているかは、書き換えたあとの週次ジョブの結果で判断する。