clay-server 3.8.1 → 4.0.0-beta.10
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/lib/ask-user-mcp-server.js +5 -119
- package/lib/background-task-timing.js +105 -0
- package/lib/builtin-mates.js +6 -6
- package/lib/claude-hook-installer.js +15 -0
- package/lib/clay-history-mcp-server.js +62 -297
- package/lib/daemon.js +23 -1
- package/lib/debate-model-selection.js +119 -0
- package/lib/home-debate-tool-policy.js +164 -0
- package/lib/home-response-notifications.js +26 -0
- package/lib/knowledge-import.js +436 -0
- package/lib/knowledge-record-store.js +188 -0
- package/lib/knowledge-search.js +224 -0
- package/lib/mate-creation-mcp-server.js +55 -0
- package/lib/mate-knowledge-mcp-server.js +151 -0
- package/lib/mate-knowledge-migration.js +283 -0
- package/lib/mate-knowledge-service.js +488 -0
- package/lib/mate-knowledge-sync.js +482 -0
- package/lib/mate-ready-creation.js +95 -0
- package/lib/mates.js +2 -0
- package/lib/notes.js +2 -1
- package/lib/project-ask-user.js +64 -0
- package/lib/project-capsule-catalog.js +101 -0
- package/lib/project-connection.js +17 -0
- package/lib/project-debate-proposal.js +133 -17
- package/lib/project-debate.js +214 -110
- package/lib/project-delegated-follow-up.js +84 -0
- package/lib/project-delegated-session.js +53 -0
- package/lib/project-filesystem.js +7 -9
- package/lib/project-knowledge.js +23 -0
- package/lib/project-logs-comments.js +137 -0
- package/lib/project-logs-mcp-server.js +290 -0
- package/lib/project-logs-query.js +167 -0
- package/lib/project-logs-root.js +67 -0
- package/lib/project-logs-schema.js +259 -0
- package/lib/project-logs-service.js +357 -0
- package/lib/project-logs-snapshot.js +202 -0
- package/lib/project-logs-store.js +498 -0
- package/lib/project-logs-versioning.js +128 -0
- package/lib/project-logs.js +347 -0
- package/lib/project-mate-creation-proposal.js +120 -0
- package/lib/project-mate-interaction.js +14 -0
- package/lib/project-mate-knowledge.js +110 -0
- package/lib/project-memory.js +36 -7
- package/lib/project-models.js +157 -32
- package/lib/project-session-notes.js +2 -2
- package/lib/project-session-pair.js +8 -8
- package/lib/project-sessions.js +66 -51
- package/lib/project-vendor-login.js +414 -0
- package/lib/project-worker-proposal.js +25 -25
- package/lib/project-workspace-query.js +144 -0
- package/lib/project.js +433 -102
- package/lib/public/app.js +109 -48
- package/lib/public/css/avatar-imprints.css +0 -1
- package/lib/public/css/base.css +4 -0
- package/lib/public/css/capsule-ui.css +389 -0
- package/lib/public/css/command-palette.css +306 -6
- package/lib/public/css/home-capsule-library.css +243 -0
- package/lib/public/css/home-capsule-source.css +192 -0
- package/lib/public/css/home-debate-live.css +146 -0
- package/lib/public/css/home-debate-planning.css +125 -0
- package/lib/public/css/home-debates-archive.css +281 -0
- package/lib/public/css/home-hub.css +896 -405
- package/lib/public/css/home-mate-creation.css +34 -0
- package/lib/public/css/home-mate-model-picker.css +131 -0
- package/lib/public/css/home-mate-settings.css +344 -0
- package/lib/public/css/home-session-actions.css +265 -0
- package/lib/public/css/home-sidebar.css +667 -0
- package/lib/public/css/icon-strip.css +1 -2
- package/lib/public/css/input.css +79 -25
- package/lib/public/css/mates.css +7 -34
- package/lib/public/css/pane.css +1 -1
- package/lib/public/css/playbook.css +0 -80
- package/lib/public/css/project-logs.css +234 -0
- package/lib/public/css/scheduler.css +1 -1
- package/lib/public/css/sticky-notes.css +53 -117
- package/lib/public/css/tui-attention.css +0 -44
- package/lib/public/css/workspace-assignment.css +45 -0
- package/lib/public/fonts/source-serif-4/LICENSE.md +93 -0
- package/lib/public/fonts/source-serif-4/SourceSerif4Caption-Semibold.ttf.woff2 +0 -0
- package/lib/public/index.html +96 -74
- package/lib/public/modules/app-connection.js +100 -5
- package/lib/public/modules/app-dm.js +43 -160
- package/lib/public/modules/app-home-hub.js +328 -585
- package/lib/public/modules/app-message-cards.js +242 -0
- package/lib/public/modules/app-message-router.js +84 -0
- package/lib/public/modules/app-messages.js +124 -38
- package/lib/public/modules/app-notifications.js +8 -119
- package/lib/public/modules/app-panels.js +43 -2
- package/lib/public/modules/app-projects.js +9 -1
- package/lib/public/modules/app-rendering.js +21 -602
- package/lib/public/modules/avatar-imprint.js +11 -8
- package/lib/public/modules/background-tasks-ui.js +139 -16
- package/lib/public/modules/chat-bubble-renderer.js +152 -0
- package/lib/public/modules/chat-render-runtime.js +198 -0
- package/lib/public/modules/command-palette.js +225 -436
- package/lib/public/modules/dm-render.js +82 -0
- package/lib/public/modules/home-capsule-creation-intent.js +31 -0
- package/lib/public/modules/home-capsule-library.js +146 -0
- package/lib/public/modules/home-capsule-source.js +383 -0
- package/lib/public/modules/home-chat-identity.js +35 -0
- package/lib/public/modules/home-chat-scroll.js +77 -0
- package/lib/public/modules/home-chat-stream-state.js +34 -0
- package/lib/public/modules/home-composer-focus.js +25 -0
- package/lib/public/modules/home-conversations-sheet.js +179 -0
- package/lib/public/modules/home-debate-activity.js +48 -0
- package/lib/public/modules/home-debate-controls.js +295 -0
- package/lib/public/modules/home-debate-launch.js +41 -0
- package/lib/public/modules/home-debate-live.js +284 -0
- package/lib/public/modules/home-debate-models.js +73 -0
- package/lib/public/modules/home-debate-planning.js +335 -0
- package/lib/public/modules/home-debates-archive.js +279 -0
- package/lib/public/modules/home-dock-resize.js +74 -0
- package/lib/public/modules/home-dock.js +446 -0
- package/lib/public/modules/home-mate-chat.js +496 -0
- package/lib/public/modules/home-mate-creation.js +109 -0
- package/lib/public/modules/home-mate-model-picker.js +281 -0
- package/lib/public/modules/home-mate-selection.js +38 -0
- package/lib/public/modules/home-mate-settings-menu.js +131 -0
- package/lib/public/modules/home-mate-settings.js +383 -0
- package/lib/public/modules/home-session-actions.js +373 -0
- package/lib/public/modules/home-session-model-confirmation.js +13 -0
- package/lib/public/modules/home-shell.js +9 -0
- package/lib/public/modules/home-sidebar-chat-list.js +63 -0
- package/lib/public/modules/home-sidebar.js +165 -0
- package/lib/public/modules/home-sub-surface.js +19 -0
- package/lib/public/modules/home-surface-boot.js +68 -0
- package/lib/public/modules/home-surface.js +141 -0
- package/lib/public/modules/home-tools.js +271 -0
- package/lib/public/modules/markdown.js +50 -2
- package/lib/public/modules/mate-management.js +86 -0
- package/lib/public/modules/mate-sidebar.js +0 -8
- package/lib/public/modules/mate-wizard.js +0 -7
- package/lib/public/modules/mention.js +17 -19
- package/lib/public/modules/pane-bridge.js +9 -0
- package/lib/public/modules/profile.js +4 -5
- package/lib/public/modules/project-logs-ambient.js +238 -0
- package/lib/public/modules/project-logs-render.js +359 -0
- package/lib/public/modules/project-logs.js +328 -0
- package/lib/public/modules/project-settings.js +34 -28
- package/lib/public/modules/project-switcher.js +11 -5
- package/lib/public/modules/project-workspace-assignment.js +23 -0
- package/lib/public/modules/scheduler.js +17 -3
- package/lib/public/modules/search-clay-chat.js +402 -0
- package/lib/public/modules/server-settings.js +14 -12
- package/lib/public/modules/session-actions.js +1 -1
- package/lib/public/modules/sidebar-mates.js +56 -552
- package/lib/public/modules/sidebar-mobile.js +12 -73
- package/lib/public/modules/sidebar-presence.js +37 -0
- package/lib/public/modules/sidebar-sessions.js +25 -1
- package/lib/public/modules/split-pair-ui.js +13 -13
- package/lib/public/modules/split-view.js +7 -0
- package/lib/public/modules/sticky-notes.js +106 -53
- package/lib/public/modules/tool-input-composition.js +48 -0
- package/lib/public/modules/tool-llm-status.js +167 -0
- package/lib/public/modules/tool-palette.js +76 -4
- package/lib/public/modules/tool-renderer-advanced.js +285 -0
- package/lib/public/modules/tool-renderer-chart.js +158 -0
- package/lib/public/modules/tool-renderer-semantics.js +35 -0
- package/lib/public/modules/tool-renderer.js +464 -0
- package/lib/public/modules/tool-runtime.js +309 -0
- package/lib/public/modules/tool-ui-evaluator.js +97 -0
- package/lib/public/modules/tool-ui-tree.js +21 -0
- package/lib/public/modules/tui-attention.js +10 -0
- package/lib/public/modules/user-settings.js +16 -23
- package/lib/public/modules/vendor-login.js +287 -0
- package/lib/public/modules/worker-proposal.js +2 -2
- package/lib/public/modules/workspace-assignment-card.js +149 -0
- package/lib/public/modules/workspace-assignment-routing.js +4 -0
- package/lib/public/style.css +14 -2
- package/lib/runtime-env.js +65 -0
- package/lib/sdk-bridge.js +120 -32
- package/lib/sdk-message-processor.js +34 -13
- package/lib/server-home-capsule-creation.js +36 -0
- package/lib/server-home-chat-events.js +287 -0
- package/lib/server-home-chat.js +518 -0
- package/lib/server-home-clay-entry.js +65 -0
- package/lib/server-home-clay-session-links.js +26 -0
- package/lib/server-home-debate-planning.js +214 -0
- package/lib/server-home-debates.js +137 -0
- package/lib/server-home-mate-creation.js +261 -0
- package/lib/server-home-models.js +241 -0
- package/lib/server-home-preferences.js +61 -0
- package/lib/server-mates.js +37 -0
- package/lib/server-tools.js +377 -0
- package/lib/server.js +166 -59
- package/lib/session-pair-mcp-server.js +6 -6
- package/lib/sessions.js +22 -4
- package/lib/tool-capsule-source.js +142 -0
- package/lib/tool-control-mcp-server.js +126 -0
- package/lib/tool-llm.js +48 -0
- package/lib/tool-storage.js +77 -0
- package/lib/tool-ui-spec-advanced.js +82 -0
- package/lib/tool-ui-spec.js +261 -0
- package/lib/tools-registry.js +286 -0
- package/lib/users-home-dock-preferences.js +77 -0
- package/lib/users-home-surface-preferences.js +99 -0
- package/lib/users-preferences.js +4 -7
- package/lib/users.js +12 -0
- package/lib/whats-new-content.js +3 -3
- package/lib/workspace-assignment-service.js +420 -0
- package/lib/workspace-query-mcp-server.js +154 -0
- package/lib/workspace-query-service.js +492 -0
- package/lib/ws-schema.js +107 -12
- package/lib/yoke/adapters/acp.js +2 -1
- package/lib/yoke/adapters/antigravity.js +2 -1
- package/lib/yoke/adapters/claude-worker.js +11 -4
- package/lib/yoke/adapters/claude.js +141 -46
- package/lib/yoke/adapters/codex.js +79 -11
- package/lib/yoke/adapters/kiro.js +2 -1
- package/lib/yoke/claude-user-input.js +38 -0
- package/lib/yoke/codex-app-server.js +20 -2
- package/lib/yoke/codex-background-tasks.js +8 -2
- package/lib/yoke/codex-user-input.js +64 -0
- package/lib/yoke/complete-once.js +164 -0
- package/lib/yoke/index.js +5 -1
- package/lib/yoke/interface.js +19 -0
- package/lib/yoke/mcp-bridge-server.js +2 -6
- package/lib/yoke/user-input.js +254 -0
- package/package.json +4 -3
- package/lib/public/css/home-chat.css +0 -380
- package/lib/public/modules/home-chat.js +0 -438
- package/lib/server-clay-home.js +0 -245
|
@@ -6,11 +6,12 @@ import { refreshIcons, iconHtml } from './icons.js';
|
|
|
6
6
|
import { escapeHtml } from './utils.js';
|
|
7
7
|
import { store } from './store.js';
|
|
8
8
|
import { getWs } from './ws-ref.js';
|
|
9
|
-
import {
|
|
9
|
+
import { showHomeHub } from './app-home-hub.js';
|
|
10
|
+
import { openHomeChat } from './home-mate-chat.js';
|
|
10
11
|
import { getCachedProjects, switchProject, renderProjectList } from './app-projects.js';
|
|
11
12
|
import { mateAvatarUrl, userAvatarUrl } from './avatar.js';
|
|
12
|
-
import { openTerminal } from './terminal.js';
|
|
13
13
|
import { openTuiModal } from './tui-attention.js';
|
|
14
|
+
import { requestVendorLogin } from './vendor-login.js';
|
|
14
15
|
import { startUrgentBlink, stopUrgentBlink } from './app-favicon.js';
|
|
15
16
|
import { playDoneSound, isNotifSoundEnabled } from './notifications.js';
|
|
16
17
|
var notifications = [];
|
|
@@ -46,7 +47,6 @@ var pendingTuiTotal = 0;
|
|
|
46
47
|
// (next hour) acts as a fresh ping.
|
|
47
48
|
var pendingUpdateMsg = null;
|
|
48
49
|
var activeAuthRequiredMsg = null;
|
|
49
|
-
var authReminderVisible = false;
|
|
50
50
|
|
|
51
51
|
// ========================================================
|
|
52
52
|
// Init
|
|
@@ -90,7 +90,6 @@ function showAllBanners() {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
if (activeAuthRequiredMsg) showAuthRequiredBanner(activeAuthRequiredMsg);
|
|
93
|
-
if (authReminderVisible) showLoginReminderBanner();
|
|
94
93
|
|
|
95
94
|
// Check if any banner actually got rendered (update/auth banners can be suppressed)
|
|
96
95
|
var hasVisibleBanner = bannerContainer.children.length > 0;
|
|
@@ -265,8 +264,9 @@ function showBanner(notif, autoDismissMs) {
|
|
|
265
264
|
removeBanner(banner);
|
|
266
265
|
dismissNotif(notif.id);
|
|
267
266
|
var authMeta = notif.meta || {};
|
|
268
|
-
|
|
269
|
-
|
|
267
|
+
// Deliberate click: re-attach to a live login terminal instead of
|
|
268
|
+
// spawning a second one (the server dedups per vendor).
|
|
269
|
+
requestVendorLogin(authMeta.vendor || "claude", { sessionId: notif.sessionId || null });
|
|
270
270
|
});
|
|
271
271
|
}
|
|
272
272
|
}
|
|
@@ -324,118 +324,6 @@ function showBanner(notif, autoDismissMs) {
|
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
-
// Open the login terminal as a modal dialog (the same modal used for TUI
|
|
328
|
-
// attention), running the vendor login command. The terminal is created with
|
|
329
|
-
// the command as its initial input, so when the modal attaches it replays the
|
|
330
|
-
// scrollback and the user sees the login URL / prompts immediately.
|
|
331
|
-
// Falls back to the sidebar terminal if the current project slug is unknown
|
|
332
|
-
// (the modal needs a slug to open its own WS to the project).
|
|
333
|
-
function currentProjectSlug() {
|
|
334
|
-
var slug = store.get('currentSlug') || "";
|
|
335
|
-
if (slug) return slug;
|
|
336
|
-
// Fallback: derive from the URL (/p/<slug>/...).
|
|
337
|
-
try {
|
|
338
|
-
var m = (window.location.pathname || "").match(/^\/p\/([a-z0-9_-]+)/);
|
|
339
|
-
if (m) return m[1];
|
|
340
|
-
} catch (e) {}
|
|
341
|
-
return "";
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
function startLoginInModal(loginCommand, vendor) {
|
|
345
|
-
if (authReminderVisible) return;
|
|
346
|
-
var ws = getWs();
|
|
347
|
-
if (!ws || ws.readyState !== 1) return;
|
|
348
|
-
var cmd = loginCommand || getVendorLoginCommand(vendor);
|
|
349
|
-
var slug = currentProjectSlug();
|
|
350
|
-
if (!slug) { startLoginCommand(cmd); return; }
|
|
351
|
-
store.set({ pendingLoginModal: { slug: slug, vendor: vendor || "claude" } });
|
|
352
|
-
ws.send(JSON.stringify({
|
|
353
|
-
type: "term_create",
|
|
354
|
-
cols: 100,
|
|
355
|
-
rows: 30,
|
|
356
|
-
initialCommand: cmd + "\n",
|
|
357
|
-
}));
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// Sidebar-terminal fallback (used when no slug is available for the modal).
|
|
361
|
-
function startLoginCommand(loginCommand) {
|
|
362
|
-
if (authReminderVisible) return;
|
|
363
|
-
var ws = getWs();
|
|
364
|
-
if (!ws || ws.readyState !== 1) return;
|
|
365
|
-
var termCommand = (loginCommand || "claude login") + "\n";
|
|
366
|
-
store.set({ pendingTermCommand: termCommand });
|
|
367
|
-
ws.send(JSON.stringify({ type: "term_create", cols: 80, rows: 24 }));
|
|
368
|
-
openTerminal();
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// Auto-open the login modal and run the login command when the server reports
|
|
372
|
-
// the vendor isn't logged in. The popup terminal runs as the connected user's
|
|
373
|
-
// own OS identity (term_create -> getOsUserInfoForWs), so login always targets
|
|
374
|
-
// the right account — we pop it unconditionally rather than gating on
|
|
375
|
-
// canAutoLogin. Idempotent: startLoginInModal is guarded by authReminderVisible
|
|
376
|
-
// so repeat auth_required events no-op.
|
|
377
|
-
export function autoStartLoginIfNeeded(msg) {
|
|
378
|
-
if (!msg) return false;
|
|
379
|
-
if (authReminderVisible) return false;
|
|
380
|
-
var vendor = msg.vendor || "claude";
|
|
381
|
-
var cmd = msg.loginCommand
|
|
382
|
-
|| getVendorLoginCommand(vendor);
|
|
383
|
-
startLoginInModal(cmd, vendor);
|
|
384
|
-
showLoginReminderBanner();
|
|
385
|
-
return true;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
function showLoginReminderBanner() {
|
|
389
|
-
if (!bannerContainer) return;
|
|
390
|
-
authReminderVisible = true;
|
|
391
|
-
var existing = bannerContainer.querySelector('[data-auth-reminder="true"]');
|
|
392
|
-
if (existing) removeBanner(existing);
|
|
393
|
-
var banner = document.createElement("div");
|
|
394
|
-
banner.className = "notif-banner notif-banner-update";
|
|
395
|
-
banner.setAttribute("data-notif-id", "_auth_reminder");
|
|
396
|
-
banner.setAttribute("data-auth-reminder", "true");
|
|
397
|
-
banner.innerHTML =
|
|
398
|
-
'<div class="notif-banner-icon">' + iconHtml("check-circle") + '</div>' +
|
|
399
|
-
'<div class="notif-banner-body">' +
|
|
400
|
-
'<div class="notif-banner-project">CLAY</div>' +
|
|
401
|
-
'<div class="notif-banner-title">Login started</div>' +
|
|
402
|
-
'<div class="notif-banner-text">After the login completes, open a new session so Clay picks up the fresh auth state.</div>' +
|
|
403
|
-
'<div class="notif-banner-actions">' +
|
|
404
|
-
'<button class="notif-banner-new-session notif-banner-update-now">Open new session</button>' +
|
|
405
|
-
'</div>' +
|
|
406
|
-
'</div>' +
|
|
407
|
-
'<button class="notif-banner-close">' + iconHtml("x") + '</button>';
|
|
408
|
-
|
|
409
|
-
bannerContainer.appendChild(banner);
|
|
410
|
-
refreshIcons();
|
|
411
|
-
|
|
412
|
-
requestAnimationFrame(function () {
|
|
413
|
-
banner.classList.add("show");
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
var newSessionBtn = banner.querySelector(".notif-banner-new-session");
|
|
417
|
-
if (newSessionBtn) {
|
|
418
|
-
newSessionBtn.addEventListener("click", function (e) {
|
|
419
|
-
e.stopPropagation();
|
|
420
|
-
authReminderVisible = false;
|
|
421
|
-
var ws = getWs();
|
|
422
|
-
if (ws && ws.readyState === 1) {
|
|
423
|
-
ws.send(JSON.stringify({ type: "new_session" }));
|
|
424
|
-
}
|
|
425
|
-
removeBanner(banner);
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
var closeBtn = banner.querySelector(".notif-banner-close");
|
|
430
|
-
if (closeBtn) {
|
|
431
|
-
closeBtn.addEventListener("click", function (e) {
|
|
432
|
-
e.stopPropagation();
|
|
433
|
-
authReminderVisible = false;
|
|
434
|
-
removeBanner(banner);
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
327
|
export function showAuthRequiredBanner(msg) {
|
|
440
328
|
if (!bannerContainer) return;
|
|
441
329
|
var vendor = (msg && (msg.vendor || (msg.meta && msg.meta.vendor))) || "claude";
|
|
@@ -726,7 +614,8 @@ function navigateToNotification(notif) {
|
|
|
726
614
|
if (notif.sessionId) {
|
|
727
615
|
try { sessionStorage.setItem("pending-notif-session", notif.sessionId); } catch (e) {}
|
|
728
616
|
}
|
|
729
|
-
|
|
617
|
+
showHomeHub();
|
|
618
|
+
openHomeChat(mateId);
|
|
730
619
|
return;
|
|
731
620
|
}
|
|
732
621
|
|
|
@@ -10,7 +10,7 @@ import { setupModelPicker, renderModelPicker, requestVendorModels, prepareModelP
|
|
|
10
10
|
|
|
11
11
|
// --- Module-owned state (not in store) ---
|
|
12
12
|
var sessionUsage = { cost: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, turns: 0 };
|
|
13
|
-
var contextData = { contextWindow: 0, maxOutputTokens: 0, model: "-", cost: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, turns: 0 };
|
|
13
|
+
var contextData = { contextWindow: 0, maxOutputTokens: 0, model: "-", cost: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, turns: 0, thinking: null, costBasis: null };
|
|
14
14
|
var ctxPopoverEl = null;
|
|
15
15
|
var ctxHoverTimer = null;
|
|
16
16
|
var statusRefreshTimer = null;
|
|
@@ -72,6 +72,10 @@ var contextCacheReadEl = null;
|
|
|
72
72
|
var contextCacheWriteEl = null;
|
|
73
73
|
var contextModelEl = null;
|
|
74
74
|
var contextCostEl = null;
|
|
75
|
+
var contextThinkingEl = null;
|
|
76
|
+
var contextThinkingRow = null;
|
|
77
|
+
var contextCostBasisEl = null;
|
|
78
|
+
var contextCostBasisRow = null;
|
|
75
79
|
var contextTurnsEl = null;
|
|
76
80
|
var contextMini = null;
|
|
77
81
|
var contextMiniFill = null;
|
|
@@ -449,6 +453,10 @@ export function initPanels() {
|
|
|
449
453
|
contextCacheWriteEl = $("context-cache-write");
|
|
450
454
|
contextModelEl = $("context-model");
|
|
451
455
|
contextCostEl = $("context-cost");
|
|
456
|
+
contextThinkingEl = $("context-thinking");
|
|
457
|
+
contextThinkingRow = $("context-thinking-row");
|
|
458
|
+
contextCostBasisEl = $("context-cost-basis");
|
|
459
|
+
contextCostBasisRow = $("context-cost-basis-row");
|
|
452
460
|
contextTurnsEl = $("context-turns");
|
|
453
461
|
contextMini = $("context-mini");
|
|
454
462
|
contextMiniFill = $("context-mini-fill");
|
|
@@ -776,6 +784,16 @@ export function updateContextPanel() {
|
|
|
776
784
|
contextCacheWriteEl.textContent = formatTokens(contextData.cacheWrite);
|
|
777
785
|
contextModelEl.textContent = contextData.model;
|
|
778
786
|
contextCostEl.textContent = "$" + contextData.cost.toFixed(4);
|
|
787
|
+
// Optional SDK fields: shown only once the CLI has actually reported them.
|
|
788
|
+
if (contextThinkingRow && contextThinkingEl) {
|
|
789
|
+
var hasThinking = typeof contextData.thinking === "number";
|
|
790
|
+
contextThinkingRow.classList.toggle("hidden", !hasThinking);
|
|
791
|
+
if (hasThinking) contextThinkingEl.textContent = formatTokens(contextData.thinking);
|
|
792
|
+
}
|
|
793
|
+
if (contextCostBasisRow && contextCostBasisEl) {
|
|
794
|
+
contextCostBasisRow.classList.toggle("hidden", !contextData.costBasis);
|
|
795
|
+
if (contextData.costBasis) contextCostBasisEl.textContent = contextData.costBasis;
|
|
796
|
+
}
|
|
779
797
|
contextTurnsEl.textContent = String(contextData.turns);
|
|
780
798
|
}
|
|
781
799
|
|
|
@@ -811,6 +829,29 @@ export function accumulateContext(cost, usage, modelUsage, lastStreamInputTokens
|
|
|
811
829
|
contextData.model = displayModel;
|
|
812
830
|
contextData.contextWindow = resolveContextWindow(displayModel, mu.contextWindow);
|
|
813
831
|
if (mu.maxOutputTokens) contextData.maxOutputTokens = mu.maxOutputTokens;
|
|
832
|
+
|
|
833
|
+
// thinkingTokens and costBasis are per-model and optional: absent on
|
|
834
|
+
// older CLI builds and, for a resumed session, on the turns that ran
|
|
835
|
+
// before the field existed. Leave them null in that case so the rows
|
|
836
|
+
// stay hidden rather than claiming a confident zero.
|
|
837
|
+
var thinkingTotal = null;
|
|
838
|
+
var basis = null;
|
|
839
|
+
var basisMixed = false;
|
|
840
|
+
for (var mi = 0; mi < models.length; mi++) {
|
|
841
|
+
var entry = modelUsage[models[mi]];
|
|
842
|
+
if (!entry) continue;
|
|
843
|
+
if (typeof entry.thinkingTokens === "number") {
|
|
844
|
+
thinkingTotal = (thinkingTotal || 0) + entry.thinkingTokens;
|
|
845
|
+
}
|
|
846
|
+
if (entry.costBasis) {
|
|
847
|
+
if (basis === null) basis = entry.costBasis;
|
|
848
|
+
else if (basis !== entry.costBasis) basisMixed = true;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
contextData.thinking = thinkingTotal;
|
|
852
|
+
// Several models in one query can be priced differently; say so rather
|
|
853
|
+
// than reporting whichever happened to come first.
|
|
854
|
+
contextData.costBasis = basisMixed ? "mixed" : basis;
|
|
814
855
|
}
|
|
815
856
|
}
|
|
816
857
|
if (!store.get('replayingHistory')) updateContextPanel();
|
|
@@ -832,7 +873,7 @@ export function applyContextView(view) {
|
|
|
832
873
|
}
|
|
833
874
|
|
|
834
875
|
export function resetContextData() {
|
|
835
|
-
contextData = { contextWindow: 0, maxOutputTokens: 0, model: "-", cost: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, turns: 0 };
|
|
876
|
+
contextData = { contextWindow: 0, maxOutputTokens: 0, model: "-", cost: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, turns: 0, thinking: null, costBasis: null };
|
|
836
877
|
store.set({ richContextUsage: null });
|
|
837
878
|
// hideCtxPopover + updateContextPanel handled by store subscriber
|
|
838
879
|
}
|
|
@@ -413,6 +413,7 @@ export function resetClientState() {
|
|
|
413
413
|
|
|
414
414
|
export function switchProject(slug) {
|
|
415
415
|
if (!slug) return;
|
|
416
|
+
document.cookie = "clay_last_project=" + encodeURIComponent(slug) + "; Path=/; SameSite=Strict; Max-Age=31536000";
|
|
416
417
|
var st = store.snap();
|
|
417
418
|
var wasDm = st.dmMode;
|
|
418
419
|
var wasMate = st.dmMode && st.dmTargetUser && st.dmTargetUser.isMate;
|
|
@@ -420,7 +421,14 @@ export function switchProject(slug) {
|
|
|
420
421
|
closeWhatsNewArticle();
|
|
421
422
|
if (isHomeHubVisible()) {
|
|
422
423
|
hideHomeHub();
|
|
423
|
-
if (slug === store.get('currentSlug'))
|
|
424
|
+
if (slug === store.get('currentSlug')) {
|
|
425
|
+
if (document.documentElement.classList.contains("pwa-standalone")) {
|
|
426
|
+
history.replaceState(null, "", "/p/" + slug + "/");
|
|
427
|
+
} else {
|
|
428
|
+
history.pushState(null, "", "/p/" + slug + "/");
|
|
429
|
+
}
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
424
432
|
}
|
|
425
433
|
if (slug === store.get('currentSlug')) {
|
|
426
434
|
var ws = getWs();
|