第1部と第2部で扱った層構造を、実際に動くコマンドと出力で追います。
掲載しているコマンドと結果は、すべて実行して確認したものです。
毎日打っているこの1行が、7つの層をどう通り抜けているか。
bash が PATH に並んだフォルダを先頭から順に見て、npm という名前のファイルを探します。見つかったら自分の複製を作り、その中身を上書きしようとします。第1部の第4章そのままです。
カーネルがそのファイルを開いて先頭を確認すると、こう書かれています。
先頭の #! はシバン(shebang)と呼ばれる印で、「これは機械語の実行ファイルではない。後ろに書いたプログラムに読ませてくれ」という指示です。
だからカーネルは npm を直接動かすのではなく、node を起動して npm のファイルを引数として渡します。npm 自体が JavaScript で書かれたプログラムであり、Node の上で動いているということです。
node が起動し、V8 エンジンが npm のコードを読み込んで実行を始めます。ここで初めて「JavaScript が動いている」状態になります。
npm が今いるフォルダの package.json を開き、scripts の中の dev という項目を探します。
つまり npm run dev それ自体は何もしません。package.json に書いてある別のコマンドを呼び出す代理人です。実際に動くのは next dev です。
ここで npm がもう一仕事します。node_modules/.bin というフォルダを PATH の先頭に一時的に付け加えます。これがあるから、next をパソコン全体にインストールしていなくても next という名前で呼べます。
npm がさらに自分の複製を作り、その中身を next で上書きします。ここでも fork と exec が起きています。プロセスの親子関係は bash → node(npm) → node(next) という三段になります。
next が app/ フォルダの中を走査し、どのファイルがどの URL に対応するかの表を組み立てます。
置き場所がそのまま URL になる。第1部の原則1「すべてはファイルである」の直系です。
Next.js がカーネルに「3000 番ポートで待ち受けたい」と依頼します。空いていればカーネルが割り当て、すでに他のプロセスが使っていれば拒否されます。
あの見慣れたエラーは、この段階で出ています。Next.js の問題でもコードの問題でもなく、OS がポートを渡せなかったという報告です。
準備が終わっても Next.js は終了しません。リクエストを待つことが仕事なので、意図的に生き続けます。
だからターミナルにプロンプトが戻ってきません。第1部で見た「親が子の終了を待つ」状態のまま、子が永遠に終わらないためです。Ctrl+C を押すと、その待機を強制的に打ち切ることになります。
なぜターミナルが戻ってこないのか ─ 子プロセスが終わらない設計だから。異常ではない。
なぜ next を単体で入れていないのに動くのか ─ npm が node_modules/.bin を PATH に一時追加しているから。
なぜ EADDRINUSE が出るのか ─ 前回のプロセスが生き残ってポートを掴んでいるから。OS 層の問題なので、コードをいくら直しても解決しない。
同じ結果を、シェル・Node スクリプト・Next.js の3通りで出します。
題材として、こういう従業員データがあるとします。employees.csv という名前のテキストファイルです。
やりたいことは「週の所定労働時間が20時間以上の人を抽出し、賃金の高い順に並べる」です。
3つの独立したプログラムが、パイプでつながっているだけです。
| 部分 | 役割 |
|---|---|
tail -n +2 | 1行目のヘッダを飛ばして、2行目以降を出す |
awk -F, '$5 >= 20' | カンマ区切りの5列目が20以上の行だけを通す |
sort -t, -k4 -nr | 4列目を数値として、降順に並べる |
awk は絞り込みしかしません。sort は並べ替えしかしません。それぞれが一つのことしかしないから、順番を入れ替えたり別のものに差し替えたりできます。第1部の原則2と原則3が、そのまま目に見える形で現れています。
部品を入れ替えると、別の集計になります。
部署の列だけ取り出し、並べ、同じものを数え、多い順に並べる。4つつないだだけで部署別人数が出ます。新しいプログラムは1行も書いていません。
向いている場面は、今この場で1回確認したいとき。所要1分、作るものはゼロです。限界は、条件が複雑になると誰も読めなくなること、そして人に渡しにくいことです。
判定条件が複数の組み合わせになると、シェルでは苦しくなります。そこで一段上げます。
上の判定条件(週20時間以上・月額8.8万円以上)は、コードの構造を示すために単純化したものです。実際の適用要件は制度ごとに異なりますので、filter の中身は各要件に合わせて差し替えてください。
ここで見ていただきたいのは、条件が構造として書けるようになるという点です。r.hours >= 20 && r.wage >= 88000 は、条件が3つ4つに増えても読めます。awk ではこうはいきません。
向いている場面は、毎月繰り返す作業。ファイルとして保存できるので、来月も同じものが動きます。限界は、ターミナルを使える人しか回せないことです。
職員が使うなら、ブラウザで完結させる必要があります。ファイルをこう置きます。
判定ロジックは方法2で書いたものがそのまま流用できます。変わるのは、結果を console.log で出すか、画面に表として描くかだけです。
向いている場面は、自分以外の人が使うとき。代償は、作る手間、保守の責任、そして誰がどこまで見られるかという設計です。
3つの方法に優劣はありません。適する場面が違うだけです。
| 状況 | 適切な層 | 理由 |
|---|---|---|
| 今1回だけ確認したい | シェル1行 | 作るものがゼロ。1分で終わる |
| 毎月自分が回す | Node スクリプト | 保存できて、条件が読める形で残る |
| 職員が使う | Next.js の画面 | ターミナルを教える必要がない |
| 顧問先が使う | 認証付きの Web アプリ | 誰が何を見られるかの制御が必須になる |
層を一段上げるたびに、作る手間は増え、使う人の負担は減ります。この交換をどこで止めるかが設計判断です。
そして重要なのは、いきなり上から作らないことです。
まずシェル1行で確かめる。繰り返すことが分かってからスクリプトにする。他人が使うと決まってから画面をつける。この順番を守ると、要らないものを作らずに済みます。逆にいきなり Next.js から始めると、月1回しか使わない機能に数日かけることになります。
「誰が使うのか」「何回やるのか」「間違ったときに誰が困るのか」。この3つを知っているのは人間だけです。
AI に「従業員データを抽出する仕組みを作って」と頼めば、たいてい Next.js のアプリが出てきます。悪意ではなく、文脈を与えなければ最も一般的な答えを返すからです。「1回確認したいだけ」と伝えれば、awk の1行が返ってきます。
実装の速さが AI の側に移った結果、人間の側に残った仕事はどの層で解くかを指定することになりました。
Excel の申請書を自動化したい、という場面でよく出る助言です。
「アプリを作るより Python のほうがいい」という言い方は、3つの別々の話を1つに束ねています。ほどくと見通しがよくなります。
| 軸 | 選択肢 |
|---|---|
| 1. 画面を作るか | 作らない(スクリプト) ↔ 作る(アプリ) |
| 2. どこで動かすか | 手元の PC ↔ サーバー |
| 3. 何語で書くか | Python ↔ JavaScript |
この助言の実質は、たいてい軸1と軸2の話です。「画面を作らず、手元で動かせ」と言っている。Python という言語名は、その結論に付いてきただけのことが多い。
同じことは Node.js でも書けます。ですので最初に立てるべき問いは「アプリか Python か」ではなく、「アプリか、スクリプトか」です。
Excel の申請書は、すでに手元のファイルとして存在しています。ここが決定的です。
上の往復は、Web アプリにしたせいで発生した工事であって、元の仕事とは無関係です。しかもアップロードとダウンロードのぶん、職員の操作手順はむしろ増えます。「自動化したのに手数が増えた」という結果になりがちなのは、この構造のためです。
軸3(何語で書くか)が本当に効く数少ない領域が、まさに Excel です。
| ライブラリ | できること |
|---|---|
openpyxl | xlsx の読み書き。書式・数式・条件付き書式を保ったまま編集できる |
pandas | 表としての集計・結合・整形 |
xlsxwriter | 書き出し専用。書式の作り込みが得意 |
xlwings | 起動中の Excel 本体を外から操縦する |
pywin32 | Windows の COM 経由で Excel を直接操作する |
JavaScript にも SheetJS があり、読み書き自体は十分できます。ただし書式まわりは無償版だと制約があり、「元のブックの体裁を崩さずに値だけ埋める」という申請書の用途では Python のほうが素直です。
決定的な差は最後の2つです。xlwings や pywin32 は、起動している Excel そのものを操作できます。Excel の計算エンジンをそのまま使い、既存の VBA マクロを呼び出し、印刷まで指示できる。Web アプリには原理的にできないことです。
VBA でマクロを組んだ経験があるなら、Python はその自然な後継にあたります。同じことを Excel の外から、より強力な道具立てで行う。
ただし条件が2つあります。Excel 本体がインストールされている必要があることと、pywin32 は Windows 専用であることです。サーバー上では動きません。「手元で動かす」という前提とセットの手法です。
| 状況 | 適する形 |
|---|---|
| 手元の Excel を加工して手元に戻す | スクリプト |
| 担当者1〜数人が回す | スクリプト |
| 毎月同じ処理を繰り返す | スクリプト |
| 職員が複数人、同時に使う | Web アプリ |
| 顧問先に使わせる | Web アプリ(認証付き) |
| 結果を蓄積して後から検索・集計する | Web アプリ + データベース |
| 承認フローや履歴が要る | Web アプリ |
| スマホからも使いたい | Web アプリ |
分かれ目はファイルが最終形かどうかです。Excel を作って終わりならスクリプト。データを溜めて後から使い回すならアプリ。この一問で、たいていの場合は決まります。
いきなり画面を作らずに済ませる手が2つあります。
| 手法 | 内容 |
|---|---|
| 実行だけボタン化 | スクリプトをバッチファイルやショートカットにする。職員はダブルクリックするだけ。ターミナルを教える必要がない |
| Streamlit / Gradio | Python のまま、数十行で簡単な画面が付く。手元で起動してブラウザから使う |
「画面が要る」ことと「Web アプリにする」ことは別です。ここを分けて考えられると、選択肢がかなり広がります。
Python スクリプトは、前章の図の「Node スクリプト」とまったく同じ位置にあります。言語が違うだけで、層としては同一です。
ですので判断基準も変わりません。誰が何回使うかに尽きます。Excel の申請書は、たいてい「担当者が毎月」なのでスクリプトの領域に落ちる。冒頭の助言は、経験則として当たっているということです。
ただし理由が「Python だから」ではなく「その仕事はスクリプトの層だから」だと理解しておくと、条件が変わったとき ─ たとえば顧問先にも使わせることになったとき ─ に判断をやり直せます。
実際によく出る4つを、層に対応づけて読みます。
何が起きているか ─ シェルが PATH に並んだフォルダを全部見たが、next という名前のファイルが無かった。next は node_modules/.bin の中にありますが、そこは PATH に入っていません。
だから npm run dev なら動く ─ npm が実行時に node_modules/.bin を PATH へ一時追加するためです。第1章の第4段階で見たとおりです。
対処 ─ npx next dev か npm run dev を使う。
何が起きているか ─ 3000 番ポートを他のプロセスが既に握っている。ほとんどの場合、前回起動した Node が終了せずに残っています。
コードを直しても解決しない ─ これは OS がポートを渡せなかったという報告で、アプリの中身とは無関係です。
何が起きているか ─ package.json には react が必要だと書いてあるが、node_modules の中に実物が無い。取り寄せていないか、途中で壊れています。
なぜ lock ファイルも消すのか ─ lock ファイル自体が壊れている可能性があるためです。ただし本番環境では消してはいけません。バージョンが変わって再現性が崩れます。
何が起きているか ─ 接続情報は .env.local に書いてあるが、このファイルは Git に含まれていません。だから Vercel 側には存在しません。
これは不具合ではなく設計 ─ 秘密情報をリポジトリに入れないのは、意図的な取り決めです。.gitignore に .env.local が書かれているのはそのためです。
対処 ─ Vercel の管理画面で環境変数を別途登録する。ローカルと本番は別の環境だという前提を持っておくと、この種の問題は最初から想定できます。
下から上へ確認する。上の層で悩む前に、下が正常であることを確かめます。
この5行を先に流すだけで、原因の大半がどの層にあるか判明します。そしてその情報を持って AI に相談すると、返答の精度が変わります。
後者に対して AI は、Vercel 側の環境変数登録が抜けているという結論に一手で到達します。前者に対しては、可能性を10個並べるしかありません。効いているのは技術力ではなく、どの層で止まったかを言語化する能力です。
Next.js プロジェクトの標準形。ファイルが20個以上並んでいても、種類は3つしかありません。
自分が書いたもの(資産。消えたら困る)、機械が自動生成したもの(消しても再生成される)、設定ファイル(自分が書くが、中身は道具への指示)。この3つです。
.claude .next .env.local のように先頭がドットの名前は、Unix の慣習で隠しファイルを意味します。ls では表示されず、ls -a で初めて見えます。
技術的な仕掛けは何もありません。「普段は意識しなくていいもの」という印にすぎません。VS Code は設定に関わらず全部表示するので、エディタ上では見えています。
| 名前 | 中身 | git |
|---|---|---|
node_modules/ | npm が取り寄せた部品の実物 | 入れない |
.next/ | Next.js のビルド結果とキャッシュ | 入れない |
.vercel/ | Vercel との紐付け情報 | 入れない |
tsconfig.tsbuildinfo | TypeScript の差分ビルド用キャッシュ | 入れない |
package-lock.json | 実際に入った正確なバージョンの記録 | 入れる |
next-env.d.ts | Next.js が用意する型定義の参照 | 入れる |
下2つが例外です。package-lock.json は「他の環境でも同じものが再現される」ための唯一の保証なので必ず記録します。next-env.d.ts は編集しても上書きされますが、記録する慣例です。
| 名前 | どの道具の設定か |
|---|---|
package.json | npm ─ 部品表とスクリプトの登録簿 |
next.config.mjs | Next.js ─ 画像の許可ドメイン、リダイレクト等 |
tsconfig.json | TypeScript ─ 厳格さの度合い、@/ などのパス別名 |
tailwind.config.ts | Tailwind CSS ─ 色、フォント、対象ファイルの範囲 |
postcss.config.mjs | PostCSS ─ CSS の変換工程。Tailwind はここのプラグインとして動く |
drizzle.config.ts | Drizzle ORM ─ スキーマの場所、DB 接続、マイグレーション出力先 |
.gitignore | Git ─ 記録から除外するものの一覧 |
| 名前 | 性格 |
|---|---|
src/ | ソース本体。この中に app/ があり、置き場所が URL になる |
scripts/ data/ docs/ | 自作の作業フォルダ。Next.js は関知しない |
deliverables/ scratchpad/ | 同上。成果物と作業場の分離 |
README.md | 人間向けの説明 |
CLAUDE.md | Claude Code への指示書 |
AGENTS.md | AI エージェント全般に向けた指示書。ツールをまたいで共通に読ませる想定の書き方 |
.claude/ | Claude Code のプロジェクト設定(権限、カスタムコマンド等) |
ここが第1部の原則に直接つながります。
ルート直下に設定が散らばっているのは、道具が独立して7つあるからです。Next.js、TypeScript、Tailwind、PostCSS、Drizzle。それぞれ別の作者が作った部品で、互いのことを知りません。だから設定もそれぞれ持ちます。
全部入りの一枚岩なら設定は1ファイルで済みます。ただし Tailwind を別の CSS ツールに差し替えることも、Drizzle を Prisma に替えることもできなくなります。
散らばっているのは混乱ではなく、原則2「一つのことをうまくやる」と原則3「組み合わせて使う」の代償です。差し替えられる自由の対価として、組み合わせを記述する手間を払っている。第1部で見た一枚岩と部品の対比が、そのままファイル一覧に現れています。
ルート直下に置く理由も単純で、各道具は起動時にカレントディレクトリから親方向へ設定を探しに上がるためです。プロジェクトの根に置くのが約束事になっています。
これは第4章の CASE 4(Vercel で DATABASE_URL が undefined)に対する予防策そのものです。
| ファイル | 役割 | git |
|---|---|---|
.env.example | 何を設定する必要があるかの一覧。キー名だけで値は空 | 入れる |
.env.local | 実際の値。接続情報や API キー | 入れない |
新しい環境で立ち上げるとき、example を見れば必要な項目が全部わかります。値そのものは漏れません。「秘密は共有しないが、秘密の一覧は共有する」という分離です。この2枚組を作っておくと、環境を移すときの事故が減ります。
この1ファイルが、プロジェクトの中に見えない線を引いています。
線の外側に置かれる理由は3つに整理できます。再生成できる(node_modules、.next)、秘密である(.env.local)、環境ごとに違う(.vercel)。この3つのどれかに当てはまるものは、記録しません。
動作が怪しいときの定番手順です。①の自動生成物のうち3つを消すだけです。
消えたものはすべて自動生成物なので、失うものはありません。node_modules の再取得に数分かかるだけです。
第4章の CASE 3 で挙げた package-lock.json の削除は、ここには含めていません。あれは lock ファイル自体が壊れている疑いがあるときの最後の手段で、通常は残します。消すとバージョンが変わりうるので、再現性を捨てる操作だと理解しておくのが安全です。
Claude Code や Codex CLI は、シェルではありません。
これらはシェルの上で動くプログラムであり、同時にシェルを使う側でもあります。二重の立場を持っているのが特徴です。
エージェントは、これまで人間が座っていた席に座っています。第1部で見た「シェルに翻訳を頼む」という立場そのものを代行している。
だから設計上の中心問題が権限になります。人間の席に座った以上、原理的には rm -rf も打てるからです。エージェント型 CLI の機能一覧が権限まわりに偏っているのは、この構造から必然的に出てきます。
主要なエージェント型 CLI は、いずれもほぼ同じ仕組みを持つところへ収束しました。
| 仕組み | 何のためにあるか |
|---|---|
| 指示書ファイル | 席に座る前に業務の文脈を渡す(CLAUDE.md / AGENTS.md) |
| plan モード | 実行前に計画を人間に承認させる |
| サンドボックス | 触れる範囲を OS レベルで制限する |
| 差分表示 | 実行後に人間が検算できる形で出す |
| サブエージェント | 作業を分割して並列で走らせる |
| MCP | 外部システムへの接続口 |
| ヘッドレスモード | CI やスクリプトから呼べるようにする(-p 等) |
| フック | 特定の場面で処理を自動実行する |
骨格が共通化した結果、各ツールの差はモデルの質・価格・エコシステムへ移りました。そこは週単位で動くのでこの資料には書きません。骨格を知っていれば、どのツールへ移っても同じ場所を探せば設定できます。
これらは全画面を占有し、カーソルキーで項目を選び、状態を表示し続けます。第2部第0章の分類でいう TUI(Text User Interface)です。
純粋な CLI は「1行打って、結果が返って、終わる」形式です。エージェント型はセッションを維持し続けるので、その意味では GUI に近い性質を持っています。
前章で見たルート直下のファイルが、そのままこの構造に対応しています。
| ファイル | 構造上の役割 |
|---|---|
CLAUDE.md | Claude Code 向けの指示書 |
AGENTS.md | ツール横断を想定した指示書 |
.claude/ | 権限設定、カスタムコマンド |
指示書を書くという行為の意味も、ここで定まります。席に座らせる前に、業務の文脈を渡しているということです。第2部第0章で挙げた「AI は事務所の業務も顧問先の事情も知らない」という制約に対する、唯一の実務的な対処がこれにあたります。
Google は2026年6月18日をもって、Gemini CLI の個人向け提供を終了し、Antigravity CLI に置き換えました。旧 Gemini CLI は Apache 2.0 の公開ソフトウェアで10万を超える GitHub スターを集めていましたが、後継は非公開です。
これは第2部第6章に書いた「依存を増やすということは、他人の責任範囲を増やすこと」の実例です。層の下側は自分で決められません。手元のコードは残っても、それを動かす道具は他社の判断で消えます。
裏返すと、指示書を CLAUDE.md と AGENTS.md の2枚で持っておくことは移行可能性を残す設計になっています。後者はツール横断を想定した書き方なので、乗り換えが必要になったときに効きます。.env.example と .env.local を分けるのと同じ発想です。
この章の内容のうち、製品名と提供状況は2026年7月時点のものです。骨格の部分は当面変わらないと見ていますが、個別の製品情報は都度確認してください。
各コマンドが、どの層に触っているかを対応させます。
| コマンド | 触る層 | 何が起きるか |
|---|---|---|
npx create-next-app | npm | 雛形を取り寄せ、依存を install し、git init までやる |
cd my-app | シェル(ビルトイン) | シェル自身の現在位置を変える。子プロセスは作られない |
npm run dev | 全層 | 第1章の8段階すべてを通る |
git add -A | ファイル | 変更を記録の候補として登録する |
git commit | ファイル | その時点の状態に名前を付けて保存する |
git push | ネットワーク | 手元の記録を GitHub へ送る |
| (自動) | Vercel | push を検知し、ビルドして公開する |
npx は npm に付属するコマンドで、インストールせずに一度だけ実行するためのものです。
create-next-app は最初の1回しか使いません。それをパソコンに常駐させるのは無駄なので、npx が一時的に取り寄せて実行し、終わったら捨てます。
第1部でシェルの仕組みと設計原則を見て、第2部で層の全体像を見て、第3部で実際のコマンドに落としました。
結局のところ、覚えておくべきことは多くありません。
| 問い | 答え |
|---|---|
| コマンドを打つとは | シェルに翻訳を頼むこと。シェル自身はほとんど何もしていない |
| 層が7つある意味 | 下の層に依存し、上の層には複雑さを隠す。隠れているが無くなっていない |
| エラーが出たら | 下から上へ確認する。層を特定してから対処する |
| どの層で作るか | 誰が何回使うかで決める。いきなり上から作らない |
| AI との分担 | 並べるのは AI、決めるのは人間 |
実装の速さは AI の側に移りました。だからこそ人間の側に残るのは、何を作るかを決める力と、出てきたものを疑う力です。そのどちらも、土台の構造を知っていることを前提にしています。