feat(bootstrap): restore rescued GuruRMM/GuruConnect WIP on rebuild
Add restore-at-risk-work.ps1 and wire it into bootstrap Phase 6. Recreates local-only WIP rescued to the recovery bundle's at-risk-work/: re-applies the three guru-rmm stash patches back AS stashes (LIFO order preserved) and drops the guru-connect tmp-spec018.diff back as its untracked working file. Patches that won't apply cleanly are reported for manual git apply --3way. Updates RESTORE.md and the session log with the rescue details. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
59
.claude/bootstrap/restore-at-risk-work.ps1
Normal file
59
.claude/bootstrap/restore-at-risk-work.ps1
Normal file
@@ -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
|
||||
@@ -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)" }
|
||||
}
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
Reference in New Issue
Block a user