@kaydash9999/banker-plugins 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +38 -0
- package/README.md +31 -6
- package/codex/manifest.json +28 -9
- package/codex/transform-matrix.md +19 -5
- package/commands/front-qa.md +2 -1
- package/commands/setup.md +31 -17
- package/package.json +1 -1
- package/skills/all-in-one/SKILL.md +3 -12
- package/skills/append_wiki/SKILL.md +1 -1
- package/skills/arch-diagram/SKILL.md +1 -1
- package/skills/arch-diagram/build_pptx_template.py +2 -0
- package/skills/audit-mock/SKILL.md +1 -1
- package/skills/audit-security/SKILL.md +1 -1
- package/skills/audit-web-page/SKILL.md +1 -1
- package/skills/compact-copy/SKILL.md +2 -6
- package/skills/compact-wiki/SKILL.md +1 -1
- package/skills/curation/SKILL.md +80 -0
- package/skills/deep-init/SKILL.md +120 -0
- package/skills/deep-research/SKILL.md +63 -0
- package/skills/docs-setup/SKILL.md +81 -0
- package/skills/harness-factory/SKILL.md +114 -0
- package/skills/humanizer/SKILL.md +1 -1
- package/skills/lineage/SKILL.md +1 -1
- package/skills/make-notion-guide/SKILL.md +1 -1
- package/skills/nothing-design/SKILL.md +1 -1
- package/skills/omc-reference/SKILL.md +35 -2
- package/skills/pdf-vision-extract/SKILL.md +1 -1
- package/skills/play-qa/SKILL.md +1 -1
- package/skills/ralph-qa/SKILL.md +70 -0
- package/skills/ready-compact/SKILL.md +1 -1
- package/skills/refresh-git-ignore/SKILL.md +1 -1
- package/skills/rfp-author/SKILL.md +1 -1
- package/skills/setup-insane-search/SKILL.md +1 -1
- package/skills/setup-java/SKILL.md +113 -0
- package/skills/setup-lsp/SKILL.md +232 -0
- package/skills/setup-mcp/SKILL.md +156 -0
- package/skills/setup-node/SKILL.md +112 -0
- package/skills/setup-omc/SKILL.md +1 -1
- package/skills/setup-omc-hud/SKILL.md +3 -1
- package/skills/setup-playwright/SKILL.md +1 -1
- package/skills/setup-pwsh/SKILL.md +106 -0
- package/skills/setup-python/SKILL.md +121 -0
- package/skills/setup-sandbox/SKILL.md +202 -0
- package/skills/{setup-stitch-proxy → setup-stitch}/SKILL.md +10 -3
- package/skills/setup-tmux/SKILL.md +105 -0
- package/skills/smart-compact/SKILL.md +81 -0
- package/skills/ultra-init/SKILL.md +2 -1
- package/skills/ultra-ui-qa/SKILL.md +1 -1
- package/skills/visual-ralph/SKILL.md +120 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-pwsh
|
|
3
|
+
description: "(banker) Windows PowerShell 7 + Git + $PROFILE(UTF-8 무BOM) 환경을 winget 으로 설치·검증(비-Windows 는 감지 후 no-op). 'setup-pwsh'/'PowerShell 설치'/'pwsh 환경 설정' 또는 /banker:setup 시 사용."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# setup-pwsh: Windows PowerShell 7 환경 설치
|
|
7
|
+
|
|
8
|
+
banker 의 Windows 워크플로 - Claude Code 의 Git Bash 배선, Codex/OMX 의 네이티브 셸 실행 - 이
|
|
9
|
+
전제하는 PowerShell 7 + Git + `$PROFILE` 환경을 구성한다. **Windows 전용 스킬**이다 - 다른 OS 에서는
|
|
10
|
+
먼저 감지해 "Windows 전용 - 해당 없음"으로 정직하게 no-op 보고한다(이것도 유효한 결과). 설치는
|
|
11
|
+
**멱등**. 답변은 한글(기술 토큰 영문).
|
|
12
|
+
|
|
13
|
+
## 런타임 배선
|
|
14
|
+
- **Claude Code**: Bash 도구가 Git Bash 를 쓰도록 `settings.json` 의 `env.CLAUDE_CODE_GIT_BASH_PATH`
|
|
15
|
+
를 설정한다(예: `C:\Program Files\Git\bin\bash.exe`). 네이티브 Windows 는 1급 지원이며 **WSL 은
|
|
16
|
+
필요 없다**(현재 공식 문서 기준 - WSL 은 샌드박싱·Linux 툴체인이 필요할 때만 선택 사항).
|
|
17
|
+
- **Codex**: 네이티브 PowerShell 셸에서 그대로 동작한다(별도 배선 불필요). AOAI 키 등 환경변수는
|
|
18
|
+
**User-scope** 로 저장하고, Process/User/Machine **3-scope 동기화**에 유의한다 - 저장 직후 현재
|
|
19
|
+
프로세스에는 반영되지 않을 수 있다.
|
|
20
|
+
|
|
21
|
+
## 0. 감지 (먼저 - 추정 금지)
|
|
22
|
+
```powershell
|
|
23
|
+
$PSVersionTable.PSVersion
|
|
24
|
+
$env:OS # Windows = 'Windows_NT' (PS 5.1·7 공통), 비-Windows 는 미설정
|
|
25
|
+
Get-Command git, pwsh -ErrorAction SilentlyContinue
|
|
26
|
+
```
|
|
27
|
+
- **Windows 판정 = `$env:OS -eq 'Windows_NT'`** (또는 `[System.Environment]::OSVersion.Platform -eq 'Win32NT'`).
|
|
28
|
+
⚠️ `$IsWindows` 자동 변수는 **PowerShell 7+ 에만** 있어, 이 스킬이 업그레이드하려는 **Windows PowerShell 5.1
|
|
29
|
+
에서는 `$null`(미정의)** 이다 - `$IsWindows` 로만 판정하면 진짜 Windows 를 비-Windows 로 오판해 no-op 한다. 보조 신호로만 쓴다.
|
|
30
|
+
- 비-Windows(PowerShell 없이 `uname` 만)면 **"Windows 전용 - 해당 없음"** 을 보고하고 멈춘다(no-op 도 유효한 결과).
|
|
31
|
+
|
|
32
|
+
## 1. winget 설치
|
|
33
|
+
```powershell
|
|
34
|
+
winget install --id Microsoft.PowerShell -e
|
|
35
|
+
winget install --id Microsoft.WindowsTerminal -e
|
|
36
|
+
winget install --id Git.Git -e
|
|
37
|
+
git config --global core.autocrlf input
|
|
38
|
+
```
|
|
39
|
+
winget 은 이미 설치된 패키지를 스스로 skip 한다(멱등) - 강제 재설치 불필요.
|
|
40
|
+
|
|
41
|
+
## 2. `$PROFILE` 작성 - UTF-8 무BOM 전용 경로
|
|
42
|
+
**`Add-Content`/`Out-File -Encoding UTF8` 금지** - 둘 다 CP949 재인코딩 또는 UTF-8 BOM 혼입으로
|
|
43
|
+
이후 한글 주석·파싱을 깨뜨린다. 반드시 아래 방식만 쓴다:
|
|
44
|
+
```powershell
|
|
45
|
+
$marker = "# BANKER_PWSH_BEGIN"
|
|
46
|
+
$existing = if (Test-Path $PROFILE) { [System.IO.File]::ReadAllText($PROFILE) } else { "" }
|
|
47
|
+
if ($existing -notmatch [regex]::Escape($marker)) {
|
|
48
|
+
# <java21-bin>/<python-dir> 은 실제 설치 경로로 교체 - 추정 금지, §0/설치 로그에서 확인 후 채운다
|
|
49
|
+
# (winget install Microsoft.OpenJDK.21 후 `Get-ChildItem "$env:ProgramFiles" -Filter "*jdk-21*"` 등으로 확인)
|
|
50
|
+
$block = @"
|
|
51
|
+
$marker
|
|
52
|
+
# PATH 순서: Java21 우선(잔존 구버전 Java 덮기) -> python -> ~/.local/bin -> jdtls
|
|
53
|
+
`$env:PATH = "<java21-bin>;`$env:PATH"
|
|
54
|
+
`$env:PATH = "`$env:PATH;<python-dir>"
|
|
55
|
+
`$env:PATH = "`$env:PATH;`$HOME\.local\bin"
|
|
56
|
+
`$env:PATH = "`$env:PATH;`$HOME\.local\jdtls\bin"
|
|
57
|
+
# BANKER_PWSH_END
|
|
58
|
+
"@
|
|
59
|
+
$content = $existing + "`n" + $block
|
|
60
|
+
[System.IO.File]::WriteAllText($PROFILE, $content, (New-Object System.Text.UTF8Encoding($false)))
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
- PATH 순서 원칙: **Java21 을 맨 앞**에 둬 PATH 상에 남아있을 수 있는 구버전 Java 를 덮고, 그다음
|
|
64
|
+
python, `~/.local/bin`, jdtls 순으로 이어붙인다.
|
|
65
|
+
- 마커 블록(`# BANKER_PWSH_BEGIN`/`END`)으로 재실행해도 중복 append 되지 않는다(사용자 기존 내용은
|
|
66
|
+
보존).
|
|
67
|
+
|
|
68
|
+
## 3. 런타임 배선 적용
|
|
69
|
+
**Claude Code** - `settings.json` 에 기존 키를 보존하며 병합:
|
|
70
|
+
```json
|
|
71
|
+
{ "env": { "CLAUDE_CODE_GIT_BASH_PATH": "C:\\Program Files\\Git\\bin\\bash.exe" } }
|
|
72
|
+
```
|
|
73
|
+
**Codex/OMX 환경변수** - User-scope 로 저장(예: AOAI 키):
|
|
74
|
+
```powershell
|
|
75
|
+
[Environment]::SetEnvironmentVariable('AZURE_OPENAI_API_KEY', $env:AZURE_OPENAI_API_KEY, 'User')
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## 검증 (보고 의무)
|
|
79
|
+
```powershell
|
|
80
|
+
pwsh -v
|
|
81
|
+
$PSVersionTable.PSVersion
|
|
82
|
+
git config --get core.autocrlf # input 기대
|
|
83
|
+
|
|
84
|
+
$b = [System.IO.File]::ReadAllBytes($PROFILE)[0..2]
|
|
85
|
+
if (("{0:X2}{1:X2}{2:X2}" -f $b[0],$b[1],$b[2]) -eq "EFBBBF") { "BOM 있음 -- 재작성 필요" } else { "무BOM 확인" }
|
|
86
|
+
|
|
87
|
+
pwsh -Command "Write-Output 'profile-load-ok'" # $PROFILE 이 에러 없이 실제 로드되는지
|
|
88
|
+
```
|
|
89
|
+
4-field 보고: 변경(설치 패키지·`$PROFILE` 마커블록·settings.json 병합 여부) / Evidence(위 출력) /
|
|
90
|
+
검증(무BOM·`profile-load-ok`·autocrlf=input) / Unknown(관리자 권한이 필요한 항목 등).
|
|
91
|
+
|
|
92
|
+
## 함정
|
|
93
|
+
- **CP949/BOM 오염**: `$PROFILE` 은 오직 `[System.IO.File]::WriteAllText(..., UTF8Encoding($false))`
|
|
94
|
+
로만 쓴다 - `Add-Content`/`Out-File -Encoding UTF8` 은 절대 쓰지 않는다.
|
|
95
|
+
- **MS Store Python stub**: `python`/`python3` 를 MS Store 앱 실행 별칭(App execution aliases)이
|
|
96
|
+
가로채 스토어를 여는 경우가 있다 → 설정 → 앱 → 고급 앱 설정 → 앱 실행 별칭에서 꺼야 실제 설치된
|
|
97
|
+
Python 이 잡힌다.
|
|
98
|
+
- **심볼릭 링크 권한**: 심볼릭 링크 생성은 개발자 모드 또는 관리자 권한이 필요하다 - 둘 다 없으면
|
|
99
|
+
조용히 실패하므로 **복사로 대체**하고 정직히 보고한다.
|
|
100
|
+
- **Process/User/Machine 3-scope 동기화**: `SetEnvironmentVariable(..., 'User')` 직후 현재
|
|
101
|
+
프로세스(`Process` scope)에는 반영되지 않을 수 있다 - 새 pwsh 세션에서 재확인.
|
|
102
|
+
- **이미지 붙여넣기**: 터미널에 이미지 붙여넣기는 `Ctrl+V` 가 아니라 **`Alt+V`**.
|
|
103
|
+
- **비-Windows 오인 실행**: 이 스킬은 Windows 전용이다 - `$IsWindows` 감지 없이 무작정 진행하지
|
|
104
|
+
않는다.
|
|
105
|
+
|
|
106
|
+
ARGUMENTS: 없음 (비-Windows 는 자동 감지 후 "Windows 전용 - 해당 없음" no-op 보고)
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-python
|
|
3
|
+
description: "(banker) Python 3.11+ 런타임 + pipx·uv 설치(OS별 PEP668·RHEL8 3.6 회피). 라이브러리(pptx·pymupdf)는 docs-setup 담당, 본 스킬은 런타임만. 'setup-python'/'Python 설치'/'pipx·uv 설치' 또는 /banker:setup 시 사용."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# setup-python: Python 3.11+ 런타임 + pipx·uv 설치
|
|
7
|
+
|
|
8
|
+
Claude Code·Codex 양쪽의 python 기반 도구가 딛고 서는 **인터프리터 런타임**과 `pipx`·`uv`를 설치한다.
|
|
9
|
+
**경계**: 이 스킬은 런타임 자체만 다룬다. python-pptx·pymupdf 같은 문서 라이브러리는 `docs-setup`이 이 런타임 위에서 담당(별도 venv). 멱등(이미 3.11+ 있으면 skip). 답변은 한글(명령·경로는 영문).
|
|
10
|
+
|
|
11
|
+
## 런타임 배선
|
|
12
|
+
- **Claude Code**: `docs-setup`(python-pptx·pymupdf) 및 `serena`·`mcp-server-git`·`mcp-server-fetch` 등 `uvx` 기반 MCP가 이 위에서 동작. 전부 python 3.8+ 요구.
|
|
13
|
+
- **Codex/OMX**: `basedpyright`·`ruff`(pipx 격리 설치), `lsp-mcp`(`pipx install --editable`)가 python 3.8+ 요구.
|
|
14
|
+
- 즉 이 스킬이 먼저 실행되어야 `docs-setup`이나 LSP 설치 스킬이 "어떤 python을 쓸지" 고민 없이 최신 버전을 찾을 수 있다.
|
|
15
|
+
|
|
16
|
+
## 0. 감지 (먼저, 추정 금지)
|
|
17
|
+
```bash
|
|
18
|
+
[ -f /etc/os-release ] && . /etc/os-release && echo "distro=$ID ${VERSION_ID}"
|
|
19
|
+
for v in 3.13 3.12 3.11; do command -v python$v >/dev/null && echo "python$v=$(python$v --version 2>&1)"; done
|
|
20
|
+
command -v python3 >/dev/null && echo "python3(default)=$(python3 --version 2>&1)" || echo "python3=미설치"
|
|
21
|
+
command -v pipx >/dev/null && echo "pipx=$(pipx --version)" || echo "pipx=미설치"
|
|
22
|
+
command -v uv >/dev/null && echo "uv=$(uv --version)" || echo "uv=미설치"
|
|
23
|
+
```
|
|
24
|
+
```powershell
|
|
25
|
+
$PSVersionTable.PSVersion
|
|
26
|
+
py -0p 2>$null # 설치된 버전 목록
|
|
27
|
+
if (Get-Command pipx -ErrorAction SilentlyContinue) { pipx --version } else { "pipx: 미설치" }
|
|
28
|
+
if (Get-Command uv -ErrorAction SilentlyContinue) { uv --version } else { "uv: 미설치" }
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 1. Rocky Linux 8
|
|
32
|
+
```bash
|
|
33
|
+
sudo dnf -y module install python311/common
|
|
34
|
+
python3.11 --version
|
|
35
|
+
```
|
|
36
|
+
- ⚠️ **RHEL8 기본 `python3`는 3.6.** `pymupdf`/`playwright` 등은 3.8+ 휠만 배포하므로 3.6/3.7에선 설치 자체가 실패한다(sdist 빌드 시도 → 헤더 부재로 재실패).
|
|
37
|
+
- 시스템 기본 `python3`를 3.11로 바꾸는 것은 **선택**이며 위험을 감수할 때만:
|
|
38
|
+
```bash
|
|
39
|
+
# sudo alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 30
|
|
40
|
+
# sudo alternatives --set python3 /usr/bin/python3.11
|
|
41
|
+
```
|
|
42
|
+
실행하지 않아도 무방하다. `docs-setup` 등 소비 스킬은 `python3.11`처럼 버전 명시 커맨드를 직접 탐지해 쓰므로 시스템 기본을 바꿀 필요가 없다.
|
|
43
|
+
|
|
44
|
+
## 2. Ubuntu 20.04~24.04
|
|
45
|
+
```bash
|
|
46
|
+
. /etc/os-release
|
|
47
|
+
if [ "${VERSION_ID}" = "20.04" ] || [ "${VERSION_ID}" = "22.04" ]; then
|
|
48
|
+
sudo add-apt-repository -y ppa:deadsnakes/ppa
|
|
49
|
+
sudo apt update
|
|
50
|
+
sudo apt install -y python3.11 python3.11-venv python3.11-dev
|
|
51
|
+
else
|
|
52
|
+
echo "24.04+: 기본 python3(3.12)가 이미 3.11+ 충족. 별도 설치 불요"
|
|
53
|
+
fi
|
|
54
|
+
python3.11 --version 2>/dev/null || python3 --version
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 3. Debian 12 (bookworm)
|
|
58
|
+
```bash
|
|
59
|
+
python3 --version # 기본 3.11.2(이미 충족)·별도 설치 불요(검증만)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 4. macOS (Apple Silicon / Intel)
|
|
63
|
+
```zsh
|
|
64
|
+
brew install python@3.11
|
|
65
|
+
```
|
|
66
|
+
- **keg-only라 PATH 자동 미등록.** `brew --prefix python@3.11`로 실제 경로를 확인해 아래 공통 rc 블록에 추가해야 `python3.11` 커맨드가 잡힌다.
|
|
67
|
+
|
|
68
|
+
## 5. Windows 10/11
|
|
69
|
+
```powershell
|
|
70
|
+
winget install --id Python.Python.3.11 -e
|
|
71
|
+
py -3.11 --version
|
|
72
|
+
```
|
|
73
|
+
> ⚠️ **MS Store 실행 별칭**: PATH에 winget 설치본보다 `WindowsApps` 스텁이 먼저 걸리면 `python`/`python3`가 스토어로 튄다 → 설정 > 앱 > 고급 앱 설정 > 앱 실행 별칭에서 `python.exe`/`python3.exe` 끄기.
|
|
74
|
+
|
|
75
|
+
## pipx·uv 공통 설치 (런타임 확보 후)
|
|
76
|
+
```bash
|
|
77
|
+
PY=$(command -v python3.11 || command -v python3.12 || command -v python3)
|
|
78
|
+
# pipx: Debian/Ubuntu 는 apt 가 1순위. 신선 Debian12·deadsnakes python3.11·Ubuntu24.04 는 인터프리터에
|
|
79
|
+
# pip 가 미번들이라 `$PY -m pip` 가 "No module named pip" 로 실패하고 --break-system-packages 로도 안 된다.
|
|
80
|
+
[ -f /etc/os-release ] && . /etc/os-release
|
|
81
|
+
case "${ID:-}${ID_LIKE:-}" in
|
|
82
|
+
*debian*|*ubuntu*) sudo apt-get install -y pipx ;; # python3-pip 동반, PEP668 무충돌
|
|
83
|
+
*) "$PY" -m pip install --user pipx \
|
|
84
|
+
|| "$PY" -m pip install --user pipx --break-system-packages ;; # RHEL8/macOS: 인터프리터에 pip 번들
|
|
85
|
+
esac
|
|
86
|
+
command -v pipx >/dev/null && pipx ensurepath || "$PY" -m pipx ensurepath
|
|
87
|
+
# macOS 대안: brew install pipx && pipx ensurepath
|
|
88
|
+
|
|
89
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS/Linux 공통, 항상 최신 fetch(버전 고정 불필요)
|
|
90
|
+
|
|
91
|
+
RC_FILE="$HOME/.bashrc" # macOS는 $HOME/.zshrc
|
|
92
|
+
grep -q '### BANKER_PYTHON_BEGIN ###' "$RC_FILE" || cat >> "$RC_FILE" <<'EOF'
|
|
93
|
+
|
|
94
|
+
### BANKER_PYTHON_BEGIN ###
|
|
95
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
96
|
+
### BANKER_PYTHON_END ###
|
|
97
|
+
EOF
|
|
98
|
+
source "$RC_FILE"
|
|
99
|
+
```
|
|
100
|
+
```powershell
|
|
101
|
+
python -m pip install --user pipx
|
|
102
|
+
python -m pipx ensurepath
|
|
103
|
+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 검증 (보고 의무)
|
|
107
|
+
```bash
|
|
108
|
+
python3.11 --version 2>/dev/null || python3 --version
|
|
109
|
+
pipx --version
|
|
110
|
+
uv --version
|
|
111
|
+
```
|
|
112
|
+
4-field 보고: 변경(설치한 python 버전·pipx/uv·rc 마커) / Evidence(위 출력) / 검증(`--version` 전부 OK) / Unknown(PEP668·권한 문제로 일부 미설치 등, 가짜 성공 금지).
|
|
113
|
+
|
|
114
|
+
## 함정
|
|
115
|
+
- **PEP668 externally-managed-environment**(Ubuntu 24.04·Debian 12): 직접 `pip install`이 거부됨 → apt `pipx` 패키지 또는 `--break-system-packages`.
|
|
116
|
+
- **macOS PATH 자동 미등록**: `python@3.11`은 keg-only → `brew --prefix`로 경로 확인 후 수동 추가하지 않으면 "command not found".
|
|
117
|
+
- **Windows MS Store 스텁**: 앱 실행 별칭을 꺼두지 않으면 `python`이 스토어 설치 페이지로 리다이렉트.
|
|
118
|
+
- **RHEL8 python3.6 잔존**: 시스템 기본을 바꾸지 않아도 소비 스킬들이 버전 명시 커맨드로 우회하므로 문제 없음.
|
|
119
|
+
- **pipx vs uv 역할 혼동**: pipx=CLI 도구 격리 설치(`basedpyright`·`ruff` 등), uv=venv/패키지 고속 관리. 상호 대체가 아니라 병행 사용.
|
|
120
|
+
|
|
121
|
+
ARGUMENTS: [--version <x.y>] (없으면 3.11 자동 설치)
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-sandbox
|
|
3
|
+
description: "(banker) 에이전트 샌드박스 공통 기반(Linux bubblewrap+socat+sysctl userns, macOS Seatbelt, Windows AppContainer)을 OS 감지 후 설치(+rust/cargo·git safe.directory 폴드인). 'setup-sandbox'/'샌드박스 설치'/'bubblewrap 설치' 또는 /banker:setup 시 사용."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# setup-sandbox: 에이전트 샌드박스 설치
|
|
7
|
+
|
|
8
|
+
Claude Code 의 sandboxed Bash 도구(`~/.claude/settings.json` 의 `sandbox` 설정)와 Codex/OMX 의 bwrap 기반 샌드박스는 **리눅스에서
|
|
9
|
+
동일한 하부 조건**(bubblewrap·socat·unprivileged user namespace)에 의존한다. 이 스킬이 그 공통 기반을
|
|
10
|
+
OS별로 설치·검증하고, 두 런타임 각각의 설정 계층(Claude=`settings.json`, Codex=`config.toml`)을 배선한다.
|
|
11
|
+
부수적으로 자주 같이 필요한 **rust/cargo**, **git safe.directory**(`$team`/worktree dubious-ownership
|
|
12
|
+
회피)도 폴드인한다. 설치는 **멱등**(이미 있으면 skip·검증만). 답변은 한글(기술 토큰 영문).
|
|
13
|
+
|
|
14
|
+
## 런타임 배선
|
|
15
|
+
- **Claude Code**: Bash 도구 샌드박스를 `~/.claude/settings.json` 의 `sandbox` 객체로 제어한다(정확한 키
|
|
16
|
+
구성은 현재 Claude Code settings 문서로 확인). **네이티브 Windows 미지원**(WSL2 안에서 실행해야 함).
|
|
17
|
+
- **Codex/OMX**: `~/.codex/config.toml` 의 `sandbox_mode`/`[sandbox_workspace_write]`(Python
|
|
18
|
+
replace-or-append + TOML 검증). Windows 는 네이티브 AppContainer 로 이미 지원.
|
|
19
|
+
- 리눅스 bwrap+socat 설치는 **1회로 두 런타임 모두** 혜택 - Claude·Codex 각자 따로 설치할 필요 없다.
|
|
20
|
+
|
|
21
|
+
## 0. 감지 (먼저, 추정 금지)
|
|
22
|
+
```bash
|
|
23
|
+
echo "OS=$(uname -s)"
|
|
24
|
+
[ -f /etc/os-release ] && . /etc/os-release && echo "distro=$ID ${VERSION_ID}"
|
|
25
|
+
for t in bwrap socat cargo; do command -v $t >/dev/null && echo "$t=yes" || echo "$t=no"; done
|
|
26
|
+
sysctl user.max_user_namespaces 2>/dev/null
|
|
27
|
+
sysctl kernel.unprivileged_userns_clone 2>/dev/null
|
|
28
|
+
sysctl kernel.apparmor_restrict_unprivileged_userns 2>/dev/null
|
|
29
|
+
git config --global --get-all safe.directory 2>/dev/null
|
|
30
|
+
[ -f ~/.codex/config.toml ] && grep -n 'sandbox_mode\|network_access' ~/.codex/config.toml
|
|
31
|
+
[ -f ~/.claude/settings.json ] && grep -A3 '"sandbox"' ~/.claude/settings.json
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 1. Linux - bubblewrap + socat + userns sysctl
|
|
35
|
+
### Rocky Linux 8 / RHEL8
|
|
36
|
+
```bash
|
|
37
|
+
sudo dnf -y install epel-release # socat 등은 EPEL 필요(bubblewrap 은 보통 AppStream 에 존재)
|
|
38
|
+
sudo dnf -y install bubblewrap socat
|
|
39
|
+
echo 'user.max_user_namespaces=15000' | sudo tee /etc/sysctl.d/99-userns.conf
|
|
40
|
+
sudo sysctl -p /etc/sysctl.d/99-userns.conf
|
|
41
|
+
```
|
|
42
|
+
### Ubuntu 22.04/24.04
|
|
43
|
+
```bash
|
|
44
|
+
sudo apt-get install -y bubblewrap socat
|
|
45
|
+
echo 'kernel.unprivileged_userns_clone=1' | sudo tee /etc/sysctl.d/99-userns.conf
|
|
46
|
+
sudo sysctl -p /etc/sysctl.d/99-userns.conf
|
|
47
|
+
```
|
|
48
|
+
24.04+ 는 AppArmor 가 bwrap 의 userns 생성을 추가로 막을 수 있다 - 먼저 확인:
|
|
49
|
+
```bash
|
|
50
|
+
sysctl kernel.apparmor_restrict_unprivileged_userns # 1 이면 아래 필요, 0/키없음이면 스킵
|
|
51
|
+
```
|
|
52
|
+
1 이면 **범위를 좁힌 공식 방법**(권장 - bwrap 에만 허용):
|
|
53
|
+
```bash
|
|
54
|
+
sudo tee /etc/apparmor.d/bwrap >/dev/null <<'EOF'
|
|
55
|
+
abi <abi/4.0>,
|
|
56
|
+
include <tunables/global>
|
|
57
|
+
|
|
58
|
+
profile bwrap /usr/bin/bwrap flags=(unconfined) {
|
|
59
|
+
userns,
|
|
60
|
+
include if exists <local/bwrap>
|
|
61
|
+
}
|
|
62
|
+
EOF
|
|
63
|
+
sudo systemctl reload apparmor
|
|
64
|
+
```
|
|
65
|
+
또는 **더 넓게(구식 가이드 방식)**: `kernel.apparmor_restrict_unprivileged_userns=0` 을 같은 sysctl 파일에
|
|
66
|
+
추가 - 시스템 전역으로 완화되므로 가능하면 위 프로필 방식을 우선한다.
|
|
67
|
+
|
|
68
|
+
### Debian 12
|
|
69
|
+
```bash
|
|
70
|
+
sudo apt-get install -y bubblewrap socat
|
|
71
|
+
echo 'kernel.unprivileged_userns_clone=1' | sudo tee /etc/sysctl.d/99-userns.conf
|
|
72
|
+
sudo sysctl -p /etc/sysctl.d/99-userns.conf
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## 2. macOS - Seatbelt(설치 불필요)
|
|
76
|
+
Claude Code·Codex 모두 macOS 내장 `sandbox-exec`(Seatbelt)를 그대로 쓴다. 확인만 한다:
|
|
77
|
+
```bash
|
|
78
|
+
command -v sandbox-exec >/dev/null && echo "Seatbelt 내장 OK"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 3. Windows - 런타임별 격리 방식이 다르다(둘 다 설치 불필요, 개념 차이만 주의)
|
|
82
|
+
- **Codex**: 네이티브 AppContainer(restricted token) 로 이미 격리 지원.
|
|
83
|
+
- **Claude Code**: 샌드박스가 **네이티브 Windows 를 지원하지 않는다** - WSL2 안에서 실행해야 한다(공식
|
|
84
|
+
정책). WSL2 안에서는 위 리눅스 절차(bwrap+socat)를 그대로 적용한다. WSL2 안에서도 `cmd.exe`·
|
|
85
|
+
`powershell.exe`·`/mnt/c/` 하위 바이너리는 호출 불가(호스트로 넘어가는 유닉스 소켓을 샌드박스가 차단) -
|
|
86
|
+
꼭 필요하면 `excludedCommands` 에 등록해 샌드박스 밖에서 실행한다.
|
|
87
|
+
|
|
88
|
+
## 4. 폴드인 - rust/cargo
|
|
89
|
+
```bash
|
|
90
|
+
command -v cargo >/dev/null || curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
|
91
|
+
source "$HOME/.cargo/env" 2>/dev/null
|
|
92
|
+
cargo --version
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## 5. 폴드인 - git safe.directory ($team/worktree)
|
|
96
|
+
공유 워크트리·컨테이너 등 소유자가 다른 repo 에서 git 이 "dubious ownership" 로 명령을 거부하는 문제를
|
|
97
|
+
미리 막는다(OMC/OMX `$team` 병렬 워커가 특히 걸린다):
|
|
98
|
+
```bash
|
|
99
|
+
git config --global --add safe.directory '*'
|
|
100
|
+
git config --global --get-all safe.directory
|
|
101
|
+
```
|
|
102
|
+
`'*'` 는 범위가 넓다 - 통제된 팀/컨테이너 환경을 전제한다(불특정 다중 사용자 공유 서버라면 특정 경로만
|
|
103
|
+
등록하는 편을 고려).
|
|
104
|
+
|
|
105
|
+
## 6. Claude Code 배선
|
|
106
|
+
Claude Code 의 Bash 도구 샌드박스는 `~/.claude/settings.json` 의 `sandbox` 객체로 설정한다(대화형 슬래시
|
|
107
|
+
커맨드가 아니라 설정·CLI 플래그 기반). 위 §1 에서 설치한 bubblewrap/socat 이 그 하부 조건이다:
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"sandbox": {
|
|
111
|
+
"enabled": true,
|
|
112
|
+
"failIfUnavailable": false
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
- `enabled`/`failIfUnavailable` 은 확인된 키다. `sandbox` 객체는 이 외에도 `network`·`excludedCommands`·
|
|
117
|
+
`autoAllowBashIfSandboxed` 등 하위 키를 가진다 - **정확한 스키마·기본값은 반드시 현재 Claude Code
|
|
118
|
+
settings 문서(`code.claude.com/docs`)로 확인**한 뒤 적용한다(버전에 따라 키가 바뀔 수 있어 추정 금지).
|
|
119
|
+
- `failIfUnavailable: true` 로 두면 의존성 누락 시 자동 폴백 없이 바로 실패한다 - 관리형 배포에만 권장.
|
|
120
|
+
|
|
121
|
+
## 7. Codex 배선
|
|
122
|
+
`tomllib` 는 Python **3.11+** 표준 라이브러리다 - RHEL8/Rocky8 등은 기본 `python3` 가 3.6 인 경우가
|
|
123
|
+
흔하므로(예: `docs-setup` 이 다루는 것과 같은 함정) 먼저 3.11+ 인터프리터를 고른다:
|
|
124
|
+
```bash
|
|
125
|
+
PY="$(command -v python3.12 || command -v python3.11 || command -v python3)"
|
|
126
|
+
"$PY" -c "import tomllib" 2>/dev/null || echo "⚠ tomllib 없음 - Python 3.11+ 설치 후 재시도(setup-python 참고)"
|
|
127
|
+
```
|
|
128
|
+
그 `$PY` 로 패치한다. `sandbox_mode` 치환은 **첫 `[` 테이블 헤더 이전(root 영역)만** 대상으로 삼아
|
|
129
|
+
`[profiles.*]` 하위의 같은 이름 override(예: 프로필별 `read-only` 강제)를 절대 건드리지 않는다(멱등):
|
|
130
|
+
```bash
|
|
131
|
+
"$PY" <<'EOF'
|
|
132
|
+
import re
|
|
133
|
+
from pathlib import Path
|
|
134
|
+
import tomllib
|
|
135
|
+
|
|
136
|
+
CFG = Path.home() / ".codex" / "config.toml"
|
|
137
|
+
CFG.parent.mkdir(parents=True, exist_ok=True)
|
|
138
|
+
text = CFG.read_text(encoding="utf-8") if CFG.exists() else ""
|
|
139
|
+
if text:
|
|
140
|
+
tomllib.loads(text) # 사전 검증
|
|
141
|
+
|
|
142
|
+
# root 영역 = 첫 '[' 테이블 헤더 이전까지만 - [profiles.*] 하위 동명 키는 손대지 않는다
|
|
143
|
+
m = re.search(r'(?m)^\[', text)
|
|
144
|
+
cut = m.start() if m else len(text)
|
|
145
|
+
head, tail = text[:cut], text[cut:]
|
|
146
|
+
|
|
147
|
+
if re.search(r'(?m)^sandbox_mode\s*=', head):
|
|
148
|
+
head = re.sub(r'(?m)^sandbox_mode\s*=.*$', 'sandbox_mode = "workspace-write"', head, count=1)
|
|
149
|
+
else:
|
|
150
|
+
head = 'sandbox_mode = "workspace-write"\n' + head
|
|
151
|
+
|
|
152
|
+
text = head + tail
|
|
153
|
+
if "[sandbox_workspace_write]" not in text:
|
|
154
|
+
text += '\n[sandbox_workspace_write]\nnetwork_access = true\n'
|
|
155
|
+
|
|
156
|
+
tomllib.loads(text) # 패치 후 재검증
|
|
157
|
+
CFG.write_text(text, encoding="utf-8")
|
|
158
|
+
print("✓ sandbox_mode=workspace-write, network_access=true")
|
|
159
|
+
EOF
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## 검증 (보고 의무)
|
|
163
|
+
```bash
|
|
164
|
+
bwrap --version 2>/dev/null || echo "bwrap 없음"
|
|
165
|
+
command -v socat >/dev/null && echo "socat OK" || echo "socat 없음(Claude sandbox 네트워크 프록시 실패 가능)"
|
|
166
|
+
# 존재만이 아니라 실제 userns 동작까지 확인
|
|
167
|
+
bwrap --unshare-user --ro-bind / / true && echo "✓ bwrap userns 동작" || echo "✗ 실패 - sysctl 재확인"
|
|
168
|
+
cargo --version 2>/dev/null || echo "cargo 없음"
|
|
169
|
+
git config --global --get-all safe.directory
|
|
170
|
+
|
|
171
|
+
grep -n 'sandbox_mode\|network_access' ~/.codex/config.toml
|
|
172
|
+
PY="$(command -v python3.12 || command -v python3.11 || command -v python3)" # tomllib=3.11+
|
|
173
|
+
"$PY" -c "import tomllib; tomllib.loads(open('$HOME/.codex/config.toml', encoding='utf-8').read()); print('✓ TOML 유효')"
|
|
174
|
+
timeout 30 codex sandbox -- echo sandbox-ok # Codex 자체 샌드박스 러너로 실제 실행 확인
|
|
175
|
+
|
|
176
|
+
python3 -m json.tool ~/.claude/settings.json >/dev/null && echo "settings.json 유효"
|
|
177
|
+
# Claude Code sandbox 설정은 settings.json 로 확인(위 json.tool). 실제 동작은 세션에서 Bash 도구 실행으로 관찰
|
|
178
|
+
```
|
|
179
|
+
4-field 보고: 변경(설치 패키지·sysctl 파일·config.toml/settings.json 변경분) / Evidence(위 출력) /
|
|
180
|
+
검증(bwrap 실제 동작·`codex sandbox` 성공) / Unknown(root 권한 없어 sysctl 미적용, Claude settings.json
|
|
181
|
+
`sandbox` 스키마는 문서 재확인 필요 등).
|
|
182
|
+
|
|
183
|
+
## 함정
|
|
184
|
+
- **sysctl 은 root 필요**: sudo 불가 환경이면 현재 값 보고 후 관리자에게 요청한다(가짜 성공 금지).
|
|
185
|
+
- **EL8 커널이 오래됨**(4.18): 기본 `user.max_user_namespaces` 가 낮거나 0 인 경우가 흔하다 - 감지 없이
|
|
186
|
+
이미 충분하다고 가정하지 않는다.
|
|
187
|
+
- **Ubuntu 24.04+ AppArmor**: bwrap 프로필(좁음) 또는 sysctl 전역 해제(넓음) 중 하나가 필요하다 - 프로필
|
|
188
|
+
방식을 우선한다.
|
|
189
|
+
- **Windows 비대칭**: Codex 는 네이티브 AppContainer 로 되지만 **Claude Code 샌드박스는 WSL2 없이 안
|
|
190
|
+
된다** - 둘을 같은 것으로 안내하지 않는다.
|
|
191
|
+
- **socat 누락**: bwrap 만 있고 socat 이 없으면 Claude 샌드박스의 네트워크 프록시 릴레이가 동작하지
|
|
192
|
+
않을 수 있다(socat 이 그 릴레이를 담당).
|
|
193
|
+
- **tomllib 는 Python 3.11+ 전용**: RHEL8/Rocky8 기본 `python3`(3.6)로 그대로 돌리면
|
|
194
|
+
`ModuleNotFoundError` - 위 `$PY` 선택 스니펫을 반드시 거친다.
|
|
195
|
+
- **config.toml 패치 범위**: `sandbox_mode` 치환은 첫 `[` 헤더 이전(root)만 대상이라 `[profiles.*]`
|
|
196
|
+
하위 override 는 건드리지 않는다 - 그래도 패치 후 `grep -n sandbox_mode ~/.codex/config.toml` 로
|
|
197
|
+
한 번 눈으로 확인하는 습관을 권장한다.
|
|
198
|
+
- **git safe.directory `'*'` 범위**: 통제된 팀/컨테이너 환경을 전제한다 - 불특정 다중 사용자 공유 서버엔
|
|
199
|
+
과하다.
|
|
200
|
+
- **rustup 은 셸 rc 를 건드린다**: 새 셸을 열거나 `source ~/.cargo/env` 해야 `cargo` 가 바로 잡힌다.
|
|
201
|
+
|
|
202
|
+
ARGUMENTS: [--skip-cargo] [--skip-git-safe] (없으면 OS 감지 기반 bwrap/socat+sysctl 설치부터 Codex config 패치까지 전부 수행)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: setup-stitch
|
|
3
|
-
description: "Stitch(Google 디자인 생성) MCP 프록시를
|
|
2
|
+
name: setup-stitch
|
|
3
|
+
description: "(banker) Stitch(Google 디자인 생성) MCP 프록시를 claude mcp add(Codex는 codex mcp add)로 등록(시크릿 미커밋). 'setup-stitch'/'stitch 설치'/'stitch mcp' 또는 /banker:setup 시 사용."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# setup-stitch
|
|
6
|
+
# setup-stitch — Stitch MCP 프록시 등록
|
|
7
7
|
|
|
8
8
|
Stitch(withgoogle) 디자인 생성 MCP 를 프록시로 Claude Code 에 붙인다. Node(npx) 필요.
|
|
9
9
|
**★시크릿(API key)은 사용자만 입력·환경변수로 — 채팅/로그/커밋에 절대 노출 금지.** 답변은 한글.
|
|
@@ -29,6 +29,13 @@ claude mcp list # stitch: … - ✔ Connected
|
|
|
29
29
|
```
|
|
30
30
|
키를 평문 파일에 두기 싫으면 `STITCH_API_KEY` 를 `~/.bashrc`(비커밋) 등에 export 하고 스크립트는 참조만.
|
|
31
31
|
|
|
32
|
+
**Codex CLI:** 같은 프록시 스크립트를 Codex에도 붙인다 — `claude mcp` 대신 `codex mcp` 를 쓴다.
|
|
33
|
+
```bash
|
|
34
|
+
codex mcp remove stitch 2>/dev/null
|
|
35
|
+
codex mcp add stitch -- ~/bin/stitch-proxy.sh
|
|
36
|
+
codex mcp list # stitch 연결 확인
|
|
37
|
+
```
|
|
38
|
+
|
|
32
39
|
## 2. windows
|
|
33
40
|
`~/bin` 셸 스크립트 대신 **WSL2** 권장(위 절차 그대로). native 면 `.cmd` 래퍼에 `set STITCH_API_KEY=…` 후
|
|
34
41
|
`npx -y @_davideast/stitch-mcp proxy` 실행, `claude mcp add stitch -- cmd /c <래퍼>.cmd`.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-tmux
|
|
3
|
+
description: "(banker) OMC team·worktree 세션과 Codex OMX $team·HUD 가 요구하는 tmux(Windows는 psmux)를 OS 감지 후 설치·소스빌드(Rocky8 3.6a). 'setup-tmux'/'tmux 설치'/'psmux 설치' 또는 /banker:setup 시 사용."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# setup-tmux: tmux(Windows는 psmux) 설치
|
|
7
|
+
|
|
8
|
+
Claude Code 의 OMC `team`/worktree 병렬 세션과 Codex 의 OMX `$team`/HUD 는 전부 tmux(Windows 는
|
|
9
|
+
psmux) 세션 **안에서 실행되는 것을 전제**한다. 이 스킬은 OS 를 감지해 알맞은 경로로 tmux 를
|
|
10
|
+
설치·검증한다. 설치는 **멱등**(이미 충족하면 skip·검증만). 답변은 한글(기술 토큰 영문).
|
|
11
|
+
|
|
12
|
+
## 런타임 배선
|
|
13
|
+
- **Claude Code**: OMC 의 `team`/worktree 세션(패널 분할·병렬 워커)은 tmux 안에서 실행된다.
|
|
14
|
+
- **Codex**: OMX 의 `$team`/HUD 는 tmux(또는 psmux) 세션 **안에서 실행이 필수**다. 세션 밖에서
|
|
15
|
+
실행하면 `outside-tmux` surface 로 표시되고 `$team`/HUD 가 동작하지 않는다 - 에러가 두드러지지
|
|
16
|
+
않아 조용히 실패한 것처럼 보일 수 있다.
|
|
17
|
+
- **공통**: worker 의 작업 디렉터리가 dubious-ownership 으로 잡히면 worktree 생성 자체가 막힌다 →
|
|
18
|
+
`git config --global --add safe.directory '*'` 를 함께 설정한다(§2).
|
|
19
|
+
|
|
20
|
+
## 0. 감지 (먼저 - 추정 금지)
|
|
21
|
+
```bash
|
|
22
|
+
command -v tmux >/dev/null && tmux -V || echo "tmux: 미설치"
|
|
23
|
+
[ -f /etc/os-release ] && . /etc/os-release && echo "distro=$ID ${VERSION_ID}"
|
|
24
|
+
type -a tmux 2>/dev/null # Rocky8: PATH 상 여러 tmux 가 있을 수 있음 - 순서 확인
|
|
25
|
+
```
|
|
26
|
+
Windows(PowerShell):
|
|
27
|
+
```powershell
|
|
28
|
+
Get-Command tmux -ErrorAction SilentlyContinue
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 1. OS별 설치
|
|
32
|
+
|
|
33
|
+
### Rocky Linux 8 / RHEL8 - 소스빌드 필수
|
|
34
|
+
시스템 기본 `tmux` 는 2.7 이며 OMX `--madmax` 모드에서 **hang** 한다(실측). EPEL 도 3.x 를 제공하지
|
|
35
|
+
않는다 → **3.6a 를 소스에서 빌드**한다.
|
|
36
|
+
```bash
|
|
37
|
+
# 이미 3.6a+ 면 재빌드 불필요(멱등)
|
|
38
|
+
/usr/local/bin/tmux -V 2>/dev/null | grep -qE '3\.[6-9]|[4-9]\.' && echo "이미 충족 - skip" || {
|
|
39
|
+
sudo dnf install -y libevent-devel ncurses-devel gcc make byacc
|
|
40
|
+
cd /tmp
|
|
41
|
+
curl -fLO https://github.com/tmux/tmux/releases/download/3.6a/tmux-3.6a.tar.gz
|
|
42
|
+
tar xzf tmux-3.6a.tar.gz && cd tmux-3.6a
|
|
43
|
+
./configure && make && sudo make install # /usr/local/bin/tmux 로 설치됨
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
> **`/usr/bin/tmux`(2.7)를 지우지 않는다** - PATH 상 `/usr/local/bin` 이 먼저 오는지만 확인해
|
|
47
|
+
> 우회한다(`type -a tmux` 첫 줄이 `/usr/local/bin/tmux` 인지 확인).
|
|
48
|
+
> ⚠️ 3.6a 는 이 시점의 버전 고정값이다. 최신 안정판은 https://github.com/tmux/tmux/releases 에서
|
|
49
|
+
> 재확인 후 필요하면 `TMUX_VER` 를 바꿔 교체한다.
|
|
50
|
+
|
|
51
|
+
### Ubuntu / Debian - apt 기본으로 충분
|
|
52
|
+
```bash
|
|
53
|
+
sudo apt-get update && sudo apt-get install -y tmux
|
|
54
|
+
tmux -V
|
|
55
|
+
```
|
|
56
|
+
Ubuntu 22.04(3.2a)·24.04(3.4)·Debian 12(3.3a) 모두 OMX 요구 버전을 충족한다 - 소스빌드 불필요.
|
|
57
|
+
|
|
58
|
+
### macOS
|
|
59
|
+
```bash
|
|
60
|
+
brew install tmux
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Windows - psmux
|
|
64
|
+
Windows 에는 tmux 가 없어 호환 레이어인 psmux 를 쓴다.
|
|
65
|
+
```powershell
|
|
66
|
+
winget install --id marlocarlo.psmux -e
|
|
67
|
+
tmux -V # psmux 가 tmux 커맨드 alias 를 자동 등록
|
|
68
|
+
```
|
|
69
|
+
- psmux 는 tmux 명령을 상당 부분 흉내내지만 **100% 호환은 아니다** - 이상 동작 시 psmux 자체
|
|
70
|
+
버전과 재현 여부를 먼저 의심한다.
|
|
71
|
+
- `$team`/HUD 를 쓰려면 psmux 세션 **안에서** `omx` 를 실행해야 한다: `tmux new-session -s codex`
|
|
72
|
+
로 세션을 연 뒤 그 안에서 `omx --madmax --xhigh`.
|
|
73
|
+
|
|
74
|
+
## 2. 공통 - dubious-ownership 가드
|
|
75
|
+
```bash
|
|
76
|
+
git config --global --add safe.directory '*'
|
|
77
|
+
```
|
|
78
|
+
worker 가 `/tmp` 등 소유권이 모호한 경로에서 실행되면 이 설정 없이는 worktree 생성이 막힌다.
|
|
79
|
+
|
|
80
|
+
## 검증 (보고 의무)
|
|
81
|
+
```bash
|
|
82
|
+
tmux -V # 존재 확인 (>=3.2; Rocky8 은 3.6a)
|
|
83
|
+
type -a tmux 2>/dev/null | head -1 # Rocky8: 첫 줄이 /usr/local/bin/tmux 여야 함
|
|
84
|
+
tmux new-session -d -s _t && tmux kill-session -t _t && echo "tmux 실동작 OK"
|
|
85
|
+
git config --global --get safe.directory
|
|
86
|
+
```
|
|
87
|
+
Windows: `tmux -V`(psmux 버전) + `Get-Command tmux`.
|
|
88
|
+
|
|
89
|
+
4-field 보고: 변경(설치 방법·버전·safe.directory 여부) / Evidence(위 출력) / 검증(new-session→
|
|
90
|
+
kill-session 성공) / Unknown(sudo 권한 없어 소스빌드 불가 등).
|
|
91
|
+
|
|
92
|
+
## 함정
|
|
93
|
+
- **Rocky8 빌드 의존성 누락**: `libevent-devel`/`ncurses-devel`/`byacc` 없이 `./configure` 하면
|
|
94
|
+
실패 → 위 dnf 목록을 먼저 설치.
|
|
95
|
+
- **PATH 우선순위**: `/usr/local/bin/tmux`(3.6a)가 `/usr/bin/tmux`(2.7)보다 먼저 잡히지 않으면
|
|
96
|
+
여전히 구버전이 실행된다 → `type -a tmux` 로 순서 확인, 필요하면 `~/.bashrc` PATH 앞쪽에 추가.
|
|
97
|
+
- **psmux 비호환**: 일부 tmux 전용 스크립트·키바인딩이 psmux 에서 다르게 동작할 수 있다 - 완전한
|
|
98
|
+
대체품이 아니라는 전제로 접근.
|
|
99
|
+
- **세션 밖 실행**: tmux/psmux 세션 밖에서 `omx --madmax`/`$team`/HUD 를 실행하면 `outside-tmux`
|
|
100
|
+
로 표시되고 기능이 동작하지 않는다 - 실패가 눈에 띄지 않을 수 있으므로 항상 세션 안에서
|
|
101
|
+
실행했는지 먼저 확인한다.
|
|
102
|
+
- **dubious-ownership 누락**: `safe.directory` 미설정 시 worker 가 조용히 worktree 를 못 만들고
|
|
103
|
+
idle 상태로만 보일 수 있다.
|
|
104
|
+
|
|
105
|
+
ARGUMENTS: 없음 (OS 자동감지 후 설치 - Rocky8 은 소스빌드, 그 외는 패키지매니저)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: smart-compact
|
|
3
|
+
description: "(banker) 컨텍스트 임계(기본 50%) 초과 시 append-wiki→ready-compact→compact-copy 자동 실행 + /copy·/compact·paste 유저 핸드오프 게이트. 'smart-compact' 활성화 / '--cancel' 해제."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# smart-compact — 컨텍스트 위생 자동 게이트
|
|
7
|
+
|
|
8
|
+
긴 세션에서 컨텍스트가 임계(기본 **50%**)를 넘으면, compaction 전에 상태를 안전하게 보존하는
|
|
9
|
+
리추얼을 **자동 발동**한다: `append-wiki` → `ready-compact` → `compact-copy` → *(유저)* `/copy`
|
|
10
|
+
→ `/compact` → paste. `smart-compact` 로 무장, `smart-compact --cancel` 로 해제한다.
|
|
11
|
+
|
|
12
|
+
## ⚠️ 정직한 실현 한계 (Claude Code 실측)
|
|
13
|
+
"컨텍스트 50%에서 완전 무인 자동"은 **부분만 가능**하다 — 근거:
|
|
14
|
+
- **감지**: 컨텍스트 사용률은 **statusLine stdin** 의 `context_window.used_percentage` 로만 실시간
|
|
15
|
+
노출된다(hook은 이 값을 못 받음; auto-compact은 ~95%에서만, 50% 이벤트 없음). → statusLine으로
|
|
16
|
+
**정확히 50% 감지 가능**.
|
|
17
|
+
- **자동 실행 가능(어시스턴트)**: `append-wiki` · `ready-compact` · `compact-copy` — 스킬/도구
|
|
18
|
+
작업이라 어시스턴트가 수행.
|
|
19
|
+
- **자동 불가(TUI 전용)**: `/copy` · `/compact` · **paste** 는 인터랙티브 TUI 동작이라 hook·스킬이
|
|
20
|
+
구동할 수 없다(hook은 슬래시명령 호출 불가, `additionalContext` 주입만 가능). → **이 3단은 유저가
|
|
21
|
+
실행**한다.
|
|
22
|
+
|
|
23
|
+
따라서 smart-compact의 자동화 천장 = **감지(정확) + 준비 자동 실행 + TUI 3단 유저 핸드오프**.
|
|
24
|
+
완전 hands-off를 약속하지 않는다(그건 별도 외부 데몬이 새 세션을 스폰해야 하고, 메인 세션이 idle일
|
|
25
|
+
때만·클립보드 보장 없이 취약). smart-compact은 **가장 신뢰 가능한 최대 자동화**를 택한다.
|
|
26
|
+
|
|
27
|
+
## 메커니즘 (무장 시 설치)
|
|
28
|
+
런타임 인식 — Claude Code 경로가 정밀, Codex는 신호 노출이 불확실(아래 참조).
|
|
29
|
+
|
|
30
|
+
**Claude Code (OMC):**
|
|
31
|
+
1. **statusLine 래퍼(compose-safe)**: 기존 `statusLine.command`(예: OMC HUD)를 **보존**하고, 그것을
|
|
32
|
+
호출해 출력을 그대로 통과시킨 뒤, stdin의 `context_window.used_percentage` 를 파싱한다. 임계 이상이면
|
|
33
|
+
신호 파일 `~/.claude/.smart-compact-signal`(uid별; `id -u`)에 timestamp를 쓰고 statusLine에
|
|
34
|
+
`⚠ smart-compact ARMED (NN%)` 를 덧붙인다. **기존 statusLine을 덮어쓰지 말고 감싼다.**
|
|
35
|
+
2. **hook 브리지**: `UserPromptSubmit`(또는 `PreToolUse`) hook이 신호 파일을 읽어 무장·미처리 상태면
|
|
36
|
+
`additionalContext` 로 "smart-compact: 컨텍스트 ≥임계 — 위생 체인 실행" 을 주입한다(hook은 명령을
|
|
37
|
+
못 부르므로 어시스턴트에게 **지시만** 한다).
|
|
38
|
+
3. **게이트 동작(어시스턴트)**: 주입을 받으면 자동파트 실행 → 이어 유저에게 TUI 3단을 정확한 명령으로 안내.
|
|
39
|
+
|
|
40
|
+
**Codex (OMX):**
|
|
41
|
+
- Codex가 statusline/hook에 컨텍스트%를 노출하는지 **미확인**(문서 부재). 노출되면 위와 동형으로 구성
|
|
42
|
+
(`~/.codex` 경로·OMX hook). 미노출이면 **휴리스틱 폴백**: 어시스턴트가 스스로 컨텍스트 압박을 감지해
|
|
43
|
+
체인을 제안하고, 유저가 트리거. 준비 스킬은 banker 것이 양 런타임 동일(아래).
|
|
44
|
+
|
|
45
|
+
## 게이트 체인
|
|
46
|
+
무장 후 임계 초과가 감지되면 순서대로:
|
|
47
|
+
|
|
48
|
+
1. **`append-wiki`** — 이번 작업의 비자명 지식을 wiki에 적재(휘발 방지). *(banker `append_wiki`, both)*
|
|
49
|
+
2. **`ready-compact`** — resume 프롬프트 + 내구 메모리 기록. *(banker `ready-compact`, both)*
|
|
50
|
+
3. **`compact-copy`** — resume 프롬프트-only 로 최종 메시지 셰이핑(response.md). *(banker `compact-copy`, both)*
|
|
51
|
+
4. *(유저 · TUI)* **`/copy`** → **`/compact`** → **paste**(복사된 resume 프롬프트 입력).
|
|
52
|
+
|
|
53
|
+
1~3은 어시스턴트가 자동 수행. 4는 어시스턴트가 **정확한 명령을 제시**하고 유저가 실행한다.
|
|
54
|
+
(Claude=`/banker:append_wiki`·`/banker:ready-compact`·`/banker:compact-copy`,
|
|
55
|
+
Codex=`$banker-append_wiki`·`$banker-ready-compact`·`$banker-compact-copy`; `/copy`·compaction은 양쪽 TUI 내장.)
|
|
56
|
+
|
|
57
|
+
## 활성화 (idempotent · compose-safe)
|
|
58
|
+
`smart-compact [--threshold N]` (기본 N=50):
|
|
59
|
+
1. `~/.claude/settings.json`(Codex는 `~/.codex/`)의 기존 `statusLine`·hook 설정을 **읽어 백업**
|
|
60
|
+
(`~/.claude/.smart-compact-prev.json`).
|
|
61
|
+
2. statusLine 래퍼 스크립트를 설치하고 `statusLine.command` 를 래퍼로 교체(래퍼가 이전 command를 위임 호출).
|
|
62
|
+
3. `UserPromptSubmit` hook 항목을 **추가**(기존 hook 보존, 중복 방지 — 이미 있으면 skip).
|
|
63
|
+
4. 임계값을 래퍼에 기록. 무장 완료를 보고.
|
|
64
|
+
|
|
65
|
+
**멱등·안전 불변식**: 두 번 활성화해도 중복 설치 안 됨. 기존 statusLine/hook을 절대 삭제·덮어쓰지
|
|
66
|
+
않고 **감싸거나 추가만** 한다(uid는 `id -u` 로 계산, 하드코딩 금지).
|
|
67
|
+
|
|
68
|
+
## 해제
|
|
69
|
+
`smart-compact --cancel`:
|
|
70
|
+
1. 백업(`~/.claude/.smart-compact-prev.json`)에서 원래 `statusLine`·hook 설정 **복원**.
|
|
71
|
+
2. 래퍼 스크립트·신호 파일·백업 제거.
|
|
72
|
+
3. 무장 해제를 보고. (백업이 없으면 smart-compact가 추가한 항목만 안전 제거.)
|
|
73
|
+
|
|
74
|
+
## 함정
|
|
75
|
+
- **statusLine 덮어쓰기 금지** — OMC HUD 등 기존 statusLine을 감싸라(복원 가능하게 백업).
|
|
76
|
+
- **완전 자동 과대약속 금지** — `/copy`·`/compact`·paste는 TUI 전용, 유저 핸드오프임을 항상 명시.
|
|
77
|
+
- **uid 하드코딩 금지** — 신호/경로는 `id -u` 로.
|
|
78
|
+
- **hook은 명령을 못 부른다** — `additionalContext` 로 어시스턴트에게 지시할 뿐, 스스로 체인을 실행하지 못함.
|
|
79
|
+
- **Codex 신호 미확인** — 노출 안 되면 휴리스틱 폴백으로 정직히 degrade(50% 정밀 트리거 미보장).
|
|
80
|
+
|
|
81
|
+
ARGUMENTS: [--threshold N] | --cancel (없으면 기본 임계 50%로 무장)
|