feat: add ISO build script and update docs to Implementation#5
Conversation
Update project status to "Implementation Phase" in README.md and FAQ.md. Clarify that MVP scripts exist and point to remaining tasks in TODO.md. Add build-iso.ps1, a new PowerShell script that automates creating a custom Windows 11 ISO. The script: - Provides parameters for source ISO, output path, and debug temp. - Locates oscdimg.exe from Windows ADK and validates prerequisites. - Mounts, prepares, and injects autounattend and OEM files (bootstrap, apps.json, Sophia-Preset) into the ISO structure. - Offers colored, step-wise console output and robust error handling. - Includes usage examples and requirements in the header comment. Motivation: move the repository from planning to an actionable MVP by including the core automation for producing a customized Windows ISO and updating documentation to reflect active development. feat: improve network checks and error reporting in scripts Enhance bootstrap network probing to use multiple ping targets and fallback HTTPS checks. Add checks for Test-NetConnection and Invoke-WebRequest availability and attempt HTTPS TCP or HEAD requests to more reliably detect connectivity. This reduces false negatives when a single ICMP target is unreachable. Refactor build-iso error output: rename Write-Error to Write-ErrorMessage and update all call sites. Replace a removed unused Get-BootImage function. Improve error messages when tools or files are missing and ensure consistent red error printing.
📝 WalkthroughWalkthroughProject phase updated from PLANNING to IMPLEMENTATION. Documentation reflects existing MVP scripts. Two new PowerShell scripts added: Changes
Sequence Diagram(s)sequenceDiagram
participant Admin as Administrator
participant Bootstrap as bootstrap.ps1
participant Network as Network
participant WinGet as WinGet
participant Apps as apps.json
participant Sophia as Sophia-Preset
Admin->>Bootstrap: Run (elevated)
Bootstrap->>Bootstrap: Init logging, paths, summary
Bootstrap->>Network: Wait-ForNetwork
Network-->>Bootstrap: Ready
Bootstrap->>Apps: Parse apps.json
Apps-->>Bootstrap: Package list
Bootstrap->>WinGet: Test-WingetPackageInstalled / Install missing
WinGet-->>Bootstrap: Install results
Bootstrap->>Sophia: Execute preset (if present)
Sophia-->>Bootstrap: Result
Bootstrap->>Admin: Create desktop shortcut & Summary report
sequenceDiagram
participant User as User
participant BuildISO as build-iso.ps1
participant Files as File Validation
participant ADK as ADK/Registry
participant ISO as Source ISO (mount/copy)
participant OSC as oscdimg.exe
participant Output as Output ISO
User->>BuildISO: Invoke with source & output paths
BuildISO->>Files: Verify autounattend.xml, bootstrap.ps1, apps.json, Sophia-Preset.ps1
Files-->>BuildISO: OK
BuildISO->>ADK: Locate oscdimg.exe
ADK-->>BuildISO: Path or error
BuildISO->>ISO: Mount source ISO & copy contents
ISO-->>BuildISO: Copied to workdir
BuildISO->>BuildISO: Inject autounattend.xml and $OEM$\Setup assets
BuildISO->>OSC: Run oscdimg to create ISO
OSC-->>Output: ISO created
BuildISO->>User: Report size, validate, cleanup
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8b5d6f1112
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
CLAUDE.md (1)
40-42: Resolve phase inconsistency in documentation.Line 42 states "planning phase" but contradicts the phase declared at line 5-7 (IMPLEMENTATION). Update this section to reflect the current implementation phase.
♻️ Suggested update
## Current State - This is an early-stage project currently in the planning phase. See `brainstorm.md` for research and design discussions. + This project is now in the implementation phase. MVP scripts (bootstrap.ps1, build-iso.ps1) are under active development. See `brainstorm.md` for prior research and design discussions.
🤖 Fix all issues with AI agents
In @build-iso.ps1:
- Around line 63-66: The custom function named Write-Error shadows PowerShell's
built-in cmdlet; rename it (e.g., to Write-ErrorMessage or Write-LogError) and
update all internal calls that use Write-Error to the new name (replace the
custom Write-Error definition and any invocations such as those later in the
script that log failures). Ensure the new function keeps the same parameter
signature and behavior (printing with red color) so callers work the same after
renaming.
- Around line 110-126: Delete the unused Get-BootImage function declaration to
remove dead code: remove the entire function block named Get-BootImage (the
param and body that builds $bootImages and iterates to return a path) since the
script currently hardcodes boot image paths elsewhere; alternatively, if you
prefer to centralize logic, replace the hardcoded boot image selection with a
call to Get-BootImage and remove the hardcoded paths — either delete the unused
Get-BootImage definition or replace the hardcoded usage with a call to
Get-BootImage so there is no unused dead code.
🧹 Nitpick comments (4)
README.md (1)
137-138: Update stale "(planned)" comments to reflect implementation status.Lines 137-138 indicate the scripts are "(planned)" but the PR is implementing them as part of the IMPLEMENTATION phase. Update the comments to remove "(planned)" or rephrase to reflect that they are being implemented.
♻️ Suggested update
- ├── bootstrap.ps1 # Main orchestration script (planned) - ├── build-iso.ps1 # ISO generation script (planned) + ├── bootstrap.ps1 # Main orchestration script + ├── build-iso.ps1 # ISO generation scriptbuild-iso.ps1 (1)
34-36: Consider validating that the source ISO is Windows 11.The script currently only validates that the source file exists but doesn't verify it's a Windows 11 ISO. Consider adding validation to check for Windows 11 markers (e.g., version info from install.wim metadata) to prevent issues downstream.
🔍 Example validation approach
After mounting the ISO, you could add a check like:
# Verify Windows 11 ISO $installWim = Join-Path $sourceRoot "sources\install.wim" if (Test-Path $installWim) { $wimInfo = dism /Get-WimInfo /WimFile:$installWim /Index:1 | Select-String "Version" if ($wimInfo -notmatch "10\.0\.22") { throw "Source ISO does not appear to be Windows 11 (22H2+)" } }Based on learnings, all scripts must target Windows 11 (22H2+) only.
bootstrap.ps1 (2)
22-22: Reconsider ErrorActionPreference setting.Setting
$ErrorActionPreference = "Continue"is unusual for a script with structured error handling. This allows non-terminating errors to proceed silently, which can mask issues. Consider using"Stop"to ensure errors are caught by your try/catch blocks, or document why "Continue" is necessary for idempotency.💡 Suggested approach
-$ErrorActionPreference = "Continue" +$ErrorActionPreference = "Stop"If certain operations should continue on error (like checking if packages are installed), handle those specifically with
-ErrorAction Continueor-ErrorAction SilentlyContinueon individual commands rather than globally.
131-140: Add WinGet availability check.The function assumes
wingetis available in PATH but doesn't verify this. If WinGet is not installed or not in PATH, the command will fail ungracefully. Consider adding a check before first use to provide a clearer error message.🔍 Suggested check
Before first WinGet use (around line 190), add:
# Verify WinGet is available if (-not (Get-Command winget -ErrorAction SilentlyContinue)) { Write-Log "ERROR: WinGet is not installed or not in PATH" -Level ERROR Write-Log "WinGet is required for application installation" -Level ERROR Add-SummaryItem -Step "WinGet" -Status "✗" -Message "WinGet not available" # Continue with rest of script instead of exiting } else { # ... existing WinGet logic }
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
CLAUDE.mdFAQ.mdREADME.mdbootstrap.ps1build-iso.ps1
🧰 Additional context used
📓 Path-based instructions (4)
{README.md,TODO.md,RESEARCH.md,SECURITY.md,CLAUDE.md,docs/**/*.md}
📄 CodeRabbit inference engine (CLAUDE.md)
All documentation must assume Windows 11 (22H2+) only and explicitly exclude Windows 10 support
Files:
README.mdCLAUDE.md
**/*.ps1
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.ps1: Do not create any PowerShell scripts (.ps1) during the planning phase
All scripts must target Windows 11 (22H2+) only; do not implement or test Windows 10 compatibility
Files:
build-iso.ps1bootstrap.ps1
build-iso.ps1
📄 CodeRabbit inference engine (CLAUDE.md)
build-iso.ps1 must place autounattend.xml at ISO root and populate the
$OEM$ $$\Setup directory with bootstrap.ps1, apps.json, and Sophia.ps1
Files:
build-iso.ps1
bootstrap.ps1
📄 CodeRabbit inference engine (CLAUDE.md)
bootstrap.ps1: bootstrap.ps1 must be idempotent: skip already-installed apps and already-applied tweaks, and produce clear status for each step
bootstrap.ps1 must produce logs: Desktop summary at C:\Users[User]\Desktop\Setup Summary.txt and detailed log at C:\Setup\install.log
Provide a desktop shortcut to re-run bootstrap.ps1 manually
Files:
bootstrap.ps1
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to build-iso.ps1 : build-iso.ps1 must place autounattend.xml at ISO root and populate the $OEM$\$$\Setup directory with bootstrap.ps1, apps.json, and Sophia.ps1
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to **/*.ps1 : All scripts must target Windows 11 (22H2+) only; do not implement or test Windows 10 compatibility
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to {README.md,TODO.md,RESEARCH.md,SECURITY.md,CLAUDE.md,docs/**/*.md} : All documentation must assume Windows 11 (22H2+) only and explicitly exclude Windows 10 support
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to {autounattend.xml,apps.json,config/**/*.json} : All configuration files must assume Windows 11 (22H2+) only; do not include Windows 10 compatibility logic
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to bootstrap.ps1 : bootstrap.ps1 must be idempotent: skip already-installed apps and already-applied tweaks, and produce clear status for each step
Applied to files:
README.mdFAQ.mdbuild-iso.ps1bootstrap.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to **/*.ps1 : Do not create any PowerShell scripts (.ps1) during the planning phase
Applied to files:
README.mdCLAUDE.md
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to build-iso.ps1 : build-iso.ps1 must place autounattend.xml at ISO root and populate the $OEM$\$$\Setup directory with bootstrap.ps1, apps.json, and Sophia.ps1
Applied to files:
README.mdbuild-iso.ps1bootstrap.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to **/*.ps1 : All scripts must target Windows 11 (22H2+) only; do not implement or test Windows 10 compatibility
Applied to files:
build-iso.ps1bootstrap.ps1CLAUDE.md
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to {autounattend.xml,apps.json,config/**/*.json} : All configuration files must assume Windows 11 (22H2+) only; do not include Windows 10 compatibility logic
Applied to files:
build-iso.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to bootstrap.ps1 : bootstrap.ps1 must produce logs: Desktop summary at C:\Users\[User]\Desktop\Setup Summary.txt and detailed log at C:\Setup\install.log
Applied to files:
bootstrap.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to bootstrap.ps1 : Provide a desktop shortcut to re-run bootstrap.ps1 manually
Applied to files:
bootstrap.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: During planning, only work on documentation, planning/design docs, and configuration schemas/examples
Applied to files:
CLAUDE.md
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to {README.md,TODO.md,RESEARCH.md,SECURITY.md,CLAUDE.md,docs/**/*.md} : All documentation must assume Windows 11 (22H2+) only and explicitly exclude Windows 10 support
Applied to files:
CLAUDE.md
🔇 Additional comments (15)
FAQ.md (1)
1-48: No issues found. FAQ.md correctly reflects the project status and is well-aligned with the PR objectives.README.md (1)
1-180: Documentation phase transition is well-executed. The project status updates, workflow examples, and Windows version support are all appropriately aligned with the IMPLEMENTATION phase transition. Windows 11 (22H2+) support is correctly stated throughout, with Windows 10 support explicitly excluded per coding guidelines.CLAUDE.md (1)
1-203: Documentation correctly reflects implementation architecture and Windows 11 requirements. The ISO structure documentation (lines 99-111) accurately reflects the required file placement with autounattend.xml at the ISO root and configuration files in the$OEM$\$$\Setupdirectory. Windows 11 (22H2+) support is correctly emphasized throughout, with Windows 10 explicitly excluded per coding guidelines. The workflows and feature descriptions align well with the MVP objectives.build-iso.ps1 (6)
73-108: LGTM! Robust oscdimg.exe discovery logic.The function properly searches common installation paths, falls back to registry lookup, and provides helpful guidance when ADK is not found. The error message includes a direct link to installation instructions.
170-190: LGTM! Proper ISO mounting and content extraction.The script correctly mounts the source ISO, extracts its contents to a working directory, and promptly unmounts it before modifications. The use of
Resolve-Pathensures absolute paths for mounting operations.
192-236: LGTM! Correct file injection per requirements.The script properly:
- Places
autounattend.xmlat the ISO root- Creates the
$OEM$\$$\Setupdirectory structure (which maps toC:\Setupduring installation)- Copies
bootstrap.ps1,apps.json, andSophia-Preset.ps1into the setup directory- Generates a desktop shortcut script for re-running bootstrap
This aligns with the requirement that build-iso.ps1 must place autounattend.xml at ISO root and populate the
$OEM$ $$\Setup directory. Based on learnings.
238-286: LGTM! ISO building logic is sound.The script correctly:
- Resolves output paths to handle relative and absolute paths
- Creates output directory if needed
- Uses appropriate oscdimg parameters for dual-boot (BIOS + UEFI) Windows 11 ISO creation
- Validates the build succeeded and reports file size
The
-bootdataparameter formatting with backtick escaping is correct for PowerShell string handling.
287-339: LGTM! Comprehensive completion and cleanup.The script provides excellent user experience with:
- Clear success messaging and next steps
- Detailed error reporting with stack traces
- Robust cleanup in the
finallyblock that safely unmounts the ISO even on failure- Configurable temp file retention via
-KeepTempfor debuggingThe defensive programming with
ErrorAction SilentlyContinueduring cleanup prevents cascading errors.
143-158: No issues found. The code correctly usesSophia-Preset.ps1(the actual file that exists in the repository) and properly places all required files:autounattend.xmlat the ISO root andbootstrap.ps1,apps.json, andSophia-Preset.ps1in the$OEM$\$$\Setupdirectory as specified.bootstrap.ps1 (6)
30-89: LGTM! Logging infrastructure meets requirements.The logging functions provide:
- Timestamped, color-coded console output with severity levels
- Persistent logging to
C:\Setup\install.log- Summary collection and desktop report generation at
Setup Summary.txtThis aligns with the requirement to produce a desktop summary at C:\Users[User]\Desktop\Setup Summary.txt and detailed log at C:\Setup\install.log. Based on learnings.
176-182: Admin privilege check is redundant but provides better UX.The script includes
#Requires -RunAsAdministrator(line 1), which prevents non-admin execution. The manual check here is defensive and provides a clearer error message, which is good for user experience, but is technically redundant.
190-257: LGTM! Excellent idempotent WinGet installation logic.The script properly implements idempotency by:
- Checking which packages are already installed before attempting installation
- Skipping installation when all packages are present
- Creating a filtered import file containing only missing packages
- Providing clear status feedback for each scenario
This aligns with the requirement that bootstrap.ps1 must be idempotent: skip already-installed apps and produce clear status for each step. Based on learnings.
259-285: LGTM! Proper Sophia Script execution with defensive error handling.The script correctly:
- Uses the call operator (
&) to execute the Sophia preset- Checks both zero and null
$LASTEXITCODEvalues (important as not all PowerShell scripts set exit codes)- Treats non-zero exit codes as warnings rather than fatal errors, allowing the setup to continue
287-316: LGTM! Desktop assets meet requirements.The script creates:
- Desktop shortcut (
Run Windows Setup.lnk) to re-run bootstrap.ps1 manually- Desktop summary report (
Setup Summary.txt) with all setup resultsBoth assets have proper error handling that logs failures without stopping execution. This aligns with the requirement to provide a desktop shortcut to re-run bootstrap.ps1 manually. Based on learnings.
318-329: LGTM! Comprehensive completion and error handling.The script provides:
- Clear completion logging with log file location
- Fatal error handling with detailed stack traces for debugging
- Appropriate exit code (1) on failure
The error handling complements the per-step try/catch blocks throughout the script.
|
@codex review |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @build-iso.ps1:
- Around line 225-227: Add existence checks for the boot image variables
$bootImage and $efiBootImage before invoking oscdimg: verify both paths
(constructed with Join-Path) exist, and if either is missing, write a clear
error via Write-Error/Throw (including the missing path) and exit with a
non-zero code; place this validation immediately after the assignments to
$bootImage and $efiBootImage so the script fails fast with an informative
message instead of letting oscdimg produce a cryptic error.
🧹 Nitpick comments (5)
build-iso.ps1 (2)
249-258: Consider capturing oscdimg output for debugging.When
oscdimgfails, the current implementation only reports the exit code. Capturing stdout/stderr would aid troubleshooting.Proposed enhancement to capture oscdimg output
- Write-Info "Running: oscdimg $($oscdimgArgs -join ' ')" - - $process = Start-Process -FilePath $oscdimgPath -ArgumentList $oscdimgArgs -NoNewWindow -Wait -PassThru + Write-Info "Running: oscdimg $($oscdimgArgs -join ' ')" + + $oscdimgLog = Join-Path $TempDir "oscdimg.log" + $process = Start-Process -FilePath $oscdimgPath -ArgumentList $oscdimgArgs -NoNewWindow -Wait -PassThru -RedirectStandardOutput $oscdimgLog -RedirectStandardError "$oscdimgLog.err" if ($process.ExitCode -eq 0) { Write-Success "ISO built successfully!" } else { + if (Test-Path "$oscdimgLog.err") { + Write-Info "oscdimg error output:" + Get-Content "$oscdimgLog.err" | ForEach-Object { Write-Info $_ } + } throw "oscdimg.exe failed with exit code: $($process.ExitCode)" }
304-311: Cleanup may fail if source ISO path was relative and working directory changed.Using
Resolve-Path $SourceISOin the finally block could fail if the original path was relative and the working directory changed during execution. Consider storing the resolved path earlier.Proposed fix to store resolved path early
At the top of the try block (around line 157), store the resolved path:
$resolvedSourceISO = (Resolve-Path $SourceISO).Path $mount = Mount-DiskImage -ImagePath $resolvedSourceISO -PassThruThen update the cleanup:
try { if ($mount) { - Dismount-DiskImage -ImagePath (Resolve-Path $SourceISO).Path -ErrorAction SilentlyContinue | Out-Null + Dismount-DiskImage -ImagePath $resolvedSourceISO -ErrorAction SilentlyContinue | Out-Null } }bootstrap.ps1 (3)
158-167: Consider stricter package ID matching.Using
-matchwith[regex]::Escape($PackageId)could match partial strings if the package ID appears as a substring in other output. Since--exactis used, the output should be precise, but consider anchoring the match or checking for the ID in a structured way.Alternative approach using line-based matching
function Test-WingetPackageInstalled { param([string]$PackageId) $result = winget list --id $PackageId --exact 2>&1 if ($LASTEXITCODE -ne 0) { return $false } - return $result -match [regex]::Escape($PackageId) + # With --exact, presence of package lines beyond headers indicates installed + $lines = $result -split "`n" | Where-Object { $_ -match [regex]::Escape($PackageId) } + return $lines.Count -gt 0 }
286-312: Consider tracking Sophia Script execution state for idempotency.Per coding guidelines, the bootstrap should "skip already-applied tweaks." Currently, Sophia Script runs on every bootstrap execution. For MVP this may be acceptable if Sophia's internal logic is safe to re-run, but consider adding a marker file check for full idempotency.
Optional marker file approach
+ $sophiaMarker = Join-Path $SetupPath ".sophia-applied" + if (Test-Path $SophiaPreset) { + if (Test-Path $sophiaMarker) { + Write-Log "Sophia Script already applied (marker exists)" -Level SUCCESS + Add-SummaryItem -Step "Sophia" -Status "✓" -Message "Already applied (skipped)" + } + else { try { Write-Log "Found Sophia preset at $SophiaPreset" -Level INFO Write-Log "Executing Sophia Script..." -Level INFO & $SophiaPreset if ($LASTEXITCODE -eq 0 -or $null -eq $LASTEXITCODE) { Write-Log "Sophia Script execution completed" -Level SUCCESS Add-SummaryItem -Step "Sophia" -Status "✓" -Message "Sophia preset applied" + New-Item -Path $sophiaMarker -ItemType File -Force | Out-Null } else { ... } } + } }
351-356: Add summary item for fatal errors before exiting.If a fatal error occurs, the desktop summary won't reflect the failure since
Write-SummaryReportis only called in the success path.Proposed fix to write summary on failure
catch { Write-Log "FATAL ERROR: $($_.Exception.Message)" -Level ERROR Write-Log "Stack Trace: $($_.ScriptStackTrace)" -Level ERROR + Add-SummaryItem -Step "Bootstrap" -Status "✗" -Message "Fatal error: $($_.Exception.Message)" + try { + $desktopPath = [Environment]::GetFolderPath("Desktop") + Write-SummaryReport -DesktopPath $desktopPath | Out-Null + } catch { } exit 1 }
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
bootstrap.ps1build-iso.ps1
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ps1
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.ps1: Do not create any PowerShell scripts (.ps1) during the planning phase
All scripts must target Windows 11 (22H2+) only; do not implement or test Windows 10 compatibility
Files:
bootstrap.ps1build-iso.ps1
bootstrap.ps1
📄 CodeRabbit inference engine (CLAUDE.md)
bootstrap.ps1: bootstrap.ps1 must be idempotent: skip already-installed apps and already-applied tweaks, and produce clear status for each step
bootstrap.ps1 must produce logs: Desktop summary at C:\Users[User]\Desktop\Setup Summary.txt and detailed log at C:\Setup\install.log
Provide a desktop shortcut to re-run bootstrap.ps1 manually
Files:
bootstrap.ps1
build-iso.ps1
📄 CodeRabbit inference engine (CLAUDE.md)
build-iso.ps1 must place autounattend.xml at ISO root and populate the
$OEM$ $$\Setup directory with bootstrap.ps1, apps.json, and Sophia.ps1
Files:
build-iso.ps1
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to build-iso.ps1 : build-iso.ps1 must place autounattend.xml at ISO root and populate the $OEM$\$$\Setup directory with bootstrap.ps1, apps.json, and Sophia.ps1
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to **/*.ps1 : All scripts must target Windows 11 (22H2+) only; do not implement or test Windows 10 compatibility
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to {README.md,TODO.md,RESEARCH.md,SECURITY.md,CLAUDE.md,docs/**/*.md} : All documentation must assume Windows 11 (22H2+) only and explicitly exclude Windows 10 support
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to bootstrap.ps1 : bootstrap.ps1 must produce logs: Desktop summary at C:\Users\[User]\Desktop\Setup Summary.txt and detailed log at C:\Setup\install.log
Applied to files:
bootstrap.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to bootstrap.ps1 : bootstrap.ps1 must be idempotent: skip already-installed apps and already-applied tweaks, and produce clear status for each step
Applied to files:
bootstrap.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to bootstrap.ps1 : Provide a desktop shortcut to re-run bootstrap.ps1 manually
Applied to files:
bootstrap.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to build-iso.ps1 : build-iso.ps1 must place autounattend.xml at ISO root and populate the $OEM$\$$\Setup directory with bootstrap.ps1, apps.json, and Sophia.ps1
Applied to files:
bootstrap.ps1build-iso.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to **/*.ps1 : All scripts must target Windows 11 (22H2+) only; do not implement or test Windows 10 compatibility
Applied to files:
bootstrap.ps1build-iso.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to {autounattend.xml,apps.json,config/**/*.json} : All configuration files must assume Windows 11 (22H2+) only; do not include Windows 10 compatibility logic
Applied to files:
build-iso.ps1
🔇 Additional comments (8)
build-iso.ps1 (3)
1-43: LGTM! Script header and parameters are well-structured.The
#Requires -RunAsAdministratordirective, comprehensive documentation block, and parameter validation usingValidateScriptare appropriate for an ISO build tool.
53-108: LGTM! Utility functions and ADK discovery logic are solid.The fallback to registry lookup for Windows ADK path and the user-friendly error message with installation link are helpful. The colored output functions provide good UX.
175-199: LGTM! File placement follows project requirements.The script correctly places
autounattend.xmlat the ISO root and populates$OEM$\$$\Setupwithbootstrap.ps1,apps.json, andSophia-Preset.ps1as specified in the coding guidelines.bootstrap.ps1 (5)
1-28: LGTM! Script configuration and initialization are well-structured.The
#Requires -RunAsAdministratordirective, documentation block stating idempotency, and configuration paths align with the coding guidelines requiring logs atC:\Setup\install.log.
30-89: LGTM! Logging and summary functions meet requirements.The implementation produces logs at
C:\Setup\install.logand desktop summary atSetup Summary.txtas specified in the coding guidelines.
91-138: LGTM! Robust network connectivity check.The multi-layered approach with ICMP ping fallback to HTTPS checks, command availability detection, and configurable timeout provides reliable network detection in various environments.
217-284: LGTM! WinGet import logic is idempotent.The implementation correctly checks for already-installed packages and only imports missing ones, satisfying the idempotency requirement from the coding guidelines. Error handling and summary reporting are comprehensive.
314-349: LGTM! Desktop assets creation meets requirements.The desktop shortcut for re-running bootstrap and the summary report generation fulfill the coding guidelines for providing a manual re-run option and desktop summary at
C:\Users\[User]\Desktop\Setup Summary.txt.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 02079a434f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
02079a4 to
0e6a832
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @bootstrap.ps1:
- Around line 158-167: In Test-WingetPackageInstalled, remove the early exit
that returns $false when $LASTEXITCODE -ne 0 and instead rely solely on matching
the captured winget output ($result) against the escaped package id; keep the
existing STDERR redirection (2>&1) so warnings/errors are included in $result,
and return the boolean of ($result -match [regex]::Escape($PackageId)) as the
authoritative presence check.
In @README.md:
- Around line 9-13: The README shows MVP scripts as implemented but the Project
Structure still labels bootstrap.ps1 and build-iso.ps1 as "(planned)"; update
the Project Structure entries for bootstrap.ps1 and build-iso.ps1 to remove the
"(planned)" label and ensure the MVP Workflow section and any mentions in lines
26-35 and 137-138 reflect that these scripts exist and include the concrete
usage examples already present (i.e., remove the planned marker and keep the
existing usage text for bootstrap.ps1 and build-iso.ps1).
🧹 Nitpick comments (4)
bootstrap.ps1 (4)
22-22: Consider using "Stop" ErrorActionPreference for more reliable error detection.Setting
$ErrorActionPreference = "Continue"allows the script to proceed even when cmdlets encounter errors, which might mask critical failures. Since the script already uses comprehensive try-catch blocks for error handling (lines 223, 271, 290, 304, 319, 332, 337, 352), consider using"Stop"to ensure errors are properly caught and logged.♻️ Proposed adjustment
-$ErrorActionPreference = "Continue" +$ErrorActionPreference = "Stop"
140-156: Consider adding structure validation for robustness.While the function correctly parses the winget import JSON format, it assumes the structure is valid (e.g.,
$data.Sourcesexists and is enumerable). Since the caller (line 231) has try-catch protection, this is acceptable, but adding a null check for$data.Sourcescould improve error messages.♻️ Optional defensive check
function Get-WingetPackageIdsFromJson { param([string]$Path) $content = Get-Content -Path $Path -Raw $data = $content | ConvertFrom-Json + + if (-not $data.Sources) { + return @() + } + $packageIds = @() foreach ($source in $data.Sources) {
203-209: Optional: Remove redundant administrator check.The manual admin check on lines 204-208 is redundant with the
#Requires -RunAsAdministratordirective on line 1, which already prevents the script from executing without admin privileges. While harmless, removing this check would reduce code duplication.♻️ Optional simplification
- # Verify admin privileges - $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) - if (-not $isAdmin) { - Write-Log "ERROR: This script must be run as Administrator" -Level ERROR - exit 1 - } Write-Log "Administrator privileges verified" -Level SUCCESS
320-327: Use dynamic script path for better portability.The shortcut currently hardcodes the script path as
C:\Setup\bootstrap.ps1(line 324). If the script is moved or copied to a different location, the shortcut will break. Consider using$PSCommandPathto reference the current script's location dynamically.♻️ Proposed enhancement for portability
$shortcutPath = Join-Path $desktopPath "Run Windows Setup.lnk" $shell = New-Object -ComObject WScript.Shell $shortcut = $shell.CreateShortcut($shortcutPath) $shortcut.TargetPath = "powershell.exe" - $shortcut.Arguments = "-ExecutionPolicy Bypass -File C:\Setup\bootstrap.ps1" - $shortcut.WorkingDirectory = "C:\Setup" + $shortcut.Arguments = "-ExecutionPolicy Bypass -File `"$PSCommandPath`"" + $shortcut.WorkingDirectory = Split-Path -Parent $PSCommandPath $shortcut.Description = "Re-run declarative Windows setup" $shortcut.Save()
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
CLAUDE.mdFAQ.mdREADME.mdbootstrap.ps1build-iso.ps1
🚧 Files skipped from review as they are similar to previous changes (1)
- build-iso.ps1
🧰 Additional context used
📓 Path-based instructions (3)
{README.md,TODO.md,RESEARCH.md,SECURITY.md,CLAUDE.md,docs/**/*.md}
📄 CodeRabbit inference engine (CLAUDE.md)
All documentation must assume Windows 11 (22H2+) only and explicitly exclude Windows 10 support
Files:
CLAUDE.mdREADME.md
**/*.ps1
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.ps1: Do not create any PowerShell scripts (.ps1) during the planning phase
All scripts must target Windows 11 (22H2+) only; do not implement or test Windows 10 compatibility
Files:
bootstrap.ps1
bootstrap.ps1
📄 CodeRabbit inference engine (CLAUDE.md)
bootstrap.ps1: bootstrap.ps1 must be idempotent: skip already-installed apps and already-applied tweaks, and produce clear status for each step
bootstrap.ps1 must produce logs: Desktop summary at C:\Users[User]\Desktop\Setup Summary.txt and detailed log at C:\Setup\install.log
Provide a desktop shortcut to re-run bootstrap.ps1 manually
Files:
bootstrap.ps1
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to **/*.ps1 : All scripts must target Windows 11 (22H2+) only; do not implement or test Windows 10 compatibility
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to build-iso.ps1 : build-iso.ps1 must place autounattend.xml at ISO root and populate the $OEM$\$$\Setup directory with bootstrap.ps1, apps.json, and Sophia.ps1
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to bootstrap.ps1 : bootstrap.ps1 must be idempotent: skip already-installed apps and already-applied tweaks, and produce clear status for each step
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to {autounattend.xml,apps.json,config/**/*.json} : All configuration files must assume Windows 11 (22H2+) only; do not include Windows 10 compatibility logic
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to bootstrap.ps1 : bootstrap.ps1 must produce logs: Desktop summary at C:\Users\[User]\Desktop\Setup Summary.txt and detailed log at C:\Setup\install.log
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to **/*.ps1 : Do not create any PowerShell scripts (.ps1) during the planning phase
Applied to files:
FAQ.mdCLAUDE.mdREADME.md
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to bootstrap.ps1 : bootstrap.ps1 must be idempotent: skip already-installed apps and already-applied tweaks, and produce clear status for each step
Applied to files:
FAQ.mdbootstrap.ps1README.md
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: During planning, only work on documentation, planning/design docs, and configuration schemas/examples
Applied to files:
CLAUDE.md
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to **/*.ps1 : All scripts must target Windows 11 (22H2+) only; do not implement or test Windows 10 compatibility
Applied to files:
CLAUDE.md
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to {README.md,TODO.md,RESEARCH.md,SECURITY.md,CLAUDE.md,docs/**/*.md} : All documentation must assume Windows 11 (22H2+) only and explicitly exclude Windows 10 support
Applied to files:
CLAUDE.md
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to bootstrap.ps1 : bootstrap.ps1 must produce logs: Desktop summary at C:\Users\[User]\Desktop\Setup Summary.txt and detailed log at C:\Setup\install.log
Applied to files:
bootstrap.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to bootstrap.ps1 : Provide a desktop shortcut to re-run bootstrap.ps1 manually
Applied to files:
bootstrap.ps1
📚 Learning: 2025-10-02T09:50:23.485Z
Learnt from: CR
Repo: Timpan4/declarative-windows PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-02T09:50:23.485Z
Learning: Applies to build-iso.ps1 : build-iso.ps1 must place autounattend.xml at ISO root and populate the $OEM$\$$\Setup directory with bootstrap.ps1, apps.json, and Sophia.ps1
Applied to files:
bootstrap.ps1README.md
🔇 Additional comments (15)
FAQ.md (1)
9-9: LGTM!Status update accurately reflects the project transition to Implementation Phase with appropriate references to MVP scripts.
README.md (1)
148-152: Windows version support is correctly documented.The file properly restricts scope to Windows 11 (22H2+) and explicitly excludes Windows 10 support, aligning with project guidelines and documentation requirements.
CLAUDE.md (4)
5-15: Phase transition properly documented.The project phase is clearly updated from planning to implementation, with explicit identification of the two MVP scripts being built (bootstrap.ps1 and build-iso.ps1) and acknowledgment that configuration files are already in place.
19-25: Windows 11 (22H2+) requirement is clearly established.The Windows Version Support section properly restricts scope to Windows 11 exclusively and explicitly excludes Windows 10 support. This aligns with project documentation guidelines.
99-111: ISO structure correctly documents file placement requirements.The ISO structure diagram accurately reflects the required file layout:
autounattend.xmlat root (line 104)bootstrap.ps1,apps.json, andSophia.ps1in$OEM$\$$\Setupdirectory (lines 108-110)This aligns with the specified build-iso.ps1 behavior.
142-158: Idempotency and logging requirements are properly documented.The Key Features section correctly documents that
bootstrap.ps1is idempotent (safe to run multiple times with status reporting) and produces the required dual-location logging:
- Desktop summary at
C:\Users\[User]\Desktop\Setup Summary.txt- Detailed log at
C:\Setup\install.logThis aligns with established requirements for the bootstrap script.
bootstrap.ps1 (9)
1-19: LGTM! Well-structured script header.The
#Requires -RunAsAdministratordirective ensures proper elevation, and the comment-based help clearly documents the script's purpose and idempotent design.
30-52: LGTM! Robust logging implementation.The centralized logging with color-coded console output and file persistence provides excellent observability. The use of
-ErrorAction SilentlyContinueon file writes prevents logging failures from disrupting the setup process.
54-71: LGTM! Clean summary tracking mechanism.The function provides a straightforward way to collect step results for the final report. Using a generic list and PSCustomObject is efficient and idiomatic for PowerShell.
73-89: LGTM! Meets desktop summary requirement.The function correctly writes the summary report to the user's desktop as specified in the coding guidelines. The format is clear and includes all necessary information.
As per coding guidelines, this implementation aligns with the requirement to produce a summary at
C:\Users\[User]\Desktop\Setup Summary.txt.
91-138: LGTM! Comprehensive network connectivity check.The multi-method approach (ICMP ping to multiple targets, fallback HTTPS checks) with cmdlet availability detection ensures robust network readiness validation across different system configurations. The 300-second timeout is reasonable for post-installation network initialization.
169-195: LGTM! Effective JSON filtering preserves winget import structure.The function correctly filters packages while maintaining the required JSON structure, including the schema reference and source details. The depth of 10 for JSON serialization should accommodate typical package configurations.
217-284: LGTM! Excellent idempotency implementation.The WinGet step correctly implements idempotency by checking for already-installed packages before attempting installation (lines 240-244), which aligns with the coding guidelines. The network wait, error handling, and temp file cleanup (finally block) are all well-designed.
The interpretation of winget exit codes (lines 259-266) as either success (0) or warning (non-zero) is pragmatic, though be aware that winget can return various exit codes that may represent different severity levels.
As per coding guidelines, this implementation fulfills the requirement for bootstrap.ps1 to be idempotent.
286-312: LGTM! Appropriate external script execution.The Sophia Script execution handles both exit code scenarios and exceptions appropriately. Checking for
$null -eq $LASTEXITCODE(line 296) is important since not all PowerShell scripts set an explicit exit code.
345-356: LGTM! Robust completion and error handling.The final logging banner and top-level exception handler with stack trace capture (line 354) provide excellent observability for troubleshooting setup failures.
| function Test-WingetPackageInstalled { | ||
| param([string]$PackageId) | ||
|
|
||
| $result = winget list --id $PackageId --exact 2>&1 | ||
| if ($LASTEXITCODE -ne 0) { | ||
| return $false | ||
| } | ||
|
|
||
| return $result -match [regex]::Escape($PackageId) | ||
| } |
There was a problem hiding this comment.
Fix potential false negatives in package detection.
The early return on line 162-164 when $LASTEXITCODE -ne 0 can cause false negatives. winget list may return non-zero exit codes even when the package is found (e.g., when package metadata has issues or minor warnings occur). The regex match on line 166 is the authoritative check.
Removing the exit code early-return and relying solely on the regex match will improve idempotency by preventing unnecessary reinstallation attempts.
🐛 Proposed fix to rely on output matching
function Test-WingetPackageInstalled {
param([string]$PackageId)
$result = winget list --id $PackageId --exact 2>&1
- if ($LASTEXITCODE -ne 0) {
- return $false
- }
return $result -match [regex]::Escape($PackageId)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function Test-WingetPackageInstalled { | |
| param([string]$PackageId) | |
| $result = winget list --id $PackageId --exact 2>&1 | |
| if ($LASTEXITCODE -ne 0) { | |
| return $false | |
| } | |
| return $result -match [regex]::Escape($PackageId) | |
| } | |
| function Test-WingetPackageInstalled { | |
| param([string]$PackageId) | |
| $result = winget list --id $PackageId --exact 2>&1 | |
| return $result -match [regex]::Escape($PackageId) | |
| } |
🤖 Prompt for AI Agents
In @bootstrap.ps1 around lines 158 - 167, In Test-WingetPackageInstalled, remove
the early exit that returns $false when $LASTEXITCODE -ne 0 and instead rely
solely on matching the captured winget output ($result) against the escaped
package id; keep the existing STDERR redirection (2>&1) so warnings/errors are
included in $result, and return the boolean of ($result -match
[regex]::Escape($PackageId)) as the authoritative presence check.
| ## ⚠️ Project Status: Implementation Phase | ||
|
|
||
| **No scripts exist yet.** This is currently planning and documentation. | ||
| **MVP scripts exist** (`bootstrap.ps1`, `build-iso.ps1`) and are in active development. | ||
|
|
||
| See [TODO.md](TODO.md) for implementation tasks. | ||
| See [TODO.md](TODO.md) for remaining implementation tasks. |
There was a problem hiding this comment.
Resolve inconsistency: Project status vs. Project Structure labels.
Lines 9-13 and the MVP Workflow section (lines 26-35) indicate that MVP scripts exist and are operational with concrete usage examples. However, the Project Structure section (lines 137-138) still labels both bootstrap.ps1 and build-iso.ps1 with (planned), suggesting they are not yet implemented.
Update lines 137-138 to remove the (planned) labels and align them with the project status:
🔧 Proposed fix
├── apps.json # Your WinGet package list (create this)
├── Sophia-Preset.ps1 # Custom Sophia Script configuration
├── autounattend.xml # Windows unattended install config
-├── bootstrap.ps1 # Main orchestration script (planned)
-├── build-iso.ps1 # ISO generation script (planned)
+├── bootstrap.ps1 # Main orchestration script
+├── build-iso.ps1 # ISO generation scriptAlso applies to: 26-35, 137-138
🤖 Prompt for AI Agents
In @README.md around lines 9 - 13, The README shows MVP scripts as implemented
but the Project Structure still labels bootstrap.ps1 and build-iso.ps1 as
"(planned)"; update the Project Structure entries for bootstrap.ps1 and
build-iso.ps1 to remove the "(planned)" label and ensure the MVP Workflow
section and any mentions in lines 26-35 and 137-138 reflect that these scripts
exist and include the concrete usage examples already present (i.e., remove the
planned marker and keep the existing usage text for bootstrap.ps1 and
build-iso.ps1).
Summary by CodeRabbit
New Features
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.