clay-server 3.4.0-beta.2 → 3.4.0-beta.21
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/daemon-projects.js +3 -3
- package/lib/daemon.js +59 -59
- package/lib/project-connection.js +35 -7
- package/lib/project-debate.js +4 -0
- package/lib/project-mate-interaction.js +21 -1
- package/lib/project-memory.js +3 -0
- package/lib/project-models.js +220 -0
- package/lib/project-session-handoff.js +162 -0
- package/lib/project-session-pair.js +14 -7
- package/lib/project-session-spawn.js +1 -1
- package/lib/project-sessions.js +13 -45
- package/lib/project-worker-proposal.js +51 -14
- package/lib/project.js +38 -80
- package/lib/public/antigravity-avatar.png +0 -0
- package/lib/public/app.js +29 -0
- package/lib/public/copilot-avatar.svg +5 -0
- package/lib/public/css/command-palette.css +22 -2
- package/lib/public/css/icon-strip.css +29 -13
- package/lib/public/css/input.css +56 -0
- package/lib/public/css/mates.css +6 -0
- package/lib/public/css/menus.css +38 -25
- package/lib/public/css/messages.css +9 -0
- package/lib/public/css/pane.css +16 -3
- package/lib/public/css/pwa-mobile.css +17 -0
- package/lib/public/css/session-actions.css +98 -0
- package/lib/public/css/title-bar.css +19 -0
- package/lib/public/grok-avatar.svg +4 -0
- package/lib/public/index.html +29 -7
- package/lib/public/junie-avatar.svg +11 -0
- package/lib/public/kimi-avatar.svg +4 -0
- package/lib/public/modules/agent-config-selects.js +69 -0
- package/lib/public/modules/app-header.js +4 -22
- package/lib/public/modules/app-messages.js +54 -11
- package/lib/public/modules/app-panels.js +36 -83
- package/lib/public/modules/app-projects.js +3 -1
- package/lib/public/modules/app-rendering.js +19 -4
- package/lib/public/modules/background-tasks-ui.js +55 -0
- package/lib/public/modules/mate-sidebar.js +11 -3
- package/lib/public/modules/model-picker.js +263 -0
- package/lib/public/modules/notifications.js +7 -1
- package/lib/public/modules/pane-bridge.js +11 -0
- package/lib/public/modules/pane-links.js +23 -0
- package/lib/public/modules/project-switcher.js +7 -6
- package/lib/public/modules/session-actions.js +294 -0
- package/lib/public/modules/sidebar-mates.js +1 -1
- package/lib/public/modules/sidebar-mobile.js +2 -1
- package/lib/public/modules/sidebar-projects.js +34 -43
- package/lib/public/modules/sidebar-sessions.js +20 -6
- package/lib/public/modules/split-pair-ui.js +16 -77
- package/lib/public/modules/split-view.js +3 -0
- package/lib/public/modules/tools.js +6 -1
- package/lib/public/modules/vendor-priority.js +14 -0
- package/lib/public/modules/vendor-selection.js +20 -0
- package/lib/public/modules/worker-proposal.js +6 -1
- package/lib/public/modules/worktree-location.js +17 -0
- package/lib/public/qwen-avatar.svg +4 -0
- package/lib/public/style.css +4 -2
- package/lib/sdk-bridge.js +103 -56
- package/lib/sdk-message-processor.js +26 -4
- package/lib/session-handoff-context.js +110 -0
- package/lib/session-notes-mcp-server.js +8 -1
- package/lib/sessions.js +4 -0
- package/lib/worktree.js +9 -4
- package/lib/ws-schema.js +9 -1
- package/lib/yoke/acp-agent-profiles.js +64 -14
- package/lib/yoke/adapters/antigravity.js +417 -0
- package/lib/yoke/adapters/claude.js +34 -0
- package/lib/yoke/adapters/codex.js +101 -5
- package/lib/yoke/adapters/copilot.js +7 -0
- package/lib/yoke/adapters/grok.js +7 -0
- package/lib/yoke/adapters/junie.js +7 -0
- package/lib/yoke/adapters/kimi.js +7 -0
- package/lib/yoke/adapters/kiro.js +2 -2
- package/lib/yoke/adapters/qwen.js +7 -0
- package/lib/yoke/codex-app-server.js +25 -8
- package/lib/yoke/index.js +67 -28
- package/lib/yoke/instructions.js +3 -0
- package/lib/yoke/interface.js +12 -0
- package/lib/yoke/vendor-registry.js +61 -6
- package/package.json +1 -1
- package/lib/public/gemini-avatar.svg +0 -11
- package/lib/yoke/adapters/gemini.js +0 -7
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#header-session-actions-btn {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
width: 28px;
|
|
6
|
+
height: 28px;
|
|
7
|
+
padding: 0;
|
|
8
|
+
border: 1px solid transparent;
|
|
9
|
+
border-radius: 8px;
|
|
10
|
+
background: transparent;
|
|
11
|
+
color: var(--text-dimmer);
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
flex-shrink: 0;
|
|
14
|
+
transition: color 0.15s, background 0.15s, border-color 0.15s;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
#header-session-actions-btn:hover,
|
|
18
|
+
#header-session-actions-btn[aria-expanded="true"] {
|
|
19
|
+
color: var(--text);
|
|
20
|
+
background: rgba(var(--overlay-rgb), 0.05);
|
|
21
|
+
border-color: var(--border);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#header-session-actions-btn.hidden { display: none; }
|
|
25
|
+
#header-session-actions-btn .lucide { width: 16px; height: 16px; }
|
|
26
|
+
|
|
27
|
+
.session-actions-menu {
|
|
28
|
+
position: fixed;
|
|
29
|
+
z-index: 10020;
|
|
30
|
+
width: 286px;
|
|
31
|
+
padding: 6px;
|
|
32
|
+
border: 1px solid var(--border);
|
|
33
|
+
border-radius: 12px;
|
|
34
|
+
background: color-mix(in srgb, var(--bg) 96%, transparent);
|
|
35
|
+
box-shadow: 0 14px 38px rgba(var(--shadow-rgb), 0.32), 0 2px 8px rgba(var(--shadow-rgb), 0.2);
|
|
36
|
+
backdrop-filter: blur(18px);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.session-actions-row {
|
|
40
|
+
width: 100%;
|
|
41
|
+
border: 0;
|
|
42
|
+
background: transparent;
|
|
43
|
+
color: var(--text);
|
|
44
|
+
font: inherit;
|
|
45
|
+
text-align: left;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.session-actions-row {
|
|
50
|
+
display: grid;
|
|
51
|
+
grid-template-columns: 30px minmax(0, 1fr) 16px;
|
|
52
|
+
align-items: center;
|
|
53
|
+
gap: 8px;
|
|
54
|
+
min-height: 54px;
|
|
55
|
+
padding: 7px 8px;
|
|
56
|
+
border-radius: 8px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.session-actions-row:hover { background: var(--bg-alt); }
|
|
60
|
+
.session-actions-row:disabled { cursor: default; opacity: 0.42; }
|
|
61
|
+
.session-actions-row:disabled:hover { background: transparent; }
|
|
62
|
+
|
|
63
|
+
.session-actions-row-icon {
|
|
64
|
+
display: grid;
|
|
65
|
+
place-items: center;
|
|
66
|
+
width: 28px;
|
|
67
|
+
height: 28px;
|
|
68
|
+
border: 1px solid var(--border-subtle);
|
|
69
|
+
border-radius: 8px;
|
|
70
|
+
background: rgba(var(--overlay-rgb), 0.035);
|
|
71
|
+
color: var(--accent2);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.session-actions-row-icon .lucide { width: 15px; height: 15px; }
|
|
75
|
+
.session-actions-row-copy { display: flex; min-width: 0; flex-direction: column; gap: 2px; }
|
|
76
|
+
.session-actions-row-copy strong { font-size: 12px; font-weight: 750; }
|
|
77
|
+
.session-actions-row-copy > span { color: var(--text-dimmer); font-size: 10px; line-height: 1.25; }
|
|
78
|
+
.session-actions-row-chevron { color: var(--text-dimmer); }
|
|
79
|
+
.session-actions-row-chevron .lucide { width: 13px; height: 13px; }
|
|
80
|
+
|
|
81
|
+
.handoff-modal { width: min(420px, calc(100vw - 32px)); }
|
|
82
|
+
.handoff-modal-desc { margin: -10px 0 14px; color: var(--text-dimmer); font-size: 12px; line-height: 1.45; }
|
|
83
|
+
.handoff-modal-source {
|
|
84
|
+
display: flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
gap: 10px;
|
|
87
|
+
margin-bottom: 14px;
|
|
88
|
+
padding: 10px;
|
|
89
|
+
border: 1px solid var(--border-subtle);
|
|
90
|
+
border-radius: 9px;
|
|
91
|
+
background: var(--bg-alt);
|
|
92
|
+
}
|
|
93
|
+
.handoff-modal-source > img { width: 26px; height: 26px; object-fit: contain; border-radius: 6px; }
|
|
94
|
+
.handoff-modal-source > span { display: grid; min-width: 0; gap: 1px; }
|
|
95
|
+
.handoff-modal-source strong { overflow: hidden; color: var(--text); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
|
|
96
|
+
.handoff-modal-source span span { color: var(--text-dimmer); font-size: 10px; }
|
|
97
|
+
.handoff-modal-field + .handoff-modal-field { margin-top: 10px; }
|
|
98
|
+
.handoff-modal-field .wt-modal-label { margin-top: 0; }
|
|
@@ -324,6 +324,25 @@
|
|
|
324
324
|
display: none !important;
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
+
.title-bar-content {
|
|
328
|
+
height: calc(48px + var(--safe-top));
|
|
329
|
+
padding: var(--safe-top) 16px 0;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/* The inline title editor must own the header while the keyboard is open.
|
|
333
|
+
Leaving the other controls visible made its usable width nearly zero. */
|
|
334
|
+
.title-bar-content.session-renaming .status,
|
|
335
|
+
.title-bar-content.session-renaming #header-left > :not(.header-rename-input) {
|
|
336
|
+
display: none !important;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.title-bar-content.session-renaming .header-rename-input {
|
|
340
|
+
flex: 1 1 100%;
|
|
341
|
+
width: 100%;
|
|
342
|
+
min-height: 36px;
|
|
343
|
+
font-size: 16px;
|
|
344
|
+
}
|
|
345
|
+
|
|
327
346
|
#sidebar-column {
|
|
328
347
|
width: 0 !important;
|
|
329
348
|
min-width: 0 !important;
|
package/lib/public/index.html
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
(function(){try{var k="clay-theme-vars",v=localStorage.getItem(k),r=document.documentElement;if(v){var o=JSON.parse(v),p;for(p in o)r.style.setProperty(p,o[p]);var vt=localStorage.getItem(k.replace("-vars","-variant"));if(vt==="light"){r.classList.add("light-theme");r.classList.remove("dark-theme")}else{r.classList.add("dark-theme");r.classList.remove("light-theme")}var m=document.querySelector('meta[name="theme-color"]');if(m&&o["--bg"])m.setAttribute("content",o["--bg"])}else{var sl=window.matchMedia&&window.matchMedia("(prefers-color-scheme: light)").matches;if(sl){r.classList.add("light-theme");r.classList.remove("dark-theme")}}}catch(e){}})();
|
|
31
31
|
</script>
|
|
32
32
|
<script>if(window.navigator.standalone||window.matchMedia("(display-mode:standalone)").matches){document.documentElement.classList.add("pwa-standalone")}</script>
|
|
33
|
-
<link rel="stylesheet" href="style.css?v=
|
|
33
|
+
<link rel="stylesheet" href="style.css?v=20260826a">
|
|
34
34
|
<style>
|
|
35
35
|
@media(max-width:768px){
|
|
36
36
|
/* User messages: vertical stack, avatar on top, right-aligned */
|
|
@@ -373,12 +373,11 @@
|
|
|
373
373
|
</div>
|
|
374
374
|
<button id="hamburger-btn" aria-label="Toggle sidebar" title="Toggle sidebar"><i data-lucide="menu"></i></button>
|
|
375
375
|
<span class="header-title" id="header-title">Connecting...</span>
|
|
376
|
+
<button id="header-rename-btn" type="button" title="Rename session"><i data-lucide="pencil"></i></button>
|
|
376
377
|
<button id="header-info-btn" type="button" title="Session info"><i data-lucide="info"></i></button>
|
|
377
378
|
<button id="header-full-access-btn" type="button" class="session-full-access hidden" role="switch" aria-checked="false" title="Skip Permissions is off — permission prompts are on">
|
|
378
379
|
<span class="session-full-access-label">Skip Permissions</span><span class="session-full-access-track" aria-hidden="true"><span></span></span>
|
|
379
380
|
</button>
|
|
380
|
-
<button id="header-rename-btn" type="button" title="Rename session"><i data-lucide="pencil"></i></button>
|
|
381
|
-
<button id="header-add-worker-btn" type="button" title="Add Worker — this session becomes the Driver of a pair"><i data-lucide="user-plus"></i></button>
|
|
382
381
|
<button type="button" id="header-tui-close-btn" class="header-tui-close-btn hidden" title="Close terminal (keeps history, resume anytime)" aria-label="Close terminal"><i data-lucide="power"></i></button>
|
|
383
382
|
<div id="mate-mobile-title" class="mate-mobile-title hidden">
|
|
384
383
|
<img id="mate-mobile-avatar" class="mate-mobile-avatar" alt="">
|
|
@@ -389,6 +388,9 @@
|
|
|
389
388
|
<div id="ralph-sticky" class="hidden"></div>
|
|
390
389
|
<div id="debate-sticky" class="hidden"></div>
|
|
391
390
|
<div class="status">
|
|
391
|
+
<button id="header-session-actions-btn" type="button" aria-label="Session actions" title="Session actions" aria-haspopup="menu" aria-expanded="false">
|
|
392
|
+
<i data-lucide="ellipsis"></i>
|
|
393
|
+
</button>
|
|
392
394
|
<button type="button" id="header-tui-font-btn" class="header-tui-font-btn hidden" title="Terminal font" aria-label="Terminal font">
|
|
393
395
|
<i data-lucide="type"></i>
|
|
394
396
|
</button>
|
|
@@ -528,14 +530,34 @@
|
|
|
528
530
|
<img src="/codex-avatar.png" class="vendor-toggle-icon" alt="Codex">
|
|
529
531
|
<span class="vendor-toggle-label">Codex</span>
|
|
530
532
|
</button>
|
|
531
|
-
<button id="vendor-btn-
|
|
532
|
-
<img src="/
|
|
533
|
-
<span class="vendor-toggle-label">
|
|
533
|
+
<button id="vendor-btn-antigravity" class="vendor-toggle-btn" data-vendor="antigravity">
|
|
534
|
+
<img src="/antigravity-avatar.png" class="vendor-toggle-icon" alt="Antigravity">
|
|
535
|
+
<span class="vendor-toggle-label">Antigravity CLI</span>
|
|
534
536
|
</button>
|
|
535
537
|
<button id="vendor-btn-opencode" class="vendor-toggle-btn" data-vendor="opencode">
|
|
536
538
|
<img src="/opencode-avatar.svg" class="vendor-toggle-icon" alt="OpenCode">
|
|
537
539
|
<span class="vendor-toggle-label">OpenCode</span>
|
|
538
540
|
</button>
|
|
541
|
+
<button id="vendor-btn-kimi" class="vendor-toggle-btn" data-vendor="kimi">
|
|
542
|
+
<img src="/kimi-avatar.svg" class="vendor-toggle-icon" alt="Kimi">
|
|
543
|
+
<span class="vendor-toggle-label">Kimi Code</span>
|
|
544
|
+
</button>
|
|
545
|
+
<button id="vendor-btn-grok" class="vendor-toggle-btn" data-vendor="grok">
|
|
546
|
+
<img src="/grok-avatar.svg" class="vendor-toggle-icon" alt="Grok">
|
|
547
|
+
<span class="vendor-toggle-label">Grok Build</span>
|
|
548
|
+
</button>
|
|
549
|
+
<button id="vendor-btn-copilot" class="vendor-toggle-btn" data-vendor="copilot">
|
|
550
|
+
<img src="/copilot-avatar.svg" class="vendor-toggle-icon" alt="GitHub Copilot">
|
|
551
|
+
<span class="vendor-toggle-label">GitHub Copilot CLI</span>
|
|
552
|
+
</button>
|
|
553
|
+
<button id="vendor-btn-qwen" class="vendor-toggle-btn" data-vendor="qwen">
|
|
554
|
+
<img src="/qwen-avatar.svg" class="vendor-toggle-icon" alt="Qwen">
|
|
555
|
+
<span class="vendor-toggle-label">Qwen Code</span>
|
|
556
|
+
</button>
|
|
557
|
+
<button id="vendor-btn-junie" class="vendor-toggle-btn" data-vendor="junie">
|
|
558
|
+
<img src="/junie-avatar.svg" class="vendor-toggle-icon" alt="Junie">
|
|
559
|
+
<span class="vendor-toggle-label">Junie CLI</span>
|
|
560
|
+
</button>
|
|
539
561
|
<button id="vendor-btn-kiro" class="vendor-toggle-btn" data-vendor="kiro">
|
|
540
562
|
<img src="/kiro-avatar.svg" class="vendor-toggle-icon" alt="Kiro">
|
|
541
563
|
<span class="vendor-toggle-label">Kiro CLI</span>
|
|
@@ -2338,7 +2360,7 @@
|
|
|
2338
2360
|
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0/lib/addon-fit.min.js"></script>
|
|
2339
2361
|
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-web-links@0/lib/addon-web-links.min.js"></script>
|
|
2340
2362
|
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-webgl@0/lib/addon-webgl.min.js"></script>
|
|
2341
|
-
<script type="module" src="app.js"></script>
|
|
2363
|
+
<script type="module" src="app.js?v=20260826a"></script>
|
|
2342
2364
|
<div id="pwa-install-modal" class="pwa-modal hidden">
|
|
2343
2365
|
<div class="pwa-modal-backdrop"></div>
|
|
2344
2366
|
<div class="pwa-modal-card">
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Junie">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="junie-gradient" x1="8" y1="8" x2="56" y2="56" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop stop-color="#8B5CF6"/>
|
|
5
|
+
<stop offset="1" stop-color="#F97316"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect width="64" height="64" rx="15" fill="url(#junie-gradient)"/>
|
|
9
|
+
<path d="M39 15v26c0 7.7-5.4 12-13.2 12-5.3 0-9.4-2.2-12-6.4l7.1-5c1.3 2 2.7 3 4.6 3 2.5 0 4-1.4 4-4.4V15H39Z" fill="#fff"/>
|
|
10
|
+
<circle cx="47.5" cy="17.5" r="4.5" fill="#fff" fill-opacity=".9"/>
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { VENDOR_NAMES, VENDOR_ORDER, isExperimentalVendor } from './app-rendering.js';
|
|
2
|
+
import { effortLevelsFor, effortDisplayName } from './app-panels.js';
|
|
3
|
+
|
|
4
|
+
function optionValue(entry) {
|
|
5
|
+
if (typeof entry === "string") return entry;
|
|
6
|
+
return entry && (entry.value || entry.id) || "";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function optionLabel(entry) {
|
|
10
|
+
if (typeof entry === "string") return entry;
|
|
11
|
+
return entry && (entry.displayName || entry.name || entry.value || entry.id) || "";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function buildAgentVendorSelect(installed, preferred) {
|
|
15
|
+
var select = document.createElement("select");
|
|
16
|
+
select.className = "wt-modal-input";
|
|
17
|
+
for (var i = 0; i < VENDOR_ORDER.length; i++) {
|
|
18
|
+
var vendor = VENDOR_ORDER[i];
|
|
19
|
+
if (installed.indexOf(vendor) === -1) continue;
|
|
20
|
+
var option = document.createElement("option");
|
|
21
|
+
option.value = vendor;
|
|
22
|
+
option.textContent = (isExperimentalVendor(vendor) ? "🧪 " : "") + (VENDOR_NAMES[vendor] || vendor);
|
|
23
|
+
if (isExperimentalVendor(vendor)) option.title = "Experimental integration; not yet validated through direct use testing";
|
|
24
|
+
select.appendChild(option);
|
|
25
|
+
}
|
|
26
|
+
if (preferred && installed.indexOf(preferred) !== -1) select.value = preferred;
|
|
27
|
+
return select;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function fillAgentModels(select, vendor, options, preferred) {
|
|
31
|
+
var models = (options.modelsByVendor && options.modelsByVendor[vendor]) || [];
|
|
32
|
+
select.innerHTML = "";
|
|
33
|
+
var automatic = document.createElement("option");
|
|
34
|
+
automatic.value = "";
|
|
35
|
+
automatic.textContent = "Automatic";
|
|
36
|
+
select.appendChild(automatic);
|
|
37
|
+
for (var i = 0; i < models.length; i++) {
|
|
38
|
+
var option = document.createElement("option");
|
|
39
|
+
option.value = optionValue(models[i]);
|
|
40
|
+
option.textContent = optionLabel(models[i]);
|
|
41
|
+
select.appendChild(option);
|
|
42
|
+
}
|
|
43
|
+
select.value = preferred || "";
|
|
44
|
+
if (select.selectedIndex === -1) select.value = "";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function buildAgentEffortSelect() {
|
|
48
|
+
var select = document.createElement("select");
|
|
49
|
+
select.className = "wt-modal-input";
|
|
50
|
+
return select;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function fillAgentEffort(select, vendor, options, modelValue, preferred) {
|
|
54
|
+
var previous = preferred === undefined ? select.value : preferred;
|
|
55
|
+
var models = (options.modelsByVendor && options.modelsByVendor[vendor]) || [];
|
|
56
|
+
var levels = effortLevelsFor(vendor, models, modelValue);
|
|
57
|
+
select.innerHTML = "";
|
|
58
|
+
var automatic = document.createElement("option");
|
|
59
|
+
automatic.value = "";
|
|
60
|
+
automatic.textContent = "Default";
|
|
61
|
+
select.appendChild(automatic);
|
|
62
|
+
for (var i = 0; i < levels.length; i++) {
|
|
63
|
+
var option = document.createElement("option");
|
|
64
|
+
option.value = levels[i];
|
|
65
|
+
option.textContent = effortDisplayName(levels[i]);
|
|
66
|
+
select.appendChild(option);
|
|
67
|
+
}
|
|
68
|
+
select.value = levels.indexOf(previous) !== -1 ? previous : "";
|
|
69
|
+
}
|
|
@@ -12,7 +12,6 @@ import { saveToolState, resetToolState, restoreToolState } from './tools.js';
|
|
|
12
12
|
import { getSessionUsage, setSessionUsage, getContextData, setContextData, updateContextPanel, updateUsagePanel } from './app-panels.js';
|
|
13
13
|
import { onHistoryPrepended as onSessionSearchHistoryPrepended } from './session-search.js';
|
|
14
14
|
import { getCachedSessions } from './sidebar-sessions.js';
|
|
15
|
-
import { openPairDialog } from './split-pair-ui.js';
|
|
16
15
|
import { showConfirm } from './app-misc.js';
|
|
17
16
|
|
|
18
17
|
// --- Module-owned state ---
|
|
@@ -23,27 +22,6 @@ export function initHeader() {
|
|
|
23
22
|
var headerRenameBtn = document.getElementById("header-rename-btn");
|
|
24
23
|
var headerTitleEl = document.getElementById("header-title");
|
|
25
24
|
var headerInfoBtn = document.getElementById("header-info-btn");
|
|
26
|
-
var headerAddWorkerBtn = document.getElementById("header-add-worker-btn");
|
|
27
|
-
|
|
28
|
-
// --- Add Worker: the current session becomes the Driver of a new pair ---
|
|
29
|
-
if (headerAddWorkerBtn) {
|
|
30
|
-
headerAddWorkerBtn.addEventListener("click", function () {
|
|
31
|
-
var sessionId = store.get('activeSessionId');
|
|
32
|
-
if (!sessionId || store.get('splitPanes') || store.get('dmMode')) return;
|
|
33
|
-
openPairDialog({
|
|
34
|
-
sessionId: sessionId,
|
|
35
|
-
title: headerTitleEl ? headerTitleEl.textContent : "",
|
|
36
|
-
vendor: store.get('currentVendor') || "claude",
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
// A split shows the GROUP in the title bar; adding a worker there makes
|
|
40
|
-
// no sense (the group already has two members), so hide the button.
|
|
41
|
-
store.subscribe(function (state, prev) {
|
|
42
|
-
if (state.splitPanes !== prev.splitPanes) {
|
|
43
|
-
headerAddWorkerBtn.classList.toggle("hidden", !!state.splitPanes);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
25
|
var headerFullAccessBtn = document.getElementById("header-full-access-btn");
|
|
48
26
|
|
|
49
27
|
function updateFullAccessButton() {
|
|
@@ -93,6 +71,8 @@ export function initHeader() {
|
|
|
93
71
|
input.type = "text";
|
|
94
72
|
input.className = "header-rename-input";
|
|
95
73
|
input.value = currentText;
|
|
74
|
+
var titleBar = headerTitleEl.closest(".title-bar-content");
|
|
75
|
+
if (titleBar) titleBar.classList.add("session-renaming");
|
|
96
76
|
headerTitleEl.style.display = "none";
|
|
97
77
|
headerRenameBtn.style.display = "none";
|
|
98
78
|
headerTitleEl.parentNode.insertBefore(input, headerTitleEl.nextSibling);
|
|
@@ -117,6 +97,7 @@ export function initHeader() {
|
|
|
117
97
|
}
|
|
118
98
|
}
|
|
119
99
|
input.remove();
|
|
100
|
+
if (titleBar) titleBar.classList.remove("session-renaming");
|
|
120
101
|
headerTitleEl.style.display = "";
|
|
121
102
|
headerRenameBtn.style.display = "";
|
|
122
103
|
}
|
|
@@ -126,6 +107,7 @@ export function initHeader() {
|
|
|
126
107
|
if (e.key === "Escape") {
|
|
127
108
|
e.preventDefault();
|
|
128
109
|
input.remove();
|
|
110
|
+
if (titleBar) titleBar.classList.remove("session-renaming");
|
|
129
111
|
headerTitleEl.style.display = "";
|
|
130
112
|
headerRenameBtn.style.display = "";
|
|
131
113
|
}
|
|
@@ -21,6 +21,7 @@ import { handlePaletteSessionSwitch, setPaletteVersion } from './command-palette
|
|
|
21
21
|
import { handleFindInSessionResults } from './session-search.js';
|
|
22
22
|
import { syncPaneTitles, maybeRestoreSplitGroup, openGroup } from './split-view.js';
|
|
23
23
|
import { showPairDialog, handlePairCreated, handleSplitDelegation, showWorkerDelegationNotice, hideWorkerDelegationNotice } from './split-pair-ui.js';
|
|
24
|
+
import { handleSessionActionMessage } from './session-actions.js';
|
|
24
25
|
import { renderWorkerProposal, updateWorkerProposal } from './worker-proposal.js';
|
|
25
26
|
import { handleInputSync, autoResize, builtinCommands, setScheduleBtnDisabled, sendShellResultToAgent } from './input.js';
|
|
26
27
|
import { startThinking, appendThinking, stopThinking, resetThinkingGroup, createToolItem, updateToolExecuting, updateToolResult, markAllToolsDone, closeToolGroup, removeToolFromGroup, resetToolState, getTools, getPlanContent, setPlanContent, renderPlanBanner, renderPlanCard, getTodoTools, handleTodoWrite, handleTaskCreate, handleTaskUpdate, applyDeadSessionTodoCompaction, isPlanFilePath, enableMainInput, addTurnMeta, updateSubagentActivity, addSubagentToolEntry, markSubagentDone, initSubagentStop, updateSubagentProgress, updateSubagentTaskStatus, renderAskUserQuestion, markAskUserAnswered, renderPermissionRequest, markPermissionCancelled, markPermissionResolved, renderElicitationRequest, markElicitationResolved, renderUserDialogRequest, markUserDialogResolved, updateThinkingTokens } from './tools.js';
|
|
@@ -52,6 +53,8 @@ import { setStatus } from './app-connection.js';
|
|
|
52
53
|
import { handleWhatsNewState, handleWhatsNewSeenResult, setKnownEntries as setWhatsNewKnownEntries } from './whats-new.js';
|
|
53
54
|
import { closeArticle as closeWhatsNewArticle } from './whats-new-article.js';
|
|
54
55
|
import { resolvePaneSession, resolveSwitchedVendor } from './pane-session.js';
|
|
56
|
+
import { selectDefaultVendorForBlankSession } from './vendor-selection.js';
|
|
57
|
+
import { getModelInfoUpdate, modelEntryValue, modelEntryMatches, handleModelSelectionResult, requestVendorModels } from './model-picker.js';
|
|
55
58
|
import { getModelEffortLevels, accumulateUsage, updateUsagePanel, accumulateContext, updateContextPanel, renderCtxPopover, updateStatusPanel } from './app-panels.js';
|
|
56
59
|
import { updateProjectList, resetClientState, showUpdateAvailable, handleRemoveProjectCheckResult, handleRemoveProjectResult, handleBrowseDirResult, handleAddProjectResult, handleCloneProgress } from './app-projects.js';
|
|
57
60
|
import { updateHistorySentinel, prependOlderHistory } from './app-header.js';
|
|
@@ -414,6 +417,15 @@ export function processMessage(msg) {
|
|
|
414
417
|
break;
|
|
415
418
|
|
|
416
419
|
case "model_info": {
|
|
420
|
+
// Installation state applies across vendors. Keep it even when the
|
|
421
|
+
// model payload itself is stale for the active session.
|
|
422
|
+
var _vendorState = {};
|
|
423
|
+
if (msg.availableVendors) _vendorState.availableVendors = msg.availableVendors;
|
|
424
|
+
if (msg.installedVendors) _vendorState.installedVendors = msg.installedVendors;
|
|
425
|
+
if (Object.keys(_vendorState).length > 0) {
|
|
426
|
+
store.set(_vendorState);
|
|
427
|
+
selectDefaultVendorForBlankSession();
|
|
428
|
+
}
|
|
417
429
|
// Drop stale model_info from a vendor that doesn't match the active
|
|
418
430
|
// session's vendor. On high-latency connections, the server's default-
|
|
419
431
|
// adapter model_info can arrive after session_switched has already
|
|
@@ -421,12 +433,12 @@ export function processMessage(msg) {
|
|
|
421
433
|
// currentModels with the wrong vendor's list and trigger app-panels
|
|
422
434
|
// to request models for the "wrong" vendor, which feeds back into a
|
|
423
435
|
// ping-pong loop of vendor flapping. See issue #336.
|
|
424
|
-
var
|
|
425
|
-
if (
|
|
436
|
+
var _modelLoadUpdate = getModelInfoUpdate(msg);
|
|
437
|
+
if (!_modelLoadUpdate) break;
|
|
426
438
|
|
|
427
439
|
var _modelVal = msg.model;
|
|
428
440
|
if (_modelVal && typeof _modelVal === "object") _modelVal = _modelVal.value || _modelVal.displayName || "";
|
|
429
|
-
var _miUpdate = { currentModels: msg.models || [] };
|
|
441
|
+
var _miUpdate = Object.assign({ currentModels: msg.models || [] }, _modelLoadUpdate);
|
|
430
442
|
if (Object.prototype.hasOwnProperty.call(msg, "model")) {
|
|
431
443
|
// Keep the user's existing selection only if it actually belongs to
|
|
432
444
|
// this vendor's model list. Otherwise (e.g. switching to a Codex
|
|
@@ -435,10 +447,15 @@ export function processMessage(msg) {
|
|
|
435
447
|
// model.
|
|
436
448
|
var _curModel = store.get('currentModel');
|
|
437
449
|
var _curInList = !!_curModel && (msg.models || []).some(function (m) {
|
|
438
|
-
|
|
439
|
-
|
|
450
|
+
return modelEntryMatches(m, _curModel);
|
|
451
|
+
});
|
|
452
|
+
var _incomingInList = !_modelVal || (msg.models || []).length === 0 || (msg.models || []).some(function (m) {
|
|
453
|
+
return modelEntryMatches(m, _modelVal);
|
|
440
454
|
});
|
|
441
|
-
if (
|
|
455
|
+
if (!_incomingInList) {
|
|
456
|
+
console.warn("[model-state] Ignoring model not listed for vendor " + (msg.vendor || store.get('currentVendor')) + ": " + _modelVal);
|
|
457
|
+
_miUpdate.currentModel = _curInList ? _curModel : modelEntryValue((msg.models || [])[0]);
|
|
458
|
+
} else if (store.get('vendorSelectionLocked') && _curInList) {
|
|
442
459
|
// Keep the user's existing (valid) selection; only update models list
|
|
443
460
|
} else {
|
|
444
461
|
_miUpdate.currentModel = _modelVal || "";
|
|
@@ -447,17 +464,31 @@ export function processMessage(msg) {
|
|
|
447
464
|
_miUpdate.currentModel = store.get('currentModel');
|
|
448
465
|
}
|
|
449
466
|
if (msg.vendor && !store.get('vendorSelectionLocked')) _miUpdate.currentVendor = msg.vendor;
|
|
450
|
-
if (msg.availableVendors) _miUpdate.availableVendors = msg.availableVendors;
|
|
451
|
-
if (msg.installedVendors) _miUpdate.installedVendors = msg.installedVendors;
|
|
452
467
|
if (msg.capabilities) _miUpdate.vendorCapabilities = msg.capabilities;
|
|
453
468
|
store.set(_miUpdate);
|
|
454
469
|
updateSettingsModels(_modelVal, msg.models || []);
|
|
455
470
|
break;
|
|
456
471
|
}
|
|
457
472
|
|
|
473
|
+
case "model_selection_result":
|
|
474
|
+
handleModelSelectionResult(msg);
|
|
475
|
+
break;
|
|
476
|
+
|
|
458
477
|
case "config_state": {
|
|
478
|
+
if ((msg.sessionId != null && msg.sessionId !== store.get('activeSessionId')) || (msg.vendor && msg.vendor !== store.get('currentVendor'))) break;
|
|
459
479
|
var _cs = {};
|
|
460
|
-
if (msg.model)
|
|
480
|
+
if (msg.model) {
|
|
481
|
+
var _knownModels = store.get('currentModels') || [];
|
|
482
|
+
var _modelKnown = _knownModels.length === 0 || _knownModels.some(function(model) { return modelEntryMatches(model, msg.model); });
|
|
483
|
+
if (_modelKnown) {
|
|
484
|
+
_cs.currentModel = msg.model;
|
|
485
|
+
} else {
|
|
486
|
+
console.warn("[model-state] Ignoring model not listed for current vendor: " + msg.model);
|
|
487
|
+
var _existingModel = store.get('currentModel');
|
|
488
|
+
var _existingKnown = _knownModels.some(function(model) { return modelEntryMatches(model, _existingModel); });
|
|
489
|
+
_cs.currentModel = _existingKnown ? _existingModel : modelEntryValue(_knownModels[0]);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
461
492
|
if (msg.mode) _cs.currentMode = msg.mode;
|
|
462
493
|
if (msg.effort) _cs.currentEffort = msg.effort;
|
|
463
494
|
if (msg.betas) _cs.currentBetas = msg.betas;
|
|
@@ -589,6 +620,13 @@ export function processMessage(msg) {
|
|
|
589
620
|
if (createdPairGroup) openGroup(createdPairGroup);
|
|
590
621
|
break;
|
|
591
622
|
|
|
623
|
+
case "session_handoff_result":
|
|
624
|
+
case "handoff_session_options":
|
|
625
|
+
case "handoff_context":
|
|
626
|
+
case "handoff_created":
|
|
627
|
+
handleSessionActionMessage(msg);
|
|
628
|
+
break;
|
|
629
|
+
|
|
592
630
|
case "worker_proposal":
|
|
593
631
|
renderWorkerProposal(msg);
|
|
594
632
|
break;
|
|
@@ -661,7 +699,7 @@ export function processMessage(msg) {
|
|
|
661
699
|
var _effectiveTerminalId = (typeof msg.runtimeTerminalId === "number")
|
|
662
700
|
? msg.runtimeTerminalId
|
|
663
701
|
: (typeof msg.terminalId === "number" ? msg.terminalId : null);
|
|
664
|
-
store.set({ activeSessionId: msg.id, cliSessionId: msg.cliSessionId || null, currentModel: msg.model ||
|
|
702
|
+
store.set({ activeSessionId: msg.id, cliSessionId: msg.cliSessionId || null, currentModel: msg.model || "", currentEffort: msg.effort || store.get('currentEffort'), vendorCapabilities: msg.capabilities || {}, sessionIsProcessing: !!msg.isProcessing, activeSessionMode: _effectiveMode, activeTerminalId: _effectiveTerminalId, sessionHasHistory: !!msg.hasHistory, sessionVendorBound: !!msg.vendor || !!msg.hasHistory, sessionFullAccess: msg.permissionMode === "bypassPermissions", currentMode: msg.permissionMode || store.get('currentMode') });
|
|
665
703
|
// TUI sessions swap the chat UI for an embedded xterm running
|
|
666
704
|
// `claude` inside a real PTY. Mount or tear down before the rest of
|
|
667
705
|
// the chat-side bookkeeping runs so we don't waste work on hidden DOM.
|
|
@@ -706,8 +744,9 @@ export function processMessage(msg) {
|
|
|
706
744
|
}
|
|
707
745
|
}
|
|
708
746
|
if (!msg.hasHistory && !msg.vendor) {
|
|
709
|
-
|
|
747
|
+
selectDefaultVendorForBlankSession();
|
|
710
748
|
}
|
|
749
|
+
if (!msg.model) requestVendorModels(store.get('currentVendor') || "claude", true);
|
|
711
750
|
// Vendor toggle visibility + active-vendor indicator next to the
|
|
712
751
|
// model chip.
|
|
713
752
|
// - Session has an explicit vendor: hide the toggle (it's
|
|
@@ -1108,6 +1147,10 @@ export function processMessage(msg) {
|
|
|
1108
1147
|
updateSubagentTaskStatus(msg.parentToolId, msg.patch);
|
|
1109
1148
|
break;
|
|
1110
1149
|
|
|
1150
|
+
case "active_background_tasks":
|
|
1151
|
+
store.set({ activeBackgroundTasks: Array.isArray(msg.tasks) ? msg.tasks : [] });
|
|
1152
|
+
break;
|
|
1153
|
+
|
|
1111
1154
|
case "result":
|
|
1112
1155
|
// Result marks turn end. Drop pre-thinking even if no delta/tool
|
|
1113
1156
|
// event ever arrived (e.g. tool-only turn whose progress signals
|