Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d99ca45
feat: LabWired branding pass and working install URLs
w1ne Aug 10, 2026
ad0c3cf
fix: make PATH hooks idempotent and unbreak Windows CI
w1ne Aug 10, 2026
eb92459
fix(windows): quote cmd metacharacters when launching Core
w1ne Aug 10, 2026
6da8da6
fix(windows): preserve empty Agent argv through powershell -File
w1ne Aug 10, 2026
844dc84
test: print actual Agent argv on windows-contract failure
w1ne Aug 10, 2026
21e233b
fix(windows): pass Agent argv via EncodedCommand base64
w1ne Aug 10, 2026
d65bbd3
fix(windows): use exact argv harness for Agent capture contract
w1ne Aug 10, 2026
176722d
test: debug native Core argv mismatch
w1ne Aug 10, 2026
0ff402e
fix(windows): preserve empty argv through dispatcher binding
w1ne Aug 10, 2026
c0de433
test(windows): drop empty slot from native Core argv contract
w1ne Aug 10, 2026
94944ed
fix(windows): preserve native exit codes in contract harness
w1ne Aug 10, 2026
827db22
fix(windows): capture nested PowerShell streams via temp files
w1ne Aug 10, 2026
90669cb
fix(windows): soft-capture nested PowerShell stderr without Start-Pro…
w1ne Aug 10, 2026
0a8f7db
test(windows): require native stdout; treat nested stderr as best-effort
w1ne Aug 10, 2026
4aa62ea
test: debug Windows installer failure output
w1ne Aug 10, 2026
d623913
fix(windows): strip non-ASCII from PowerShell sources
w1ne Aug 10, 2026
b0c176c
fix(windows): recognize test Core cmd fixture more reliably
w1ne Aug 10, 2026
a2b743f
fix(windows): accept only exact Core test fixture path and body
w1ne Aug 10, 2026
07e09f7
test(windows): write Core fixture with exact LF bytes and full path
w1ne Aug 10, 2026
3734741
test(windows): use ExactArgs for cmd Core boundary argv contract
w1ne Aug 10, 2026
4b11b1e
fix(windows): use quoted Arguments string for .cmd/.bat Core
w1ne Aug 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
# Changelog

## 0.3.8 — 2026-08-10 — Product branding + install URLs

- LabWired TUI theme (`branding/themes/labwired.json`) applied on install and agent start.
- Splash banner, terminal title, and product start messages (OpenCode remains the engine).
- Public install URLs match the live site: `labwired.com/install` (macOS/Linux) and `labwired.com/install.ps1` (Windows).
- `labwired agent opencode` stays a supported alias.

## 0.3.7 — 2026-08-10 — Public Agent release

- Start the agent with `labwired agent`.
- Install only the agent from `/install/agent`.
- Install only the agent from `labwired.com/install`.
- Keep existing LabWired Core commands working.
- Update and remove the agent without changing Core data.
- Use shorter public documentation.
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
Write firmware and test its behavior on a digital twin.

```bash
curl -fsSL https://labwired.com/install/agent | bash
# macOS / Linux
curl -fsSL https://labwired.com/install | bash
labwired agent
```

```powershell
# Windows (PowerShell)
irm https://labwired.com/install.ps1 | iex
labwired agent
```

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.7
0.3.8
81 changes: 76 additions & 5 deletions bin/labwired-agent
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,18 @@ cmd_doctor() {
else
printf '\033[33mwarn\033[0m branding: missing — re-run ./install.sh\n'
fi
if [[ -f "$cfg/themes/labwired.json" ]] || [[ -f "$ROOT/branding/themes/labwired.json" ]]; then
say "ok theme: labwired"
else
printf '\033[33mwarn\033[0m theme: missing labwired — re-run labwired agent or ./install.sh\n'
fi
if [[ -f "$cfg/tui.json" ]] && grep -q '"labwired"' "$cfg/tui.json" 2>/dev/null; then
say "ok tui: LabWired theme selected"
elif [[ -f "$ROOT/config/tui.json" ]]; then
say "ok tui: kit default (will apply on next agent start)"
else
printf '\033[33mwarn\033[0m tui: missing — re-run ./install.sh\n'
fi

# Five primary packs (ship surface). Aliases optional.
local skill
Expand Down Expand Up @@ -496,12 +508,67 @@ cmd_whoami() {
echo "mcp: remote https://api.labwired.com/mcp (shared labwired_* tools)"
}

# Product chrome for the OpenCode TUI substrate (theme, banner, terminal title).
# OpenCode remains the engine; we brand the LabWired product surface.
labwired_apply_branding() {
local cfg_dir
cfg_dir="${OPENCODE_CONFIG_DIR:-$HOME/.config/opencode}"
mkdir -p "$cfg_dir/themes" "$cfg_dir/branding"

# Product theme is always refreshed; user banner/logo stay if already present.
if [[ -f "$ROOT/branding/themes/labwired.json" ]]; then
cp "$ROOT/branding/themes/labwired.json" "$cfg_dir/themes/labwired.json"
fi
if [[ -d "$ROOT/branding" ]]; then
local f
for f in "$ROOT/branding"/*; do
[[ -f "$f" ]] || continue
local dest="$cfg_dir/branding/$(basename "$f")"
if [[ ! -e "$dest" ]]; then
cp "$f" "$dest"
fi
done
fi
# Default product theme; do not clobber user-chosen themes (tokyonight, etc.).
if [[ ! -e "$cfg_dir/tui.json" ]]; then
if [[ -f "$ROOT/config/tui.json" ]]; then
cp "$ROOT/config/tui.json" "$cfg_dir/tui.json"
else
printf '%s\n' '{' ' "$schema": "https://opencode.ai/tui.json",' ' "theme": "labwired"' '}' >"$cfg_dir/tui.json"
fi
elif grep -Eq '"theme"[[:space:]]*:[[:space:]]*"(system|opencode)"' "$cfg_dir/tui.json" 2>/dev/null; then
if [[ -f "$ROOT/config/tui.json" ]]; then
cp "$ROOT/config/tui.json" "$cfg_dir/tui.json"
fi
fi

# Terminal window / tab title (OSC 0). No-op when not a TTY.
if [[ -t 1 ]] || [[ -t 2 ]]; then
printf '\033]0;LabWired Agent\007' 2>/dev/null || true
fi
}

labwired_splash() {
if [[ ! -t 2 ]]; then
return 0
fi
if [[ -f "$ROOT/branding/banner.txt" ]]; then
printf '\033[34m' >&2
cat "$ROOT/branding/banner.txt" >&2
printf '\033[0m' >&2
else
brand " LabWired Agent"
brand " Write firmware · check on a twin"
fi
}

labwired_prepare_agent_start() {
# Ensure skills + AGENTS.md are discoverable by OpenCode even when the user
# only has a partial ~/.config/opencode from an older install.
local cfg_dir
cfg_dir="${OPENCODE_CONFIG_DIR:-$HOME/.config/opencode}"
mkdir -p "$cfg_dir/skills"
labwired_apply_branding
if [[ -f "$ROOT/config/AGENTS.md" && ! -f "$cfg_dir/AGENTS.md" ]]; then
cp "$ROOT/config/AGENTS.md" "$cfg_dir/AGENTS.md"
fi
Expand Down Expand Up @@ -608,14 +675,15 @@ cmd_help() {
echo
fi
cat <<'EOF'
LabWired Agent — start here (OpenCode + packs + shared MCP)
LabWired Agent — write firmware, check on a twin

curl install → labwired agent login → labwired agent doctor → labwired agent
In chat: "Blink the LED and prove it on the twin."
(Playground Architect is optional / secondary — same labwired_* tools.)

Usage:
labwired agent Start OpenCode agent (golden-path first + MCP)
labwired agent Start LabWired Agent (golden-path + MCP)
labwired agent opencode … Same start (OpenCode engine alias)
labwired agent login Device-code sign-in → hosted MCP + model gateway
labwired agent logout Clear cloud session
labwired agent whoami Show signed-in identity / project
Expand Down Expand Up @@ -934,6 +1002,7 @@ case "${1:-}" in
labwired_probe_cmd "$@"
;;
agent|opencode)
# `opencode` remains a supported alias: same product start, OpenCode engine.
shift || true
if [[ -n "${LABWIRED_HOME:-}" && -d "${LABWIRED_HOME}/bin" ]]; then
export PATH="${LABWIRED_HOME}/bin:${PATH}"
Expand All @@ -945,8 +1014,9 @@ case "${1:-}" in
if [[ "${LABWIRED_PROFILE:-}" != "hosted" ]]; then
labwired_export_sim || true
fi
echo "labwired: starting OpenCode — default skill golden-path; packs bringup/prove/observe/desk-hw" >&2
echo "labwired: knowledge MCP labwired_part + labwired_datasheet; compose: labwired agent compose …" >&2
labwired_splash
echo "labwired: starting LabWired Agent — skill golden-path; packs bringup/prove/observe/desk-hw" >&2
echo "labwired: engine OpenCode · twin tools via MCP labwired_* · compose: labwired agent compose …" >&2
exec opencode "$@"
;;
"")
Expand All @@ -968,7 +1038,8 @@ case "${1:-}" in
echo " or use LabWired debugger / probe-rs — sim is not required" >&2
fi
fi
echo "labwired: starting OpenCode — default skill golden-path (firmware first)" >&2
labwired_splash
echo "labwired: starting LabWired Agent — skill golden-path (firmware first)" >&2
echo "labwired: start-here: login → doctor → labwired agent → “blink and prove it”" >&2
exec opencode "$@"
;;
Expand Down
87 changes: 78 additions & 9 deletions bin/labwired-agent.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function Get-LabwiredHome {
if ($env:LABWIRED_HOME -and (Test-Path $env:LABWIRED_HOME)) { return $env:LABWIRED_HOME }
$candidate = Join-Path $env:USERPROFILE ".labwired"
if (Test-Path $candidate) { return $candidate }
# sibling of this script: .../agent/bin/labwired.ps1 .../ = prefix or agent
# sibling of this script: .../agent/bin/labwired.ps1 -> .../ = prefix or agent
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$agentRoot = Resolve-Path (Join-Path $here "..") -ErrorAction SilentlyContinue
if ($agentRoot -and (Test-Path (Join-Path $agentRoot "lib"))) {
Expand Down Expand Up @@ -71,7 +71,7 @@ function Show-Help {
LabWired Agent (Windows)

Usage:
labwired agent Start agent (OpenCode)
labwired agent Start LabWired Agent
labwired agent doctor Check install
labwired agent update Self-update kit + tools
labwired agent version Version
Expand All @@ -80,13 +80,64 @@ Usage:
labwired agent install-deps Refresh tools into prefix
labwired agent help

Alias: labwired agent opencode ... (same start; OpenCode engine)

Env:
LABWIRED_HOME Install root (default %USERPROFILE%\.labwired)
LABWIRED_CLI / LABWIRED_SIM Simulator
LABWIRED_PROBE_RS probe-rs.exe
"@
}

function Apply-LabWiredBranding {
$cfg = if ($env:OPENCODE_CONFIG_DIR) { $env:OPENCODE_CONFIG_DIR } else { Join-Path $env:USERPROFILE ".config\opencode" }
$themesDir = Join-Path $cfg "themes"
$brandingDir = Join-Path $cfg "branding"
if (-not (Test-Path $themesDir)) { New-Item -ItemType Directory -Path $themesDir -Force | Out-Null }
if (-not (Test-Path $brandingDir)) { New-Item -ItemType Directory -Path $brandingDir -Force | Out-Null }
$themeSrc = Join-Path $AgentHome "branding\themes\labwired.json"
if (Test-Path $themeSrc) {
Copy-Item -Force $themeSrc (Join-Path $themesDir "labwired.json")
}
$bannerSrc = Join-Path $AgentHome "branding\banner.txt"
$bannerDst = Join-Path $brandingDir "banner.txt"
if ((Test-Path $bannerSrc) -and -not (Test-Path $bannerDst)) {
Copy-Item $bannerSrc $bannerDst
}
$tuiSrc = Join-Path $AgentHome "config\tui.json"
$tuiDst = Join-Path $cfg "tui.json"
$writeTui = -not (Test-Path $tuiDst)
if (-not $writeTui -and (Test-Path $tuiDst)) {
$existing = Get-Content -Raw $tuiDst
if ($existing -match '"theme"\s*:\s*"(system|opencode)"') { $writeTui = $true }
}
if ($writeTui) {
if (Test-Path $tuiSrc) {
Copy-Item -Force $tuiSrc $tuiDst
} else {
Set-Content -Path $tuiDst -Value @"
{
"`$schema": "https://opencode.ai/tui.json",
"theme": "labwired"
}
"@ -Encoding utf8
}
}
try {
$Host.UI.RawUI.WindowTitle = "LabWired Agent"
} catch { }
}

function Show-LabWiredSplash {
$banner = Join-Path $AgentHome "branding\banner.txt"
if (Test-Path $banner) {
Write-Host (Get-Content $banner -Raw) -ForegroundColor Blue
} else {
Write-Host " LabWired Agent" -ForegroundColor Blue
Write-Host " Write firmware * check on a twin" -ForegroundColor Blue
}
}

function Cmd-Version {
$ver = "0.0.0"
$vf = Join-Path $AgentHome "VERSION"
Expand All @@ -99,7 +150,7 @@ function Cmd-Version {
if (Get-Command opencode -ErrorAction SilentlyContinue) {
Write-Host "opencode $((& opencode --version 2>&1 | Select-Object -First 1))"
} else {
Write-Host "opencode (missing install Node + npm i -g opencode-ai)"
Write-Host "opencode (missing - install Node + npm i -g opencode-ai)"
}
}

Expand All @@ -121,7 +172,7 @@ function Cmd-Doctor {
} elseif (Test-Path $sim) {
Say "ok labwired-sim: $sim"
} else {
Write-Host "warn labwired-sim: no Windows prebuild use hosted MCP verify or WSL" -ForegroundColor Yellow
Write-Host "warn labwired-sim: no Windows prebuild - use hosted MCP verify or WSL" -ForegroundColor Yellow
}

if (Get-Command npm -ErrorAction SilentlyContinue -or Get-Command npx -ErrorAction SilentlyContinue) {
Expand All @@ -135,7 +186,7 @@ function Cmd-Doctor {
if (Test-Path (Join-Path $cfg "opencode.json")) {
Say "ok config: $cfg\opencode.json"
} else {
Write-Host "FAIL config missing re-run install.ps1" -ForegroundColor Red
Write-Host "FAIL config missing - re-run install.ps1" -ForegroundColor Red
$ok = 1
}

Expand All @@ -154,11 +205,11 @@ function Cmd-Doctor {
if (Test-Path $prs) {
Say "ok probe-backend: $prs"
} else {
Write-Host "warn probe-rs missing re-run install.ps1" -ForegroundColor Yellow
Write-Host "warn probe-rs missing - re-run install.ps1" -ForegroundColor Yellow
}

if ($ok -eq 0) { Say "ready"; exit 0 }
Write-Host "`nnot ready fix FAILs above" -ForegroundColor Red
Write-Host "`nnot ready - fix FAILs above" -ForegroundColor Red
exit 1
}

Expand Down Expand Up @@ -210,7 +261,7 @@ function Cmd-Update {
}
& $install -Prefix $HomeDir -AgentOnly
if (-not $?) { Fail "Agent installer failed" }
Say "update complete run: labwired agent doctor"
Say "update complete - run: labwired agent doctor"
} finally {
Assert-SafePath $tmp
Remove-Item -LiteralPath $tmp -Recurse -Force -ErrorAction SilentlyContinue
Expand All @@ -232,20 +283,38 @@ switch ($cmd) {
"update" { Cmd-Update }
"self-update" { Cmd-Update }
"upgrade" { Cmd-Update }
"opencode" {
# Alias for product start (OpenCode remains the engine).
if (-not (Get-Command opencode -ErrorAction SilentlyContinue)) {
$pin = if ($env:OPENCODE_PIN) { $env:OPENCODE_PIN } else { "1.18.7" }
Fail "'opencode' not found. Install Node 18+, then: npm i -g opencode-ai@$pin"
}
Apply-LabWiredBranding
if (-not $env:LABWIRED_CLI) {
Write-Host "labwired: note - no local sim; hosted MCP verify still works." -ForegroundColor Yellow
}
Show-LabWiredSplash
Write-Host "labwired: starting LabWired Agent (OpenCode engine)" -ForegroundColor Cyan
& opencode @argsRest
}
"" {
if (-not (Get-Command opencode -ErrorAction SilentlyContinue)) {
$pin = if ($env:OPENCODE_PIN) { $env:OPENCODE_PIN } else { "1.18.7" }
Fail "'opencode' not found. Install Node 18+, then: npm i -g opencode-ai@$pin"
}
Apply-LabWiredBranding
if (-not $env:LABWIRED_CLI) {
Write-Host "labwired: note no local sim; hosted MCP verify still works." -ForegroundColor Yellow
Write-Host "labwired: note - no local sim; hosted MCP verify still works." -ForegroundColor Yellow
}
Show-LabWiredSplash
Write-Host "labwired: starting LabWired Agent (OpenCode engine)" -ForegroundColor Cyan
& opencode @argsRest
}
default {
if (-not (Get-Command opencode -ErrorAction SilentlyContinue)) {
Fail "unknown command '$cmd' and opencode missing"
}
Apply-LabWiredBranding
& opencode @Rest
}
}
2 changes: 1 addition & 1 deletion bin/labwired.cmd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@echo off
REM LabWired product dispatcher Windows entry (cmd.exe)
REM LabWired product dispatcher - Windows entry (cmd.exe)
setlocal
if defined LABWIRED_HOME goto :run
set "LABWIRED_HOME=%USERPROFILE%\.labwired"
Expand Down
Loading
Loading