chore: 저장소 구조 정리 및 문서화, 첫 커밋

- src/dist 산출물 분리 원칙 정리(.gitignore, .gitattributes)
- 루트 및 주요 폴더(config/scripts/prompts/tests/src, 런타임 폴더 5종)에
  안내용 README.md 추가
- CHANGELOG.md, LICENSE, docs/ops/05-release-and-versioning.md 추가
- docs/README.md 문서 지도 갱신
This commit is contained in:
Yun Chan 2026-09-04 09:25:44 +09:00
commit 56a6e2da93
159 changed files with 145825 additions and 0 deletions

149
scripts/bootstrap_agy.ps1 Normal file
View file

@ -0,0 +1,149 @@
#Requires -Version 5.1
<#
.SYNOPSIS
agy.exe 존재를 확인하고, 없으면 공식 install.ps1 무인 설치한다.
.DESCRIPTION
1순위: 공식 설치 스크립트 https://antigravity.google/cli/install.ps1
(SHA512 무결성 검증 내장, 이미 설치돼 있으면 아무 것도 하지 않고
종료 코드 0 으로 빠지는 멱등한 스크립트 agy CLI SSOT §3.3 실측).
2순위: winget (1순위가 실패했을 때만 시도).
설치 여부와 별개로 "인증(로그인) 여부" 가볍게 점검한다. agy OAuth
토큰을 사용자 프로필 아래 평문 파일로 저장한다(agy CLI SSOT §4.2 실측:
~\.gemini\antigravity-cli\antigravity-oauth-token). 파일의 존재만
확인하고, 실제로 토큰이 유효한지 확인하는 헤드리스 왕복 호출은 하지
않는다 호출 자체가 수만 토큰 비용을 태우므로(SSOT §4.3 경고),
설치 스크립트 안에서 매번 돌릴 일이 아니다. 진짜 유효성 판정은 실제
작업 호출의 성공/실패로 한다(agy/client.py 책임).
.PARAMETER Force
이미 정상 설치되어 있어도 재설치를 시도한다.
.OUTPUTS
표준 출력에 사람이 읽을 진행 메시지, 마지막 줄에 "VERSION=<버전>"
(설치가 확인됐을 때만) GUI/CLI 파싱하고 싶으면 줄만 보면 된다.
.EXITCODE
0 : 정상 agy.exe 설치 확인 + 인증 토큰 파일 존재.
10 : 설치 필요 agy.exe ()설치하지 못했다.
11 : 인증 필요 agy.exe 설치돼 있지만 로그인 토큰 파일이 없다.
`agy login` 사용자가 직접 수행해야 한다(대화형 브라우저 로그인이라
무인화할 없다 agy CLI SSOT §4.1).
.EXAMPLE
powershell -ExecutionPolicy Bypass -File .\scripts\bootstrap_agy.ps1
#>
[CmdletBinding()]
param(
[switch]$Force
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Continue'
function Write-Step { param([string]$Message) Write-Host "[bootstrap_agy] $Message" }
function Write-Warn { param([string]$Message) Write-Host "[bootstrap_agy] ! $Message" -ForegroundColor Yellow }
function Write-Good { param([string]$Message) Write-Host "[bootstrap_agy] + $Message" -ForegroundColor Green }
# 설치·점검 도중 백그라운드 self-update 가 끼어들면 바이너리가 교체돼
# 검증이 흔들린다. 이 프로세스 범위에서만 끈다(agy CLI SSOT §3.6).
$env:AGY_CLI_DISABLE_AUTO_UPDATE = 'true'
# 절대경로 고정 — where.exe 는 winget Links 심볼릭까지 잡아 두 경로가
# 나올 수 있으므로(agy CLI SSOT §3.2 실측) 신뢰하지 않는다.
$agyExe = Join-Path $env:LOCALAPPDATA 'agy\bin\agy.exe'
$agyToken = Join-Path $env:USERPROFILE '.gemini\antigravity-cli\antigravity-oauth-token'
function Test-AgyOk {
<#
agy.exe 존재하고 실제로 실행되는지 확인한다.
0바이트 스텁·중단된 다운로드를 걸러낸다(실측 정상 크기 187MB).
성공하면 버전 문자열을, 실패하면 $null 돌려준다.
#>
if (-not (Test-Path -LiteralPath $agyExe)) { return $null }
$item = Get-Item -LiteralPath $agyExe -ErrorAction SilentlyContinue
if (-not $item -or $item.Length -lt 1MB) { return $null }
try {
$v = & $agyExe --version 2>$null
} catch {
return $null
}
if ($LASTEXITCODE -ne 0 -or -not $v) { return $null }
return ($v | Select-Object -First 1).ToString().Trim()
}
function Test-AgyAuthenticated {
<#
인증 여부의 가벼운(비용 없는) 근사치: 토큰 파일 존재 여부.
실제 유효성(만료 여부)까지는 확인하지 않는다 §4.3 경고 참조.
#>
return (Test-Path -LiteralPath $agyToken)
}
Write-Step "확인 경로: $agyExe"
$version = Test-AgyOk
if ($version -and -not $Force) {
Write-Good "이미 설치되어 있습니다. (버전 $version)"
} else {
if ($Force) {
Write-Step '재설치를 요청받았습니다. 설치를 진행합니다.'
} else {
Write-Step '설치되어 있지 않거나 손상된 것으로 보입니다. 설치를 진행합니다.'
}
# ------------------------------------------------------------ 1순위: 공식 설치 스크립트
Write-Step '공식 설치 스크립트를 받는 중... (irm https://antigravity.google/cli/install.ps1 | iex)'
try {
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
} catch {
Write-Warn 'TLS 1.2 강제 설정에 실패했습니다. 기본 프로토콜로 계속합니다.'
}
try {
Invoke-Expression (Invoke-RestMethod -Uri 'https://antigravity.google/cli/install.ps1' -UseBasicParsing)
} catch {
Write-Warn "공식 설치 스크립트 실행 실패: $($_.Exception.Message)"
}
$version = Test-AgyOk
if ($version) {
Write-Good "설치 확인: 버전 $version"
} else {
# -------------------------------------------------------- 2순위: winget
Write-Step '1순위 설치가 확인되지 않았습니다. winget 으로 다시 시도합니다...'
$winget = Get-Command winget.exe -ErrorAction SilentlyContinue
if ($winget) {
try {
& $winget.Source install --id Google.AntigravityCLI --silent `
--accept-package-agreements --accept-source-agreements | Out-Null
} catch {
Write-Warn "winget 설치 실패: $($_.Exception.Message)"
}
} else {
Write-Warn 'winget 을 사용할 수 없습니다.'
}
$version = Test-AgyOk
if ($version) {
Write-Good "설치 확인: 버전 $version"
}
}
}
if (-not $version) {
Write-Warn '설치에 실패했습니다. 네트워크 연결 또는 방화벽 설정을 확인해 주세요.'
Write-Warn " 수동 설치: irm https://antigravity.google/cli/install.ps1 | iex"
exit 10
}
Write-Host "VERSION=$version"
if (-not (Test-AgyAuthenticated)) {
Write-Warn '로그인 토큰을 찾을 수 없습니다. 로그인이 필요합니다.'
Write-Warn " 다음 명령을 배치를 돌릴 그 계정으로 실행하세요:"
Write-Warn " & `"$agyExe`" login"
exit 11
}
Write-Good '설치와 로그인 토큰 확인이 모두 끝났습니다.'
exit 0