Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions RUN-ME-FIRST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Claude Code Game Studios - Windows Launcher

This repository is not a normal EXE game or desktop app. It is a Claude Code
project template. The usable program is Claude Code running inside this folder.

To start it on Windows:

1. Double-click `Start-Claude-Game-Studio.bat`.
2. If the launcher says you are not logged in, complete `claude auth login`.
3. Double-click `Start-Claude-Game-Studio.bat` again.
4. Inside Claude Code, type `/start`.

The launcher checks these dependencies:

- Git
- Node.js and npm
- Git Bash
- jq
- Claude Code

If Claude Code says `Not logged in`, the install is fine. The missing step is
account login/authorization.
5 changes: 5 additions & 0 deletions Start-Claude-Game-Studio.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@echo off
setlocal
set "SCRIPT_DIR=%~dp0"
powershell.exe -NoProfile -File "%SCRIPT_DIR%launch-claude-game-studio.ps1"
endlocal
108 changes: 108 additions & 0 deletions launch-claude-game-studio.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
param(
[switch]$DryRun,
[string]$AuthStatusJson
)

$ErrorActionPreference = "Stop"

function Convert-ClaudeAuthStatus {
param([string[]]$JsonText)

if (-not $JsonText) {
throw "claude auth status did not return a JSON response."
}

$auth = ($JsonText -join [Environment]::NewLine) | ConvertFrom-Json -ErrorAction Stop
if ($null -eq $auth.loggedIn) {
throw "claude auth status JSON is missing the loggedIn field."
}

return $auth
}

function Add-PathEntry {
param([string]$PathEntry)
if ($PathEntry -and (Test-Path -LiteralPath $PathEntry) -and ($env:Path -notlike "*$PathEntry*")) {
$env:Path = "$PathEntry;$env:Path"
}
}

function Require-Command {
param([string]$Name)
$cmd = Get-Command $Name -ErrorAction SilentlyContinue
if (-not $cmd) {
throw "Missing command: $Name"
}
return $cmd.Source
}

$ProjectDir = Split-Path -Parent $MyInvocation.MyCommand.Path
Set-Location -LiteralPath $ProjectDir

$machinePath = [Environment]::GetEnvironmentVariable("Path", "Machine")
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
$env:Path = "$machinePath;$userPath;$env:Path"

Add-PathEntry "C:\Program Files\Git\cmd"
Add-PathEntry "C:\Program Files\Git\bin"
Add-PathEntry "C:\Program Files\nodejs"
Add-PathEntry "$env:APPDATA\npm"
Add-PathEntry "$env:LOCALAPPDATA\Microsoft\WinGet\Links"

Write-Host ""
Write-Host "Claude Code Game Studios Launcher"
Write-Host "Project: $ProjectDir"
Write-Host ""

$required = @("git", "node", "npm", "bash", "jq", "claude")
foreach ($name in $required) {
$source = Require-Command $name
Write-Host ("OK {0,-6} {1}" -f $name, $source)
}

Write-Host ""
Write-Host "Versions:"
git --version
node --version
npm --version
jq --version
claude --version

Write-Host ""
Write-Host "Checking Claude login..."
try {
if ($PSBoundParameters.ContainsKey("AuthStatusJson")) {
$auth = Convert-ClaudeAuthStatus $AuthStatusJson
} else {
$authJson = claude auth status 2>$null
if ($LASTEXITCODE -ne 0) {
throw "claude auth status exited with code $LASTEXITCODE."
}

$auth = Convert-ClaudeAuthStatus $authJson
}
} catch {
throw "Unable to read Claude login status. Run 'claude auth status' manually to see the underlying error. Details: $($_.Exception.Message)"
}

if (-not $auth.loggedIn) {
Write-Host ""
Write-Host "Claude Code is installed, but you are not logged in."
Write-Host "A login window will open now. Finish login, then run this launcher again."
Write-Host ""

if (-not $DryRun) {
claude auth login
}

exit 0
}

Write-Host "Logged in. Starting Claude Code..."
Write-Host ""
Write-Host "When Claude opens, type: /start"
Write-Host ""

if (-not $DryRun) {
claude
}
39 changes: 39 additions & 0 deletions test-launcher.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
param()

$ErrorActionPreference = "Stop"

$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$Launcher = Join-Path $ScriptDir "launch-claude-game-studio.ps1"

function Invoke-LauncherCase {
param(
[string]$Name,
[string]$AuthStatusJson,
[int]$ExpectedExitCode,
[string]$ExpectedText
)

$previousErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference = "Continue"
try {
$output = & powershell.exe -NoProfile -File $Launcher -DryRun -AuthStatusJson $AuthStatusJson 2>&1
$exitCode = $LASTEXITCODE
} finally {
$ErrorActionPreference = $previousErrorActionPreference
}
$text = $output -join [Environment]::NewLine

if ($exitCode -ne $ExpectedExitCode) {
throw "$Name failed: expected exit code $ExpectedExitCode, got $exitCode. Output: $text"
}

if ($text -notlike "*$ExpectedText*") {
throw "$Name failed: expected output containing '$ExpectedText'. Output: $text"
}

Write-Host "PASS $Name"
}

Invoke-LauncherCase -Name "logged-in" -AuthStatusJson '{"loggedIn":true}' -ExpectedExitCode 0 -ExpectedText "Logged in. Starting Claude Code..."
Invoke-LauncherCase -Name "logged-out" -AuthStatusJson '{"loggedIn":false}' -ExpectedExitCode 0 -ExpectedText "Claude Code is installed, but you are not logged in."
Invoke-LauncherCase -Name "malformed-json" -AuthStatusJson '{bad json' -ExpectedExitCode 1 -ExpectedText "Unable to read Claude login status."