背景
私は Claude Code(Anthropic の CLI 型コーディングエージェント)の定期タスクで、20 個ほどのサイトを毎日自動更新しています。
主役は Mac ですが、持ち歩いて発火できない時間帯を Windows 機に拾わせています。
困ったのは設定ファイル。
タスクの定義は JSON で、リポジトリの場所が /Users/hashito/git/web/... という Mac の絶対パスで書いてある。
Windows 用に書き換えると、設定が 2 系統になって必ず片方が腐る気がする…。
なので「設定は 1 つのまま、Windows 側で辻褄を合わせる」方向で逃げました。
結論
PowerShell で下記を 1 回だけやります。
C:\Users\hasit\git\web が各サイトの実体、C:\Users\hasit\git\scripts が自動化スクリプトの実体、という前提です。
PS> mkdir C:\Users\hasit\.fleet-vroot\Users\hashito\git
PS> cmd /c mklink /J C:\Users\hasit\.fleet-vroot\Users\hashito\git\web C:\Users\hasit\git\web
PS> cmd /c mklink /J C:\Users\hasit\.fleet-vroot\Users\hashito\git\scripts C:\Users\hasit\git\scripts
PS> subst V: C:\Users\hasit\.fleet-vroot
あとは、自動実行の先頭で下記を打ってから、V ドライブ上で作業するだけです。
PS> if (-not (Test-Path "V:\Users\hashito\git\scripts\web-fleet")) { subst V: C:\Users\hasit\.fleet-vroot }
PS> Set-Location "V:\Users\hashito\git\scripts\web-fleet"
これで、設定ファイルの /Users/hashito/git/web/manga-deals が、Windows では V:\Users\hashito\git\web\manga-deals として読まれます。
なぜこれで動くのか
mklink /J は、ジャンクションという Windows のフォルダのリンクを作るコマンドだ。
subst は、フォルダをドライブ文字に割り当てるコマンドだ。
鍵になるのは Node.js の挙動です。
Windows の Node.js は、/Users/... のようにスラッシュで始まるパスを「カレントドライブのルートからの相対パス」として解決する。
手元で確かめた結果が下記です。
path.resolve は、相対パスを絶対パスに直す標準関数で、引数はさきほどの設定ファイルに書いてある値そのものです。
PS C:\> node -e "console.log(require('path').resolve('/Users/hashito/git/web'))"
C:\Users\hashito\git\web
PS V:\Users\hashito\git\scripts\web-fleet> node -e "console.log(require('path').resolve('/Users/hashito/git/web'))"
V:\Users\hashito\git\web
カレントドライブが C: のときは C:\ 配下、V: のときは V:\ 配下に化けているのがわかると思います。
つまり、プロセスのカレントディレクトリを V: に置いておけば、設定ファイルの Mac パスは全部 V:\Users\hashito\... に読み替わる。
あとは V:\Users\hashito\git\web が実体を指していればよくて、それをジャンクションでやっている、というだけの仕組みだ。
subst の割り当て状態は、引数なしで確認できます。
PS> subst
V:\: => C:\Users\hasit\.fleet-vroot
なぜ C:\Users\hashito に直接リンクしないのか
一番単純なのは mklink /J C:\Users\hashito C:\Users\hasit の 1 行です。
これなら subst も要らない。
ただ C:\Users 直下への書き込みは管理者権限が要って、私の環境では Access denied で止まりました。
自動実行は管理者で動かしたくなかったので、自分のホーム配下に土台(.fleet-vroot)を作って、そこをドライブに見せる形にしています。
設定を書き換えない代わりに、OS 側の見え方を合わせる。
これがトレードオフで、設定は 1 系統のままにできた一方、Windows 側に「V: が無いと動かない」という前提が増えました。
落とし穴
-
substはログオンセッション単位なので、再起動すると消えます。ジャンクションは残る。だから毎回の先頭でTest-Pathを見て張り直しています - git は V: 上だと
git statusの変更検知を取りこぼすことがあったので、git だけはC:\Users\hasit\git\...の綴りで打っています(原因は追えていません…) - 逆に Node.js は C: 上だと
/Users/hashitoをC:\Users\hashitoに解決して存在しないパスを踏むので、Node は必ず V: 上で動かす
この仕組みで、今日もこのサイトが Windows 側から更新されています。
https://manga.autoarticles.net/
Mac 絶対パスの設定は、書き換えるのではなく、Windows の側に同じ階層を作って読ませる。
これが私の結論です。
本記事はAI補助で執筆した、個人開発の紹介記事です。