BREAKING CHANGE: Removes --target and --gpu-driver flags, unified ISO for all use cases
## Phase 0: GPU Fix + Unified ISO
### Core Changes
**GPU Package Installation (FIXES CRITICAL GAP):**
- Add clawdie_shell_nvidia_install() function to shell-nvidia.sh
- NVIDIA drivers now installed after detection (previously only configured)
- Works offline (USB packages) or online (pkg install)
- Resolves issue where rc.conf was set but driver not installed
**Unified ISO Architecture:**
- Remove --target flag from build.sh (no more vps/baremetal branching)
- Remove --gpu-driver flag from build.sh (runtime detection instead)
- All packages included on every ISO (desktop + all GPU drivers)
- Single image works on VPS, baremetal, and cloud
**Runtime Detection:**
- Add shell-desktop.sh for display detection at firstboot
- VPS/cloud: no display → lightdm disabled (headless)
- Baremetal: display detected → lightdm enabled (Lumina desktop)
- GPU detection always runs, installs correct driver version
**Sudo Unification:**
- Replace all doas references with sudo across entire codebase
- Update AGENTS.md with system configuration guidelines
- Update all documentation (BUILD.md, README.md, REQUIREMENTS.md, etc.)
- Admin panel now uses sudo for privileged operations
### Files Modified
**Core System:**
- build.sh: Remove target/gpu-driver logic, unified package selection
- firstboot/firstboot.sh: Add desktop detection module
- firstboot/shell-nvidia.sh: Add package installation function (+33 lines)
**New Files:**
- firstboot/shell-desktop.sh: Display detection and desktop enablement
- packages/pkg-list-nvidia-all.txt: All three NVIDIA driver versions (390/470/590)
- .opencode/plans/phase0-gpu-fix-unified-iso.md: Implementation plan
**Documentation:**
- PLAN-UNIFY.md: Update Step 3 for unified approach
- REQUIREMENTS.md: Simplify (no target choice), update for sudo
- BUILD.md: Update for unified ISO, sudo commands
- README.md: Update installation instructions
- AGENTS.md: Add system configuration section (sudo standardization)
- ADMIN-PANEL.md: Update privileged operations to use sudo
- CLAWDIE-SHELL.md: Update example commands to sudo
- CLAWDIE-ISO-REFACTORED.md: Update access paths to sudo
- REFACTOR-SUMMARY.md: Update permissions section to sudo
### Benefits
**Simplicity:**
- One build command: ./build.sh (no flags needed)
- One ISO to test and maintain
- No wrong choices for users
- No documentation explaining target differences
**Flexibility:**
- VPS can use GUI via VNC (wayvnc always available)
- Baremetal can run headless (disable lightdm)
- Repurpose hardware without reinstall
- All GPU drivers available for any hardware
**Technical:**
- Fixes critical GPU driver installation gap
- Runtime detection replaces build-time decisions
- Disk overhead: ~650MB (1-2% of 50GB - acceptable)
- No runtime overhead on VPS (services disabled by detection)
### Testing Required
- [ ] Build unified ISO: ./build.sh
- [ ] Test on VPS (no display): lightdm disabled, packages installed
- [ ] Test on baremetal (display): lightdm enabled, Lumina boots
- [ ] Test on NVIDIA hardware: driver installed and loaded
- [ ] Test sudo commands work without password prompts
- [ ] Verify all doas references removed
- Change default FEATURE_TAILSCALE from NO to YES
- Add build-time warning if TAILSCALE_AUTHKEY not set
- Update firstboot wizard: Tailscale moves to screen 2
- Add summary screen showing Tailscale status
- Update shell-tailscale.sh to handle missing auth key gracefully
- Update BUILD.md with new recommended/optional flow
User experience:
- With auth key: Tailscale auto-connects (secure)
- Without auth key: Warning shown, build continues (public SSH)
- Wizard allows enabling/disabling with clear warnings
No breaking changes - existing builds still work.
- Archive clawdie-shell, merge everything into clawdie-iso
- --target vps|baremetal build flag
- Tailscale mandatory: security perimeter, glasspane feature
- Port shell-pf.sh + NETWORKING.md from clawdie-shell
- Full implementation plan for next agent session
The .env template was missing two vars that src/config.ts reads at
runtime. Without them embeddings silently fall back to wrong defaults
(768 dims vs the 1024 the pgvector schema expects).
- shell-env.sh: add EMBED_API_KEY + EMBED_DIMENSIONS to template
- build.cfg: add matching defaults (1024 dims)
- firstboot.sh: export the new vars
- cloud-path-test.sh: add EMBED var checks (now 19 total)
Build: not tested | Tests: PASS (cloud-path 19/19, integration 7/7)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- shell-system.sh: exit → return in sourced module (would kill firstboot)
- maintenance-mode.sh: replace bash += with POSIX concat, fix subshell
scope in pipe-to-while-read (vdev_status/failed_disks were always
empty), quote all $POOL_NAME and $disk expansions
- build-vps.sh: portable _sed_i() wrapper for FreeBSD/Linux
- firstboot.sh: set -eu; set USB_PKG_PATH to SHARE/packages so offline
package repo works after HDD boot (was defaulting to /mnt/media)
- firstboot-vps.sh: remove plaintext password log, check loader.efi
exists before EFI copy
Integration test: PASS (7/7 modules)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
shell-deploy.sh now branches on CLAWDIE_BOOT_MODE:
- install: existing fresh path (extract tarball, seed .env, install-all)
- upgrade: extract to staging dir, run skills-engine applyUpdate()
for three-way merge preserving customizations, restore existing
.env, then install-all for db migrations. Falls back to overwrite
+ migrateExisting() if no .nanoclaw/ present.
Overwrite fallback preserves data/, store/, logs/, groups/,
.nanoclaw/, node_modules/ across the upgrade.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite vps/firstboot-vps.sh as phase-1 only: partition disk,
create ZFS pool "clawdie", install FreeBSD base, inject firstboot
payload, install bootloader, reboot. On first HDD boot the standard
firstboot.sh modular pipeline runs (zfs detect, wizard, gpu, pkg,
ssh, env, system, tailscale, deploy).
Pre-baked clawdie.conf values get written to build.cfg with
TARGET=cloud so the wizard is skipped. Pool named "clawdie"
(not zroot) for pool detection compatibility.
Remove duplicate clawdie-vps-setup.sh.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New shell-zfs.sh module: detects existing clawdie pool, presents
boot mode menu (install/upgrade/maintenance/shell). Runs as first
step in firstboot.sh before wizard. Upgrade mode loads existing
.env and skips wizard. Maintenance mode exec's to maintenance-mode.sh.
Also: fix POSIX herestrings in maintenance-mode.sh, fix paren
mismatch in snapshot age calc, add nda (NVMe) to disk detection
patterns across all ZFS scripts for FreeBSD 15.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add .nanoclaw/ and bootstrap artifact checks to shell-deploy.sh
post-install verification. Complements the new skills-init step
added to clawdie-ai's install pipeline.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Moves bhyve VMs off warden0 (jail bridge) to avoid ARP/routing conflicts
with running agent jails. Auto-picks unused tap interface, adds PF NAT
idempotently, cleans up tap on exit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
build.cfg now uses ${VAR:-} pattern so env vars take precedence,
enabling cloud builds with arbitrary agent config via environment.
build.sh step 6 now injects all new fields (AGENT_GENDER,
PI_TUI_PROVIDER, PI_TUI_MODEL, API keys, Telegram, embeddings)
into the baked build.cfg inside the image.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- build.sh: force LC_TIME=C so date +%b always outputs "Mar" not "Mar."
Prevents double-dot filenames (e.g. 30.mar..2026.img) on sl_SI locale
- bhyve-test.sh: auto-detect newest baremetal .img or accept path as $1
Removes hardcoded filename that breaks after each new build
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wraps build.sh, captures stdout+stderr with tee, generates a styled
HTML page matching the site's dark theme (DM Mono terminal block,
status badge, duration). Publishes two copies:
- /docs/iso-build-log.html (always latest)
- /docs/iso-build-YYYY-MM-DD.html (dated archive permalink)
Usage: sudo ./scripts/build-and-log.sh [build.sh args...]
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
firstboot.sh:
- Set SHELL_{GPU,NVIDIA,PKG,ENV,DEPLOY}_TEST=1 before sourcing modules
(prevents double-execution on source — same bug fixed in integration-test)
- Add --resume: run_step() skips steps already recorded in progress file
- Add --reset: clears progress file, starts over from scratch
- Add --help
- Wizard tracked as checkpoint so --resume skips re-prompting the user
- run_step() helper: guard → run → mark done in one call
scripts/bhyve-test.sh (was tmp/bhyve-test-setup.sh):
- Moved to tracked scripts/ directory (tmp/ is gitignored)
- Timeout 300→1800s (full install is 20–25 min, not 5)
scripts/run-bhyve-test.sh (was tmp/run-bhyve-test.sh):
- Moved to scripts/, log output redirected to logs/ (also gitignored)
BUILD.md, TESTING.md, IMPLEMENTATION-PLAN.md:
- Update all bhyve script references to scripts/bhyve-test.sh
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each shell module guards auto-run with SHELL_*_TEST env vars but the
integration test wasn't setting them, causing every module to execute
twice (once on source, once on explicit call).
Fixes:
- Set SHELL_{ENV,PKG,GPU,NVIDIA,SYSTEM,DEPLOY}_TEST=1 before sourcing
- Mock CLAWDIE_TARBALL with a real tar.gz of the pre-populated test dir
so the deploy module can extract + verify without needing the ISO
- Redirect shell-system stdout+stderr to /dev/null (service enables
write "does not exist" to stdout on a headless host)
All 6 modules now execute exactly once, cleanly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
integration-test.sh still sourced old clawdie-shell-*.sh names after
the rename in 66484dc. BUILD.md and TESTING.md referenced /tmp/ (system)
instead of ./tmp/ (repo-local) for bhyve-test-setup.sh. Add /tmp/ to
.gitignore.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Create packages/pkg-list-lumina.txt with Lumina desktop environment packages
- Delete pkg-list-xfce.txt, pkg-list-mate.txt, pkg-list-kde.txt
- Remove desktop-installer from pkg-list-desktop-base.txt
- build.cfg: DEFAULT_DESKTOP=lumina (sole supported DE)
- build.sh: use pkg-list-lumina.txt instead of pkg-list-xfce.txt
- BUILD.md: update DEFAULT_DESKTOP comment
- CLAWDIE-ISO.md: add deprecation notice, update all DE references to Lumina only
Lumina is the sole supported FreeBSD-native desktop environment as per
LUMINA-INTEGRATION.md and CLAWDIE-ISO-REFACTORED.md specifications.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>