diff --git a/scripts/verify_setup.ps1 b/scripts/verify_setup.ps1 index 3b9c270..8089b42 100644 --- a/scripts/verify_setup.ps1 +++ b/scripts/verify_setup.ps1 @@ -86,170 +86,6 @@ if ($paths) { } } -# 2. Claude 사용자 메모리 junction 검증 -$orgMemoryTarget = Join-Path $repoRoot "memory\org" -Check "memory/org 실체 존재" (Test-Path $orgMemoryTarget) $orgMemoryTarget - -$claudeMemoryBase = "$env:USERPROFILE\.claude\projects" -if (Test-Path $claudeMemoryBase) { - $found = $false - $junctionOk = $false - foreach ($d in (Get-ChildItem $claudeMemoryBase -Directory -ErrorAction SilentlyContinue)) { - $memLink = Join-Path $d.FullName "memory" - if (Test-Path $memLink) { - $found = $true - $item = Get-Item $memLink -Force - $isReparse = ($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0 - if ($isReparse) { - # 타깃이 memory\org 인지 확인 (memory 자체가 memory\org를 가리킴) - $target = (Get-Item $memLink -Force).Target - if (-not $target) { $target = (& cmd /c "dir `"$($item.Parent.FullName)`" 2>&1" | Out-String) } - $pointsToOrg = $target -like "*memory\org*" -or $target -like "*memory/org*" - if ($pointsToOrg) { - Check "junction [$($d.Name)/memory]" $true "-> memory\org (reparse OK)" - $junctionOk = $true - } else { - Warn "junction 타깃 확인 불가" "[$($d.Name)/memory] target=$target (수동 확인 권장)" - } - } else { - Check "junction [$($d.Name)/memory]" $false "reparse point 아님 (실체 폴더). setup 재실행 필요" - } - } - } - if (-not $found) { - Check "Claude 프로젝트 해시 폴더 내 memory 링크" $false "$claudeMemoryBase 에서 memory 링크를 찾지 못함. setup_windows.ps1 재실행 필요" - } elseif (-not $junctionOk) { - Warn "junction 상태" "타깃 검증에 성공한 링크가 없음. 수동 확인 권장" - } - - # MEMORY.md 로드 가능 여부 (junction 통해 읽기) - $memoryMdCandidates = Get-ChildItem $claudeMemoryBase -Directory -ErrorAction SilentlyContinue | - ForEach-Object { Join-Path $_.FullName "memory\MEMORY.md" } | - Where-Object { Test-Path $_ } - if ($memoryMdCandidates.Count -gt 0) { - Check "MEMORY.md junction 경유 읽기" $true ($memoryMdCandidates[0]) - } else { - Warn "MEMORY.md 읽기" "junction 경유로 MEMORY.md 를 찾지 못함" - } -} else { - Warn "Claude 메모리 베이스" "$claudeMemoryBase 미존재. Claude Code 첫 실행 전일 가능성" -} - -# 2.5. Live 증분 동기화 Junction 3축 검증 (C34, 2026-04-18 신설) -# 축 1: 중앙 저장소 실체 / 축 2: reparse point / 축 3: marker 경유 읽기 -$centralLive = Join-Path $env:USERPROFILE ".claude\burningtimes-live" -$localLive = Join-Path $repoRoot ".live" -$markerName = ".junction-marker" - -Check "Live 중앙 저장소 실체 존재" (Test-Path $centralLive) $centralLive - -if (Test-Path $localLive) { - $liveItem = Get-Item $localLive -Force - $isReparse = ($liveItem.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0 - if ($isReparse) { - Check "Live .live/ Junction reparse 실체" $true "reparse point OK" - # 축 3: marker 경유 읽기 (A→B worktree 동기화 가능성 실증) - $markerPath = Join-Path $localLive $markerName - Check "Live Junction marker 경유 읽기" (Test-Path $markerPath) $markerPath - } else { - Check "Live .live/ Junction reparse 실체" $false "실체 디렉토리 (setup 재실행 필요)" - } -} else { - Warn "Live .live/ 존재" "$localLive 미존재 (세션 1회 시작 시 hook 자동 생성)" -} - -# 2.6. memory/org/ 중앙 저장소 + Junction 3축 검증 (C34-16, 2026-04-19 신설) -$centralMemory = Join-Path $env:USERPROFILE ".claude\burningtimes-memory" -$memoryMarker = ".memory-junction-marker" - -Check "memory 중앙 저장소 실체 존재" (Test-Path $centralMemory) $centralMemory - -if (Test-Path $claudeMemoryBase) { - $centralCount = 0 - $repoRootCount = 0 - $otherCount = 0 - - foreach ($d in (Get-ChildItem $claudeMemoryBase -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -like "E--BurningTimesAi*" })) { - $memLink = Join-Path $d.FullName "memory" - if (Test-Path (Join-Path $memLink $memoryMarker)) { - $centralCount += 1 - } elseif (Test-Path $memLink) { - $repoRootCount += 1 - } else { - $otherCount += 1 - } - } - - if ($centralCount -gt 0 -and $repoRootCount -eq 0) { - Check "memory junction 전원 중앙 연결" $true "$centralCount 건 (부재 $otherCount)" - } elseif ($centralCount -gt 0) { - Warn "memory junction 타깃 혼재" "중앙 $centralCount / 레포 루트 $repoRootCount / 부재 $otherCount — setup 재실행 권장" - } else { - Warn "memory junction 중앙 미연결" "레포 루트 $repoRootCount / 부재 $otherCount — C34-16 setup 재실행 필요" - } - - # unflushed 중앙 대피본 감지 - $conflictDirs = Get-ChildItem "$env:USERPROFILE\.claude" -Directory -Filter "burningtimes-memory.conflict-*" -ErrorAction SilentlyContinue - if ($conflictDirs.Count -gt 0) { - Warn "memory unflushed 중앙 대피본 잔류" "$($conflictDirs.Count) 건 — 수동 병합 후 정리 필요: $($conflictDirs[0].FullName)" - } -} - -# 2.7. audit 중앙 저장소 + Junction 3종 검증 (C34-17, 2026-04-20 #48 I-1 부분 집행 — verify_setup 2.7 단독) -$centralAudit = Join-Path $env:USERPROFILE ".claude\burningtimes-audit" -$auditMarker = ".junction-marker" - -Check "audit 중앙 저장소 실체 존재" (Test-Path $centralAudit) $centralAudit - -if (Test-Path $centralAudit) { - Check "audit 중앙 최상위 marker" (Test-Path (Join-Path $centralAudit $auditMarker)) "$centralAudit\$auditMarker" - - $auditSubs = @("auditor_calls", "warning_ignored", "bypass_log") - $subOk = 0 - $subMissing = @() - foreach ($sub in $auditSubs) { - $subDir = Join-Path $centralAudit $sub - $subMarkerPath = Join-Path $subDir $auditMarker - if ((Test-Path $subDir) -and (Test-Path $subMarkerPath)) { - $subOk += 1 - } else { - $subMissing += $sub - } - } - - if ($subOk -eq 3) { - Check "audit 중앙 하위 3종 marker" $true "auditor_calls / warning_ignored / bypass_log" - } else { - Warn "audit 중앙 하위 marker 결손" "정상 $subOk/3 — 부재: $($subMissing -join ', ') — audit_junction_ensure.sh 재실행 필요" - } - - # Junction 연결 검증 ($HOME/.claude/.burningtimes_* → 중앙 하위) - $junctionMap = @{ - ".burningtimes_auditor_calls" = "auditor_calls" - ".burningtimes_warning_ignored" = "warning_ignored" - ".burningtimes_bypass_log" = "bypass_log" - } - $linkedCount = 0 - $unlinkedList = @() - foreach ($localName in $junctionMap.Keys) { - $localPath = Join-Path $env:USERPROFILE ".claude\$localName" - $markerViaJunction = Join-Path $localPath $auditMarker - if (Test-Path $markerViaJunction) { - $linkedCount += 1 - } else { - $unlinkedList += $localName - } - } - - if ($linkedCount -eq 3) { - Check "audit junction 3종 연결" $true "전수 정상" - } elseif ($linkedCount -gt 0) { - Warn "audit junction 부분 연결" "정상 $linkedCount/3 — 미연결: $($unlinkedList -join ', ')" - } else { - Warn "audit junction 미연결" "세션 재시작 후 audit_junction_ensure.sh 자동 실행 필요" - } -} - # 3. 경로 추상화 적용 여부 (CLAUDE.md 계열에 구 하드코딩 경로 잔존 확인) $hardcodePatterns = @("C:/Users/PC/Documents", "D:/BurningTimes/FilGoodBandits", "D:/BurningTimes/BurningTimes.Framework") $scanTargets = @( diff --git a/setup/setup_macos.sh b/setup/setup_macos.sh index 166ea52..4e30a3d 100644 --- a/setup/setup_macos.sh +++ b/setup/setup_macos.sh @@ -37,98 +37,6 @@ else echo "paths.local.json 이미 존재. 유지." fi -# 3. 메모리 symlink -ORG_MEM="$BURNINGTIMES_ROOT/memory/org" -mkdir -p "$ORG_MEM" - -CLAUDE_BASE="$HOME/.claude/projects" -if [ -d "$CLAUDE_BASE" ]; then - for d in "$CLAUDE_BASE"/*Documents*/ "$CLAUDE_BASE"/*BurningTimes*/; do - [ -d "$d" ] || continue - MEM="$d/memory" - if [ -L "$MEM" ]; then - echo "이미 symlink. 유지: $MEM" - elif [ -d "$MEM" ]; then - mv "$MEM" "$MEM.bak_$(date +%Y%m%d_%H%M)" - ln -s "$ORG_MEM" "$MEM" - echo "Symlink 생성: $MEM -> $ORG_MEM" - else - ln -s "$ORG_MEM" "$MEM" - echo "Symlink 생성: $MEM -> $ORG_MEM" - fi - done -fi - -# 3.5. Live 증분 동기화 중앙 저장소 + Symlink (C34, 2026-04-18 PD님 직접 지시) -# worktree 격리로 인한 .live/ 물리 분리 해결을 위해 -# $HOME/.claude/burningtimes-live/ 중앙 디렉토리로 symlink 연결한다. -CENTRAL_LIVE="$HOME/.claude/burningtimes-live" -LOCAL_LIVE="$BURNINGTIMES_ROOT/.live" -MARKER_NAME=".junction-marker" - -mkdir -p "$CENTRAL_LIVE" -if [ ! -f "$CENTRAL_LIVE/$MARKER_NAME" ]; then - echo "burningtimes-live central junction target (C34, 2026-04-18)" > "$CENTRAL_LIVE/$MARKER_NAME" -fi - -if [ -L "$LOCAL_LIVE" ]; then - echo "Live symlink 이미 존재. 유지: $LOCAL_LIVE" -elif [ -d "$LOCAL_LIVE" ]; then - BAK="$LOCAL_LIVE.bak_$(date +%Y%m%d_%H%M)" - for f in "$LOCAL_LIVE"/*.md "$LOCAL_LIVE"/*.json; do - [ -f "$f" ] || continue - DST="$CENTRAL_LIVE/$(basename "$f")" - [ ! -f "$DST" ] && cp "$f" "$DST" - done - mv "$LOCAL_LIVE" "$BAK" - ln -s "$CENTRAL_LIVE" "$LOCAL_LIVE" - echo "Live Symlink 생성: $LOCAL_LIVE -> $CENTRAL_LIVE (백업: $BAK)" -else - ln -s "$CENTRAL_LIVE" "$LOCAL_LIVE" - echo "Live Symlink 생성: $LOCAL_LIVE -> $CENTRAL_LIVE" -fi - -# 3.6. memory/org/ 중앙 저장소 + Symlink (C34-16, 2026-04-19 신설) -CENTRAL_MEM="$HOME/.claude/burningtimes-memory" -MEMORY_MARKER=".memory-junction-marker" - -mkdir -p "$CENTRAL_MEM" -if [ ! -f "$CENTRAL_MEM/$MEMORY_MARKER" ]; then - echo "burningtimes-memory central (C34-16, 2026-04-19)" > "$CENTRAL_MEM/$MEMORY_MARKER" -fi - -# 초기 sync 레포 → 중앙 -if [ -d "$BURNINGTIMES_ROOT/memory/org" ]; then - for f in "$BURNINGTIMES_ROOT/memory/org"/*.md "$BURNINGTIMES_ROOT/memory/org"/*.json; do - [ -f "$f" ] || continue - BASENAME=$(basename "$f") - [ ! -f "$CENTRAL_MEM/$BASENAME" ] && cp "$f" "$CENTRAL_MEM/$BASENAME" - done -fi - -# user memory symlink 중앙 재연결 -if [ -d "$CLAUDE_BASE" ]; then - for d in "$CLAUDE_BASE"/E--BurningTimesAi*/; do - [ -d "$d" ] || continue - mem_link="${d}memory" - - if [ -L "$mem_link" ] && [ -f "$mem_link/$MEMORY_MARKER" ]; then - continue - fi - - if [ -d "$mem_link" ] && [ ! -L "$mem_link" ]; then - mv "$mem_link" "$mem_link.bak_$(date +%Y%m%d_%H%M)" - elif [ -L "$mem_link" ]; then - rm -f "$mem_link" - fi - - ln -s "$CENTRAL_MEM" "$mem_link" - echo "memory Symlink 중앙 연결: $mem_link -> $CENTRAL_MEM" - done -fi - -# 3.7. Unity MCP 외부 저장소 자동 clone (A안, 2026-04-21 PD님 직접 승인) -UNITY_MCP_PATH="$BURNINGTIMES_ROOT/코어코드/unity-mcp" if [ ! -d "$UNITY_MCP_PATH" ]; then echo "[setup] unity-mcp 외부 저장소 clone 시작..." mkdir -p "$(dirname "$UNITY_MCP_PATH")" diff --git a/setup/setup_windows.ps1 b/setup/setup_windows.ps1 index 605324e..308189d 100644 --- a/setup/setup_windows.ps1 +++ b/setup/setup_windows.ps1 @@ -61,158 +61,6 @@ if (-not (Test-Path $pathsFile)) { Write-Host "paths.local.json 이미 존재. 유지." } -# 3. Claude 사용자 메모리 연결 (junction) -$claudeMemoryBase = "$env:USERPROFILE\.claude\projects" -$orgMemoryTarget = Join-Path $BurningTimesRoot "memory\org" - -if (-not (Test-Path $orgMemoryTarget)) { - New-Item -ItemType Directory -Path $orgMemoryTarget | Out-Null -} - -$hashDirs = @() -if (Test-Path $claudeMemoryBase) { - # Claude Code는 프로젝트 경로의 각 세그먼트를 '-'로 이어 해시 폴더명을 만든다 - # (예: E:\BurningTimesAi → E--BurningTimesAi, C:\Users\PC\Documents\BurningTimes → C--Users-PC-Documents-BurningTimes) - # BurningTimesRoot의 리프 이름·드라이브 prefix·관례적 키워드를 모두 포괄하도록 필터 확장 - $rootLeaf = Split-Path $BurningTimesRoot -Leaf - $rootDrive = (Split-Path $BurningTimesRoot -Qualifier).TrimEnd(':') - $hashDirs = Get-ChildItem $claudeMemoryBase -Directory -ErrorAction SilentlyContinue | - Where-Object { - $_.Name -like "*Documents*" -or - $_.Name -like "*BurningTimes*" -or - $_.Name -like "*BurningTimes*" -or - $_.Name -like "*$rootLeaf*" -or - $_.Name -like "$rootDrive--*" - } -} - -foreach ($d in $hashDirs) { - $memLink = Join-Path $d.FullName "memory" - if (Test-Path $memLink) { - $attr = (Get-Item $memLink -Force).Attributes - if (($attr -band [IO.FileAttributes]::ReparsePoint) -eq 0) { - # 실체 폴더. 백업 후 junction으로 교체 - $bak = "$memLink.bak_$(Get-Date -Format yyyyMMdd_HHmm)" - Rename-Item $memLink $bak - Write-Host "기존 memory 폴더 백업: $bak" - cmd /c mklink /J "`"$memLink`"" "`"$orgMemoryTarget`"" | Out-Null - Write-Host "Junction 생성: $memLink -> $orgMemoryTarget" - } else { - Write-Host "이미 junction/symlink. 유지: $memLink" - } - } else { - cmd /c mklink /J "`"$memLink`"" "`"$orgMemoryTarget`"" | Out-Null - Write-Host "Junction 생성: $memLink -> $orgMemoryTarget" - } -} - -if ($hashDirs.Count -eq 0) { - Write-Warning "Claude 프로젝트 해시 폴더를 찾지 못했습니다. 수동 연결 필요." -} - -# 3.5. Live 증분 동기화 중앙 저장소 + Junction (C34, 2026-04-18 PD님 직접 지시) -# worktree 격리로 인한 .live/ 물리 분리 문제를 해결하기 위해 -# $HOME\.claude\burningtimes-live\ 중앙 디렉토리로 junction 연결한다. -# 헌법 제1원칙 ⑤ 세션·PC 연속성의 근원 보장 장치. -$centralLive = Join-Path $env:USERPROFILE ".claude\burningtimes-live" -$localLive = Join-Path $BurningTimesRoot ".live" -$markerName = ".junction-marker" -$markerText = "burningtimes-live central junction target (C34, 2026-04-18)" - -if (-not (Test-Path $centralLive)) { - New-Item -ItemType Directory -Path $centralLive -Force | Out-Null - Write-Host "Live 중앙 저장소 생성: $centralLive" -} - -$centralMarker = Join-Path $centralLive $markerName -if (-not (Test-Path $centralMarker)) { - [System.IO.File]::WriteAllText($centralMarker, $markerText, [System.Text.UTF8Encoding]::new($false)) -} - -if (Test-Path $localLive) { - $liveItem = Get-Item $localLive -Force - $isReparse = ($liveItem.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0 - if (-not $isReparse) { - # 실체 디렉토리 — 백업 후 junction 전환 (C6-1 원본 보호) - $bak = "$localLive.bak_$(Get-Date -Format yyyyMMdd_HHmm)" - # 기존 파일 중앙으로 복사 (기존 중앙 파일 덮어쓰기 안 함) - Get-ChildItem $localLive -File -ErrorAction SilentlyContinue | ForEach-Object { - $dst = Join-Path $centralLive $_.Name - if (-not (Test-Path $dst)) { Copy-Item $_.FullName $dst -Force } - } - Rename-Item $localLive $bak - Write-Host "기존 .live/ 백업: $bak" - New-Item -ItemType Junction -Path $localLive -Target $centralLive -Force | Out-Null - Write-Host "Live Junction 생성: $localLive -> $centralLive" - } else { - Write-Host "Live Junction 이미 존재. 유지: $localLive" - } -} else { - New-Item -ItemType Junction -Path $localLive -Target $centralLive -Force | Out-Null - Write-Host "Live Junction 생성: $localLive -> $centralLive" -} - -# 3.6. memory/org/ 중앙 저장소 + Junction (C34-16, 2026-04-19 신설) -# Claude user memory junction 대상을 $HOME\.claude\burningtimes-memory\로 변경. -# 레포 `memory/org/`는 git 추적 SOT로 실체 디렉토리 유지 + sync 스크립트가 양방향 동기화. -$centralMemory = Join-Path $env:USERPROFILE ".claude\burningtimes-memory" -$memoryMarkerName = ".memory-junction-marker" -$memoryMarkerText = "burningtimes-memory central (C34-16, 2026-04-19)" - -if (-not (Test-Path $centralMemory)) { - New-Item -ItemType Directory -Path $centralMemory -Force | Out-Null - Write-Host "memory 중앙 저장소 생성: $centralMemory" -} - -$centralMemoryMarker = Join-Path $centralMemory $memoryMarkerName -if (-not (Test-Path $centralMemoryMarker)) { - [System.IO.File]::WriteAllText($centralMemoryMarker, $memoryMarkerText, [System.Text.UTF8Encoding]::new($false)) -} - -# 초기 sync — 레포 memory/org → 중앙 (기존 중앙 파일 덮어쓰기 안 함) -$repoMemoryOrg = Join-Path $BurningTimesRoot "memory\org" -if (Test-Path $repoMemoryOrg) { - Get-ChildItem $repoMemoryOrg -File -ErrorAction SilentlyContinue | Where-Object { $_.Extension -in @('.md','.json') } | ForEach-Object { - $dst = Join-Path $centralMemory $_.Name - if (-not (Test-Path $dst)) { Copy-Item $_.FullName $dst -Force } - } - Write-Host "memory 초기 sync 레포 → 중앙 완료" -} - -# 모든 E--BurningTimesAi* 해시 폴더 순회하여 junction 중앙으로 재연결 (광범위 filter) -$allHashDirs = Get-ChildItem $claudeMemoryBase -Directory -ErrorAction SilentlyContinue | - Where-Object { $_.Name -like "E--BurningTimesAi*" -or $_.Name -like "*BurningTimesAi*" } - -foreach ($d in $allHashDirs) { - $memLink = Join-Path $d.FullName "memory" - $markerPath = Join-Path $memLink $memoryMarkerName - - # 이미 중앙으로 연결된 경우 skip (sentinel 경유) - if (Test-Path $markerPath) { continue } - - if (Test-Path $memLink) { - $item = Get-Item $memLink -Force - $isReparse = ($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0 - if (-not $isReparse) { - # 실체 디렉토리 — 내용 중앙으로 흡수 후 백업 - Get-ChildItem $memLink -File -ErrorAction SilentlyContinue | Where-Object { $_.Extension -in @('.md','.json') } | ForEach-Object { - $dst = Join-Path $centralMemory $_.Name - if (-not (Test-Path $dst)) { Copy-Item $_.FullName $dst -Force } - } - Rename-Item $memLink "$memLink.bak_$(Get-Date -Format yyyyMMdd_HHmm)" - } else { - Remove-Item $memLink -Force -ErrorAction SilentlyContinue - } - } - - try { - New-Item -ItemType Junction -Path $memLink -Target $centralMemory -Force | Out-Null - Write-Host "memory Junction 중앙 연결: $memLink -> $centralMemory" - } catch { - Write-Warning "memory Junction 생성 실패: $memLink" - } -} - # 3.7. Unity MCP 외부 저장소 자동 clone (A안, 2026-04-21 PD님 직접 승인) # - CoplayDev/unity-mcp 외부 저장소를 BT 레포 내부에 clone # - BT 레포 `.gitignore`로 추적 제외 (외부 저장소 분리 유지)