Skip to content

feat: Windows ネイティブ環境のセットアップサポートを追加 - #700

Merged
keito4 merged 3 commits into
mainfrom
feat/windows-support
Apr 27, 2026
Merged

feat: Windows ネイティブ環境のセットアップサポートを追加#700
keito4 merged 3 commits into
mainfrom
feat/windows-support

Conversation

@keito4

@keito4 keito4 commented Apr 27, 2026

Copy link
Copy Markdown
Owner

Summary

  • WSL2 を使わない Windows ホスト向けに、winget ベースの最小ブートストラップを追加 (script/import.ps1 + brew/Winfile.json)
  • script/lib/platform.sh に Windows 検出を追加し、ネイティブ Windows シェルから script/import.sh を起動した場合は PowerShell 版へ誘導
  • README に Windows セクションを追記

実機検証で2件の小バグも修正:

  • VS Code 拡張インストール失敗の誤報告 (exit 0 で返るため文字列マッチで判定)
  • git/gitconfiggh 固定パス (/opt/homebrew/bin/gh) を PATH 解決に変更しクロスプラットフォーム化

Closes #698

変更点

ファイル 種別 概要
brew/Winfile.json new winget 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 new PowerShell 5.1 / 7+ 両対応。-DryRun / -SkipWinget / -SkipExtensions / -SkipNpm / -SkipRepos の各スイッチ対応。VS Code 拡張機能の失敗は出力文字列マッチで検知
script/lib/platform.sh mod platform::is_windows, platform::assert_not_windows を追加
script/import.sh mod ネイティブ Windows 起動時に PowerShell 版へ誘導
git/gitconfig mod gh のフルパスを PATH 解決に変更
vscode/extensions.txt mod Win64 で取得できない 4 拡張を除去 (amazonwebservices.codewhisperer-for-command-line-companion, anysphere.cursorpyright, betajob.modulestf, sryze.uridecode)
README.md mod "Native Windows (winget)" セクションを追記

スコープ外 (フォローアップ候補)

  • WSL2 自動セットアップ手順
  • script/credentials.sh の Windows 対応 (1Password CLI 連携)
  • script/export.ps1 (PowerShell 版エクスポート)
  • Cursor 専用拡張 (anysphere.cursorpyright 等) の cursor --install-extension での別系統インストール

既存フローへの影響

  • macOS (nix-darwin), Linux (Homebrew), DevContainer の各フローは無変更
  • WSL2 内で 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 5.1 で powershell -ExecutionPolicy Bypass -File script/import.ps1 -DryRun がエラーなく完走
  • 全 winget パッケージ ID を winget search --id <id> --exact で実在確認
  • winget import 16/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)
  • dotfile/設定コピー: ~/.gitconfig ~/.gitignore ~/.mcp.json および ~/.claude/ (115 files, 既存 settings.local.json / sessions/ を破壊せずマージ確認), ~/.codex/, ~/.cursor/, ~/.gemini/ 配置成功
  • npm globals: npm/global.json の 17 パッケージ (codex, gemini-cli, n8n, pm2, vercel, commitlint, bash-language-server, ほか) を npm install -g で展開完了
  • VS Code 拡張: 72/72 成功 (extensions.txt の 4 件除去後)
  • platform::assert_not_windows: ネイティブ Windows シェルから script/import.sh を呼び出した場合、PowerShell 版への誘導メッセージが出ることを確認
  • 新規 pwsh セッション: PATH リフレッシュ後に git, gh, node, npm, go, kubectl, helm, terraform, k9s, gpg, op, jq, code, cursor, pwsh, codex, gemini が全て解決することを確認
  • gh credential helper: 旧 /opt/homebrew/bin/gh 固定パスから PATH 解決へ変更したことで Windows / Linux でも git push が成功することを確認

🤖 Generated with Claude Code

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>
@coderabbitai

coderabbitai Bot commented Apr 27, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This 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

Cohort / File(s) Summary
Documentation & Configuration
README.md, brew/Winfile.json
Added Windows setup section with winget invocation examples and constraints; created winget package manifest targeting Git, GitHub CLI, ghq, PowerShell, VS Code, Node.js, Go, Terraform, Helm, kubectl, and other dev tools.
Windows Bootstrap Script
script/import.ps1
New PowerShell script with -DryRun and selective step-skipping parameters; orchestrates winget package import, Git/tool config installation, VS Code extension setup, npm global package installation, and user repo cloning via ghq.
Platform Detection & Guards
script/lib/platform.sh, script/import.sh
Added platform::is_windows() and platform::assert_not_windows() helpers to detect native Windows shells; script/import.sh now asserts non-Windows execution to prevent shell syntax errors and direct users to PowerShell bootstrap or WSL2.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • #137: Adds platform::is_windows() detection and Windows-related assertion logic to script/lib/platform.sh, directly supporting Windows platform checks.
  • #202: Modifies script/import.sh with formatting and GitHub CLI pagination changes, sharing the same shell script foundations as the Windows guard addition.

Poem

🐰 PowerShell hops where bash cannot tread,
Winget gathers tools, by Windows' decree,
From Git to Go, the packages spread,
Hop-skip-jump—now Windows is free! 🪟✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly identifies the main change: adding native Windows setup support.
Linked Issues check ✅ Passed All coding requirements from issue #698 are met: Winfile.json created, import.ps1 implemented, platform detection added, and README updated.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #698 scope; out-of-scope items (WSL2 auto-setup, credentials.sh Windows support, export.ps1) are properly identified as future work.
Description check ✅ Passed The PR description provides comprehensive coverage of all required template sections with detailed implementation details, test results, and scope clarification.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/windows-support

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@keito4 keito4 self-assigned this Apr 27, 2026
@claude

claude Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Claude finished @keito4's task in 3m 2s —— View job


コードレビュー完了

  • コンテキスト収集・ファイル読み込み
  • 変更ファイルの詳細分析
  • レビューフィードバック作成

レビュー結果: ✅ APPROVE(minor 指摘のみ)

Windows ネイティブ対応として適切な実装です。WSL2 との区別、-DryRun フラグ、$ErrorActionPreference = 'Stop' によるエラー処理など、品質は高いです。以下はマイナーな改善提案です。


🔍 指摘事項

[minor] ghq get に渡す URL にキャリッジリターンが混入する可能性

ファイル: script/import.ps1:199

$sshUrls = & gh api user/repos --paginate --jq '.[].ssh_url'
($sshUrls -split "`n") | Where-Object { $_ } | ForEach-Object { & ghq get $_ }

Windows 環境では gh api の出力が \r\n 改行を含む場合があります。`n だけで分割すると各 URL に末尾 \r が残り、ghq get が失敗します。

修正案:

($sshUrls -split '\r?\n') | Where-Object { $_.Trim() } | ForEach-Object { & ghq get $_.Trim() }

Fix this →


[minor] .vscode/settings.json (ワークスペース設定) を VS Code ユーザー設定に上書き

ファイル: script/import.ps1:129-134

$vscodeUserDir = Join-Path $env:APPDATA 'Code\User'
if (Test-Path $vscodeUserDir) {
    Copy-Tracked (Join-Path $RepoRoot '.vscode\settings.json') (Join-Path $vscodeUserDir 'settings.json')
}

.vscode/settings.json はリポジトリのワークスペース設定であり、ユーザーのグローバル VS Code 設定ではありません。これを %APPDATA%\Code\User\settings.json に上書きすると、既存ユーザー固有の設定が無警告で失われます。

Linux 版 (import.sh) にはこの操作は存在しないため、動作の非対称性もあります。

選択肢:

  1. この操作を削除(最も安全)
  2. コピー前にバックアップを取る (Copy-Tracked の拡張)
  3. Write-Warn2 で上書き警告を出してから実行

Fix this →


[minor] Write-Warn2 という関数名

ファイル: script/import.ps1:34

function Write-Warn2($msg) { Write-Host "  ! $msg" -ForegroundColor Yellow }

Write-Warning との衝突を避ける意図は理解できますが、Write-Warn2 は直感的ではありません。Write-WarnMsg または Write-Alert などがより分かりやすいです(必須ではありません)。


[minor] ツール設定のコピーがマージではなく上書き

ファイル: script/import.ps1:116-126

foreach ($t in $toolDirs) {
    Copy-Tracked (Join-Path $RepoRoot $t.Source) (Join-Path $UserHome $t.Target) -Recurse
}

import.sh では config::import_claude / config::import_codex などのマージ関数を使いますが、PS1 版は単純な Copy-Item -Force で上書きします。既存ユーザーカスタマイズが失われる可能性があります。

初回ブートストラップとして割り切るならこのままでも許容範囲ですが、README の制約事項に明記することを推奨します。


[recommendation] platform::is_windows / platform::assert_not_windows のテストがない

ファイル: test/integration/platform_basic.bats

既存のテストファイル (platform_basic.bats) に新関数のテストが追加されていません。特に PLATFORM_OS=windows を強制した場合の assert_not_windows の挙動テストがあると安心です。


✅ 良かった点

  • $ErrorActionPreference = 'Stop'Set-StrictMode -Version Latest による堅牢なエラー処理
  • PowerShell 5.1 / 7+ 両対応の設計
  • -DryRun / -SkipWinget 等の細かいスイッチ対応
  • platform::assert_not_windows の誘導メッセージが丁寧で分かりやすい
  • WSL2 環境では PLATFORM_OS=linux となり既存フローが維持されるという明確な設計判断
  • winget import --ignore-versions --no-upgrade で冪等性を考慮

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread script/import.ps1 Outdated
Comment on lines +154 to +155
& code --install-extension $ext --force | Out-Null
Write-Ok $ext

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
script/import.ps1 (1)

105-109: Drift from import.sh: missing user.signingkey reminder.

script/import.sh lines 60-64 print three git config reminders, including user.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 in Winfile.json but 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.json line 11 also includes Microsoft.WindowsTerminal. Worth adding for accuracy so the docs match what winget import actually 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

📥 Commits

Reviewing files that changed from the base of the PR and between a12cfcb and efcd992.

📒 Files selected for processing (5)
  • README.md
  • brew/Winfile.json
  • script/import.ps1
  • script/import.sh
  • script/lib/platform.sh

Comment thread script/import.ps1
Comment on lines +1 to +15
# ============================================================================
# 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+ の両方で動作する。
# ============================================================================

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 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:


🏁 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"
fi

Repository: 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.ps1

Repository: 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.ps1

Repository: 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 $ext

Compare 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.

Comment thread script/import.ps1
Comment on lines +153 to +156
} else {
& code --install-extension $ext --force | Out-Null
Write-Ok $ext
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
} 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.

keito4 and others added 2 commits April 27, 2026 10:17
実機検証で判明した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>
@keito4
keito4 merged commit e1ec41e into main Apr 27, 2026
4 checks passed
@keito4
keito4 deleted the feat/windows-support branch April 27, 2026 01:48
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.111.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released リリース済み

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows ネイティブ環境のサポート

1 participant