clay-server 3.4.0-beta.7 → 3.4.0-beta.8

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.
@@ -44,29 +44,64 @@
44
44
  #header-rename-btn .lucide { width: 13px; height: 13px; }
45
45
 
46
46
  #header-add-worker-btn {
47
- display: flex;
47
+ display: inline-flex;
48
48
  align-items: center;
49
49
  justify-content: center;
50
- width: 24px;
51
- height: 24px;
52
- border: 1px solid transparent;
53
- background: none;
54
- color: var(--text-dimmer);
50
+ gap: 7px;
51
+ width: auto;
52
+ height: 28px;
53
+ border: 1px solid color-mix(in srgb, var(--accent2) 28%, var(--border));
54
+ background: var(--accent2-8);
55
+ color: var(--accent2);
55
56
  cursor: pointer;
56
57
  border-radius: 8px;
57
58
  flex-shrink: 0;
58
- padding: 0;
59
- margin-left: 4px;
59
+ padding: 0 9px 0 7px;
60
+ margin-left: 0;
61
+ font-family: inherit;
62
+ font-size: 11px;
63
+ font-weight: 700;
64
+ line-height: 1;
65
+ white-space: nowrap;
60
66
  transition: color 0.15s, background 0.15s, border-color 0.15s;
61
67
  }
62
- #header-add-worker-btn:hover { color: var(--text-secondary); background: rgba(var(--overlay-rgb),0.04); border-color: var(--border); }
63
- #header-add-worker-btn .lucide { width: 13px; height: 13px; }
68
+ #header-add-worker-btn:hover {
69
+ color: var(--accent2-hover);
70
+ background: var(--accent2-15);
71
+ border-color: color-mix(in srgb, var(--accent2) 48%, var(--border));
72
+ }
73
+ .header-worker-icon {
74
+ position: relative;
75
+ display: inline-flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ width: 16px;
79
+ height: 16px;
80
+ flex-shrink: 0;
81
+ }
82
+ .header-worker-icon > .lucide { width: 15px; height: 15px; }
83
+ .header-worker-add-badge {
84
+ position: absolute;
85
+ right: -4px;
86
+ bottom: -3px;
87
+ display: inline-flex;
88
+ align-items: center;
89
+ justify-content: center;
90
+ width: 9px;
91
+ height: 9px;
92
+ border-radius: 50%;
93
+ background: var(--accent2);
94
+ color: var(--bg);
95
+ box-shadow: 0 0 0 2px var(--bg);
96
+ }
97
+ .header-worker-add-badge .lucide { width: 7px; height: 7px; stroke-width: 3; }
98
+ .header-worker-label { letter-spacing: 0.01em; }
64
99
  #header-add-worker-btn.hidden { display: none; }
65
100
  body.dm-mode #header-add-worker-btn { display: none; }
66
101
 
67
- /* "Close terminal" button: sits just left of the rename pencil during a live
68
- TUI session. Matches the rename button's chrome; reds out on hover since it
69
- stops the running claude (the session stays resumable). */
102
+ /* "Close terminal" button for a live TUI session. Matches the session-control
103
+ chrome; reds out on hover since it stops the running agent while preserving
104
+ the resumable session. */
70
105
  #header-tui-close-btn {
71
106
  display: flex;
72
107
  align-items: center;
@@ -980,4 +1015,3 @@ body.dm-mode #header-add-worker-btn { display: none; }
980
1015
  #config-chip .config-chip-icon { display: inline; width: 14px; height: 14px; }
981
1016
  #config-chip-label { display: none; }
982
1017
  }
983
-
@@ -23,6 +23,10 @@ body.pane-mode #sticky-notes-container {
23
23
  display: none !important;
24
24
  }
25
25
 
26
+ body.pane-mode .notif-banner-container {
27
+ display: none !important;
28
+ }
29
+
26
30
  body.pane-mode #main-area {
27
31
  border: 0;
28
32
  border-radius: 0;
@@ -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,13 @@
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-add-worker-btn" type="button" aria-label="Add AI Worker" title="Add an AI Worker — this session becomes the Driver of a pair">
392
+ <span class="header-worker-icon" aria-hidden="true">
393
+ <i data-lucide="bot"></i>
394
+ <span class="header-worker-add-badge"><i data-lucide="plus"></i></span>
395
+ </span>
396
+ <span class="header-worker-label">Add Worker</span>
397
+ </button>
392
398
  <button type="button" id="header-tui-font-btn" class="header-tui-font-btn hidden" title="Terminal font" aria-label="Terminal font">
393
399
  <i data-lucide="type"></i>
394
400
  </button>
@@ -861,7 +861,9 @@ export function updateContextPanel() {
861
861
  hCtxEl = document.createElement("div");
862
862
  hCtxEl.className = "header-context";
863
863
  hCtxEl.innerHTML = '<div class="header-context-bar"><div class="header-context-fill"></div></div><span class="header-context-label"></span>';
864
- statusArea.insertBefore(hCtxEl, statusArea.firstChild);
864
+ var workerBtn = document.getElementById("header-add-worker-btn");
865
+ var contextAnchor = workerBtn && workerBtn.parentNode === statusArea ? workerBtn.nextSibling : statusArea.firstChild;
866
+ statusArea.insertBefore(hCtxEl, contextAnchor);
865
867
  hCtxEl.addEventListener("mouseenter", function() {
866
868
  if (store.get('richContextUsage')) {
867
869
  showCtxPopover();
@@ -5,6 +5,7 @@
5
5
 
6
6
  import { store } from './store.js';
7
7
  import { applyContextView, getContextView } from './app-panels.js';
8
+ import { forceExternalLinkToNewTab } from './pane-links.js';
8
9
 
9
10
  var panelOpen = false;
10
11
 
@@ -29,9 +30,19 @@ function togglePaneContextPanel() {
29
30
  applyContextView(panelOpen ? "panel" : "off");
30
31
  }
31
32
 
33
+ function preparePaneLink(event) {
34
+ var target = event.target;
35
+ if (!target || typeof target.closest !== "function") return;
36
+ var anchor = target.closest("a[href]");
37
+ if (!anchor || anchor.hasAttribute("download")) return;
38
+ forceExternalLinkToNewTab(anchor, window.location.href);
39
+ }
40
+
32
41
  export function initPaneBridge() {
33
42
  if (!store.get('paneMode')) return;
34
43
  panelOpen = getContextView() === "panel";
44
+ document.addEventListener("click", preparePaneLink, true);
45
+ document.addEventListener("auxclick", preparePaneLink, true);
35
46
  window.addEventListener("message", function (event) {
36
47
  if (event.origin !== window.location.origin) return;
37
48
  var msg = event.data;
@@ -0,0 +1,23 @@
1
+ export function isExternalWebLink(href, currentHref) {
2
+ if (!href) return false;
3
+ try {
4
+ var url = new URL(href, currentHref);
5
+ var currentUrl = new URL(currentHref);
6
+ if (url.protocol !== "http:" && url.protocol !== "https:") return false;
7
+ return url.origin !== currentUrl.origin;
8
+ } catch (err) {
9
+ return false;
10
+ }
11
+ }
12
+
13
+ export function forceExternalLinkToNewTab(anchor, currentHref) {
14
+ if (!anchor || !isExternalWebLink(anchor.href, currentHref)) return false;
15
+
16
+ var rel = (anchor.getAttribute("rel") || "").split(/\s+/).filter(Boolean);
17
+ if (rel.indexOf("noopener") === -1) rel.push("noopener");
18
+ if (rel.indexOf("noreferrer") === -1) rel.push("noreferrer");
19
+
20
+ anchor.setAttribute("target", "_blank");
21
+ anchor.setAttribute("rel", rel.join(" "));
22
+ return true;
23
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "3.4.0-beta.7",
3
+ "version": "3.4.0-beta.8",
4
4
  "description": "Self-hosted team workspace for Claude Code and Codex. Multi-user, browser-based, with persistent AI mates.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",