Files
homeclaw/glm-1m-fix/install-windows.ps1
T
kimandClaude Opus 5 e85ebe6608 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>
2026-07-29 14:55:37 +09:00

114 lines
5.4 KiB
PowerShell

# 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"