FAMILY BASIC から積み上げてきたものを npm パッケージに詰め込んだ話

またまた応援チップをいただきました!
本当にありがとうございます。エアコン代として使わせてもらいます。
応援してくれる方がいると「もっといいものを作りたい」という気持ちが強くなる。そしてその気持ちを実際に形にするには、開発環境の土台がちゃんと整っていることが前提になる。だからこそ今回は、その土台として整えてきた @joshuafolkken/kit の話をしたいと思います。
FAMILY BASIC からずっとめんどくさかった
最初に触れたのは FAMILY BASIC でした。友達の家で触らせてもらって、「なんだこれは!」となって。でも家は貧乏で買ってもらえない。「頼む、貸してくれ!」と頼み込んで、ずっと借りて使っていました。あの友達が僕の人生を大きく変えたのは、本当の話です。
あの頃は、画面でマリオが動くだけで楽しかった。本を見ながらプログラムを打ち込んで、カセットテープに保存する。でもカセットテープのデータって、すぐ読み込めなくなるんですよ。だからまた打つ。また保存する。また読めなくなる——それでも楽しかった。そんな日々でした。
その頃からずっと感じてきたのが「新しいプロジェクトを始めるたびに、同じ設定を繰り返している」という苦痛です。ESLint の設定、 Prettier の設定、 TypeScript の設定、 Git フックの設定、 VS Code の設定……。
毎回「あ、あの設定ここにも必要だ」って思いながら、別のプロジェクトから設定ファイルをコピーして貼り付ける。でも更新が入ったら全プロジェクトに手動で反映しないといけない。管理が分散している状態って、本当にじわじわストレスが溜まるんですよね。
というわけで、よく使うものを全部外部パッケージにまとめてしまいました。それが @joshuafolkken/kit です。
最初は @joshuafolkken/config という名前でした。作ってみたら即バグ祭りで、最初の10個の Issue がほぼ全部「Fix 〜」でした。今思い返しても笑えない(笑)。パッケージ名を kit に改名してからも改善を続けて、現在 v0.56.0。マイナーバージョンを55回上げてきました。
FAMILY BASIC から積み上げてきたこだわりを1つのパッケージに
このパッケージには、僕がこれまで試行錯誤してきた「これがあると開発が気持ちいい」という設定が全部詰まっています。
| # | カテゴリ | 入っているもの | 何をやっているか |
|---|---|---|---|
| 1 | コード品質 | ESLint / Prettier / TypeScript | お作法・フォーマット・型を機械的に強制 |
| 2 | ESLint 追加陣 | sonarjs / unicorn / promise / import-x / svelte | バグ臭・冗長表現・import 順序までガード |
| 3 | スペルチェック | cspell | typo を変数名・ Markdown まで検出 |
| 4 | Git フック | Lefthook | コミット前に全チェックを自動実行 |
| 5 | エディタ設定 | VS Code extensions / workspace settings | 入れるだけで開発環境が整う |
| 6 | AI アシスタント | CLAUDE.md / AGENTS.md / GEMINI.md / .cursorrules | AI にルールを一括で伝える |
| 7 | CI/CD | GitHub Actions ワークフロー 4 本 / SonarQube 設定 | プッシュしたら自動でチェックが走る |
| 8 | セキュリティ | pnpm audit スクリプト | 脆弱なパッケージをインストール時に検出 |
以前の記事でも書いた「10層のガードレール」の土台が、全部このパッケージに入っているイメージです。
josh init 一発で終わる
新しいプロジェクトでこのパッケージを入れたら、最初にやることは1つ。
pnpm josh init これだけで、 ESLint の設定、 Prettier の設定、 TypeScript の設定、 Lefthook の Git フック、 VS Code の推奨拡張機能リスト、 AI 用の指示書ファイル( CLAUDE.md など)、 GitHub Actions のワークフロー……全部一気に展開されます。自動生成・マージされるファイルは 25本以上。
SvelteKit プロジェクトかそうじゃないかも自動判定してくれるので、設定を選ぶ手間すらない。しかも、すでにファイルがある場合は上書きせずにマージしてくれるので、既存プロジェクトに後から入れることもできます。
以前なら新しいプロジェクトを立ち上げるたびに1時間くらい設定作業に費やしていたのが、コマンド1つで終わるようになりました。この快感は何度やっても飽きない。(めんどくさいから自動化する、という哲学はこちらに書いてあります)
日常のコマンドも全部入り
josh は開発中に使うコマンドも全部まとめてあります。毎回 package.json に scripts を書き足す必要がない。全部で 25種類以上のサブコマンドがあって、pnpm josh help で一覧が出てきます。
pnpm josh lint— ESLint と Prettier でコードをチェックpnpm josh format— 自動フォーマットpnpm josh test:unit— Vitest でユニットテストpnpm josh test:e2e— Playwright で E2E テストpnpm josh latest— 依存パッケージを最新に更新 + セキュリティ監査pnpm josh bump— バージョンを上げる(major/minor/patchで指定)
毎日使うのがこのあたり。プロジェクトをまたいで全部同じコマンドで動くのが地味に最高です。
個人的に特に気に入っているのが josh git と josh followup です。
pnpm josh git -y "タイトル #123" と叩けば、ステージング・コミット・プッシュ・ PR 作成をまとめてやってくれる。pnpm josh followup --merge は、 CI が通るまで待機し、 CodeRabbit や Claude Review の指摘を確認し、 Telegram で通知して、マージまで全部やってくれます。人間が介在しなくていい部分は全部自動。ブラウザで CI の状態をチェックする作業が完全になくなりました。
一番力を入れたのが AI ワークフロー
pnpm josh help の一覧には出てこないんですが、実は一番力を入れているのが AI 向けのワークフロー機能です。
kickoff と fullrun。
これらはターミナルで叩く CLI コマンドではありません。AI さん(Claude Code)に対して「kickoff して」「fullrun して」と伝えると、 AI がワークフローを最初から最後まで実行してくれる。人間で言えば「着手してください」「全部やってください」という言葉に相当します。コマンドというより、AI への指示語です。
kickoff と伝えたら、 AI が GitHub Issue を作成し、タイトルと本文を英語で整えて、計画をコメントして、 Telegram で通知してくれます。ここまで全部自動。
fullrun はさらに上。計画から始まって、実装・テスト・ PR 送信・ AI レビュー対応・マージ・完了通知まで、ワークフローを全部通してくれます。僕がやることは「これをやりたい」と伝えるだけ。
前の記事で「社長になったつもりで全部任せた」という話をしましたが、あの話のインフラがこれです。「fullrun して」と一声かけたら、あとはコーヒーでも飲みながら Telegram の通知を待つだけ。これが今の開発スタイルです。
プロンプトを少しずつ育てていくやり方は以前書いたのですが、今は「育てたプロンプトをどのプロジェクトにも持ち込める体制」にたどり着いた気がしています。 AI を育てる → 育てたものをパッケージ化する、というのが自然な次のステップだったんだなぁと。
なぜ一言で動くのか
では、なぜ一言で AI がここまで動けるのか。
今回 @joshuafolkken/kit を作るにあたって、自分が最もエネルギーを注いだのが「AI を適切に動かすためのプロンプト・スクリプト・ワークフロー」です。実際に今一番役に立っているのも、ここです。
裏では3つの層が噛み合っています。
① プロンプト層(AI の教科書)
コードを書かせる前に、 AI に渡すルールブックを徹底的に書きました。coding-standards.md(コーディング規約)、testing-guide.md(テスト方針)、refactoring.md(リファクタリング方針)、agent-rules.md(AI が守るべき行動規範)、review.md(セルフレビュー手順)など、9本のドキュメント。この教科書がないと、 AI は毎回バラバラな判断をします。教科書があると、「この場面ではこうする」が自然に揃ってくる。
② スクリプト層(実行エンジン)
kickoff や fullrun の裏で実際に走る TypeScript スクリプト群です。 Issue の作成・ PR のフォローアップ・ CI 待機・ Telegram 通知など、専用の AI ワークフロースクリプトが9ファイルあります。コマンドを叩く側から見ると1行で終わりますが、裏ではかなり複雑な処理が動いています。
③ ワークフロー層(チェック機構)
「信頼じゃなくてゲートで判断する」という部分です。GitHub Actions の CI/CD と Telegram を使った完了通知の仕組みです。 AI が「できました!マージしました!」と言ったときに、本当に CI が通っているか、 CodeRabbit の指摘が残っていないか、 SonarQube が怒っていないかを自動で確認してからマージする。 AI を信頼してマージするのではなく、チェックをパスしたらマージされる仕組み。この違いは大きいです。
この3層が揃って初めて、fullrun 一発が成立します。コマンドは入口に過ぎなくて、中身を支える教科書とチェック機構が本体。それが今回の kit で一番伝えたかったことです。
気になった方は GitHub リポジトリを覗いてみてください。プロンプトもスクリプトもワークフローも、全部オープンにしてあります。
55回更新した、その裏側
v0.56.0 まで来るには、それなりの歴史があります。
まず、パッケージの名前が違いました。最初は @joshuafolkken/config という名前で始めたんです。でも途中で「config って言葉、なんかしっくりこないな」ってなって、 @joshuafolkken/kit にリネームしました(issue #70)。名前を変えるだけなのに、依存してるプロジェクト全部の参照を直すことになるので、そこそこ大変でした。
コマンド体系もかなり迷走しました。最初は jf-git、jf-check-upstream みたいな jf-* 形式の個別バイナリを作っていたんです。それがあるとき「全部 josh というコマンドに統一しよう」という方向に変わって、また全部書き直し。しかも josh に統一する過程で、コマンド名を何度かリネームして、古い名前を参照したままのドキュメントが各所に残ったりして(issue #54〜#56 あたり、笑)。
tsx が PATH にない問題には少し頭を抱えました(issue #77)。 TypeScript のスクリプトを直接実行するために tsx を使っているんですが、パッケージをインストールした環境によっては tsx がシステムの PATH に含まれていなくて、 josh コマンドを叩いても「command not found」になる。動いているはずのコマンドが動かない、という状態は精神的にこたえます。
地味に印象的だったのが trailing newline(末尾の改行)のエッジケース(issue #107)です。ファイルをマージする処理を書いていたんですが、ファイルの末尾に改行があるかないかで動作が変わるケースがある。「そんな細かいところで?」って感じですが、ソフトウェアのバグは大体そういうところに潜んでいる。
あと、 CodeRabbit に何度も怒られました。 PR を出すたびに「ここが良くない」「ここを直して」と指摘が来て、その対応コミットが何度も入っています。自分が AI にコードを書かせて、 AI がコードをレビューして、また自分が直す、という構図。AI の保護者会どころか、 AI 同士が殴り合っている感じです(笑)。
まだアプリを作っていないんだけど
正直に言うと、このパッケージを使って新しいアプリをまだ1本も作っていません。
土台を整えることに集中しすぎて、その上に何かを作る前に土台だけで満足してしまいました。
ただ、ちゃんと動くことは確認できています。このブログ(joshuafolkken.com のプロジェクト)自体が、もともと一体化していた kit 部分を引き剥がして外部パッケージ化したものなんです。つまり、このサイト自体が最初のユーザーです。数々の調整を経て、いまは @joshuafolkken/kit を使いながらちゃんと動いていることを確認できました。v0.56.0 まで来て、55回更新してやっと使えるようになった——そういうことです。
土台はできた。josh init 一発で AI との協業環境が整う。fullrun で計画から PR まで全部流れる。あとはこれを使って新しいアプリを量産するだけ。
これから始める。楽しみ!
みなさんの開発環境は?
共通の設定をパッケージ化している方、それとも各プロジェクトで管理している方、いろんなスタイルがあると思います。「こういうやり方もあるよ」という話があればぜひ聞かせてください。
AI と一緒に開発している方、kickoff / fullrun みたいなワークフロー自動化、どんな感じにやっていますか?一緒に考えましょう!
ボツタイトル供養
- FAMILY BASIC から積み上げてきたものを npm パッケージに詰め込んだ話(採用)
josh init一発で終わる開発環境を作った話- 設定のコピペとサヨナラ。積み上げてきたこだわりをパッケージ化した
- AI にアプリを量産させるために、土台を1つのパッケージにまとめた
- 「またこの設定書くの?」がゼロになった仕組み
fullrunで計画からマージまで全自動。AI 協業の土台を作った話- FAMILY BASIC から逃げ続けた「めんどくさい」を、パッケージに全部詰め込んだ