fix(welcome): gate Gemini button on availability, drop unconditional tunnel button

- Remove the always-visible Cloudflare Tunnel welcome button and QR
  widget; offering it regardless of whether cloudflared is installed
  is a bad default.
- Hide the "Run Gemini" welcome button by default and only show it
  when /api/gemini/status reports available:true, via new
  loadGeminiAvailability() called from showWelcome().
This commit is contained in:
timkjr
2026-08-04 16:21:55 -05:00
parent 529d8fa8ea
commit 62008fb408
3 changed files with 15 additions and 9 deletions
+1 -9
View File
@@ -315,23 +315,15 @@
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"/></svg> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"/></svg>
Run Claude Code Run Claude Code
</button> </button>
<button class="welcome-btn welcome-btn-tunnel" id="welcomeTunnelBtn" onclick="app.toggleTunnelFromWelcome()">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
Cloudflare Tunnel
</button>
<button class="welcome-btn welcome-btn-opencode" onclick="app.setRunMode('opencode'); app.runOpenCode()"> <button class="welcome-btn welcome-btn-opencode" onclick="app.setRunMode('opencode'); app.runOpenCode()">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"/></svg> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"/></svg>
Run OpenCode Run OpenCode
</button> </button>
<button class="welcome-btn welcome-btn-gemini" onclick="app.setRunMode('gemini'); app.runGemini()"> <button class="welcome-btn welcome-btn-gemini" id="welcomeGeminiBtn" style="display: none;" onclick="app.setRunMode('gemini'); app.runGemini()">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"/></svg> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"/></svg>
Run Gemini Run Gemini
</button> </button>
</div> </div>
<div class="welcome-qr" id="welcomeQr" onclick="app.toggleWelcomeQrSize()">
<div class="welcome-qr-inner" id="welcomeQrInner"></div>
<div class="welcome-qr-url" id="welcomeQrUrl"></div>
</div>
<div class="history-sessions" id="historySessions" style="display:none"> <div class="history-sessions" id="historySessions" style="display:none">
<div class="search-panel" id="searchPanel"> <div class="search-panel" id="searchPanel">
<div class="search-input-row"> <div class="search-input-row">
+13
View File
@@ -694,6 +694,19 @@ Object.assign(CodemanApp.prototype, {
this._updatePollTimer = setInterval(poll, 1500); this._updatePollTimer = setInterval(poll, 1500);
}, },
async loadGeminiAvailability() {
const btn = document.getElementById('welcomeGeminiBtn');
if (!btn) return;
try {
const res = await fetch('/api/gemini/status');
const env = await res.json();
const status = env?.success === true ? env.data : env;
btn.style.display = status?.available ? 'flex' : 'none';
} catch {
btn.style.display = 'none';
}
},
async loadTunnelStatus() { async loadTunnelStatus() {
try { try {
const res = await fetch('/api/tunnel/status'); const res = await fetch('/api/tunnel/status');
+1
View File
@@ -1195,6 +1195,7 @@ Object.assign(CodemanApp.prototype, {
if (overlay) { if (overlay) {
overlay.classList.add('visible'); overlay.classList.add('visible');
this.loadTunnelStatus(); this.loadTunnelStatus();
this.loadGeminiAvailability();
this.loadHistorySessions(); this.loadHistorySessions();
this.initSearchPanel(); this.initSearchPanel();
} }