diff --git a/.gitignore b/.gitignore index 3f01530..ac37313 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ dist/ node_modules/ vendor/ -# pi +# agents .pi/ +.antigravitycli/ thought/ diff --git a/README.md b/README.md index ef756bd..7363700 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ ## 지원 도구 - [tmux](https://github.com/tmux/tmux) - 터미널 멀티플렉서 +- [ttyd](https://github.com/tsl0922/ttyd) - 웹 기반 터미널 공유 유틸리티 - [bottom](https://github.com/ClementTsang/bottom) - 호스트 모니터링 - [superfile](https://github.com/yorukot/superfile) - 터미널 파일 관리자 - [dua](https://github.com/byron/dua-cli) - 디스크 사용량 분석기 @@ -24,6 +25,12 @@ curl -fsSL "https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-tmux.sh?ref_type=heads" | bash ``` +**ttyd:** + +```bash +curl -fsSL "https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-ttyd.sh?ref_type=heads" | bash +``` + **bottom:** ```bash @@ -99,6 +106,12 @@ curl -fsSL "https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-pi.s powershell -ExecutionPolicy Bypass -c "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $t=\"$env:TEMP\install-tmux.ps1\"; iwr -useb 'https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-tmux.ps1' -OutFile $t; & $t" ``` +**ttyd:** + +```powershell +powershell -ExecutionPolicy Bypass -c "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $t=\"$env:TEMP\install-ttyd.ps1\"; iwr -useb 'https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-ttyd.ps1' -OutFile $t; & $t" +``` + **bottom:** ```powershell @@ -193,6 +206,28 @@ tmux ls # 세션 목록 > `install-tmux` 스크립트는 `.tmux.conf`를 홈 디렉토리에 자동 배포합니다. 기존 파일이 있으면 백업 후 덮어씁니다. +### ttyd + +웹 브라우저를 통해 터미널을 접속할 수 있도록 해주는 유틸리티입니다. tmux 등과 연동하여 원격 모니터링/제어가 가능합니다. + +- **터미널 웹 공유** — 특정 포트를 통해 쉘(bash/zsh 등) 또는 명령어 실행 화면을 웹에 호스팅 +- **읽기 전용 모드** — 보안을 위해 웹 접속자가 터미널을 조작할 수 없도록 보기 전용 모드로 설정 가능 +- **인증 설정** — 웹 접속 시 사용자 이름과 비밀번호를 검증하도록 설정 가능 + +```bash +ttyd bash # 기본 bash 쉘을 웹(기본 포트 7681)에 호스팅 +ttyd tmux attach # 현재 실행 중인 tmux 세션을 웹에 연동 +ttyd -p 8080 zsh # 포트 8080을 사용하여 zsh 호스팅 +ttyd -c user:pass bash # 아이디/패스워드 로그인 설정 +``` + +| 옵션 | 설명 | +| --------------------- | ------------------------------------ | +| `-p, --port ` | 사용할 네트워크 포트 지정 (기본 7681)| +| `-i, --interface `| 바인딩할 네트워크 인터페이스 | +| `-c, --credential `| 웹 접속 인증용 사용자 계정 정보 | +| `-R, --readonly` | 접속자가 터미널을 입력할 수 없는 모드| + ### bottom 호스트 모니터링 터미널 UI 도구입니다. diff --git a/agyc.sh b/agyc.sh new file mode 100755 index 0000000..b95e106 --- /dev/null +++ b/agyc.sh @@ -0,0 +1 @@ +agy --conversation=e87c738b-1930-48bb-988f-5e86f98ecfff diff --git a/install-lazygit.sh b/install-lazygit.sh old mode 100644 new mode 100755 diff --git a/install-ttyd.ps1 b/install-ttyd.ps1 new file mode 100644 index 0000000..dd2acf0 --- /dev/null +++ b/install-ttyd.ps1 @@ -0,0 +1,133 @@ +#Requires -Version 5.1 +<# +.SYNOPSIS + GitHub Releases에서 최신 ttyd 안정 버전을 다운로드하고 Windows 환경에 설치합니다. + +.DESCRIPTION + https://github.com/tsl0922/ttyd/releases 에서 제공하는 최신 Windows 릴리스인 + ttyd.win32.exe 바이너리를 다운로드하여 지정된 디렉토리에 ttyd.exe로 설치하고 + 사용자 PATH 환경 변수에 영구적으로 등록합니다. + +.PARAMETER InstallDir + ttyd.exe가 설치될 디렉토리 경로입니다. 기본값: $env:USERPROFILE\.local\bin + +.PARAMETER AddToPath + 설치 디렉토리를 사용자 PATH 환경 변수에 영구적으로 추가할지 여부입니다. 기본값: $true + +.EXAMPLE + .\install-ttyd.ps1 + .\install-ttyd.ps1 -InstallDir "C:\tools\bin" + .\install-ttyd.ps1 -AddToPath $false + + # Windows 원라인 원격 실행 명령어: + powershell -ExecutionPolicy Bypass -c "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $t=\"$env:TEMP\install-ttyd.ps1\"; iwr -useb 'https://gl.isitsoft.kr/publicproj/install-sh/-/raw/main/install-ttyd.ps1' -OutFile $t; & $t" + +.NOTES + 실행 정책 에러가 발생하는 경우 다음 명령어로 해결할 수 있습니다: + Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser +#> + +[CmdletBinding()] +param( + [string] $InstallDir = "$env:USERPROFILE\.local\bin", + [bool] $AddToPath = $true +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +# HTTPS 다운로드를 위한 TLS 1.2 강제 (Windows 7/10 및 PowerShell 5.1 호환성 보장) +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +# ──────────────────────────────────────────── +# 유틸리티 함수 정의 +# ──────────────────────────────────────────── +function Write-Info { param([string]$msg) Write-Host "[INFO] $msg" -ForegroundColor Cyan } +function Write-Warn { param([string]$msg) Write-Host "[WARN] $msg" -ForegroundColor Yellow } +function Write-Success { param([string]$msg) Write-Host "[OK] $msg" -ForegroundColor Green } +function Write-Err { param([string]$msg) Write-Host "[ERROR] $msg" -ForegroundColor Red; exit 1 } + +# ──────────────────────────────────────────── +# 상수 정의 +# ──────────────────────────────────────────── +$REPO = "tsl0922/ttyd" +$API_URL = "https://api.github.com/repos/$REPO/releases/latest" + +# ──────────────────────────────────────────── +# 메인 설치 프로세스 +# ──────────────────────────────────────────── + +# 1) GitHub 최신 릴리스 정보 획득 +Write-Info "GitHub API를 통해 ttyd 최신 릴리스 정보를 가져오는 중..." +try { + $release = Invoke-RestMethod -Uri $API_URL -UseBasicParsing -Headers @{ 'User-Agent' = 'install-ttyd-ps1' } +} catch { + Write-Err "GitHub API 호출에 실패했습니다: $_" +} + +$tagName = $release.tag_name +Write-Info "최신 ttyd 버전 확인 완료: $tagName" + +# 2) ttyd.win32.exe 에셋 탐색 +$assetName = "ttyd.win32.exe" +$asset = $release.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1 + +if (-not $asset) { + Write-Err "릴리스($tagName)에서 '$assetName' 바이너리를 찾을 수 없습니다." +} + +$downloadUrl = $asset.browser_download_url +$destExeName = "ttyd.exe" + +# 3) 다운로드 및 디렉토리 생성 +if (-not (Test-Path $InstallDir)) { + Write-Info "설치 디렉토리 생성 중: $InstallDir" + New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null +} + +$destPath = Join-Path $InstallDir $destExeName +$tmpDir = Join-Path $env:TEMP "ttyd_install_$(Get-Random)" +New-Item -ItemType Directory -Path $tmpDir -Force | Out-Null +$tmpFilePath = Join-Path $tmpDir $assetName + +try { + Write-Info "바이너리 다운로드 중: $downloadUrl" + $ProgressPreference = 'SilentlyContinue' # 다운로드 진행 바 숨김으로 속도 향상 + Invoke-WebRequest -Uri $downloadUrl -OutFile $tmpFilePath -UseBasicParsing + $ProgressPreference = 'Continue' + + Write-Info "설치 경로로 바이너리 배포 중: $destPath" + Move-Item -Path $tmpFilePath -Destination $destPath -Force +} finally { + if (Test-Path $tmpDir) { + Remove-Item -Path $tmpDir -Recurse -Force -ErrorAction SilentlyContinue + } +} + +# 4) PATH 환경 변수 등록 +if ($AddToPath) { + if ($env:Path -notlike "*$InstallDir*") { + $env:Path = "$InstallDir;$env:Path" + Write-Info "현재 세션 PATH에 $InstallDir 경로를 임시 추가했습니다." + } + + $userPath = [System.Environment]::GetEnvironmentVariable('Path', 'User') + if ($userPath -notlike "*$InstallDir*") { + [System.Environment]::SetEnvironmentVariable('Path', "$InstallDir;$userPath", 'User') + Write-Success "사용자 PATH 환경 변수에 $InstallDir 경로를 영구 등록했습니다." + Write-Warn "변경된 PATH 설정을 반영하려면 열려 있는 터미널 창을 재시작해 주세요." + } else { + Write-Info "$InstallDir 경로는 이미 사용자 PATH에 등록되어 있습니다." + } +} + +# 5) 설치 완료 검증 +if (Test-Path $destPath) { + Write-Host "" + Write-Host "==================================================" -ForegroundColor Green + Write-Success "ttyd ($tagName) 설치가 완료되었습니다!" + Write-Host "==================================================" -ForegroundColor Green + Write-Info "실행 명령어: ttyd --version" +} else { + Write-Err "설치가 성공적으로 완료되지 않은 것으로 보입니다. 설치 파일 존재 여부를 확인해 주세요." +} diff --git a/install-ttyd.sh b/install-ttyd.sh new file mode 100755 index 0000000..e979ae1 --- /dev/null +++ b/install-ttyd.sh @@ -0,0 +1,199 @@ +#!/usr/bin/env bash +# shellcheck disable=SC2086 + +# GitHub Releases에서 최신 ttyd 안정 버전을 다운로드하고 설치합니다. +# ttyd: https://github.com/tsl0922/ttyd +# +# 지원 플랫폼: +# macOS : Intel (x86_64), Apple Silicon (arm64) — Homebrew를 통해 설치 +# Linux : x86_64, aarch64(arm64), armhf(32bit), i686 +# FreeBSD : 지원 안 함 (필요 시 소스 빌드) +# Windows : Git Bash / MSYS2 / Cygwin (윈도우 네이티브 바이너리 설치) + +set -euo pipefail + +# ──────────────────────────────────────────── +# 상수 정의 +# ──────────────────────────────────────────── +REPO="tsl0922/ttyd" +API_URL="https://api.github.com/repos/${REPO}/releases/latest" +INSTALL_DIR="${HOME}/.local/bin" + +# ──────────────────────────────────────────── +# 유틸리티 함수 (모두 stderr 출력) +# ──────────────────────────────────────────── +info() { echo "[INFO] $*" >&2; } +warn() { echo "[WARN] $*" >&2; } +error() { echo "[ERROR] $*" >&2; exit 1; } +success() { echo "[OK] $*" >&2; } + +# ──────────────────────────────────────────── +# macOS용 Homebrew 확인 및 설치 +# ──────────────────────────────────────────── +ensure_brew() { + if command -v brew &>/dev/null; then + return 0 + fi + info "Homebrew가 설치되어 있지 않습니다. Homebrew 설치를 진행합니다..." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + if [ -d /opt/homebrew/bin ]; then + export PATH="/opt/homebrew/bin:$PATH" + fi + if [ -d /usr/local/bin ]; then + export PATH="/usr/local/bin:$PATH" + fi + command -v brew &>/dev/null || error "Homebrew 설치에 실패했습니다. 수동으로 설치한 후 다시 실행해 주세요: https://brew.sh/" + success "Homebrew 설치 완료" +} + +# ──────────────────────────────────────────── +# 필수 명령어 확인 +# ──────────────────────────────────────────── +for cmd in curl uname; do + command -v "$cmd" &>/dev/null || error "'$cmd' 명령어가 필요합니다." +done + +# Fallback: jq가 없을 경우 python3를 사용해 JSON 정보 분석 +if command -v jq &>/dev/null; then + _json_latest_tag() { + jq -r '.tag_name' + } +else + command -v python3 &>/dev/null || error "'jq' 또는 'python3' 명령어가 설치되어 있어야 합니다." + _json_latest_tag() { + python3 -c " +import sys, json +data = json.load(sys.stdin) +print(data.get('tag_name', '')) +" + } +fi + +# ──────────────────────────────────────────── +# OS 및 아키텍처 분석 +# ──────────────────────────────────────────── +# 반환 형식: "바이너리명:설치방식" +# 설치방식 = brew | binary +detect_platform() { + local os arch + + os="$(uname -s)" + arch="$(uname -m)" + + case "$os" in + # ── macOS ────────────────────────────────────────────── + Darwin) + # macOS는 brew 설치 방식을 권장 + echo "brew:brew" + ;; + + # ── Linux ────────────────────────────────────────────── + Linux) + case "$arch" in + x86_64|amd64) + echo "ttyd.x86_64:binary" ;; + aarch64|arm64) + echo "ttyd.aarch64:binary" ;; + armv7l|armv6l) + echo "ttyd.armhf:binary" ;; + i686|i386) + echo "ttyd.i686:binary" ;; + *) + error "지원하지 않는 Linux 아키텍처입니다: $arch" ;; + esac + ;; + + # ── Windows (Git Bash / MSYS2 / Cygwin) ─────────────── + MINGW*|MSYS*|CYGWIN*) + warn "Windows 터미널 환경(Git Bash/MSYS2/Cygwin)이 감지되었습니다." + echo "ttyd.win32.exe:binary" + ;; + + *) + error "지원하지 않는 운영체제입니다: $os (uname -a: $(uname -a))" + ;; + esac +} + +# ──────────────────────────────────────────── +# 최신 릴리스 태그 가져오기 +# ──────────────────────────────────────────── +get_latest_release_tag() { + info "GitHub API를 통해 ttyd 최신 릴리스 버전을 가져오는 중..." + + local release_json tag + release_json="$(curl -fsSL "${API_URL}")" || error "GitHub API 호출에 실패했습니다." + + tag="$(echo "$release_json" | _json_latest_tag)" + if [[ -z "$tag" || "$tag" == "null" ]]; then + error "최신 릴리스 태그를 확인하는 데 실패했습니다." + fi + echo "$tag" +} + +# ──────────────────────────────────────────── +# 메인 설치 로직 +# ──────────────────────────────────────────── +main() { + local platform_info asset_name install_method + platform_info="$(detect_platform)" + asset_name="${platform_info%%:*}" + install_method="${platform_info##*:}" + + info "설치 환경 감지 완료: $asset_name ($install_method 방식)" + + # 1) macOS (Homebrew 설치 방식) + if [[ "$install_method" == "brew" ]]; then + info "macOS 환경에서 brew를 통해 ttyd 설치를 진행합니다." + if command -v ttyd &>/dev/null; then + success "ttyd가 이미 설치되어 있습니다: $(command -v ttyd)" + exit 0 + fi + ensure_brew + brew install ttyd + success "Homebrew를 통해 ttyd 설치를 완료했습니다." + exit 0 + fi + + # 2) Linux / Windows Bash (바이너리 직접 설치 방식) + local tag download_url + tag="$(get_latest_release_tag)" + info "최신 버전 감지: $tag" + + download_url="https://github.com/tsl0922/ttyd/releases/download/${tag}/${asset_name}" + + # 설치 디렉토리 생성 + mkdir -p "$INSTALL_DIR" + + local dest_file="${INSTALL_DIR}/ttyd" + if [[ "$asset_name" == *.exe ]]; then + dest_file="${INSTALL_DIR}/ttyd.exe" + fi + + local tmp_dir + tmp_dir="$(mktemp -d)" + local tmp_file="${tmp_dir}/${asset_name}" + + info "바이너리 다운로드 중: $download_url" + if ! curl -fsSL "$download_url" -o "$tmp_file"; then + rm -rf "$tmp_dir" + error "바이너리 다운로드에 실패했습니다. URL: $download_url" + fi + + info "설치 경로로 복사 중: $dest_file" + mv "$tmp_file" "$dest_file" + chmod +x "$dest_file" + rm -rf "$tmp_dir" + + success "ttyd ($tag) 설치가 성공적으로 완료되었습니다!" + info "설치 경로: $dest_file" + + # PATH 확인 및 안내 + if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then + warn "설치 경로($INSTALL_DIR)가 현재 PATH 환경 변수에 등록되어 있지 않습니다." + warn "사용하시는 쉘 프로필 파일(예: ~/.bashrc 또는 ~/.zshrc)에 아래 설정을 추가해 주세요:" + warn " export PATH=\"\$HOME/.local/bin:\$PATH\"" + fi +} + +main "$@"