おそらくはそれさえも平凡な日々

tapgrのドキュメントを整備しました

GitHub - Songmu/tagpr: automatically creates and updates a pull request for unreleased items, tag them when they are merged, and create releases.

おかげさまで、tagpr は多くの場所で導入いただいています。ただ、機能も増えてきて、その割にはドキュメントが不十分だと言う指摘があった為、READMEをアップデートすると共に、ドキュメンテーションサイトを作成しました。

https://junkyard.song.mu/tagpr/

主要なユースケースや躓きポイントなどがまとめられています。

かなり、GitHub Copilotと相談しながら書いてもらった感じにはなっているので、もう少し自分の言葉で書いたヤツをtagpr handbookの様な形でまとめたいと思っています。それを元にまたドキュメントサイトを改善する、みたいな流れになれば良いかなと思っています。

tagpr、便利なので、これから使いはじめる方の参考にもなると幸いです。

関連

フットペダルデバイスと最近の音声入力環境

AI Agentに指示を与えるために音声入力を使うことが増えてきたので、フットペダルを導入した。左手デバイスで有名なStream Deckシリーズのこのフットペダル。

ペダルを踏んでいる間は音声入力ソフトの入力モードになるように設定して、AI Agentのプロンプトだけではなく、任意のエディタに対して音声入力できるようにした。とは言え、文章作成には私はうまく使いこなせないが、Agentに渡すプロンプトなどは、多少誤字があってもほぼ問題ないのでうまくいっている。

音声入力ソフト Handy

音声入力には、HandyというOSSを使っている。これはダウンロードしたSpeech to Textモデルを使うので、ローカル完結できて無料で使える。とても便利なので作者をスポンサーした。

Sponsor @cjpais on GitHub Sponsors

設定画面はこんな感じ。Option + Space でバックグラウンドで音声入力を受け付けてくれるようになるので、それをフットペダルに割り当てている。言語は自動検知してくれるモデルを利用していて、日本語も英語もいける。

モデルはNVIDIAのNemotron Streaming 3.5を使っている。精度はかなり良い。他のモデルも設定画面から色々選べて、選んだものを簡単にダウンロードしてきてくれる。Whisperとかも選べる。

AI Agent自体が音声入力機能を備えることも増えてきたが、別ソフトウェアに分かれていると複数のエディタ環境にまたがって利用することができるし、アーキテクチャ的にも疎結合できれいだと思う。もちろん、密結合されていることでインテグレートされた体験を提供できたりもする場合もあるわけですが。

何にせよ、このフットペダルとHandyを組み合わせた構成はおすすめです。

codocを導入してチップを送ってもらえるようにしました

このブログと、はてなブログのサブブログ、とポッドキャスト、趣味でOSSをやっている者だ にチップボタンを導入して少額での支援を受けられるようにしました。いわゆる投げ銭的なやつなので、送ってもらえると嬉しいです。メッセージも送れます。

今回利用したcodoc は、はてなブログと連携したときに知って、アカウントを作っていた。なので、今回は画面の指示に従ってタグを貼り付けるだけで簡単に導入できた。個人サイトに簡単に追加できるのは嬉しい。codocは社長の石川さんに以前お世話になったこともあって、応援しています。

有料記事販売みたいなペイウォールを設けるのは、私自身の手間の観点からもやろうとは考えていないのですが、codocがそういう限定コンテンツの有料販売以外の用途でも使えることに気付いて導入した次第です。送ってもらった体験がどういう感じになるかや、正しく設定できているかなどが分からないので、是非100円でもお送りいただけると嬉しいです。

Markdownからpptxを出力するslidown

最近は仕事でPowerPointを使うことが増えたのだが、やはりMarkdownからプレゼンテーションを作りたいという偏執狂的な欲求が抑えられなくなったのと、私も開発に参加しているk1LoW/deckの快適な体験をPowerPointでも得たくなったため、deckと同様のMarkdownからpptxを出力するOSSを作った。名前はslidown。

https://github.com/Songmu/slidown/

Go製なのでgo install でも入るが、例によってHomebrewでもインストールできるようにもした。

$ brew install tap/Songmu/slidown

deckの「デザインとコンテンツの分離」という素晴らしいコンセプトを踏襲し、スライドマスタでデザインを調整する思想となっている。

使い方

deckと同じ様な、--- をスライド区切りとしたMarkdownを使えば、pptxが出力できる。ローカル完結なので、 slidown new などもなく slidown apply でいきなりpptxを出力できる

$ slidown apply slide.md
Wrote slide.pptx (11 slide(s))

出力先の指定や、テンプレートファイルの指定 (potxやpptx)も可能。--watch モードもあり、Markdown編集を見て、pptxを自動で出力し直してもくれる。詳細はリポジトリやドキュメントを参照して欲しい。

slidown apply slide.md --template template.potx

オープンフォーマットとしてのpptx

pptxは主にXMLを中心とするファイル群をzipでまとめたOffice Open XML (OOXML)というオープンフォーマットであり、ECMA-376で定められている。Microsoft 365 (Office) の他にも LibreOffice なども読み書きができる。おそらくそれぞれ独自拡張などはあると思うが詳しくはない。結局全部XMLに中には収まってはいるのは確かだ。

なので、実はローカル完結で機械的に読み書きさせすい。slidownの出力スピードもとても早い。仕様を確認しながらの実装は大変だが、今ならAIを使えばそれほど難しくない。

どの様にslidownを作ったか

実はslidownは完全にdeckのforkです。GitHubのfork機能は作っていないが、deckのリポジトリを引き継いでいます。古い履歴にはdeckの履歴が残っています。ライセンスなども引き継いでいます。

fork当時の最新のコミットからGitHub Copilotに一気に書き換えてもらいました。実装を簡単にするためと、deck自体にpptx出力機能が欲しいかと言うと、そうでもないなと思ったので、一旦別プロダクトとすることにしました。AI Slop Fork的なことをやったわけだけど、まあ、私もdeckの開発にはだいぶ参加させてもらったので大丈夫かなと思っています。

兄弟プロダクトとして、コラボレーションなり共通化なりはできるところはできると良いかと思っている。今回の実装の中でも、ヒントがえられた部分もあったので、deck側にアイデアとして戻せても良いかな、と思っています。

使い方などは別途まとめたいと思っていますし、まだできたばかりで不安定だとは思いますが、今の段階でも結構便利なので、是非ご利用ください。

仕事用のフォントを合成して公開してみた

https://github.com/Songmu/OctoBiz

GitHub社はMona Sansというオープンソースのフォントを公開していて、社内で作られて公開されるプレゼンテーションはこのフォントが使われることが多い。ただ、このフォントには当然日本語のフォントが含まれておらず、プレゼンテーションを和訳する際には他のフォントを使わざるを得ず、テイストが変わってしまうのが気になっていた。

なので、このMona Sansと日本語フォントを合成し、日本語の資料に使うためのフォントを作った。合成する日本語フォントは、モリサワのユニバーサルデザインフォントのBIZ UDゴシックのプロポーショナル版のBIZ UDPゴシックを採用し、OctoBizと命名した。今後業務で使っていけると良いかなと思っている。

BIZ UDPゴシックは400(Regular)と700(Bold)の2種類を提供しているので、OctoBizもStaticフォントとしてその2種類を用意しています。GitHub Releases からダウンロードしても良いですし、Homebrewでインストールもできるようにもしました。

$ brew install Songmu/tap/octobiz

作ってみて、フォント周りの知識が少し増えたので面白かった。

インスパイア元

私は今は白源/HackGenというプログラミングフォントを使っているのですが、このフォント作者のyuru7さんが、BIZTERという合成フォントを作られていて、そのリポジトリ内の合成用スクリプトを流用させてもらいました。なので、アイデア・着想・手法すべてBIZTERから頂いています。ありがとうございます。

OctoBizのリポジトリはBIZTERのリポジトリを参考にしつつ、簡単な依存管理的な仕組みと、tagprによるリリースの自動化も実現できて満足している。Homebrewでのインストールも簡単にできて良かった。

余談

GitHubはMonaspaceというプログラミングフォントも公開しているので、これもまた日本語フォントと合成してみようかと思っていたら、yuru7さんがすでにMoralerspaceというフォントを作られていた。バリエーションも色々あって良い感じなので、プログラミングフォントはこちらに乗り換えようかと検討している。

感謝の意味も込め、yuru7さんにはGitHub Sponsorさせてもらいました。ありがとうございます!

サプライチェーンアタック対策とdependabot活用

注: 本記事は執筆時点(2026年4月)の情報をもとに書いています。実際のご利用にあたっては、公式ドキュメント等の最新情報を参照し、正確性を確認の上ご利用ください。

さて、axiosへの攻撃の件で、サプライチェーンアタックの恐ろしさを改めて感じさせられました。外部ライブラリを使う場合、基本的にはセキュリティ面も含めて最新バージョンを使いたいわけですが、その更新作業は脆弱性が入り込みやすいタイミングでもあるというジレンマがあるわけです。

なので、以下のようなポリシーとフローでの外部ライブラリ利用が現状の推奨要件と言えるでしょう。

  1. 基本は最新バージョンを使う
    • 機能面、パフォーマンス、セキュリティ面でより良い
    • 追随を怠ると更新が困難になり、新機能が使えないだけではなく、セキュリティリスクも高まる
  2. ただし、新バージョンリリース直後ではなく、しばらくしてから最新版を適用する
    • 最新バージョンに問題が無いか様子見をしてから入れるということ
    • 特に最近は単なるバグや脆弱性だけではなくmalwareが仕込まれるケースが出てきた
  3. 検証してから最新バージョンに更新する
    • CIでテストが通るか・おかしな挙動が無いか確認してからコードベースに反映する
    • その後、開発者の手元、本番環境でも更新をおこなう

特に2点目が最近よく言われるようになってきたポイントです。"Minimum release age" や "cooldown" と言われる、リリースから一定の期間経過後に最新バージョンを入れるというものです。dependabotやrenovateなどの更新ツール、JavaScript周辺のパッケージマネージャーは一通りそのための機能をすでに備えています。

3点目の「検証してから最新バージョンに更新する」も簡単に書きましたが、厳密に考えると少し厄介です。検証時点でmalwareが混入する可能性があるからです。今回のaxiosの件もまさにそういうケースでした。

そう考えると先程の要件を一通り満たすためには以下のプラクティスが必要です。

  1. 自動的にバージョンアップが促されるワークフローを構築する
  2. "Minimum release age" 設定ができるツールを利用する
  3. 秘匿情報にアクセスできない隔離された環境で新バージョンの検証を行う

これらをDependabotで実現する方法を紹介します。

Dependabotでの実践例

Dependabotを導入し、自動的にバージョンアップが促されるようにする

Dependabotは依存ライブラリ更新のワークフローを構築するGitHub組み込みの機能であり、無償で利用できます。定期的に依存関係の更新をチェックし、PRを起票してくれます。

以下のようなYAML設定を配置するだけで利用を開始できます。

# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
  directory: "/"
  schedule:
    interval: "weekly"
  cooldown:
    default-days: 7

上記はnpmに対して週次でチェックをするシンプルな設定例ですが、チェック頻度の変更、他のパッケージシステムでの利用、グルーピング設定なども出来ます。詳しくはドキュメントを参照ください。

Dependabot quickstart guide - GitHub Docs

cooldown項目でminimum release ageを設定する

先のYAMLの例の中にも書いていましたが、cooldown項目で、リリースから一定期間経過してから最新バージョンを入れるようにできます。これも細かい設定が可能で、例えば、一部のライブラリは除外したり、上がったバージョンがメジャーバージョンかマイナーかで期間を変えたりもできます。これもドキュメントを参照してください。

Dependabot options reference - GitHub Docs

dependabotが起票したpull request上で検証を行う

dependabotはpull requestの形でバージョンアップの提案をしてくれます。ですので、そのPR上のGitHub ActionsのCIワークフローで検証を行えます。

dependabotはリポジトリシークレットにアクセスできない

ここで嬉しいのは、このPR上のワークフローは外部のforkリポジトリからのPRと似たような権限モデルで動くことです。具体的にはリポジトリシークレットなどにはアクセスできないため、そこからトークン等が漏洩する心配はありません。GITHUB_TOKEN もデフォルトではread-onlyになります。

Dependabot が更新する依存パッケージには信頼できないコードが含まれる可能性があるため、fork からの PR と同等に扱うということなのでしょう。その点では、package.json などのバージョンファイルを開発者が更新してPRを起票するより、dependabotに任せた方が安全とも言えます。詳しくは以下を参照してください。

Troubleshooting Dependabot on GitHub Actions - GitHub Docs

github actions workflow runs that are triggered by dependabot from push, pull_request, pull_request_review, or pull_request_review_comment events are treated as if they were opened from a repository fork.

Dependency reviewと組み合わせる

パブリックリポジトリや、GitHub Advanced Security (GHAS) の契約がある場合、dependency reviewを使えば、PR上の依存関係変更に対するレビューを追加でおこなえます。具体的にはGitHub Advisory Databaseを参照し、依存関係に脆弱性がないかをチェックしてくれます。これもPR上で動くワークフローで実行できるため、問題がある場合に変更をブロックできます。

# .github/workflows/dependency-review.yml
name: Dependency Review
on: [pull_request]
permissions:
  contents: read
jobs:
  dependency-review:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v6
      with:
        persist-credentials: false
    - uses: actions/dependency-review-action@v4

Dependency reviewには、自分たちのコードベースに望ましくないライセンスのコードの混入を防ぐ機能などもあります。OSSだと無償なので積極的に使うと良いでしょう。詳しくはドキュメントを参照してください。

About dependency review - GitHub Docs

ローカルマシンのリスク軽減

ここまで説明した通り、依存ライブラリの安全性を確認してから、各開発者のローカルマシンに展開していくのが安全なフローです。

ただ、開発者やローカルのコーディングエージェントがこのフローを守らず手元でうっかりアップデートしてしまう場合には無力です。それを防ぐためにはやはり、.npmrc など、手元の開発環境の設定も合わせてしっかりやることも重要です。

また、AIコーディングエージェントはかなり気軽にnpm installpip install 等を実行するため、変なサイトに情報を流さないようにサンドボックス機能があるとやはり嬉しいところです。先日紹介したfenceのようなサンドボックスツールを活用するのも一つの方法でしょう。

コードベース窃取等の外部送信への対策

どこまで気にするかという話もありますが、今回のaxiosのようにシークレットを狙うのではなく、コードベースを丸ごと盗もうとするようなmalwareの場合には、上記の方法だけでは不十分です。ただ、こういった無差別型の攻撃の場合、攻撃者はコードベースよりシークレットを窃取しようとすることが多いため、気にするべきリスクの優先順位としては低くはなります。

ただ、その辺りも含めて外部への情報送信リスクを懸念するようであれば、CI環境で怪しいサイトへの通信をブロックすることでリスクを低減できます。GitHub ActionsのGitHub-hosted runnerの場合、etc/hosts ファイルのプロビジョニングで怪しいサイトへの通信はブロックするという基本的な対策は入っています。

更に追加で自分たちで監査したり、許可・拒否リストの管理をしたいケースでは、サードパーティのStepSecurityのHarden-Runnerなどの導入が手軽ですが、プライベートリポジトリの場合は有料です。他には、GitHub Actionsからの外部通信をAzure private networking経由にする方法Self-hosted runnerで自分たちでしっかりネットワーク制限をかける方法もありますが、運用コストは上がります。

これについての本命として、GitHubも最近発表したセキュリティロードマップの中で、"Native egress firewall for GitHub-hosted runners" を年内くらいのターゲットで提供予定であることを公表しているので、期待したいところです。それ以外の下記の記事に記載されているロードマップ機能にはいずれも期待しています。

What's coming to our GitHub Actions 2026 security roadmap

fence - AI AgentをOSサンドボックスの中で動かす

AI Agentも賢くなってきたとはいえ、ローカルで何をしでかすかわからない怖さは拭いきれない。かと言って、細かく認可を与えるのもめんどいし、ザルな見過ごしも起こりやすくなって危ないので、できればファイル・ネットワークアクセス、コマンド実行等に適切に制限をかけたサンドボックス環境で放し飼いにしたい。

CLIとして動かすAI Agentの場合、引数に指定したコマンドをサンドボックス内で動かすコマンドラッパーがあると嬉しい。自作しようかと思っていたが fence というツールがまさしくそれだったので、これを使うことにした。Goで書かれていて、macOSとLinuxをサポートしている。早速、GitHub Copilot CLIでも利用しやすいようにpull requestを送って、取り込んでもらった。

使い方

使い方は簡単で fence コマンドの引数にサンドボックス内で動かしたいコマンド、今回のユースケースであればAI AgentのCLIを指定するだけだ。

$ fence copilot
$ fence claude

ただ、最初は外部へのネットワークアクセスが遮断されているので最低限の設定ファイルは必要だ。これも簡単で、fence config init とすれば ~/.config/fence/fence.json に初期設定を書き込んでくれる。初期設定は以下のように簡素だ。

// Starter config generated by `fence config init`; this file extends "code".
// Rules from "code" are inherited and not shown below.
// Add your project-specific overrides in this file.
// Run `fence --list-templates` to see available templates.
// Configuration reference: https://github.com/Use-Tusk/fence/blob/main/docs/configuration.md
{
  "extends": "code"
}

これは、code というCoding Agent用のビルトインテンプレートを継承している。このテンプレートの中身は以下から参照可能だ。特定のAI関係のドメインのみにアクセス許可を与え、ローカルの秘匿ファイルへのアクセスや git push などのコマンドは拒否するようになっている。実際の項目ごとの設定内容は fence config show で確認できる。ここから適宜調整すると良いでしょう。

https://github.com/Use-Tusk/fence/blob/main/internal/templates/code.json

動作確認とデバッグログ

fence の中でAI Agentを動かしていると、ファイルやサイトアクセスのブロック起因で意図しない挙動になることがある。それを確認するために、--monitor--debug オプションをつけて起動すると、モニターログが出力され、実際にブロックされたファイルやサイトを確認できる。ログは標準エラー出力に出るので、ファイルにリダイレクトして、tail で確認するとよいでしょう。ブロック状況を確認して、必要に応じて許可設定を追加すると良いでしょう。

$ fence --debug --monitor -- copilot 2>> .fence-monitor.log
$ tail -f .fence-monitor.log

Appendix

同種のソフトウェア

fence は600 starsなので、srtやnonoほどではないが、十分に信用がおけると判断し、Go製であることが私にとっては好ましいので採用することにした。

ちなみに、もともとはcageの存在だけ認識していて、そのネットワーク版を作ろうと思ってプロキシ設計までやっていたのだけど、調べたら同種のソフトウェアが流石にあるということが分かったのでそれに乗ることにしたというのがある。ラッパーコマンド自身がプロキシになってそれ経由の通信しか通さなくするというアーキテクチャは面白いので作ってみたかったが、こういうツールは既存の成熟したものを使う方が安心。

いずれのツールでもmacOSではApple SeatbeltというOS組み込みのサンドボックスを使っている。非推奨な機能らしいが、CLIでは代替手段が提供されてておらず、多くのツール内で使われているため、もはや廃止は難しそうになっているようだ。

Linuxではsrtとfenceはbubblewrap, nonoとcageはLandlockを使っている。

この辺りは以下の記事が参考になります。

Claude Code組み込みのサンドボックス機能を使えばよいのでは?

これまでの説明どおり、内部的には同様のことをしているのでそれで良いと思います。まあ、こういうのは別の専用のツールに分かれていた方が責務分離的に安心だし、細かい設定も可能だというのはあるでしょう。

というより、私が主に使っているGitHub Copilot CLIがまだサンドボックス機能が無いので、使っているというのが現実でもあります…。Copilot CLIのissueでも実装も望まれているので、そのうち機能追加されるとは思いますが、早めの対応を期待したいところです。

Add sandbox mode to restrict Copilot CLI file access to a specified working directory · Issue #892 · github/copilot-cli

ファイルにプロンプトを書き込むと非同期にAI Agentが召喚されるツールを作った

Markdownの中に 「@copilot 〇〇について調べて」みたいなプロンプトを書けば、コーディングエージェントが自動でそれを認識して非同期で動作してくれると嬉しい。なので、そういうツールを作った。それが ghsummon。その名の通り、手元からAI Agentを召喚するツールで、GitHub Actions上で動かす。

https://github.com/Songmu/ghsummon

@copilotで始まる行がGitHub上にpushされると、pull requestが自動で作成される。該当行をプロンプトとして認識し、GitHub Actions上でCopilot coding agentが動き、pull request上でファイルを編集してくれるという仕組みだ。

動作イメージのpull requestがこちら。"Who is @Songmu" というプロンプトに対して、GitHub Actionsが動き、README.mdを編集してくれている。

これは、GitHub Copilot coding agentというGitHub Actions上でCoding Agentを動かす機能を単に利用しているだけなのですが、ファイルにプロンプトを書き込んでpushするだけでAIにタスクを依頼できるのは便利。

私の利用法

私は日常のメモやドキュメントを Obsidian で書き、Gitプラグインで定期的にGitHubにpushしている。なので、プロンプトをファイルに書いておけば、定期pushのタイミングで自動的にCoding agentが動き始めてくれるようになり早速捗っている。

GitHub Copilot coding agentではカスタムエージェントも利用でき、サブエージェントも動作できる。なので、調査タスクなどを任せる場合、検証・再調査ループを回してくれるリサーチ用のカスタムエージェントを定義しておけば、かなり精度の高いレポートを生成してくれる。

pull request上で生成された内容を確認できるのも嬉しい。何か追加調査や調整してもらいたかったら、pull requestのコメント上で @copilot 〇〇について最新の情報を調べて追記して 指示を与えれば、さらに調査を続けて内容を更新してくれる。内容を確認してからマージすればよいので、調査をやらせっぱなしにして内容を読まないで腐らせてしまうことが減るのも嬉しいポイントだ。

使い方

リポジトリに以下のようなGitHub Actionsのワークフローファイルを置けばよい。あとはリポジトリ内でCopilot coding agentを動かすために、 copilot-setup-steps.yml というファイルも置く必要がある。詳細はREADMEを参照して欲しい。

name: ghsummon
on:
  push:
    branches: [main]
    paths: ['**.md']

permissions:
  contents: write
  pull-requests: write

jobs:
  research:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          persist-credentials: false
      - uses: Songmu/ghsummon@v0
        with:
          token: ${{ secrets.GHSUMMON_TOKEN }}

また、APIでpull requestにcoding agentをアサインするために、PAT(Personal Access Token)を作る必要があるのが現状ちょっと悩ましいポイントではあります。

注意点

GitHub Copilot coding agentを動かすので、GitHub Actionsの実行時間やCopilotのプレミアムリクエストを消費します。

同じファイルに対してはpull requestとリモートブランチが生きている限り重複実行はされません。なので、逆に該当pull requestをマージなり閉じたりしたあとは、ブランチを削除しないと、そのファイルにプロンプトを書いてpushしても反応してくれないので注意が必要です。

今後の展望

今は、Markdownファイルにプロンプトを書く私のユースケースに最適化されているが、コードファイルへのプロンプトもサポートできると嬉しいかも知れない。例えば // @copilot ここ実装して みたいな具合。

また、現状は、pushされたコミットから新しいブランチを切るようになっているが、ブランチを維持してほしい場合もあるだろう。あとは、 @copilot 以外のエージェントも呼び出せるとかも。

そのあたりはissueに積んでありますが、使ってみて要望などがあればご意見いただけると嬉しいです。

あなたのGo製CLIをAI Agent Readyにするskillsmith

CLIをAI AgentフレンドリーにするためにAgent Skillsがあると嬉しい。Agent Skillsは絶賛リポジトリで協議されているが、オープンスタンダードであり、各ベンダーがそれなりに足並みをそろえながら仕様がアップデートされている。フロントマッター付きのSKILL.md というMarkdownを .agents/skills/skill-name/SKILL.md のような場所に配置することで、Agentにskillを備えさせられる。配置場所も各ベンダー独自の場所もあったが、最近は主要ベンダーが .agents/skills もサポートし、その点では安定した。

OSS作者もリポジトリルートに skills/ ディレクトリを掘り、その中にAgent Skillsを置く人も増えてきた。そうしておけば、skills add などのインストーラーでスキルを導入しやすくなる。

そこで思いついたのがCLI自体にもAgent Skillsのインストーラーをバンドルしてしまう方法だ。mycli skills install などとすればCLIが自分のスキルをインストールしてくれると嬉しい。

Goの場合、embed パッケージがあり、リポジトリ内の skills/ ディレクトリを簡単にコードに埋め込むことができる。これを利用すれば簡単にインストーラーを作れるはずだ。バージョン情報も含めればスキルの更新も管理できるし、CLIとAgent Skillsのバージョンの食い違いによる問題も減らせる。

そこで作ったのが github.com/Songmu/skillsmith である。これを使えば、Go製の任意のCLIにサブコマンド skills を生やせる。以下のようなコマンドが利用できるようになるのだ。

mytool skills list        # List embedded skills
mytool skills install     # Install skills to ~/.agents/skills
mytool skills update      # Update skills to newer versions
mytool skills reinstall   # Reinstall all managed skills
mytool skills uninstall   # Remove managed skills
mytool skills status      # Show install status and version diff

組み込むのも簡単だ。以下は最小の組み込み例だが雰囲気は伝わるだろう。実際に、最近作った fmd2jsongitrail といったツールに組み込んでいるので、興味がある人はそちらも参考にして欲しい。

import (
    "context"
    "embed"
    "log"

    "github.com/Songmu/skillsmith"
)

//go:embed skills
var skillsFS embed.FS

func run(ctx context.Context, args []string) error {
    if len(args) > 0 && args[0] == "skills" {
        s, err := skillsmith.New("mytool", version, skillsFS)
        if err != nil {
            log.Fatal(err)
        }
        return s.Run(ctx, args[1:])
    }
    // ... existing command handling
    return nil
}

特定のCLIライブラリに依存しない形で作っているため、逆に任意のCLIライブラリで作られたCLIにも組み込みやすいはずだ。

とは言え、まだまだ出来たばかりで発展途上だし、既存のメジャーなCLIライブラリの cobraurfave/cli, kong などに組み込みやすいように、アダプターも用意したいとは思っている。ニッチなツールだが是非組み込んでみてフィードバックいただけると嬉しい。

ちなみに、CLI用のAgent Skillsを作るに当たっては、まずCLIの出力をndjsonにして、そのJSON SchemaをSKILL.mdに書いておくとAI Friendlyかなと思い、上記の2ツールはそのようにしてみた。

開発環境現状確認2026

開示ブームに乗り遅れたが、去年末から今年頭にかけてアップデートがあったので記録しておく。ものぐさなので、割と古いままだったりデフォルト厨寄りだったりするのだが、AIコーディングの流れもあり、多少は新しめのものも導入した。

OS: Mac

長く惰性で使っている。バックアップや他のスマートフォンやタブレットとの連携や、ファミリーアカウントなどの兼ね合いもあって、お金はかかるがAppleプラットフォームにどっぷりになっている。

dotfiles管理: 自前リポジトリ管理

https://github.com/Songmu/dotfiles

去年末に業務Macの設定する時に、リポジトリcloneしてリポジトリ内のsymlinkを適当に張るスクリプトを動かしたら大体動いたので、それで満足して良いかとなっている。

chezmoiへの乗せ変えを検討したが、dotfileはPC設定の初期にやることなのでその為に独自ツールが必要なのもイマイチだな考えて辞めた。ファイルのネーミングルールとかもちょっと余り好きではなかった。

生の設定ファイルを管理してsymlinkを張る方が単純でデバッグも容易。コーディングエージェントと一緒にデバッグもしてもらいやすい利点もある。

ただ、.ssh とかシークレット関連の管理は余りちゃんとやれてないのでその辺りは再考の余地があるがお茶を濁している。

エディタ: vim

neovimではない。プラグイン管理はvim-plug。

コーディングエージェント: GitHub Copilot

最近はGitHub Copilot CLIの開発が活発でターミナル上の体験も良くなったので、Claude Code MAXを使う必要もなくなった。CLIでプラン作って、シームレスにCopilot Coding Agentに切り替えてpull request上で作業してもらえのは体験が良い。

ターミナルエミュレータ: Ghostty

2024年にTerminal.appからWezTermに乗り換えていたのだが、Ghosttyに今年から乗り換えた。単にMitchell Hashimotoファンボだから。タブや画面分割はターミナルマルチプレクサに任せる主義で、別にターミナル固有の機能は使っていないので、乗り換えは楽。

シェル: zsh

あまり独自の .zshrc を太らせたくもないので、zplug でプラグインマネジメントしている。

ターミナルマルチプレクサ: tmux

ついにGNU Screenからtmuxに乗り換えた。流石にAI Agent周りのエコシステムを考えた時にWindowやペインを跨いだ制御がやりやすいtmuxの方が良いと判断した。

GNU Screenでやりくりするのも結構楽しかったし、2024年にWezTermを導入したのも、GNU Screen 5.0で20年ぶりにメジャーアップデートしてtrue color対応したのがきっかけだったりするので、最近の僕の開発環境刷新の契機にもなっている。

ランチャー: Spotlight

Alfredを買っていた時期もあったが、長らくSpotlight。最近だとアクション機能も追加されたし、Automatorとかと組み合わせて色々できそう。とは言え特にカスタマイズはしていない。

フォント: HackGen

https://github.com/yuru7/HackGen

ブラウザ: Choosy, Google Chrome

プロファイル切り替えや固有アプリで開く等の制御をするためにスイッチャーの Choosy をデフォルトブラウザにしている。実際に使っているブラウザは主にGoogle Chrome。

Choosyは開くアプリやプロファイルのルール設定を以前は頑張っていたが、特に頑張らずにポップアップから選ぶので全然困らないことに最近気付いた。

ノートテイキング: Obsidian

欠かせない。昔はターミナルが一番開いている時間が長かったが今はObsidianが一番長いと思う。バックアップはgitプラグインでGitHubとDropboxに同期している。

タスク管理: TaskMD Shelf, Obsidian

GitHub - Songmu/TaskMD-Shelf での管理が続いている。Obsidianでの管理と相性が良い。もっとAI支援してもらっても良いと思っているがまだできていない。

キーボード: MD770 JP 静音赤軸

いわゆる分割キーボード。特にカスタマイズとかなく吊るしで不自由なく使えるので長らく愛用している。外付けキーボードを使わないでMacbook Airのキーボードをそのまま使うこともある。

クラウドストレージ: Dropbox

周りに使う人は減った気がするが、Dropboxを引き続き使っている。メモや書類などはGitHub上置いている。なんだかんだでファイルが手元にすぐに持ってこられる安心感がある。旧世代っぽい…。あとは、iCloudをファミリー契約している。

日本語入力: Google日本語入力 or かわせみ

プライベートではかわせみを購入していて、業務用の端末にはGoogle日本語入力を入れている。かわせみ用の辞書を色々作りたいと思っているがやっていない。

Mac Mouse Fix

トラックパッドとマウスホイールの方向を逆にできるので便利。長らくScroll Reverserを使っていたが、マウス関連の設定も色々出来るので乗り換えた。

Window Manager

特にこれまで使ってこなかったが、typester/yashikiが気になっている。

Git関連

ghq

メモなど含め、開発以外でも様々なリソースをGitHub上で管理しているので、それらがghq get ですぐに手元に持ってこられるのは便利。GitHub社自体も多くのリソースをGitHubで管理しているのでそれらをパッと取得できるのも便利ですね。

TUIクライアント: tig

複雑なTUIクライアントは使っていないが、tigだけは手放せない感じになっている。主にgit log 代替として履歴を手元で確認するために使っているくらい。

diff表示: delta

git-diff-highlight から乗り換えてみた。とは言え、tig内部でgit-diff-highlightを使う設定を残してあるので、git-diff-highlight もまだ併用している。tigとdeltaの連携issueもあるが、難航しているようだ。

CLI

インタラクティブフィルタ: peco

fzfに乗り換えようかとも思ったが特に困っていないし、愛着もあるのでpecoを使っている。と思ったら、最近約3年ぶりに v0.6.0 がリリースされたので歓喜。軽快に動いている。

検索: ag

Ackからagに乗り換えたのがいつかもう覚えていない。今だとrgを使っている人が多いと思うけど、agはタイプしやすい…。rgのaliasをagにするという手もあるとは思っているが、それはちょっとagを蔑ろにしている感じがするのでやっていない。