Skip to content

Commit 71544b5

Browse files
authored
adds live model updates from the server and fixes premature task completion.
What's new Model list updated from the server — no Bridge reinstall needed Model lists are now fetched from the CtrlNode backend on startup and refreshed after every connection. New models — including Claude Fable 5 and Claude Mythos 5 — become available automatically without installing a new Bridge version. When the server is unreachable the previous cached list is used; if no cache exists, the built-in fallback list applies. Auto-update on startup Bridge checks for a newer version before connecting. When one is available it shows the versions and a link to the release notes, then asks [Y/n]. Answering Y downloads the new binary, replaces the current executable, and restarts automatically. Non-interactive environments (no TTY, Docker) skip the prompt and continue with the current version. Network errors are ignored so the Bridge always starts. Fix: task marked done too early Agents that write several output files in sequence could trigger a premature task_complete signal when the first file landed. Bridge now waits 45 seconds after the last file write before declaring the task done, giving the agent time to finish all its output. An explicit <TASK_COMPLETED:…> or <TASK_FAILED:…> tag cancels the wait immediately. Upgrade Replace the binary and restart. No configuration changes are required. Run ctrlnode --setup if you want to update your workspace, pairing token, or provider API keys.
1 parent 629e516 commit 71544b5

21 files changed

Lines changed: 1109 additions & 250 deletions

README.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
### Orchestrate AI coding agents — tasks, routines, and workflows — from anywhere.
1010

1111
[![License: ELv2](https://img.shields.io/badge/License-Elastic_v2-007EC6?style=flat-square)](LICENSE)
12-
[![Release](https://img.shields.io/badge/release-v2.2-1aff8c?style=flat-square)](https://github.com/ctrlnode-ai/ctrlnode/releases)
12+
[![Release](https://img.shields.io/badge/release-v2.4-1aff8c?style=flat-square)](https://github.com/ctrlnode-ai/ctrlnode/releases)
1313
[![Website](https://img.shields.io/badge/ctrlnode.ai-0A0A23?style=flat-square&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTEyIDJhMTAgMTAgMCAxIDAgMCAyMEExMCAxMCAwIDAgMCAxMiAyeiIgZmlsbD0id2hpdGUiLz48L3N2Zz4=&logoColor=white)](https://ctrlnode.ai)
1414

1515
[Website](https://ctrlnode.ai) · [Releases](https://github.com/ctrlnode-ai/ctrlnode/releases) · [Bridge setup](src/bridge/README.md)
@@ -24,13 +24,11 @@ Works with **Claude, Copilot, Gemini, Codex, Cursor, OpenClaw**, or any combinat
2424

2525
---
2626

27-
## What's new in v2.2 and 2.3
27+
## What's new in v2.4
2828

29-
- **Hermes provider** — native support for Hermes agents via ACP; each agent gets its own isolated profile
30-
- **Binary renamed**`ctrlnode-bridge` is now just `ctrlnode`; install scripts update PATH automatically
31-
- **Setup wizard** — run `ctrlnode --setup` to configure workspace and pairing token interactively; config is saved and reused on every subsequent run
32-
- **Model selection** — choose the exact AI model per agent (claude-sonnet-4-6, gpt-5.5, gemini-3.1-pro, …); the Bridge reports available models on connect and the UI surfaces them as a searchable drop-down
33-
- **Claude-opus-4-8** — is now included in the known-models fallback lists for Anthropic, Copilot, and Cursor providers. When no API key is configured the model is available immediately; with an API key it is returned directly from the live API.
29+
- **Auto-update** — Bridge checks for a newer version on startup, shows a prompt with the release link, and replaces itself with one keypress. Skipped automatically when running non-interactively.
30+
- **Live model updates** — model lists are now fetched from the server on startup and refreshed after every connection. New models (including **Claude Fable 5** and **Claude Mythos 5**) become available without reinstalling the Bridge.
31+
- **Fix: task completion debounce** — agents that write multiple output files in sequence no longer trigger a premature done signal; Bridge waits 45 s after the last file write before closing the task.
3432

3533
---
3634

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## CtrlNode Bridge v2026.2.4 Release Notes
2+
3+
This release adds live model updates from the server and fixes premature task completion.
4+
5+
---
6+
7+
### What's new
8+
9+
#### Model list updated from the server — no Bridge reinstall needed
10+
11+
Model lists are now fetched from the CtrlNode backend on startup and refreshed after every connection. New models — including **Claude Fable 5** and **Claude Mythos 5** — become available automatically without installing a new Bridge version.
12+
13+
When the server is unreachable the previous cached list is used; if no cache exists, the built-in fallback list applies.
14+
15+
#### Auto-update on startup
16+
17+
Bridge checks for a newer version before connecting. When one is available it shows the versions and a link to the release notes, then asks `[Y/n]`. Answering Y downloads the new binary, replaces the current executable, and restarts automatically.
18+
19+
Non-interactive environments (no TTY, Docker) skip the prompt and continue with the current version. Network errors are ignored so the Bridge always starts.
20+
21+
#### Fix: task marked done too early
22+
23+
Agents that write several output files in sequence could trigger a premature `task_complete` signal when the first file landed. Bridge now waits 45 seconds after the last file write before declaring the task done, giving the agent time to finish all its output. An explicit `<TASK_COMPLETED:…>` or `<TASK_FAILED:…>` tag cancels the wait immediately.
24+
25+
26+
27+
---
28+
29+
### Upgrade
30+
31+
Replace the binary and restart. No configuration changes are required. Run `ctrlnode --setup` if you want to update your workspace, pairing token, or provider API keys.

Releases/v2026.2.4/install.ps1

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# CtrlNode Bridge — Windows installer
2+
# Usage:
3+
# iwr https://github.com/ctrlnode-ai/ctrlnode/releases/latest/download/install.ps1 | iex
4+
#
5+
# With custom install directory:
6+
# & ([scriptblock]::Create((iwr https://github.com/ctrlnode-ai/ctrlnode/releases/latest/download/install.ps1))) -InstallDir "C:\tools\ctrlnode"
7+
8+
param(
9+
[string]$InstallDir = "$env:LOCALAPPDATA\Programs\ctrlnode"
10+
)
11+
12+
$ErrorActionPreference = "Stop"
13+
$REPO = "ctrlnode-ai/ctrlnode"
14+
$BINARY_NAME = "ctrlnode.exe"
15+
$DEFAULT_WORKSPACE = $env:USERPROFILE
16+
17+
Write-Host ""
18+
Write-Host "CtrlNode Bridge Installer" -ForegroundColor Cyan
19+
Write-Host "--------------------------" -ForegroundColor Cyan
20+
Write-Host ""
21+
22+
# --- workspace directory ---
23+
Write-Host "Where is your workspace?"
24+
Write-Host "This is the root folder where ctrlnode will read and write files." -ForegroundColor DarkGray
25+
Write-Host "For security, the bridge cannot access anything outside this folder." -ForegroundColor DarkGray
26+
Write-Host "If you are a developer, point this to your source code root (e.g. C:\Code)." -ForegroundColor DarkGray
27+
$workspaceAnswer = Read-Host "Workspace [$DEFAULT_WORKSPACE]"
28+
$WorkspaceRoot = if ($workspaceAnswer.Trim()) { $workspaceAnswer.Trim() } else { $DEFAULT_WORKSPACE }
29+
Write-Host " Workspace: $WorkspaceRoot" -ForegroundColor Gray
30+
Write-Host " Tip: to change it later, set the BASE_PATH environment variable and restart ctrlnode." -ForegroundColor DarkGray
31+
Write-Host ""
32+
33+
[System.Environment]::SetEnvironmentVariable('BASE_PATH', $WorkspaceRoot, 'User')
34+
35+
# --- fetch latest release from GitHub ---
36+
Write-Host "Fetching latest release..."
37+
$releaseInfo = Invoke-RestMethod "https://api.github.com/repos/$REPO/releases/latest"
38+
$tag = $releaseInfo.tag_name
39+
40+
if (-not $tag) {
41+
Write-Error "Could not determine latest release tag."
42+
exit 1
43+
}
44+
45+
Write-Host " Release: $tag"
46+
Write-Host " Asset: $BINARY_NAME"
47+
Write-Host ""
48+
Write-Host "Downloading..."
49+
50+
$downloadUrl = "https://github.com/$REPO/releases/download/$tag/$BINARY_NAME"
51+
$tmpFile = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), $BINARY_NAME)
52+
Invoke-WebRequest -Uri $downloadUrl -OutFile $tmpFile -UseBasicParsing
53+
54+
# --- install ---
55+
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
56+
$dest = Join-Path $InstallDir $BINARY_NAME
57+
if (Test-Path $dest) {
58+
Get-Process | Where-Object { $_.Path -eq $dest } | ForEach-Object {
59+
Write-Host " Stopping running instance (PID $($_.Id))..." -ForegroundColor Yellow
60+
Stop-Process -Id $_.Id -Force
61+
Start-Sleep -Milliseconds 500
62+
}
63+
Remove-Item $dest -Force
64+
}
65+
Copy-Item $srcFile $dest -Force
66+
67+
Write-Host ""
68+
Write-Host "OK Installed: $dest" -ForegroundColor Green
69+
Write-Host " Version: $tag"
70+
71+
# --- add to PATH if not already there ---
72+
$currentPath = [System.Environment]::GetEnvironmentVariable("PATH", "User")
73+
if ($currentPath -notlike "*$InstallDir*") {
74+
[System.Environment]::SetEnvironmentVariable("PATH", "$currentPath;$InstallDir", "User")
75+
Write-Host "OK Added $InstallDir to your PATH (restart terminal to apply)" -ForegroundColor Green
76+
} else {
77+
Write-Host " $InstallDir is already in PATH"
78+
}
79+
$env:PATH = "$InstallDir;$env:PATH"
80+
81+
Write-Host ""
82+
Write-Host "Next: start the Bridge:" -ForegroundColor Cyan
83+
Write-Host " ctrlnode"
84+
Write-Host ""
85+
Write-Host "Workspace: $WorkspaceRoot"
86+
Write-Host "When you run the Bridge for the first time, it will prompt for your pairing token or read it from a .env file."
87+
Write-Host "Full setup (token + API keys): ctrlnode --setup"
88+
Write-Host "Get your token at: https://app.ctrlnode.ai (Settings -> Bridge)"
89+
Write-Host ""
90+
91+
# --- optional: run the bridge now ---
92+
$runNow = Read-Host "Do you want to run ctrlnode now? (Y/n)"
93+
if ($runNow.Trim().ToLower() -ne 'n') {
94+
Write-Host "Starting ctrlnode..." -ForegroundColor Cyan
95+
$env:BASE_PATH = $WorkspaceRoot
96+
& $dest
97+
}

Releases/v2026.2.4/install.sh

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
#!/usr/bin/env sh
2+
# CtrlNode Bridge — Linux/macOS installer
3+
# Usage:
4+
# curl -fsSL https://github.com/ctrlnode-ai/ctrlnode/releases/latest/download/install.sh | sh
5+
#
6+
# With custom install directory:
7+
# curl -fsSL https://github.com/ctrlnode-ai/ctrlnode/releases/latest/download/install.sh | sh -s -- --dir ~/.local/bin
8+
9+
set -e
10+
11+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
12+
BINARY_NAME="ctrlnode"
13+
DEFAULT_DIR="/usr/local/bin"
14+
INSTALL_DIR="$DEFAULT_DIR"
15+
16+
# --- parse args ---
17+
while [ $# -gt 0 ]; do
18+
case "$1" in
19+
--dir) INSTALL_DIR="$2"; shift 2 ;;
20+
--dir=*) INSTALL_DIR="${1#*=}"; shift ;;
21+
*) shift ;;
22+
esac
23+
done
24+
25+
DEFAULT_WORKSPACE="$HOME"
26+
WORKSPACE_ROOT=""
27+
28+
echo ""
29+
echo "CtrlNode Bridge Installer"
30+
echo "--------------------------"
31+
echo ""
32+
33+
# --- workspace directory ---
34+
echo "Where is your workspace?"
35+
echo " This is the root folder where ctrlnode will read and write files."
36+
echo " For security, the bridge cannot access anything outside this folder."
37+
echo " If you are a developer, point this to your source code root (e.g. ~/code)."
38+
if [ -t 1 ] && [ -e /dev/tty ]; then
39+
printf "Workspace [%s]: " "$DEFAULT_WORKSPACE" > /dev/tty
40+
read -r ws_answer < /dev/tty
41+
WORKSPACE_ROOT="${ws_answer:-$DEFAULT_WORKSPACE}"
42+
else
43+
WORKSPACE_ROOT="$DEFAULT_WORKSPACE"
44+
fi
45+
echo " Workspace: $WORKSPACE_ROOT"
46+
echo " Tip: to change it later, set BASE_PATH and restart ctrlnode."
47+
echo ""
48+
49+
# Persist workspace
50+
SHELL_RC=""
51+
if [ -f "$HOME/.bashrc" ]; then SHELL_RC="$HOME/.bashrc"
52+
elif [ -f "$HOME/.zshrc" ]; then SHELL_RC="$HOME/.zshrc"
53+
elif [ -f "$HOME/.profile" ]; then SHELL_RC="$HOME/.profile"
54+
fi
55+
56+
if [ -n "$SHELL_RC" ]; then
57+
grep -v 'BASE_PATH' "$SHELL_RC" > "${SHELL_RC}.tmp" && mv "${SHELL_RC}.tmp" "$SHELL_RC"
58+
echo "export BASE_PATH=\"$WORKSPACE_ROOT\"" >> "$SHELL_RC"
59+
fi
60+
export BASE_PATH="$WORKSPACE_ROOT"
61+
62+
# --- detect OS and arch ---
63+
OS="$(uname -s)"
64+
ARCH="$(uname -m)"
65+
66+
case "$OS" in
67+
Linux)
68+
case "$ARCH" in
69+
x86_64)
70+
if grep -q avx2 /proc/cpuinfo 2>/dev/null; then
71+
ASSET="ctrlnode-linux-x64"
72+
else
73+
ASSET="ctrlnode-linux-x64-baseline"
74+
fi
75+
;;
76+
aarch64|arm64)
77+
echo "ERROR: Linux ARM64 binary not yet available." >&2
78+
exit 1
79+
;;
80+
*)
81+
echo "ERROR: Unsupported architecture: $ARCH" >&2
82+
exit 1
83+
;;
84+
esac
85+
;;
86+
Darwin)
87+
case "$ARCH" in
88+
arm64) ASSET="ctrlnode-darwin-arm64" ;;
89+
x86_64)
90+
echo "ERROR: macOS Intel binary not yet available." >&2
91+
exit 1
92+
;;
93+
*)
94+
echo "ERROR: Unsupported architecture: $ARCH" >&2
95+
exit 1
96+
;;
97+
esac
98+
;;
99+
*)
100+
echo "ERROR: Unsupported OS: $OS. On Windows use install.ps1 instead." >&2
101+
exit 1
102+
;;
103+
esac
104+
105+
# --- fetch latest release from GitHub ---
106+
echo "Fetching latest release..."
107+
if command -v curl >/dev/null 2>&1; then
108+
TAG="$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" | grep '"tag_name"' | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')"
109+
elif command -v wget >/dev/null 2>&1; then
110+
TAG="$(wget -qO- "https://api.github.com/repos/$REPO/releases/latest" | grep '"tag_name"' | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')"
111+
else
112+
echo "ERROR: curl or wget required." >&2
113+
exit 1
114+
fi
115+
116+
if [ -z "$TAG" ]; then
117+
echo "ERROR: Could not determine latest release tag." >&2
118+
exit 1
119+
fi
120+
121+
echo " Release: $TAG"
122+
echo " Asset: $ASSET"
123+
echo ""
124+
echo "Downloading..."
125+
126+
DOWNLOAD_URL="https://github.com/$REPO/releases/download/$TAG/$ASSET"
127+
TMP_FILE="$(mktemp)"
128+
129+
if command -v curl >/dev/null 2>&1; then
130+
curl -fsSL "$DOWNLOAD_URL" -o "$TMP_FILE"
131+
else
132+
wget -qO "$TMP_FILE" "$DOWNLOAD_URL"
133+
fi
134+
135+
# --- install ---
136+
mkdir -p "$INSTALL_DIR"
137+
DEST="${INSTALL_DIR}/${BINARY_NAME}"
138+
139+
# Stop any running instance before replacing the binary
140+
if [ -f "$DEST" ]; then
141+
if command -v pkill >/dev/null 2>&1; then
142+
pkill -x "$BINARY_NAME" 2>/dev/null && sleep 0.5 || true
143+
fi
144+
fi
145+
146+
if [ -w "$INSTALL_DIR" ]; then
147+
cp "$SRC_FILE" "$DEST"
148+
else
149+
echo "Requires sudo to install to $INSTALL_DIR..."
150+
sudo cp "$SRC_FILE" "$DEST"
151+
fi
152+
153+
chmod +x "$DEST"
154+
155+
# macOS: remove quarantine flag
156+
if [ "$OS" = "Darwin" ]; then
157+
xattr -d com.apple.quarantine "$DEST" 2>/dev/null || true
158+
fi
159+
160+
echo ""
161+
echo "OK Installed: $DEST"
162+
echo " Version: $TAG"
163+
echo ""
164+
echo "Next: start the Bridge:"
165+
echo " ctrlnode"
166+
echo ""
167+
echo "Workspace: $WORKSPACE_ROOT"
168+
echo "When you run the Bridge for the first time, it will prompt for your pairing token or read it from a .env file."
169+
echo "Full setup (token + API keys): ctrlnode --setup"
170+
echo "Get your token at: https://app.ctrlnode.ai (Settings -> Bridge)"
171+
echo ""
172+
173+
# --- optional: run the bridge now ---
174+
if [ -t 1 ] && [ -e /dev/tty ]; then
175+
printf "Do you want to run ctrlnode now? (Y/n): " > /dev/tty
176+
read -r run_now < /dev/tty
177+
case "$run_now" in
178+
n|N|no|No)
179+
echo "You can start it later with: ctrlnode"
180+
;;
181+
*)
182+
echo "Starting ctrlnode..."
183+
BASE_PATH="$WORKSPACE_ROOT" "$DEST"
184+
;;
185+
esac
186+
fi

0 commit comments

Comments
 (0)