clementine-agent 1.12.1 → 1.12.2
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.
- package/dist/cli/dashboard.js +54 -8
- package/package.json +1 -1
package/dist/cli/dashboard.js
CHANGED
|
@@ -15444,7 +15444,14 @@ function navigateTo(page, opts) {
|
|
|
15444
15444
|
if (bt === 'learning' && typeof refreshSelfImprove === 'function') refreshSelfImprove();
|
|
15445
15445
|
break;
|
|
15446
15446
|
case 'settings':
|
|
15447
|
-
|
|
15447
|
+
// Settings tabs use the switchTab() system (id="tab-settings-<tab>"),
|
|
15448
|
+
// not switchDestTab's [data-tab] selector. Default tab name is
|
|
15449
|
+
// 'general' (the "Channels & Env" pane) to match the HTML id.
|
|
15450
|
+
switchTab('settings', opts.tab || 'general');
|
|
15451
|
+
// 'general' has no auto-refresh in switchTab — kick it manually so
|
|
15452
|
+
// the Channels & Env card actually loads from /api/settings instead
|
|
15453
|
+
// of stalling on "Loading settings…".
|
|
15454
|
+
if ((opts.tab || 'general') === 'general' && typeof refreshSettings === 'function') refreshSettings();
|
|
15448
15455
|
break;
|
|
15449
15456
|
}
|
|
15450
15457
|
|
|
@@ -15846,6 +15853,7 @@ function switchTab(group, tab) {
|
|
|
15846
15853
|
if (tab === 'learning' && typeof refreshSelfImprove === 'function') refreshSelfImprove();
|
|
15847
15854
|
}
|
|
15848
15855
|
if (group === 'settings') {
|
|
15856
|
+
if (tab === 'general' && typeof refreshSettings === 'function') refreshSettings();
|
|
15849
15857
|
if (tab === 'integrations') { refreshSalesforce(); refreshComposioConnections(); }
|
|
15850
15858
|
if (tab === 'remote') refreshRemoteAccess();
|
|
15851
15859
|
if (tab === 'security') refreshAuthSessions();
|
|
@@ -25936,9 +25944,13 @@ async function saveComposioApiKey() {
|
|
|
25936
25944
|
}
|
|
25937
25945
|
|
|
25938
25946
|
async function connectComposio(slug) {
|
|
25947
|
+
// Open a blank popup SYNCHRONOUSLY inside the click handler. Browsers
|
|
25948
|
+
// only let popups through if they're a direct user gesture — once we
|
|
25949
|
+
// hit the await below, the gesture is "consumed" and any later
|
|
25950
|
+
// window.open() gets silently blocked by Chrome/Safari/Firefox.
|
|
25951
|
+
// We'll redirect this blank window to the OAuth URL once we have it.
|
|
25952
|
+
var popup = window.open('about:blank', '_blank');
|
|
25939
25953
|
try {
|
|
25940
|
-
// Use apiFetch (not raw fetch) so the Authorization: Bearer header is
|
|
25941
|
-
// attached — the /api/* middleware rejects unauth'd POSTs with 401.
|
|
25942
25954
|
var res = await apiFetch('/api/composio/toolkits/' + encodeURIComponent(slug) + '/authorize', {
|
|
25943
25955
|
method: 'POST',
|
|
25944
25956
|
headers: { 'content-type': 'application/json' },
|
|
@@ -25947,27 +25959,61 @@ async function connectComposio(slug) {
|
|
|
25947
25959
|
var d = await res.json();
|
|
25948
25960
|
if (res.status === 409 && d.needsAuthConfig) {
|
|
25949
25961
|
toast('This toolkit needs a BYO OAuth app — opening Composio dashboard.', 'warn');
|
|
25950
|
-
|
|
25962
|
+
if (popup && !popup.closed) popup.location.href = d.setupUrl;
|
|
25963
|
+
else showOAuthLinkPrompt(slug, d.setupUrl);
|
|
25951
25964
|
return;
|
|
25952
25965
|
}
|
|
25953
25966
|
if (!res.ok) {
|
|
25967
|
+
if (popup && !popup.closed) popup.close();
|
|
25954
25968
|
var reason = d.error || ('HTTP ' + res.status);
|
|
25955
25969
|
toast('Connect failed: ' + reason, 'error');
|
|
25956
25970
|
console.error('[composio] connect failed', { slug: slug, status: res.status, body: d });
|
|
25957
25971
|
return;
|
|
25958
25972
|
}
|
|
25959
25973
|
if (d.redirectUrl) {
|
|
25960
|
-
|
|
25961
|
-
|
|
25962
|
-
|
|
25974
|
+
if (popup && !popup.closed) {
|
|
25975
|
+
popup.location.href = d.redirectUrl;
|
|
25976
|
+
toast('Authorize ' + slug + ' in the new tab, then come back here.', 'info');
|
|
25977
|
+
} else {
|
|
25978
|
+
// Popup got blocked even with the synchronous-open trick (some
|
|
25979
|
+
// browsers / extensions block about:blank too). Fall back to a
|
|
25980
|
+
// visible "click to open" dialog — that click is a direct gesture
|
|
25981
|
+
// and reliably bypasses the blocker.
|
|
25982
|
+
showOAuthLinkPrompt(slug, d.redirectUrl);
|
|
25983
|
+
}
|
|
25963
25984
|
setTimeout(refreshComposioConnections, 5000);
|
|
25964
25985
|
setTimeout(refreshComposioConnections, 15000);
|
|
25965
25986
|
setTimeout(refreshComposioConnections, 30000);
|
|
25966
25987
|
} else {
|
|
25988
|
+
if (popup && !popup.closed) popup.close();
|
|
25967
25989
|
toast('Connected ' + slug, 'success');
|
|
25968
25990
|
refreshComposioConnections();
|
|
25969
25991
|
}
|
|
25970
|
-
} catch (e) {
|
|
25992
|
+
} catch (e) {
|
|
25993
|
+
if (popup && !popup.closed) popup.close();
|
|
25994
|
+
toast('Connect failed: ' + e, 'error');
|
|
25995
|
+
}
|
|
25996
|
+
}
|
|
25997
|
+
|
|
25998
|
+
function showOAuthLinkPrompt(slug, url) {
|
|
25999
|
+
// Renders a modal with a clickable link. User clicking the link is a
|
|
26000
|
+
// direct gesture, so the new tab will open even when popup blockers are
|
|
26001
|
+
// aggressive. Used as the fallback when window.open returns null.
|
|
26002
|
+
var existing = document.getElementById('composio-oauth-prompt');
|
|
26003
|
+
if (existing) existing.remove();
|
|
26004
|
+
var overlay = document.createElement('div');
|
|
26005
|
+
overlay.id = 'composio-oauth-prompt';
|
|
26006
|
+
overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:9999;display:flex;align-items:center;justify-content:center';
|
|
26007
|
+
overlay.innerHTML =
|
|
26008
|
+
'<div style="background:var(--bg-primary,#1e1e1e);border:1px solid var(--border);border-radius:8px;padding:20px;max-width:480px;width:90%;box-shadow:0 8px 32px rgba(0,0,0,0.4)">' +
|
|
26009
|
+
'<div style="font-size:14px;font-weight:600;margin-bottom:8px">Authorize ' + esc(slug) + '</div>' +
|
|
26010
|
+
'<div style="font-size:12px;color:var(--text-muted);margin-bottom:14px;line-height:1.5">Your browser blocked the popup. Click below to open the authorization page in a new tab — after approving, come back here and the connection will show up within a few seconds.</div>' +
|
|
26011
|
+
'<div style="display:flex;gap:8px;justify-content:flex-end">' +
|
|
26012
|
+
'<button class="btn-sm" onclick="document.getElementById(\\'composio-oauth-prompt\\').remove()" style="padding:6px 12px;background:transparent;border:1px solid var(--border);color:var(--text-primary);border-radius:4px;cursor:pointer;font-size:12px">Cancel</button>' +
|
|
26013
|
+
'<a href="' + esc(url) + '" target="_blank" rel="noopener" onclick="setTimeout(function(){var e=document.getElementById(\\'composio-oauth-prompt\\');if(e)e.remove();},500)" class="btn btn-sm btn-primary" style="text-decoration:none;padding:6px 14px;display:inline-block;font-size:12px">Open authorization</a>' +
|
|
26014
|
+
'</div>' +
|
|
26015
|
+
'</div>';
|
|
26016
|
+
document.body.appendChild(overlay);
|
|
25971
26017
|
}
|
|
25972
26018
|
|
|
25973
26019
|
async function disconnectComposio(slug, connectionId) {
|