mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
fix: tunnel button stuck on "Connecting..." due to settings validation
Root cause: toggleTunnelFromWelcome() sent the entire settings object
back to PUT /api/settings, but the Zod schema uses .strict() which
rejects unknown fields (lastUsedCase, localEchoEnabled, etc.). The PUT
silently failed, so the tunnel never started.
Fix: send only {tunnelEnabled: true/false} instead of the full blob.
Also added polling fallback for tunnel status and server-side re-broadcast
when tunnel is already running.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
# codeman
|
||||
|
||||
## 0.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Fix tunnel button not working: settings PUT was rejected by strict Zod validation when sending full settings blob; now sends only `{tunnelEnabled}`. Added polling fallback for tunnel status in case SSE events are missed.
|
||||
|
||||
## 0.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -50,7 +50,7 @@ When user says "COM":
|
||||
4. **Sync CLAUDE.md version**: Update the `**Version**` line below to match the new version from `package.json`
|
||||
5. **Commit and deploy**: `git add -A && git commit -m "chore: version packages" && git push && npm run build && systemctl --user restart codeman-web`
|
||||
|
||||
**Version**: 0.2.3 (must match `package.json`)
|
||||
**Version**: 0.2.4 (must match `package.json`)
|
||||
|
||||
## Project Overview
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "codeman",
|
||||
"version": "0.2.3",
|
||||
"version": "0.2.4",
|
||||
"description": "The missing control plane for AI coding agents - run 20 autonomous agents with real-time monitoring and session persistence",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
||||
+31
-4
@@ -8946,17 +8946,16 @@ class CodemanApp {
|
||||
const isActive = btn.classList.contains('active');
|
||||
btn.disabled = true;
|
||||
try {
|
||||
const res = await fetch('/api/settings');
|
||||
const current = res.ok ? await res.json() : {};
|
||||
const newEnabled = !isActive;
|
||||
current.tunnelEnabled = newEnabled;
|
||||
await fetch('/api/settings', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(current),
|
||||
body: JSON.stringify({ tunnelEnabled: newEnabled }),
|
||||
});
|
||||
if (newEnabled) {
|
||||
this._showTunnelConnecting();
|
||||
// Poll tunnel status as fallback in case SSE event is missed
|
||||
this._pollTunnelStatus();
|
||||
} else {
|
||||
this._dismissTunnelConnecting();
|
||||
this.showToast('Tunnel stopped', 'info');
|
||||
@@ -9001,6 +9000,8 @@ class CodemanApp {
|
||||
}
|
||||
|
||||
_dismissTunnelConnecting() {
|
||||
clearTimeout(this._tunnelPollTimer);
|
||||
this._tunnelPollTimer = null;
|
||||
const toast = document.getElementById('tunnelConnectingToast');
|
||||
if (toast) {
|
||||
toast.classList.remove('show');
|
||||
@@ -9010,6 +9011,32 @@ class CodemanApp {
|
||||
if (btn) btn.classList.remove('connecting');
|
||||
}
|
||||
|
||||
_pollTunnelStatus(attempt = 0) {
|
||||
if (attempt > 15) return; // give up after ~30s
|
||||
this._tunnelPollTimer = setTimeout(async () => {
|
||||
try {
|
||||
const res = await fetch('/api/tunnel/status');
|
||||
const status = await res.json();
|
||||
if (status.running && status.url) {
|
||||
// Tunnel is up — update UI
|
||||
this._dismissTunnelConnecting();
|
||||
this._updateTunnelUrlDisplay(status.url);
|
||||
const welcomeVisible = document.getElementById('welcomeOverlay')?.classList.contains('visible');
|
||||
if (welcomeVisible) {
|
||||
this._updateWelcomeTunnelBtn(true, status.url, true);
|
||||
this.showToast('Tunnel active', 'success');
|
||||
} else {
|
||||
this._updateWelcomeTunnelBtn(true, status.url);
|
||||
this.showToast(`Tunnel active: ${status.url}`, 'success');
|
||||
this.showTunnelQR();
|
||||
}
|
||||
return;
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
this._pollTunnelStatus(attempt + 1);
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
_updateWelcomeTunnelBtn(active, url, firstAppear = false) {
|
||||
const btn = document.getElementById('welcomeTunnelBtn');
|
||||
if (btn) {
|
||||
|
||||
Reference in New Issue
Block a user