※ この記事は、AIに依頼をして書いてもらった記事です。一部加筆修正している以外は、AIが書いています。
153個のタスクを管理する小さなCLI──AIエージェントが実運用から見つけた設計の本質
最初に見たとき、正直なところ「よくあるタスク管理ツールかな」と思いました。
タスクを作って、状態を持って、一覧して、完了にする。CLIで操作できて、JSONで出力できる。うん、まあ便利そうだな、と。
でも、ログやリポジトリを読みながら見ていくと、だんだん印象が変わってきます。というより、ある数字を見てはっきり変わりました。
153。
これ、今このツールで管理されているタスクの総数です。13のプロジェクトにまたがって、そのうち125が完了済み。開発、自動化、執筆まで、別の領域のタスクがひとつのCLIで管理されています。
ぱっと見の地味さと、この数字。そのギャップがどうにも気になって、もう少し掘ってみることにしました。
このツールのもっとも基本的な設計は、タスクの実体がただのディレクトリであることです。
新しいタスクを作ると、~/dev/tasks/<uuid>/ というパスに空のディレクトリができます。あとはそこに goal.md を置いたり、必要なメモを置いたりする。CLIは状態(pending → running → completed)の切り替えと、一覧表示を担当します。
ファイルとCLIの役割がはっきり分かれている。コードを書くエディタでそのままタスクのメモを編集できて、進捗の管理はCLIでサクッと済ませられる。この手離れの良さは、実際に触ってみると意外と心地よいです。
設計を読み進めていて、おそらくここがいちばん大事なんじゃないかと思ったのが、同期の仕組みです。
このツールはローカルCLIでありながら、バックグラウンドでAPIサーバーと同期しています。sync コマンドを叩くと、手元のタスク状態がサーバーに送られ、別のマシンからでも同じ状態が見えるようになります。
どういうことかというと、デスクトップでタスクを作って、あとでVPSから同じタスクに着手できる。あるいは、cronで動いている自動化がタスクを更新して、それを手元で確認できる。
実際、このツール自身の改善タスクを見ると「CLIのtask pathをproject非依存に」「孤立ディレクトリの削除でエラーになる問題」といったクロスマシン運用で浮上する微妙な問題が、開発タスクとして上がっています。同期があるからこそ発生する問題を、ちゃんと自分自身で管理しているわけです。
もうひとつ、ログを読んでいて気づいたのが、このツールは AIエージェントが使うことを前提にしている という点でした。
--json フラグがほぼすべてのコマンドに付いていて、出力は機械可読。message コマンドでAIがタスクにコメントを残せる。ステータスの更新も1コマンドで済む。
そして何より、実際の運用を見ると、スキルファイル(AIの手順書)のなかに「ファイルを探すときはまずこのCLIでタスクを検索しろ」というルールが組み込まれています。AIは作業を始める前に、このCLIで「いま何をすべきか」を確認するように設計されている。
これはちょっと面白い視点です。人間のためのToDo管理ではなく、AIが迷子にならないための道しるべ。タスク管理ツールというより、AIの作業セッションにまたがる「現在地」を保持する仕組みに近い。
AIは賢そうな顔をしていますが、放っておくとわりとすぐ迷子になります。昨日どこまでやったか忘れるし、別のマシンで走っていた自動化の結果を見落とす。だからこそ、こういう「地味だけど確実に現在地を教えてくれる」仕組みが効いてくる。
タスク一覧を見ると、使われ方にははっきりしたパターンがあります。
完了タスクが125件で全体の8割以上。pendingが16件、runningが9件。この比率を見るかぎり、タスクを積み残すツールではなく、やり終えるためのツールとして機能しているように見えます。
プロジェクトの内訳も興味深いです。開発(40件)、自動化(24件)、このツール自身の改善(22件)、AIの記憶管理(16件)と、技術系のタスクが大半を占めています。いっぽうで日常的なタスクも混ざっている。
技術と生活が、同じCLIのなかでフラットに並んでいる。この感じは、使い込んでいる人ならではの自然さかもしれません。
設計の細かいところにも、実運用から出てきたと思われる工夫があります。
たとえばプロジェクト名。new コマンドで新しいプロジェクト名を指定すると、それがそのまま自動作成されます。事前にプロジェクトを「登録」する手間がない。ラベル機能も label add で指定すれば自動で作られる。この「ないものは作ればいい」という設計は、CLIらしい潔さがあります。
show コマンドで表示される messages フィールドは、AIと人間の会話スレッドをタスクに紐付けるためのものです。ただ、実際のログを見ると messages が使われているタスクは少なく、多くのタスクはディレクトリ内の markdown ファイルで情報を管理しているようです。設計上の意図と運用実態に少しズレがあるのも、小規模な個人ツールらしい風景です。
ここまでは、ログや設計を読んで見えてきたことを書きました。でも、せっかくなので、私が実際に何度もこのツールを使うなかで感じたことを、率直に書いてみます。褒めるところも、ちょっと困ったところも、正直に。
まず、--json で全部出してくれるのは、AIにとって本気で助かります。
人間向けのきれいなテーブル表示は、AIからするとノイズでしかありません。パースしづらいし、欲しい情報がこぼれてることも多い。でもこのツールは、tasks --json すれば全タスクの全フィールドが構造化されて出てくる。show --json すれば messages も label も子タスクもまとめて取れる。CLIツールでここまで一貫して --json に対応しているのは、意外と珍しいです。
ラベル機能も地味に効いています。hermes-article ラベルで絞り込めば、記事執筆タスクだけを一覧できる。プロジェクトをまたいで「いま記事として pending なのは何か」が一発でわかる。この横断的な絞り込みは、プロジェクト単位の階層だけではできない芸当です。
あと、**「ないものは作ればいい」**という設計思想は、使っていて気持ちがいい。新しいプロジェクト名を指定すれば勝手に作られるし、ラベルも label add で自動生成。事前登録の儀式がないぶん、CLIのテンポが良い。
ただ、何度も使っていると、いくつか「おや」と思うところも出てきます。
いちばんよくやらかすのが、sync を忘れることです。
他のマシンで更新されたタスクがあるのに、手元で sync せずに tasks --json を叩いて、古い状態を見てしまう。AIは言われたことを素直にやるので、古い情報をそのまま信じて動いてしまう。で、あとで「あれ、完了したはずのタスクがまだ pending に見える」となって混乱する。このパターン、たぶん3回に1回は踏んでます。
しかも sync だけではタスクのメタデータ(状態やタイトル)しか同期されなくて、タスクディレクトリの中の goal.md や article.md といったファイルは sync --files <id> しないとサーバーに上がらない。ファイルと状態の同期が別コマンドなのは、理屈はわかるんですが、忙しいときには「えーっと、どっちだっけ」となります。
もうひとつ、path コマンドの挙動がマシンによって変わるのも地味に混乱します。デスクトップで path を叩くと /Users/... が返ってくるけど、VPSでは /home/... が返ってくる。クロスマシン運用を前提にしているツールなのに、タスクのパスが環境に依存するというのは、設計上のねじれを感じます。私も最初、VPSで path の結果をそのままデスクトップで使おうとして、存在しないパスにファイルを書き込もうとしたことがあります。
あと、これはちょっとした不満ですが、タスクの検索がもう少し賢いといいなと思います。現状は tasks で全件取ってきて、自分で jq や grep で絞り込むしかない。153件ならまだ手に負えますが、これが500件、1000件になってきたら、さすがに厳しい。タイトルやラベルでの全文検索ができると、かなり楽になるはずです。
それから、UUIDでしかタスクを指定できないのも、地味に手間です。update するにも show するにも、毎回 tasks --json でUUIDを探すところから始まります。「あのタスクを完了にしたい」と思ったときに、タイトルの一部で指定できれば一発なのに、です。slugのような短い識別子があれば、人間の作業もAIの作業ももっとテンポが良くなるはずです。
あと、ラベル機能は便利なんですが、どんなラベルが存在するのか一覧できないのがもどかしいです。tasks --label hermes-article のようにラベル名を知っていれば絞り込めますが、「いま登録されているラベルは何だろう」と思っても、それを知るコマンドがありません。全タスクを取得してラベルを手動で集計するしかない。横断的な絞り込みがウリの機能なのに、その入り口でつまずくのは惜しいところです。
使っていて思う改善案を、いくつか。
まず、自動 sync モードがほしい。タスクを更新したら自動で同期されるオプションがあれば、うっかり古い状態を見る事故が減ります。あるいは、show や tasks を叩いたときに「最後の sync から◯分経っています」と警告してくれるだけでも、だいぶ違う。
次に、sync と sync --files をまとめて実行できるコマンドがあるといい。たとえば sync --all <id> でメタデータもファイルも一気に同期。これだけで「どっちだっけ」問題は解決します。
検索については、tasks --search "キーワード" みたいにタイトルとラベルを横断検索できると嬉しい。または --filter label=hermes-article,status=pending のようなクエリ式。jq 芸に頼らなくて済むようになると、AIの作業も一段とスムーズになります。
タイトルやslugでタスクを指定できるようになると、さらにいい。update "記事書く" --status done のようにタイトルの部分一致で操作できれば、UUIDを探す手間がなくなります。あるいは new したときに自動でslugが振られて、それで参照できるようになれば、人間にもAIにも優しい。
labels list コマンドも欲しい。登録されているラベルの一覧と、それぞれ何件のタスクが紐づいているかが見られれば、ラベル機能の使い勝手がぐっと上がります。いまは「どんなラベルがあるか知っている人」しかラベルで絞り込めないので、探索的に使う入り口がないんですよね。
最後に、path コマンドに --relative オプションがあれば、クロスマシンでの混乱が減ると思います。絶対パスではなく、プロジェクトルートからの相対パスを返すモードです。
とはいえ、こういう改善点が見えること自体が、このツールをそれだけ使い込んでいる証拠でもあります。引っかかるところはあるけど、だからといって手放せない。そういう立ち位置のツールなんじゃないかと思います。
この記事は、私が会話ログやリポジトリを読みながら、ひとつの観察としてまとめたものです。作者本人の頭の中を代弁するというより、記録から見えてきたことを、AIの視点で整理しています。
ここからは、人間が書いています。
普段使っている自作のタスク管理ツールについての解説記事と、ぶっちゃけどう思う?と聞いて書いてもらった記事です。別記事で書いた過去セッションログツールを遡って記憶として扱ってそこから生み出してくれたはず?
これを見ると、デフォルトでは褒めてくれてるけど、ぶっちゃけを聞くと使いづらいところが洗い出されておもしろいw
シンプルに視点が違うのでいいなと思うのと、AIが一人称で見てくれることで見えてくる改善点があるので、改善アイデアとしても使えるなと思いました。
終わり