Skip to content

feat: add PowerShell support to wt init#60

Merged
es5h merged 1 commit into
crevissepartners:mainfrom
rootsong0220:feat/windows-powershell-wrapper
May 15, 2026
Merged

feat: add PowerShell support to wt init#60
es5h merged 1 commit into
crevissepartners:mainfrom
rootsong0220:feat/windows-powershell-wrapper

Conversation

@rootsong0220

@rootsong0220 rootsong0220 commented May 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • wt initpowershell 케이스 추가. Windows 사용자가 zsh/bash/fish와 동일한 wtr/wtg/wcd cd helper를 쓸 수 있게 하고, Windows Terminal의 wt App Execution Alias 충돌을 피하는 wtp alias를 노출.
  • 스니펫은 where.exe wt\WindowsApps\ 경로를 제외한 첫 wt.exe를 찾아 $Global:WtBin에 캐시하고, Set-Alias -Scope Global/function global:로 caller scope에 등록. Invoke-Expression 어떤 scope에서 호출돼도 동일 동작.
  • 문서(README, docs/ux/shell.md, docs/ux/agents.md, docs/spec/cli.md)에 Windows 흐름과 wtp 계약 반영.

User impact

  • macOS/Linux: 변화 없음. 기존 wt init zsh|bash|fish 그대로.
  • Windows (PowerShell): go install github.com/crevissepartners/wt/cmd/wt@latest& "$env:USERPROFILE\go\bin\wt.exe" init powershell >> $PROFILE 한 번 → wtp/wtr/wtg/wcd 사용 가능.
  • 신규 명령/플래그 없음. stdout/stderr/exit code 정책 변경 없음.

Behavior (examples)

PS> & "$env:USERPROFILE\go\bin\wt.exe" init powershell | Select-Object -First 12
# wt shell integration for PowerShell (output-only; no profile changes are made)
# Note: Windows Terminal's 'wt' App Execution Alias may shadow this binary.
#       Bootstrap (first time) via absolute path:
#         & "$env:USERPROFILE\go\bin\wt.exe" init powershell | Out-String | Invoke-Expression
#         & "$env:USERPROFILE\go\bin\wt.exe" init powershell >> $PROFILE
#       After the snippet below has loaded, 'wtp' is safe to use for re-invocation:
#         wtp init powershell | Out-String | Invoke-Expression
# ...
PS> wtp list
wt  feat/x  abc1234  C:\Users\me\.wt\feat\x  [current,primary]
PS> wtg feat/x
PS C:\Users\me\.wt\feat\x>

Safety

  • wt init powershell은 다른 init과 동일하게 output-only. 사용자가 명시적으로 Invoke-Expression/>> $PROFILE 해야 적용.
  • Windows Terminal alias를 직접 조작하지 않음.
  • 스니펫 헤더에서 "Apply now / Persist"를 wt로 안내하지 않고 절대경로 / 부트스트랩 후 wtp 사용을 명시 (alias 충돌 회피 일관).

Tests

  • go test ./cmd/wt/ -run TestInit (zsh/bash/fish/powershell): PASS.
  • 수동 e2e: PowerShell에서 & "$env:USERPROFILE\go\bin\wt.exe" init powershell | Out-String | Invoke-Expression 후 같은 셸에서 wtp --version, wtp list, wtr, wtg, 에러 경로 모두 정상 동작.
  • 윈도우 사전존재 path-separator 테스트 실패(\repo vs /repo)는 이번 PR과 무관.

E2E guide

# 1) Install wt (Go required for now)
go install github.com/crevissepartners/wt/cmd/wt@latest

# 2) Bootstrap PowerShell helpers via absolute path
& "$env:USERPROFILE\go\bin\wt.exe" init powershell >> $PROFILE
. $PROFILE

# 3) Use wtp / cd helpers
wtp --version
wtp list
wtg <branch-query>

macOS/Linux:

go install ./cmd/wt
eval "$(wt init zsh)"
wtg feature/x

Docs

  • README.md: Installation Windows 섹션(go install + 부트스트랩), Quick Start wt→wtp 노트, PowerShell shell-helper 형제 블록, wt upgrade Windows 주의, Core Commands wt init <shell> 표.
  • docs/ux/shell.md: PowerShell init/completion 절, where.exe alias 회피, 부트스트랩 절대경로.
  • docs/ux/agents.md: Windows agents → wtp.
  • docs/spec/cli.md: 지원 shell에 powershell 추가, wtp/$Global:WtBin/function global: 계약 명시.

Release

  • PR title은 Conventional Commit 형식 (feat: ...).
  • CHANGELOG.md/internal/buildinfo/buildinfo.go 직접 수정 없음 (release-please 처리 대상).

🤖 Generated with Claude Code

@es5h es5h left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

확인했습니다. 이번 PR은 Windows/PowerShell 지원에 초점을 맞추는 방향이 더 좋겠습니다. 방향 자체는 좋지만, 현재 상태로는 Windows installer와 release asset 계약이 조금 섞여 있어서 수정 후 다시 보는 게 안전해 보입니다.

  1. workflow_dispatch에서 입력받은 tag로 source checkout이 고정되지 않습니다.
    Windows installer가 받을 binary를 release asset으로 올리는 구조라면, 수동 재실행 시에도 vX.Y.Z release에 정확히 해당 tag의 source로 빌드한 wt-windows-*.exe가 올라가야 합니다. release event/manual dispatch 양쪽 모두 실제 build source가 release tag와 일치하도록 actions/checkoutref를 명시해 주세요.

  2. 이번 PR의 목적이 Windows installer라면 release-binaries도 Windows asset 생성에만 집중하는 편이 좋아 보입니다.
    linux/darwin binary까지 함께 추가하면 “Windows PowerShell 지원”을 넘어 전체 플랫폼 release 배포 정책 변경이 됩니다. Windows용 wt-windows-amd64.exe/wt-windows-arm64.exe만 유지하거나, 전체 플랫폼 binary release는 별도 PR로 분리해 주세요.

  3. install.ps1은 latest release asset을 전제로 하는데, 이 PR이 merge된 직후부터 다음 release가 publish되고 asset upload가 끝나기 전까지 README의 one-line install은 실패할 수 있습니다.
    README에 “Windows binary asset이 포함된 다음 release부터 사용 가능”을 명확히 쓰거나, asset missing 상황에서 installer가 더 구체적인 안내를 하도록 해 주세요.

  4. PowerShell 문서/출력에서 wt init powershell을 그대로 안내하고 있는데, 이 PR의 핵심 문제가 Windows Terminal의 wt alias 충돌이라면 같은 문제를 다시 밟을 수 있습니다.
    설치 후 흐름은 wtp init powershell ... 또는 & "$env:LOCALAPPDATA\Programs\wt\wt.exe" init powershell ...처럼 충돌을 피하는 예시로 맞추는 게 안전해 보입니다.

  5. 사용자-facing 명령/출력 계약이 바뀌었는데 docs/spec/cli.md가 갱신되지 않았습니다.
    wt init <shell> 지원 목록에 powershell을 추가하고, Windows에서는 wtp alias를 쓰는 계약도 spec에 반영해 주세요.

요약하면, 이 PR은 “Windows PowerShell init + Windows installer + Windows release asset” 범위로 좁히는 게 가장 명확해 보입니다. 전체 플랫폼 release binary 자동화는 별도 PR에서 release process 문서와 같이 다루는 편이 리뷰하기 좋겠습니다.

@rootsong0220 rootsong0220 force-pushed the feat/windows-powershell-wrapper branch from d3557e4 to b61bd3e Compare May 15, 2026 16:55
@rootsong0220 rootsong0220 changed the title feat: PowerShell init, Windows installer, and release binaries feat: add PowerShell support to wt init May 15, 2026
@rootsong0220

Copy link
Copy Markdown
Contributor Author

리뷰 감사합니다. 지적해주신 5개 항목 반영해서 PR 범위를 좁히고 force-push 했습니다.

범위 축소: 이번 PR을 wt init powershell + 문서 갱신으로 한정했습니다. 구체적으로 install.ps1.github/workflows/release-binaries.yml을 이번 PR에서 제거했습니다. Windows binary release 배포 (그리고 install.ps1 기반 한 줄 설치)는 별도 PR에서 release process 문서와 함께 다루겠습니다.

개별 응답:

  1. workflow_dispatch checkout ref 고정 — workflow 자체를 이번 PR에서 제거했으므로 해소. 별도 PR에서 dispatch 시 actions/checkoutrefrelease.tag_name / dispatch input 양쪽 모두 명시하는 형태로 작성하겠습니다.

  2. release-binaries Windows asset에만 집중 — 이번 PR에서 workflow 자체 제거. 별도 PR로 분리하되, Windows 한정으로 시작할지 전체 플랫폼으로 갈지는 release 정책 합의 후 결정.

  3. install.ps1 / release asset 타이밍 — install.ps1 제거되었으므로 이번 PR에선 해소. 별도 PR에서 (a) README에 "Windows binary asset이 포함된 다음 release부터 사용 가능" 명시, (b) installer가 asset missing 시 구체 안내 출력하도록 반영하겠습니다.

  4. alias 충돌 일관성 — 반영. 스니펫 헤더의 "Apply now: wt init powershell" / "Persist: wt init powershell >> $PROFILE" 문구를 제거하고, 절대경로 부트스트랩 (& \"\$env:USERPROFILE\go\bin\wt.exe\" init powershell ...)과 부트스트랩 후 wtp init powershell 재호출을 명시했습니다. README/docs/ux/shell.md의 Windows 설명도 절대경로 부트스트랩 흐름으로 다시 썼습니다.

  5. docs/spec/cli.mdwt init <shell> 지원 목록에 powershell 추가, where.exe로 alias 회피 + \$Global:WtBin 캐시 + Set-Alias wtp -Scope Global + function global:wtr/wtg 계약을 spec에 명시했습니다.

브랜치는 단일 commit (feat: add PowerShell support to wt init)으로 정리해서 force-push 했습니다.

@es5h

es5h commented May 15, 2026

Copy link
Copy Markdown
Collaborator

반영 감사합니다. 범위 축소와 spec 반영은 좋아 보입니다. 다만 아직 하나 남은 흐름 문제가 있습니다.

README는 첫 설정을 & "$env:USERPROFILE\go\bin\wt.exe" init powershell >> $PROFILE로 안내하지만, 실제 PowerShell snippet은 $Global:WtBinwhere.exe wt로만 찾습니다. 따라서 go install$env:USERPROFILE\go\bin이 PATH에 없으면 절대경로로 init을 실행해도 snippet 로드 후 wtp/wtr/wtg가 바로 실패할 수 있습니다.

절대경로 bootstrap을 지원하려면 init 출력에 현재 실행 중인 wt.exe 경로를 fallback으로 포함하거나, 문서에서 Go bin PATH 선행 조건을 명확히 해 주세요.

그리고 문서에 아직 wt init powershell | Out-String | Invoke-Expression 예시가 남아 있습니다. Windows Terminal alias 충돌을 피하려는 PR이므로 README/UX 문서의 PowerShell 예시는 절대경로 bootstrap 또는 bootstrap 이후 wtp init powershell로 통일해 주세요. docs/ux/agents.mdinstall.ps1 언급도 이번 PR에서 installer가 제거됐으니 정리해야 합니다.

Comment thread cmd/wt/init.go
Comment thread README.md Outdated
Comment thread docs/ux/shell.md Outdated
Comment thread docs/ux/agents.md Outdated
Comment thread docs/ux/shell.md Outdated
Extends `wt init` with a `powershell` case so Windows users can use the
same wtr/wtg/wcd cd helpers as zsh/bash/fish, plus a `wtp` alias to
invoke the CLI without colliding with Windows Terminal's `wt` App
Execution Alias.

The snippet:

- Resolves the real wt.exe via `where.exe wt`, skipping any entry
  inside `\WindowsApps\` (which is where the Windows Terminal alias
  lives), and caches the result in $Global:WtBin.
- Exposes the CLI as `wtp` via `Set-Alias -Scope Global`. Windows
  users call `wtp list`, `wtp create`, etc. instead of `wt`.
- Defines wtr/wtg as `function global:` and `wcd` as a global alias so
  the helpers survive Invoke-Expression from any scope (e.g. when the
  snippet is sourced via $PROFILE).

The header comment explains that the very first invocation must use
the absolute path (e.g. & "$env:USERPROFILE\go\bin\wt.exe" init
powershell) because `wt` is still shadowed at that moment; once the
snippet has loaded, `wtp init powershell` is safe.

Docs:

- README adds a Windows section walking through `go install` + the
  absolute-path bootstrap; adds a `wt` -> `wtp` callout above Quick
  Start; shows a PowerShell shell-helper block next to the zsh one;
  enumerates supported shells in the Core Commands table; notes that
  on Windows `wtp upgrade` is the alias-safe form.
- docs/ux/shell.md describes the `where.exe` filter, the wtp alias,
  and the absolute-path bootstrap step.
- docs/ux/agents.md adds a one-line note that Windows PowerShell
  agents call the CLI as wtp.
- docs/spec/cli.md adds powershell to the supported shell list and
  documents the wtp alias contract.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rootsong0220 rootsong0220 force-pushed the feat/windows-powershell-wrapper branch from b61bd3e to 3b1d6c6 Compare May 15, 2026 17:11
@rootsong0220

Copy link
Copy Markdown
Contributor Author

추가 지적 3개 모두 반영해서 force-push 했습니다.

1. PATH 의존성 갭 → fallback embed로 해소

wt init powershell 스니펫 본문 첫 줄에 init을 실행한 wt.exe의 절대경로를 embed 합니다. snippet 로직은:

$wtBinFallback = '<os.Executable() 결과>'
$Global:WtBin = $null
foreach ($candidate in (& where.exe wt 2>$null)) {
    if ($candidate -notlike '*\WindowsApps\*') { $Global:WtBin = $candidate; break }
}
if (-not $Global:WtBin -and $wtBinFallback -and (Test-Path -LiteralPath $wtBinFallback)) {
    $Global:WtBin = $wtBinFallback
}

이렇게 하면 $env:USERPROFILE\go\bin이 PATH에 없어 where.exe가 WindowsApps만 잡는 케이스에서도, 부트스트랩에 쓴 절대경로의 wt.exe가 그대로 fallback으로 사용됩니다. 헤더 주석도 같은 동작을 명시합니다 ("if none is found there, they fall back to the path that generated this snippet"). 실측: PATH에서 모든 wt.exe-제공 디렉터리 제거 → WindowsApps만 남긴 상태로 절대경로 부트스트랩 → $Global:WtBin이 fallback 경로로 설정되고 wtp/wtr 정상 동작 확인.

2. 남은 raw wt init powershell 예시 정리

README.md(Quick Start PowerShell 블록), docs/ux/shell.md 두 곳(빠른 시작/Apply helpers) 모두 절대경로 부트스트랩으로 교체했습니다. shell.md의 영구 적용 예시도 "첫 회는 절대경로, 이후엔 wtp init powershell >> $PROFILE" 형태로 명시. 잔존 wt init powershell 언급은 모두 서술용(spec/README 도입부에서 명령 이름을 가리키는 용도)이라 그대로 둡니다.

3. docs/ux/agents.md install.ps1 잔존 언급 정리

install.ps1이 노출하는 별칭wt init powershell 스니펫이 노출하는 별칭으로 교체.

브랜치는 여전히 단일 commit(feat: add PowerShell support to wt init)으로 amend하여 force-push 했습니다.

@es5h es5h left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

반영 확인했습니다. 범위가 wt init powershell 중심으로 정리됐고, 절대경로 bootstrap 이후 PATH에 Go bin이 없어도 $wtBinFallback으로 동작하는 흐름까지 들어와서 주요 우려는 해소됐습니다.

CI premerge 성공도 확인했습니다.

@es5h es5h merged commit 27ef604 into crevissepartners:main May 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants