clementine-agent 1.0.75 → 1.0.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12380,14 +12380,24 @@ async function checkAnthropicAuth() {
12380
12380
  var btn = document.getElementById('gs-auth-btn');
12381
12381
  if (d.authenticated && card) {
12382
12382
  card.className = 'gs-card gs-done';
12383
- if (desc) desc.textContent = 'Connected as ' + d.email;
12383
+ // Email is null when auth comes from the Claude Code keychain (OAuth
12384
+ // login via clementine-login or claude-login that we do not have read
12385
+ // access to). Avoid rendering "Connected as null" — looks broken and
12386
+ // makes users re-click login, which hits an SDK bug in claudeAuthenticate.
12387
+ var label = d.email
12388
+ ? 'Connected as ' + d.email
12389
+ : 'Connected via ' + (d.apiKeySource === 'keychain' ? 'Claude Code keychain' : d.apiKeySource || 'API');
12390
+ if (desc) desc.textContent = label;
12384
12391
  if (btn) { btn.textContent = 'Connected'; btn.disabled = true; }
12385
12392
  }
12386
12393
  // Also update settings auth indicator
12387
12394
  var settingsAuth = document.getElementById('settings-auth-status');
12388
12395
  if (settingsAuth) {
12396
+ var sLabel = d.authenticated
12397
+ ? (d.email ? 'Connected as ' + d.email : 'Connected via ' + (d.apiKeySource || 'API'))
12398
+ : '';
12389
12399
  settingsAuth.innerHTML = d.authenticated
12390
- ? '<span style="color:var(--green)">Connected as ' + d.email + '</span>'
12400
+ ? '<span style="color:var(--green)">' + sLabel + '</span>'
12391
12401
  : '<span style="color:var(--text-muted)">Not connected</span>';
12392
12402
  }
12393
12403
  return d;
@@ -12397,6 +12407,23 @@ async function checkAnthropicAuth() {
12397
12407
  async function startAnthropicOAuth() {
12398
12408
  var btn = document.getElementById('gs-auth-btn');
12399
12409
  var desc = document.getElementById('gs-auth-desc');
12410
+ // Precheck: if the user is already authenticated (env var or keychain),
12411
+ // don't trigger the SDK OAuth flow — which has an upstream bug where
12412
+ // claudeAuthenticate sends a malformed Messages API request with
12413
+ // cache_control on an empty text block (HTTP 400).
12414
+ try {
12415
+ var statusResp = await apiFetch('/api/auth/anthropic/status');
12416
+ var statusData = await statusResp.json();
12417
+ if (statusData && statusData.authenticated) {
12418
+ var card = document.getElementById('gs-step-auth');
12419
+ if (card) card.className = 'gs-card gs-done';
12420
+ if (desc) desc.textContent = statusData.email
12421
+ ? 'Connected as ' + statusData.email
12422
+ : 'Already connected via ' + (statusData.apiKeySource || 'API') + ' — no login needed';
12423
+ if (btn) { btn.textContent = 'Connected'; btn.disabled = true; }
12424
+ return;
12425
+ }
12426
+ } catch (_) { /* fall through to real login */ }
12400
12427
  if (btn) { btn.textContent = 'Opening login...'; btn.disabled = true; }
12401
12428
  try {
12402
12429
  var r = await apiFetch('/api/auth/anthropic/login', { method: 'POST' });
@@ -12417,7 +12444,15 @@ async function startAnthropicOAuth() {
12417
12444
  throw new Error(wd.error || 'Login did not complete');
12418
12445
  }
12419
12446
  } catch (err) {
12420
- if (desc) desc.textContent = 'Login failed: ' + err.message;
12447
+ // Special case: the SDK's claudeAuthenticate has a known bug where it
12448
+ // sends malformed API payloads ("cache_control cannot be set for empty
12449
+ // text blocks"). If that fires, point the user at the CLI login path.
12450
+ var msg = err && err.message ? err.message : String(err);
12451
+ if (/cache_control.+empty text blocks/i.test(msg)) {
12452
+ if (desc) desc.textContent = 'In-browser login hit a known SDK bug. Run "clementine login" in your terminal instead, or check if you are already logged in — the daemon only needs to start once.';
12453
+ } else {
12454
+ if (desc) desc.textContent = 'Login failed: ' + msg;
12455
+ }
12421
12456
  if (btn) { btn.textContent = 'Retry Login'; btn.disabled = false; }
12422
12457
  }
12423
12458
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.0.75",
3
+ "version": "1.0.76",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",