feat: Windows ネイティブ環境のセットアップサポートを追加 - #700
Conversation
WSL2 を使わない Windows ホスト向けに、winget ベースの最小ブートストラップを提供する。 既存の macOS (nix-darwin) / Linux (Homebrew) / DevContainer フローには影響しない。 - brew/Winfile.json: winget import 用パッケージマニフェスト - script/import.ps1: PowerShell 5.1 / 7+ 両対応のブートストラップ - script/lib/platform.sh: Windows 検出 + import.sh 実行時の誘導 - README.md: Windows セクション追加 Closes #698 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR introduces native Windows support by adding a PowerShell bootstrap script, a winget package manifest, Windows platform detection helpers, and corresponding documentation. Users on native Windows can now run a single PowerShell command to install packages and sync tool configurations without relying on WSL2. Changes
Sequence DiagramsequenceDiagram
participant User
participant PowerShell as import.ps1<br/>(PowerShell)
participant Winget
participant FileSystem as Local Files<br/>(Git/Tool Configs)
participant VSCode
participant NPM
participant GH as GitHub CLI<br/>(gh/ghq)
User->>PowerShell: Run with parameters<br/>(-DryRun, -Skip*)
alt Skip Winget == false
PowerShell->>Winget: winget import<br/>(brew/Winfile.json)
Winget->>Winget: Install packages<br/>(Git, Node.js, etc.)
end
PowerShell->>FileSystem: Copy .gitconfig,<br/>.gitignore,<br/>.gitattributes
PowerShell->>FileSystem: Copy tool configs<br/>(Claude, Cursor,<br/>Gemini, .mcp.json)
alt VS Code exists
PowerShell->>FileSystem: Copy VS Code<br/>settings.json
alt Skip Extensions == false && code CLI available
PowerShell->>VSCode: Install extensions from<br/>vscode/extensions.txt
end
end
alt Skip NPM == false && npm available
PowerShell->>NPM: npm install -g from<br/>npm/global.json
end
alt Skip Repos == false && gh/ghq available
PowerShell->>GH: Fetch user repos via<br/>gh api user/repos
GH->>FileSystem: Clone repos with ghq
end
PowerShell->>User: Bootstrap complete
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Claude finished @keito4's task in 3m 2s —— View job コードレビュー完了
レビュー結果: ✅ APPROVE(minor 指摘のみ)Windows ネイティブ対応として適切な実装です。WSL2 との区別、 🔍 指摘事項[minor]
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: efcd9927c6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| & code --install-extension $ext --force | Out-Null | ||
| Write-Ok $ext |
There was a problem hiding this comment.
Check extension install exit code before success log
If code --install-extension fails (for example due to network issues, marketplace outages, or an invalid extension ID), this block still prints a success message for that extension because Write-Ok is unconditional and $LASTEXITCODE is never checked. That can leave Windows setups partially configured while the script appears successful. Mirror the npm section’s pattern by checking the command exit code and warning on failure.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
script/import.ps1 (1)
105-109: Drift fromimport.sh: missinguser.signingkeyreminder.
script/import.shlines 60-64 print threegit configreminders, includinguser.signingkey. The PowerShell version drops the signingkey line, so Windows users following the same docs won't be reminded to configure commit signing. Trivial to align.♻️ Match the bash reminder set
Write-Warn2 '~/.gitconfig has commented-out user info. Configure manually:' Write-Host ' git config --global user.name "Your Name"' Write-Host ' git config --global user.email "your.email@example.com"' + Write-Host ' git config --global user.signingkey ~/.ssh/id_ed25519.pub' }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@script/import.ps1` around lines 105 - 109, The PowerShell check block that warns about a commented-out ~/.gitconfig is missing the Git signing key reminder present in import.sh; update the conditional in script/import.ps1 (the if block that calls Write-Warn2 and Write-Host) to include an additional Write-Host line reminding users to run git config --global user.signingkey "your-signing-key" so the Windows import mirrors the bash import.sh reminders.README.md (1)
728-728: Minor doc/manifest drift: Windows Terminal is inWinfile.jsonbut not listed here.The parenthetical inventory at line 728 lists git, gh, ghq, Node.js, Go, kubectl, helm, terraform, 1Password CLI, VS Code, Cursor, PowerShell 7, jq, GnuPG, but
brew/Winfile.jsonline 11 also includesMicrosoft.WindowsTerminal. Worth adding for accuracy so the docs match whatwinget importactually installs.♻️ Doc fix
-- `brew/Winfile.json` を `winget import` で適用 (git, gh, ghq, Node.js, Go, kubectl, helm, terraform, 1Password CLI, VS Code, Cursor, PowerShell 7, jq, GnuPG など) +- `brew/Winfile.json` を `winget import` で適用 (git, gh, ghq, Node.js, Go, kubectl, helm, terraform, 1Password CLI, VS Code, Cursor, PowerShell 7, Windows Terminal, jq, GnuPG など)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` at line 728, The README's list of packages is missing Microsoft.WindowsTerminal which is present in brew/Winfile.json; update the parenthetical inventory in README.md (the line describing `brew/Winfile.json` → `winget import`) to include Windows Terminal (Microsoft.WindowsTerminal) so the documentation matches the manifest, referencing the manifest name `brew/Winfile.json` and the package identifier `Microsoft.WindowsTerminal`.brew/Winfile.json (1)
32-32:WinGetVersion: "1.6.0"is significantly outdated; consider updating to a supported version.The current stable version of Microsoft winget CLI is 1.28.240. Pinning to 1.6.0 can suppress newer schema fields and produce confusing compatibility warnings on fresh hosts. Update to a version that matches your minimum supported requirement (e.g.,
"1.10.0"or higher), or omit the field entirely if no version constraint is needed — the import file will still validate against the v2.0 schema.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@brew/Winfile.json` at line 32, The WinGetVersion key currently set to "1.6.0" in Winfile.json is outdated; update the "WinGetVersion" value to a supported minimum (for example "1.10.0" or a newer stable release such as "1.28.240") or remove the "WinGetVersion" key entirely if you don't need to pin a winget CLI version so the import validates against the v2.0 schema without suppressing newer fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@script/import.ps1`:
- Around line 153-156: The installer reports VS Code extension installs as
successful unconditionally; update the else branch that runs "& code
--install-extension $ext --force | Out-Null" to check $LASTEXITCODE (as the npm
install block does) and only call Write-Ok $ext when $LASTEXITCODE -eq 0,
otherwise call Write-Error (or fail/exit) with the exit code and error context
so failed installs are not masked; locate the else branch handling code installs
around the "& code --install-extension $ext --force | Out-Null" invocation and
mirror the exit-code branching used in the npm install block.
- Around line 1-15: Add a UTF-8 BOM to the top of script/import.ps1 so
PowerShell 5.1 correctly interprets the Japanese header comments, and update the
VS Code extension install block that currently runs "& code --install-extension
$ext --force | Out-Null; Write-Ok $ext" to check $LASTEXITCODE like the npm
block does (run & code --install-extension $ext --force, then if ($LASTEXITCODE
-eq 0) { Write-Ok $ext } else { Write-Warn2 "code --install-extension failed:
$ext" }) so failures are detected and reported.
---
Nitpick comments:
In `@brew/Winfile.json`:
- Line 32: The WinGetVersion key currently set to "1.6.0" in Winfile.json is
outdated; update the "WinGetVersion" value to a supported minimum (for example
"1.10.0" or a newer stable release such as "1.28.240") or remove the
"WinGetVersion" key entirely if you don't need to pin a winget CLI version so
the import validates against the v2.0 schema without suppressing newer fields.
In `@README.md`:
- Line 728: The README's list of packages is missing Microsoft.WindowsTerminal
which is present in brew/Winfile.json; update the parenthetical inventory in
README.md (the line describing `brew/Winfile.json` → `winget import`) to include
Windows Terminal (Microsoft.WindowsTerminal) so the documentation matches the
manifest, referencing the manifest name `brew/Winfile.json` and the package
identifier `Microsoft.WindowsTerminal`.
In `@script/import.ps1`:
- Around line 105-109: The PowerShell check block that warns about a
commented-out ~/.gitconfig is missing the Git signing key reminder present in
import.sh; update the conditional in script/import.ps1 (the if block that calls
Write-Warn2 and Write-Host) to include an additional Write-Host line reminding
users to run git config --global user.signingkey "your-signing-key" so the
Windows import mirrors the bash import.sh reminders.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 24774a6f-5af0-476d-a023-209789966c97
📒 Files selected for processing (5)
README.mdbrew/Winfile.jsonscript/import.ps1script/import.shscript/lib/platform.sh
| # ============================================================================ | ||
| # Windows ネイティブ環境セットアップ | ||
| # ---------------------------------------------------------------------------- | ||
| # - Bash / nix / Homebrew が無い Windows ホスト向けのブートストラップ。 | ||
| # - winget で基本パッケージを一括導入し、各種 dotfile / ツール設定を | ||
| # %USERPROFILE% 配下にコピーする。 | ||
| # - WSL2 上のセットアップは引き続き script/import.sh を使う。 | ||
| # | ||
| # Usage: | ||
| # pwsh -File script/import.ps1 # 通常実行 | ||
| # pwsh -File script/import.ps1 -DryRun # 実行せず内容のみ表示 | ||
| # pwsh -File script/import.ps1 -SkipWinget -SkipNpm | ||
| # | ||
| # 互換: Windows PowerShell 5.1 / PowerShell 7+ の両方で動作する。 | ||
| # ============================================================================ |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
PowerShell 5.1 default script file encoding when no BOM is present
💡 Result:
In PowerShell 5.1, when executing a script file (.ps1) with no Byte Order Mark (BOM), the PowerShell engine defaults to the system's active code page encoding, referred to as the "Default" ANSI encoding. This corresponds to the ANSI code page for the current system locale (e.g., Windows-1252 for en-US locales).
Citations:
- 1: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_character_encoding?view=powershell-7.4
- 2: https://github.com/MicrosoftDocs/PowerShell-Docs/blob/main/reference/5.1/Microsoft.PowerShell.Core/About/about_Character_Encoding.md
- 3: https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/vscode/understanding-file-encoding?view=powershell-7.6
- 4: https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/vscode/understanding-file-encoding?view=powershell-7.4
🏁 Script executed:
#!/bin/bash
# Check if the file exists and read the first 20 lines to confirm Japanese characters
if [ -f script/import.ps1 ]; then
echo "=== FILE EXISTS ==="
head -20 script/import.ps1 | cat -n
echo ""
echo "=== HEX DUMP OF FIRST 4 BYTES (BOM CHECK) ==="
xxd -l 4 script/import.ps1
echo ""
else
echo "File script/import.ps1 not found"
fiRepository: keito4/config
Length of output: 1061
🏁 Script executed:
#!/bin/bash
# Check file encoding using file command
echo "=== FILE ENCODING INFO ==="
file -i script/import.ps1
echo ""
echo "=== FILE SIZE AND LINE COUNT ==="
wc -l script/import.ps1
stat --format="%n: %s bytes" script/import.ps1Repository: keito4/config
Length of output: 247
🏁 Script executed:
#!/bin/bash
# Extract specific sections mentioned in the review:
# Lines 100-109 (git config block for signingkey)
# Lines 148-157 (code --install-extension for exit code check)
# Lines 70-95 (winget block)
# Lines 173-184 (npm block)
echo "=== LINES 70-95 (WINGET BLOCK) ==="
sed -n '70,95p' script/import.ps1
echo ""
echo "=== LINES 100-109 (GIT CONFIG BLOCK - SIGNINGKEY CHECK) ==="
sed -n '100,109p' script/import.ps1
echo ""
echo "=== LINES 148-157 (CODE --INSTALL-EXTENSION BLOCK) ==="
sed -n '148,157p' script/import.ps1
echo ""
echo "=== LINES 173-184 (NPM BLOCK) ==="
sed -n '173,184p' script/import.ps1Repository: keito4/config
Length of output: 2576
Add a UTF-8 BOM — required for the documented PowerShell 5.1 compatibility.
The file contains Japanese characters in its header (lines 2, 4, 5, 14) but lacks a UTF-8 BOM. Without it, PowerShell 5.1 reads .ps1 files using the system's ANSI code page (e.g., Windows-1252, code page 932 on Japanese locales). Even though the file is UTF-8 encoded in the repository, PS 5.1 will attempt to interpret the UTF-8 bytes as ANSI, producing mojibake for the Japanese comments and potentially breaking the parser on multi-byte sequences.
The script header explicitly promises "Windows PowerShell 5.1 / PowerShell 7+ の両方で動作する" — without the BOM, this contract is not met.
Additionally, add exit code check for code --install-extension (lines 153–156).
The command currently calls Write-Ok regardless of success:
& code --install-extension $ext --force | Out-Null
Write-Ok $extCompare this with the npm block (lines 178–180), which properly checks $LASTEXITCODE:
& npm install -g $pkg
if ($LASTEXITCODE -eq 0) { Write-Ok $pkg } else { Write-Warn2 "npm install failed: $pkg" }Apply the same pattern to the code extension installation for consistency and correct error reporting.
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)
[warning] Missing BOM encoding for non-ASCII encoded file 'import.ps1'
(PSUseBOMForUnicodeEncodedFile)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@script/import.ps1` around lines 1 - 15, Add a UTF-8 BOM to the top of
script/import.ps1 so PowerShell 5.1 correctly interprets the Japanese header
comments, and update the VS Code extension install block that currently runs "&
code --install-extension $ext --force | Out-Null; Write-Ok $ext" to check
$LASTEXITCODE like the npm block does (run & code --install-extension $ext
--force, then if ($LASTEXITCODE -eq 0) { Write-Ok $ext } else { Write-Warn2
"code --install-extension failed: $ext" }) so failures are detected and
reported.
| } else { | ||
| & code --install-extension $ext --force | Out-Null | ||
| Write-Ok $ext | ||
| } |
There was a problem hiding this comment.
code --install-extension failures are reported as success.
Write-Ok $ext runs regardless of whether code exited non-zero, unlike the npm block at lines 179-180 which correctly branches on $LASTEXITCODE. This silently hides extension-install failures (network blips, marketplace 404s, unsigned-extension blocks) and makes triage harder.
♻️ Apply the same exit-code branching as the npm block
- } else {
- & code --install-extension $ext --force | Out-Null
- Write-Ok $ext
- }
+ } else {
+ & code --install-extension $ext --force | Out-Null
+ if ($LASTEXITCODE -eq 0) { Write-Ok $ext } else { Write-Warn2 "code --install-extension failed: $ext" }
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| } else { | |
| & code --install-extension $ext --force | Out-Null | |
| Write-Ok $ext | |
| } | |
| } else { | |
| & code --install-extension $ext --force | Out-Null | |
| if ($LASTEXITCODE -eq 0) { Write-Ok $ext } else { Write-Warn2 "code --install-extension failed: $ext" } | |
| } |
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)
[warning] Missing BOM encoding for non-ASCII encoded file 'import.ps1'
(PSUseBOMForUnicodeEncodedFile)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@script/import.ps1` around lines 153 - 156, The installer reports VS Code
extension installs as successful unconditionally; update the else branch that
runs "& code --install-extension $ext --force | Out-Null" to check $LASTEXITCODE
(as the npm install block does) and only call Write-Ok $ext when $LASTEXITCODE
-eq 0, otherwise call Write-Error (or fail/exit) with the exit code and error
context so failed installs are not masked; locate the else branch handling code
installs around the "& code --install-extension $ext --force | Out-Null"
invocation and mirror the exit-code branching used in the npm install block.
実機検証で判明した2点を修正する。 - import.ps1: `code --install-extension` は対象拡張がマーケットに存在しない、 または当該プラットフォーム向けにビルドが無い場合でも exit 0 を返すため、 従来は失敗を成功と誤報告していた。マージ済み出力を文字列マッチして 「Failed Installing」「not found」「not available」を検知し、Write-Warn2 で報告する。 - vscode/extensions.txt: Windows 64bit の VS Code で恒常的に取得できない 4 件を除去 (amazonwebservices.codewhisperer-for-command-line-companion, anysphere.cursorpyright, betajob.modulestf, sryze.uridecode)。 Refs #698 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`/opt/homebrew/bin/gh` 固定パスは macOS 専用で、Linux (`/home/linuxbrew/.linuxbrew/bin/gh`) や Windows (`C:\Program Files\GitHub CLI\gh.exe`) で git push が失敗していた。 PATH 解決にすることで `gh` がインストールされている全環境で動作する。 Refs #698 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
🎉 This PR is included in version 1.111.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Summary
script/import.ps1+brew/Winfile.json)script/lib/platform.shに Windows 検出を追加し、ネイティブ Windows シェルからscript/import.shを起動した場合は PowerShell 版へ誘導実機検証で2件の小バグも修正:
git/gitconfigのgh固定パス (/opt/homebrew/bin/gh) を PATH 解決に変更しクロスプラットフォーム化Closes #698
変更点
brew/Winfile.jsonwinget import用マニフェスト (Git, GitHub CLI, ghq, Node.js LTS, Go, kubectl, helm, k9s, terraform, 1Password CLI, VS Code, Cursor, PowerShell 7, jq, GnuPG, Windows Terminal — 16 packages)script/import.ps1-DryRun/-SkipWinget/-SkipExtensions/-SkipNpm/-SkipReposの各スイッチ対応。VS Code 拡張機能の失敗は出力文字列マッチで検知script/lib/platform.shplatform::is_windows,platform::assert_not_windowsを追加script/import.shgit/gitconfigghのフルパスを PATH 解決に変更vscode/extensions.txtamazonwebservices.codewhisperer-for-command-line-companion,anysphere.cursorpyright,betajob.modulestf,sryze.uridecode)README.mdスコープ外 (フォローアップ候補)
script/credentials.shの Windows 対応 (1Password CLI 連携)script/export.ps1(PowerShell 版エクスポート)anysphere.cursorpyright等) のcursor --install-extensionでの別系統インストール既存フローへの影響
script/import.shを走らせる場合はPLATFORM_OS=linuxとして検出されるため従来どおりgit/gitconfigの helper パス変更は macOS/Linux/Windows の全環境でghが PATH に通っている前提が必要 — すでに各 setup スクリプトが入れる必須ツールなので影響なしTest plan
実機検証 (Windows 11 Home, MINGW64 + Windows PowerShell 5.1) で完走確認済:
powershell -ExecutionPolicy Bypass -File script/import.ps1 -DryRunがエラーなく完走winget search --id <id> --exactで実在確認winget import16/16 完走: Git (既存 2.53 と衝突で installer exit 1 だが既存 git で動作問題なし), PowerShell 7.6.1, VS Code 1.117, Cursor 3.2.11, Node.js 24.15, Go 1.26.2, Terraform 1.14.9, Helm 4.1.4, kubectl 1.36.0, k9s 0.50.18, GnuPG 2.5.19, 1Password CLI 2.34.0, jq 1.8.1, ほか既存検出 (GitHub CLI / ghq / Windows Terminal)~/.gitconfig~/.gitignore~/.mcp.jsonおよび~/.claude/(115 files, 既存settings.local.json/sessions/を破壊せずマージ確認),~/.codex/,~/.cursor/,~/.gemini/配置成功npm/global.jsonの 17 パッケージ (codex, gemini-cli, n8n, pm2, vercel, commitlint, bash-language-server, ほか) をnpm install -gで展開完了platform::assert_not_windows: ネイティブ Windows シェルからscript/import.shを呼び出した場合、PowerShell 版への誘導メッセージが出ることを確認git,gh,node,npm,go,kubectl,helm,terraform,k9s,gpg,op,jq,code,cursor,pwsh,codex,geminiが全て解決することを確認/opt/homebrew/bin/gh固定パスから PATH 解決へ変更したことで Windows / Linux でもgit pushが成功することを確認🤖 Generated with Claude Code