diff --git a/.claude/bootstrap/RESTORE.md b/.claude/bootstrap/RESTORE.md index 8b99298..891ddc0 100644 --- a/.claude/bootstrap/RESTORE.md +++ b/.claude/bootstrap/RESTORE.md @@ -34,6 +34,11 @@ The recovery bundle lives on the removable drives: - `config\` — Windows Terminal settings, fleet `hosts` file, quote-wizard `.env.production` - `manifests\` — `installed-tools.txt`, `ollama-models.txt`, `git-global-config.txt`, `repos.txt`, `user-environment.reg` / `.txt` (incl. `OLLAMA_MODELS`/`OLLAMA_HOST`/`PROTOC`), `scheduled-tasks\*.xml` +- `at-risk-work\` — local-only WIP rescued from the submodules (not on any remote): + guru-rmm stashes as `.patch` files + guru-connect `tmp-spec018.diff`. The bootstrap + re-applies these automatically in Phase 6 (`restore-at-risk-work.ps1`) — the guru-rmm + ones are put back **as stashes** (`git stash list`), the guru-connect diff is dropped + back as its untracked working file. See `RESTORE-at-risk-work.txt` for manual steps. - `data\` (F: only) — large non-Gitea client/project data, repo-relative paths Everything else (all tracked code, skills, commands, docs, session logs, wiki) comes diff --git a/.claude/bootstrap/restore-at-risk-work.ps1 b/.claude/bootstrap/restore-at-risk-work.ps1 new file mode 100644 index 0000000..582a15b --- /dev/null +++ b/.claude/bootstrap/restore-at-risk-work.ps1 @@ -0,0 +1,59 @@ +<# +.SYNOPSIS + Restore local-only WIP (stashes + untracked diffs) that was rescued into the + recovery bundle's at-risk-work\ folder. Run AFTER the repos + submodules are cloned. + +.DESCRIPTION + guru-rmm : each stashN-*.patch is applied to the working tree and then re-stashed, + faithfully recreating the original `git stash` entries. Patches are + processed highest-N-first so stash0 ends up on top (stash@{0}), matching + the original LIFO order. The working tree is left CLEAN (changes live in + the stash, exactly as before). + guru-connect : tmp-spec018.diff was an UNTRACKED working file, so it is copied back + into the repo as-is (not applied). Apply it yourself if/when you want it. + + Non-destructive and re-runnable. If a patch won't apply cleanly (submodule moved on), + it is reported and the .patch file is left in place for manual `git apply --3way`. + +.PARAMETER BundlePath Recovery bundle root (auto-detect F:\ then E:\). +.PARAMETER ClaudeToolsRoot Default D:\claudetools. +#> +[CmdletBinding()] +param([string]$BundlePath,[string]$ClaudeToolsRoot='D:\claudetools') +$ErrorActionPreference='Stop' + +if (-not $BundlePath) { foreach ($d in 'F:','E:','D:') { if (Test-Path "$d\claudetools-recovery\at-risk-work") { $BundlePath="$d\claudetools-recovery"; break } } } +$aw = "$BundlePath\at-risk-work" +if (-not $BundlePath -or -not (Test-Path $aw)) { Write-Host "[INFO] no at-risk-work folder found in bundle - nothing to restore"; return } +Write-Host "[INFO] restoring at-risk WIP from $aw" -ForegroundColor Cyan + +function Have-Git($repo){ Test-Path "$repo\.git" } + +# ---- guru-rmm stashes ---- +$rmm = "$ClaudeToolsRoot\projects\msp-tools\guru-rmm" +if ((Test-Path "$aw\guru-rmm") -and (Have-Git $rmm)) { + if (git -C $rmm status --porcelain) { + Write-Host "[WARN] guru-rmm working tree is dirty; skipping auto-restore to avoid mixing changes. Apply patches in $aw\guru-rmm manually." -ForegroundColor Yellow + } else { + # highest N first so stash0 lands at stash@{0} + $patches = Get-ChildItem "$aw\guru-rmm" -Filter '*.patch' | Sort-Object Name -Descending + foreach ($p in $patches) { + $check = git -C $rmm apply --check --3way $p.FullName 2>&1 + if ($LASTEXITCODE -ne 0) { Write-Host "[WARN] won't apply cleanly, left for manual restore: $($p.Name) ($check)" -ForegroundColor Yellow; continue } + git -C $rmm apply --3way $p.FullName 2>$null + git -C $rmm stash push -u -m "restored WIP: $($p.BaseName)" 2>$null | Out-Null + Write-Host "[OK] re-stashed guru-rmm: $($p.BaseName)" -ForegroundColor Green + } + Write-Host "[INFO] guru-rmm stashes now:" -ForegroundColor Cyan + git -C $rmm stash list + } +} + +# ---- guru-connect untracked diff ---- +$gc = "$ClaudeToolsRoot\projects\msp-tools\guru-connect" +$diff = "$aw\guru-connect\tmp-spec018.diff" +if ((Test-Path $diff) -and (Test-Path $gc)) { + Copy-Item $diff "$gc\tmp-spec018.diff" -Force + Write-Host "[OK] guru-connect\tmp-spec018.diff restored (untracked working file - 'git apply --3way tmp-spec018.diff' to apply it)" -ForegroundColor Green +} +Write-Host "[DONE] at-risk WIP restore" -ForegroundColor Cyan diff --git a/.claude/bootstrap/windows-bootstrap.ps1 b/.claude/bootstrap/windows-bootstrap.ps1 index 4fc4028..a93619c 100644 --- a/.claude/bootstrap/windows-bootstrap.ps1 +++ b/.claude/bootstrap/windows-bootstrap.ps1 @@ -185,8 +185,13 @@ if (Phase 5 'Clone repos') { } # ============================================================ PHASE 6 -if (Phase 6 'Restore repo-local identity') { - if ($script:Bundle) { & "$here\restore-secrets.ps1" -BundlePath $script:Bundle -Group repo -ClaudeToolsRoot $ClaudeToolsRoot } +if (Phase 6 'Restore repo-local identity + at-risk WIP') { + if ($script:Bundle) { + & "$here\restore-secrets.ps1" -BundlePath $script:Bundle -Group repo -ClaudeToolsRoot $ClaudeToolsRoot + # Recreate local-only WIP (guru-rmm stashes, guru-connect untracked diff) that + # would otherwise have been lost - faithfully puts the stashes back as stashes. + & "$here\restore-at-risk-work.ps1" -BundlePath $script:Bundle -ClaudeToolsRoot $ClaudeToolsRoot + } else { Warn "no bundle - you must hand-create .claude/identity.json (see CLAUDE.md multi-user section)" } } diff --git a/session-logs/2026-06-06-windows-bootstrap-recovery.md b/session-logs/2026-06-06-windows-bootstrap-recovery.md index 52c008c..2e2ccdf 100644 --- a/session-logs/2026-06-06-windows-bootstrap-recovery.md +++ b/session-logs/2026-06-06-windows-bootstrap-recovery.md @@ -65,6 +65,22 @@ Full read-only sweep of the environment: - Bootstrap toolkit committed to repo (3rd copy, fleet-reusable). - Part 2 (the actual reset + rebuild) pending — driven by `F:\claudetools-recovery\bootstrap\windows-bootstrap.ps1`. +## At-risk WIP rescued (addendum) + +Checked the GuruRMM/GuruConnect repos for local-only work a reset would destroy. +All committed code was already pushed (every submodule HEAD is on origin), but found +uncommitted WIP and preserved it to `at-risk-work\` on both E: and F: + +- **guru-rmm** (3 stashes, exported as patches): `stash@{0}` +119 lines `docs/FEATURE_ROADMAP.md`; + `stash@{1}` `CONTEXT.md`; `stash@{2}` `agent/Dockerfile` + `docs/unraid-ca-template.xml`. +- **guru-connect**: untracked `tmp-spec018.diff` (54 KB; `agent/src/install.rs` + more). +- `D:\work\gururmm`: only a local deletion of a legacy file still on remote — no loss. + +Original stashes left intact (not dropped). Added `restore-at-risk-work.ps1` and wired it +into bootstrap Phase 6: on rebuild it re-applies the guru-rmm patches **back as stashes** +(LIFO order preserved) and drops the guru-connect diff back as its untracked file. Patches +that won't apply cleanly are reported and left for manual `git apply --3way`. + ## Follow-ups - When ready to reset: run the bootstrap from the drive; verify vault decrypts via `vault.sh get-field projects/claudetools/database.sops.yaml credentials.password`.