v4.3.20: 미커밋 자산 일괄 정리 + 유저 워크스페이스/세션토큰 gitignore

그동안 쌓여 있던 미커밋 파일들을 정리. 소스·자산만 올리고, 개인 데이터와
런타임 상태는 gitignore로 차단.

추가된 자산:
- web-ui/audiomass, web-ui/wavacity — 자체 호스팅 오디오 에디터
- web-ui/drums — 드럼 샘플
- wol-gate — WOL 프록시 컨테이너(Dockerfile + server.js)
- glm-1m-fix — GLM 1M 컨텍스트 설치 스크립트(linux/windows)
- RENODE_FIXES_SUMMARY*.md, CCTV정보_서울특별시.csv, .claude/plans

수정:
- edge_tts_synth.py: rate 인자 추가(말하기 속도 조절)
- .smallclaw/config.json: google(gemini) provider 등록 — 키는 vault 참조
- assets/SmallClaw*.png 삭제분 반영

gitignore (중요):
- .smallclaw/users/*/workspace/ 전체 차단. 기존 패턴이 memory/uploads와 일부
  확장자만 막아서 detective/(고소장·통화녹취·의사소견서·가족관계증명서),
  generated-media/, music/, pptx/ 등 앱 생성 개인 데이터 403MB가 노출돼 있었음
- .smallclaw/active-sessions.json 차단 — 살아있는 bearer 토큰과 admin 역할이
  평문으로 들어있어 커밋 시 게이트웨이 관리자 자격증명이 그대로 공개됨
- google-usage.json, config.json.bak-*, workspace/memory·weather-maps·
  task_result_*, voice/ 등 런타임 상태도 함께 차단

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
kim
2026-07-29 14:55:37 +09:00
co-authored by Claude Opus 5
parent 8359901cac
commit e85ebe6608
127 changed files with 122199 additions and 7 deletions
+124
View File
@@ -0,0 +1,124 @@
#!/bin/bash
# GLM context 보정 패치 v2 (Linux) — 옵션 3: 모델별 런타임 env 주입
#
# 설치 파일:
# ~/.claude/statusline-glm-fix.js stdin 보정 wrapper (표시 fallback)
# ~/.claude/launch-claude.sh 모델별 context 를 ollama에서 읽어
# CLAUDE_CODE_MAX_CONTEXT_TOKENS 로 주입하고 exec
# settings.json:
# statusLine -> statusline-glm-fix.js
# env.CLAUDE_CODE_MAX_CONTEXT_TOKENS 제거 (launch-claude.sh 가 모델별로 주입)
#
# 사용: bash install-linux.sh
# 이후 claude 실행: bash ~/.claude/launch-claude.sh (ollama launch claude 대신)
# 되돌리기: settings.json statusLine.command 를 원래 dist/index.js 경로로.
set -euo pipefail
HC="$HOME/.claude"
WRAPPER="$HC/statusline-glm-fix.js"
LAUNCH="$HC/launch-claude.sh"
SETTINGS="$HC/settings.json"
PATCHER="$(mktemp -t glm-patch.XXXXXX.js)"
trap 'rm -f "$PATCHER"' EXIT
mkdir -p "$HC"
# --- 1) statusline wrapper ---
cat > "$WRAPPER" <<'WRAPPER_EOF'
// Thin statusline wrapper: Claude Code reports context_window_size=200000 for
// non-Anthropic models like glm-5.2:cloud, but GLM's real context window is 1M.
// Patch the stdin before forwarding to the real claude-dashboard, so it shows
// e.g. "0/1M" instead of "0/200K". Leaves the plugin cache untouched.
// (launch-claude.sh 가 모델별 env를 주입하면 이 wrapper는 대부분 no-op 이지만,
// env 없이 그냥 실행한 경우의 표시 fallback 역할.)
// To revert: set settings.json statusLine.command back to the dist/index.js path.
const { spawn } = require('child_process');
const fs = require('fs');
const os = require('os');
const path = require('path');
function resolveDashboard() {
const base = path.join(os.homedir(), '.claude/plugins/cache/claude-dashboard/claude-dashboard');
let dirs;
try { dirs = fs.readdirSync(base); } catch { dirs = []; }
const ver = dirs.filter((d) => /^\d+\.\d+\.\d+$/.test(d)).sort((a, b) => {
const pa = a.split('.').map(Number), pb = b.split('.').map(Number);
for (let i = 0; i < 3; i++) if (pa[i] !== pb[i]) return pa[i] - pb[i];
return 0;
}).pop();
return ver ? path.join(base, ver, 'dist/index.js') : path.join(base, '1.30.0/dist/index.js');
}
const DASHBOARD = resolveDashboard();
let raw = '';
process.stdin.setEncoding('utf8');
process.stdin.on('data', (c) => { raw += c; });
process.stdin.on('end', () => {
let payload = raw;
try {
const json = JSON.parse(raw);
const cw = json?.context_window;
const size = cw?.context_window_size;
const modelId = String(json?.model?.id || '').toLowerCase();
if (modelId.includes('glm') && size === 200000) {
cw.context_window_size = 1000000;
const usage = cw.current_usage;
if (usage) {
const input = (usage.input_tokens || 0) + (usage.cache_creation_input_tokens || 0) + (usage.cache_read_input_tokens || 0);
cw.used_percentage = Math.round((input / 1000000) * 100);
if (typeof cw.remaining_percentage === 'number') cw.remaining_percentage = 100 - cw.used_percentage;
}
payload = JSON.stringify(json);
}
} catch { /* pass through */ }
const child = spawn('node', [DASHBOARD], { stdio: ['pipe', 'inherit', 'inherit'] });
child.stdin.write(payload);
child.stdin.end();
});
WRAPPER_EOF
# --- 2) launch-claude.sh ---
cat > "$LAUNCH" <<'LAUNCH_EOF'
#!/bin/bash
# claude를 모델별 실제 context window에 맞춰 실행.
# config.json 의 claude 모델 -> ollama show 로 context length -> CLAUDE_CODE_MAX_CONTEXT_TOKENS 주입 -> exec.
# compact 트리거 = min(AUTO_COMPACT_WINDOW, 모델 context) 이라 MAX_CONTEXT_TOKENS 만 주면 됨.
set -euo pipefail
CFG="$HOME/.ollama/config.json"
[ ! -f "$CFG" ] && { echo "⚠️ $CFG 없음 — env 없이 실행" >&2; exec ollama launch claude; }
MODEL=$(node -e 'const fs=require("fs"),os=require("os");const p=os.homedir()+"/.ollama/config.json";const d=JSON.parse(fs.readFileSync(p,"utf8"));const m=(d.integrations&&d.integrations.claude&&d.integrations.claude.models)||[];process.stdout.write(m[0]||"");' 2>/dev/null || true)
if [ -z "$MODEL" ]; then echo "⚠️ claude 모델 못 읽음 — env 없이 실행" >&2; exec ollama launch claude; fi
CTX=$(ollama show "$MODEL" 2>/dev/null | awk '/context length/{print $3; exit}' || true)
if ! [[ "$CTX" =~ ^[0-9]+$ ]] || [ "$CTX" -eq 0 ]; then echo "⚠️ '$MODEL' context length 못 읽음 — env 없이 실행" >&2; exec ollama launch claude; fi
echo "▶ model=$MODEL context=$CTX → CLAUDE_CODE_MAX_CONTEXT_TOKENS=$CTX" >&2
export CLAUDE_CODE_MAX_CONTEXT_TOKENS="$CTX"
exec ollama launch claude
LAUNCH_EOF
chmod +x "$LAUNCH"
# --- 3) settings.json 패치: statusLine 교체 + 정적 env 제거 ---
cat > "$PATCHER" <<'PATCHER_EOF'
const fs = require('fs');
const settingsPath = process.argv[2];
const wrapperPath = process.argv[3];
const s = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
const beforeSL = s.statusLine && s.statusLine.command;
const beforeEnv = s.env && s.env.CLAUDE_CODE_MAX_CONTEXT_TOKENS;
s.statusLine = { type: 'command', command: 'node ' + wrapperPath };
// launch-claude.sh 가 모델별로 env를 주입하므로 정적 env는 제거 (충돌 방지).
if (s.env) {
delete s.env.CLAUDE_CODE_MAX_CONTEXT_TOKENS;
if (Object.keys(s.env).length === 0) delete s.env;
}
fs.writeFileSync(settingsPath, JSON.stringify(s, null, 2) + '\n');
console.log('statusLine before: ' + beforeSL);
console.log('statusLine after : ' + s.statusLine.command);
console.log('env removed (was): ' + (beforeEnv || '(none)'));
console.log('env now : ' + JSON.stringify(s.env || {}));
PATCHER_EOF
node "$PATCHER" "$SETTINGS" "$WRAPPER"
echo ""
echo "✅ 설치 완료."
echo " 이후 claude 실행은 ollama launch claude 대신"
echo " bash ~/.claude/launch-claude.sh 로 하세요 (모델별 context 자동 주입)."
+114
View File
@@ -0,0 +1,114 @@
# GLM context 보정 패치 v2 (Windows) — 옵션 3: 모델별 런타임 env 주입
#
# 설치 파일:
# %USERPROFILE%\.claude\statusline-glm-fix.js stdin 보정 wrapper (표시 fallback)
# %USERPROFILE%\.claude\launch-claude.ps1 모델별 context 를 ollama에서 읽어
# CLAUDE_CODE_MAX_CONTEXT_TOKENS 로 주입하고 exec
# settings.json:
# statusLine -> statusline-glm-fix.js
# env.CLAUDE_CODE_MAX_CONTEXT_TOKENS 제거 (launch-claude.ps1 가 모델별로 주입)
#
# 사용: powershell -ExecutionPolicy Bypass -File .\install-windows.ps1
# 이후 claude 실행: powershell -ExecutionPolicy Bypass -File ~/.claude/launch-claude.ps1
# (ollama launch claude 대신. 단 Windows 에서 ollama launch 통합이 있을 때.)
# 되돌리기: settings.json statusLine.command 를 원래 dist/index.js 경로로.
$ErrorActionPreference = 'Stop'
$HC = Join-Path $env:USERPROFILE '.claude'
$Wrapper = Join-Path $HC 'statusline-glm-fix.js'
$Launch = Join-Path $HC 'launch-claude.ps1'
$Settings = Join-Path $HC 'settings.json'
$Patcher = Join-Path $env:TEMP "glm-patch-$([System.Guid]::NewGuid()).js"
New-Item -ItemType Directory -Force -Path $HC | Out-Null
# --- 1) statusline wrapper ---
$wrapperJs = @'
const { spawn } = require('child_process');
const fs = require('fs');
const os = require('os');
const path = require('path');
function resolveDashboard() {
const base = path.join(os.homedir(), '.claude/plugins/cache/claude-dashboard/claude-dashboard');
let dirs;
try { dirs = fs.readdirSync(base); } catch { dirs = []; }
const ver = dirs.filter((d) => /^\d+\.\d+\.\d+$/.test(d)).sort((a, b) => {
const pa = a.split('.').map(Number), pb = b.split('.').map(Number);
for (let i = 0; i < 3; i++) if (pa[i] !== pb[i]) return pa[i] - pb[i];
return 0;
}).pop();
return ver ? path.join(base, ver, 'dist/index.js') : path.join(base, '1.30.0/dist/index.js');
}
const DASHBOARD = resolveDashboard();
let raw = '';
process.stdin.setEncoding('utf8');
process.stdin.on('data', (c) => { raw += c; });
process.stdin.on('end', () => {
let payload = raw;
try {
const json = JSON.parse(raw);
const cw = json?.context_window;
const size = cw?.context_window_size;
const modelId = String(json?.model?.id || '').toLowerCase();
if (modelId.includes('glm') && size === 200000) {
cw.context_window_size = 1000000;
const usage = cw.current_usage;
if (usage) {
const input = (usage.input_tokens || 0) + (usage.cache_creation_input_tokens || 0) + (usage.cache_read_input_tokens || 0);
cw.used_percentage = Math.round((input / 1000000) * 100);
if (typeof cw.remaining_percentage === 'number') cw.remaining_percentage = 100 - cw.used_percentage;
}
payload = JSON.stringify(json);
}
} catch { /* pass through */ }
const child = spawn('node', [DASHBOARD], { stdio: ['pipe', 'inherit', 'inherit'] });
child.stdin.write(payload);
child.stdin.end();
});
'@
Set-Content -Path $Wrapper -Value $wrapperJs -Encoding UTF8
# --- 2) launch-claude.ps1 ---
$launchPs = @'
$ErrorActionPreference = 'Stop'
$Cfg = Join-Path $env:USERPROFILE '.ollama\config.json'
if (-not (Test-Path $Cfg)) { Write-Host "⚠️ $Cfg 없음 — env 없이 실행" -ForegroundColor Yellow; & ollama launch claude; return }
$Model = node -e "const fs=require('fs'),os=require('os');const p=os.homedir()+'/.ollama/config.json';const d=JSON.parse(fs.readFileSync(p,'utf8'));const m=(d.integrations&&d.integrations.claude&&d.integrations.claude.models)||[];process.stdout.write(m[0]||'');"
if (-not $Model) { Write-Host "⚠️ claude 모델 못 읽음 — env 없이 실행" -ForegroundColor Yellow; & ollama launch claude; return }
$line = ollama show $Model 2>$null | Select-String -Pattern 'context length'
$Ctx = ($line -split '\s+')[-1]
if (-not ($Ctx -match '^\d+$') -or $Ctx -eq '0') { Write-Host "⚠️ '$Model' context length 못 읽음 — env 없이 실행" -ForegroundColor Yellow; & ollama launch claude; return }
Write-Host "▶ model=$Model context=$Ctx → CLAUDE_CODE_MAX_CONTEXT_TOKENS=$Ctx" -ForegroundColor Cyan
$env:CLAUDE_CODE_MAX_CONTEXT_TOKENS = $Ctx
& ollama launch claude
'@
Set-Content -Path $Launch -Value $launchPs -Encoding UTF8
# --- 3) settings.json 패치: statusLine 교체 + 정적 env 제거 ---
$patcherJs = @'
const fs = require('fs');
const settingsPath = process.argv[2];
const wrapperPath = process.argv[3];
const s = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
const beforeSL = s.statusLine && s.statusLine.command;
const beforeEnv = s.env && s.env.CLAUDE_CODE_MAX_CONTEXT_TOKENS;
s.statusLine = { type: 'command', command: 'node ' + wrapperPath };
if (s.env) {
delete s.env.CLAUDE_CODE_MAX_CONTEXT_TOKENS;
if (Object.keys(s.env).length === 0) delete s.env;
}
fs.writeFileSync(settingsPath, JSON.stringify(s, null, 2) + '\n');
console.log('statusLine before: ' + beforeSL);
console.log('statusLine after : ' + s.statusLine.command);
console.log('env removed (was): ' + (beforeEnv || '(none)'));
console.log('env now : ' + JSON.stringify(s.env || {}));
'@
Set-Content -Path $Patcher -Value $patcherJs -Encoding UTF8
& node $Patcher $Settings $Wrapper
Remove-Item -Path $Patcher -Force -ErrorAction SilentlyContinue
Write-Host ""
Write-Host "✅ 설치 완료."
Write-Host " 이후 claude 실행은 ollama launch claude 대신"
Write-Host " powershell -ExecutionPolicy Bypass -File ~/.claude/launch-claude.ps1"