Term-gotchi まとめ | zshで育つターミナル相棒を作った記録 | UNIX Cafe

* 当サイトでは、コンテンツの一部に広告を掲載しています。

System Note $ cat /proc/ai-disclosure

本記事の構成および論理分析にはAI(人工知能)を使用しています。情報の正確性は、システム管理者(UNIXユーザー)による手動検証済みです。

Term-gotchi まとめ | zshで育つターミナル相棒を作った記録 | UNIX Cafe

zsh の中で育つ小さな相棒アプリ「Term-gotchi」を作ってみました!

Term-gotchiは、普段どおりにターミナルでコマンドを実行しているだけで、少しずつ経験値がたまっていきます。気が向いたときに tg_status で様子を覗いてみたり、tg_feed や tg_talk でちょっとしたお世話をしたりもできます。

最初に作りたかったのは、小さなターミナルアプリです。

毎日開くターミナルに、ほんの少しだけ反応があったら楽しいんじゃないか。いつもの ls や git のあとに、何かが少し育っていたら、作業場としての shell にも愛着がわくかもしれない。

そんな思いつきから始めた、小さな実験です。

この連載では、安全なインストールの方法から、状態ファイルの管理、成長の履歴システム、さらには英語学習の要素、そして最終的に GitHub で公開するまでのステップを、実際に作りながら少しずつ紹介していきます。

ソースコードはこちらです。

https://github.com/k1117n-cmyk/termgotchi

目次

作ったもの

Term-gotchi は、ターミナルでの作業を少しだけ育成ゲームのようにする zsh アプリです。できることを並べると、次のようになります。

  • zsh の中で動くターミナル相棒アプリ
  • tg_status で状態と ASCII アートを表示
  • tg_feed、tg_clean、tg_talk、tg_train でお世話や交流をする
  • 普段のコマンド実行から経験値を得る
  • egg -> sprout -> buddy -> builder -> sage と進化する
  • hunger、health、mood、XP、level などの状態を持つ
  • tg_history で成長記録を振り返る
  • tg_talk で短い英語表現に触れる
  • tg_export、tg_import で状態をバックアップ・移行する
  • install.zsh と uninstall.zsh で導入と削除を扱う

使う側から見ると、かなり小さなアプリです。

ただ、作っていく中では、シェル hook、状態保存、JSON の更新、インストール処理、アンインストール処理、README、CHANGELOG、配布パッケージなど、CLI ツールを作るときに避けて通れない要素がいくつも出てきました。

インストール後は、例えば次のように使います。

tg_status
tg_feed
tg_clean
tg_talk
tg_train
tg_history
tg_export ~/Desktop/termgotchi-state.json
tg_import ~/Desktop/termgotchi-state.json

便利な作業効率化ツールというより、毎日開くターミナルに小さな反応を置いてみる試みです。

コマンドを実行すると少しずつ育ち、たまに話しかけると短い英語のフレーズを返してくれる。そうした小さな変化があるだけでも、いつもの作業場所が少し違って見えてきます。

全体の流れ

本連載は全4回に分けてお届けします。大きな流れは次の通りです。

• 第1回: zsh の中で育つ最小の相棒を作る
• 第2回: 成長記録と進化の仕組みを足す
• 第3回: tg_talk を英語学習モードに育てる
• 第4回: GitHub で公開・更新できる形に整える

第1回では、まず安全に動く土台を作りました。データは ~/.termgotchi/ の中に閉じ込め、.zshrc への追加は 1 行のみ。preexec や precmd は直接上書きせず、add-zsh-hook を使って安全に処理しています。最初から機能を増やすよりも、毎日のシェル環境を壊さないことを最優先しました。

第2回では、育った軌跡があとから確認できるように、成長記録と進化の仕組みを追加しました。単に数字が増えるだけではなく、「いつ、どんなきっかけで変化したのか」を見返せるようにしたことで、育成アプリとしての手触りが大きく変わりました。

第3回では、tg_talk を英語学習寄りの機能に育てました。ただ英語のセリフを表示するだけでなく、Phrase、Theme、Tone、Meaning、Example というメタデータを持たせ、短い表現を文脈ごと見られるようにしています。

第4回では、Git と GitHub で公開・管理できる形に整えました。コード、README、CHANGELOG、インストール・アンインストール手順、そしてユーザーごとの状態ファイルを綺麗に切り分け、誰でも clone して試せる小さなプロジェクトに仕上げています。

第1回: ターミナルで育つ相棒を作る

第1回では、Term-gotchi の最小構成を作りました。

最初に考えたのは、どんな機能を入れるかよりも、どこまでなら安心してシェル(zsh)に入れられるかでした。

ターミナルアプリは毎日の作業環境に入り込みます。だからこそ、楽しくする前に、まず作業の邪魔をしないことが大切です。.zshrc を壊したり、既存のフックを上書きしたり、状態(state)ファイルの更新に失敗して JSON を壊したりするようでは、安心して使うことができません。

  • データは ~/.termgotchi/ に閉じ込める
  • .zshrc には guarded source line を 1 行だけ追加する
  • preexec() や precmd() を直接上書きしない
  • state 更新は一時ファイルに書いてから mv する
  • まず tg_status が動くところを目指す

ここで中心になったのは、tg_status、tg_feed、tg_clean、tg_talk、tg_train です。

特に先に作ってよかったのは tg_status でした。現在の姿、レベル、XP、hunger(空腹度)、health(健康状態)、mood(機嫌)が画面に表示されると、state に何を持たせるべきかが見えてきます。画面に出るものから逆算して考えると、内部のデータ構造も決めやすくなります。

最初の到達点は小さいものでした。それでも、ターミナルに相棒が表示され、普段のコマンド実行で少しずつ育つようになると、このアプリでやりたいことが具体的に見えてきました。

第1回の記事はこちらです。

第2回: 成長記録と進化を実装する

第2回では、Term-gotchi に成長記録と進化の仕組みを追加しました。

第1回の時点でも相棒は育ち、コマンドを実行すると XP が増え、レベルも上がります。ただ、しばらく使っていると、数字が増えるだけでは少し物足りなくなってきました。

いつレベルが上がったのか、どんな操作がきっかけだったのか、進化したときにどんなメッセージが表示されたのか。そういう変化があとから見返せないと、「育った」という感覚が少し薄くなってしまいます。

そこで追加したのが tg_history です。育成アプリにとって、記録は思っていた以上に大事でした。今の状態だけでなく、そこに至るまでの変化が見えると、相棒との付き合いが少し「続きもの」になります。

この回では tg_status も見やすくしました。XP や hunger / health / mood をゲージで表示し、コマンドの total / unique、フォームごとの trait(特性)、次の進化条件も見えるようにしています。

さらに、進化後の違いを見た目だけで終わらせないために、「builder」と「sage」という後半フォームも足しました。第2回の記事では buddy の先に分岐進化を作る形で紹介していますが、その後の整理で、最終的には buddy -> builder -> sage と進む段階進化に変更しました。

  • sage: 学習や理解に寄った相棒
  • builder: 作業を前に進める感じの相棒

進化の道筋は段階式に整理しましたが、普段使うコマンドの種類や回数は、XP や unique command、履歴として少しずつ残るようにしました。

この回で面白かったのは、派手な機能よりも、毎回見る表示や履歴のほうが効果があったことです。育成アプリらしさは、大きな演出だけではなく、日々の小さな変化をどう見せるかにもかなり左右されるのだと分かりました。

第2回の記事はこちらです。

第3回: 育てた相棒に、英語を教わる

第3回では、tg_talk を軽い英語教材として育てました。

Term-gotchi には、最初から「English-learning flavor(英語学習の要素)」という方向性がありました。ただ、第2回までの tg_talk は、まだ「英語のセリフが表示される」くらいの機能でした。雰囲気はありますが、学習としては少し弱い状態です。

例えば、英語の一文が表示されても、それがどういう場面で自然なのか、同僚に使ってもよい表現なのか、どう返すと会話になるのかまでは分かりません。

そこで第3回では、tg_talk の出力を「micro lesson」として整理し、次の要素を追加しました。

  • Phrase(フレーズ)
  • Theme(シチュエーション)
  • Tone(丁寧さ・ニュアンス)
  • Meaning(意味)
  • Example(会話例)

単に “Sounds good.” と表示するだけではなく、それがどういう雰囲気の表現なのか、どんなテーマで使えるのか、短い会話例ではどう続くのかまで見られるようにしました。

ここで目指したのは、長い会話を生成することではなく、短い表現を何度も見て、文脈ごと覚えられる形です。
また、Meaning も日本語訳ではなく、英英辞典のような短い英語の説明にしました。日本語に戻らず、英語を英語のまま受け取る練習にしたかったからです。

さらに、時間帯や直近コマンドの文脈によって、表示される表現が少し変わるようにもしました。git のあと、rg や ls のあと、あるいは夜にビルド系のコマンドを触ったあと。同じ tg_talk でも、その時の作業に少し寄った英語が表示されると、ターミナルの中に学習が自然に混ざります。

この回で、Term-gotchi はただ話す相棒から、英語表現の小さな練習相手に近づきました。

第3回の記事はこちらです。

第4回: 公開・配布のためのプロジェクト構成を整える

第4回では、Term-gotchi を Git と GitHub で公開・管理できる形に整えました。

手元の zsh スクリプトとして動いているだけなら、多少ファイルが散らばっていても何とかなります。でも、育てるほど気になることが増えてきます。

  • どのファイルが最新なのか
  • 変更前の状態に戻せるのか
  • 別の Mac に入れるとき、何をコピーすればいいのか
  • README と実際のコマンドがずれていないか

小さなツールでも、長く育てるなら、このあたりを早めに整理しておきたくなります。そこで、プロジェクトの形を次のように整えました。

termgotchi/
  install.zsh
  uninstall.zsh
  termgotchi.zsh
  art/
  docs/
  scripts/
  README.md
  CHANGELOG.md
  LICENSE

ここで大事だったのは、Git で管理するものと、管理しないものを分けることです。

アプリ本体、README、CHANGELOG、インストール手順、ドキュメントは Git に入れます。一方で、ユーザーごとの育成状態や一時ファイル、生成された配布アーカイブは Git 管理から外します。

Term-gotchi は育成アプリなので、コードと個人の状態を混ぜないことが特に大事でした。

第4回では、インストールとアンインストールの導線も整えています。

git clone https://github.com/k1117n-cmyk/termgotchi.git
cd termgotchi
zsh ./install.zsh

削除するときは、次のようにします。

zsh ./uninstall.zsh

ツールを配布するのであれば、「簡単に入れられること」と同じくらい「きれいに消せること」が重要だからです。

その他にも、git pull で更新しやすくすること、CHANGELOG.md を読むための履歴にすること、README を最初の体験として整えることも意識しました。

GitHub にリポジトリを置いたからといって、急に大きなソフトウェアになるわけではありません。それでも、誰かが触れるかもしれない形にすると、プロジェクトの輪郭はかなりはっきりします。

第4回の記事はこちらです。

おすすめの読み方

基本的には、第1回から順番に読むのが一番分かりやすいと思います。

ただ、目的がはっきりしている場合は、次のように途中から読んでも大丈夫です。

zsh で小さなターミナルアプリを作りたい
  第1回

育成アプリらしい記録や進化を考えたい
  第2回

CLI に英語学習の要素を入れたい
  第3回

GitHub で公開・配布できる形にしたい
  第4回

ターミナルは毎日使うものです。

そこに小さな反応があるだけで、作業の感触は少し変わります。

Term-gotchi は、本格的なゲームでも、巨大な TUI でもありません。

ただ、zsh の hook、状態管理、JSON、README、インストール処理、GitHub 公開までを一通り触れる題材としては、ちょうどよいサイズでした。

作ってみて分かったこと

作ってみて一番大きかったのは、CLI ツールでも「体験」はかなり作れるということです。

Term-gotchi は、画面いっぱいの UI を持っていません。動く場所は、いつものターミナルです。それでも、状態があり、履歴があり、反応があり、少しずつ成長すると、ただのコマンド以上の手触りが出てきます。

もうひとつ大きかったのは、安全性を先に決めることでした。シェルに読み込まれて動くツールは、楽しい以前に、既存の環境の邪魔をしないことが大切です。

  • .zshrc への追記を最小限に留める
  • 既存のフック(hook)を直接上書きしない
  • 状態ファイルの更新に失敗しても、データが破損しにくい設計にする
  • 設定とデータをまとめて削除できるようにする

こういう地味な部分を先に決めておくと、あとから思いついた機能を追加するときにも、安心して開発を進めることができます。

そして、ログや履歴の力も再確認しました。tg_history は相棒の成長記録です。CHANGELOG.md はプロジェクトの成長記録です。Git のコミットログも、同じように「何を育てたか」を残す場所になります。

小さなアプリでも、変化を記録すると、あとから見返せる物語になります。

zsh アプリとしての面白さ

Term-gotchi は、zsh の練習題材としてもちょうどよかったです。

シェルスクリプトだけで状態を読み書きし、フック(hook)でコマンド実行を拾い、jq で JSON を扱い、mv で安全に更新する。必要なことは多いですが、巨大なフレームワークはありません。その分、ひとつひとつの設計がそのまま使い心地に跳ね返ってきます。

例えば、XP(経験値)を増やす対象を雑に判定すると、自分の状態を確認する tg_status コマンドを実行しただけで経験値が増えてしまいます。

状態(state)の保存処理を雑にすると、途中で JSON が壊れるかもしれません。

フックを雑に扱うと、ユーザーがもともと設定しているシェル環境と衝突してしまうかもしれません。

小さいツールだからこそ、こういう課題や設計の工夫がよく見えます。そして、そこを丁寧に整えていくと、CLI ツールはかなり愛着の持てるものになります。

まとめ

Term-gotchi は、小さな zsh アプリです。

しかしその中には、ターミナルアプリの安全設計、状態管理、育成ゲームの手触り、英語学習、Git 管理、GitHub での公開、そしてインストールやアンインストールまで、いろいろな要素が詰まっています。

作ってみて感じたのは、ターミナルはまだまだ遊べる場所だということです。

普段の ls や git や rg が、少しだけ相棒の成長につながる。作業の途中で tg_talk を叩くと、短い英語表現が表示される。それだけでも、いつものシェルに少し生活感が生まれます。

もちろん、実用だけを考えれば、相棒がいなくてもターミナル作業は問題なくできます。でも、毎日使う道具に少しだけ愛着が乗ると、作業そのものの印象が変わります。Term-gotchi は、そのための小さな実験でした。

zsh で何か作ってみたい人、CLI ツールを安全に配布してみたい人、あるいはターミナルに少し遊び心を入れてみたい人には、ちょうどよい題材だと思います。

まずは第1回で、zsh の中で育つ小さな相棒を作るところから始めます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

のいのアバター のい UNIX Cafe マスター

Macintosh Color Classicから始まった旅は、長いWindows時代を経て、Windows10のサポート終了をきっかけにUNIXの世界へ戻ってきました。UNIX Cafeでは、UNIX・Linux・そしてMacな世界を、むずかしい言葉を使わず、物語のように書いています。プログラミングは、アイデアをコンピューターに伝えるための言葉です。簡単な単語と文法を覚えれば、誰でもコマンドを使えます。ぜひ一度、やさしいプログラミングの世界をのぞいてみてください。

目次