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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { store } from './store.js';
|
|
2
2
|
import { getWs } from './ws-ref.js';
|
|
3
|
-
import { VENDOR_AVATARS
|
|
4
|
-
import {
|
|
3
|
+
import { VENDOR_AVATARS } from './app-rendering.js';
|
|
4
|
+
import { buildAgentVendorSelect, fillAgentModels, buildAgentEffortSelect, fillAgentEffort } from './agent-config-selects.js';
|
|
5
5
|
import { showToast } from './utils.js';
|
|
6
6
|
|
|
7
7
|
var pairDialog = null;
|
|
@@ -9,77 +9,14 @@ var pairDialog = null;
|
|
|
9
9
|
// that session becomes the Driver and the dialog only configures the Worker.
|
|
10
10
|
var pendingDriver = null;
|
|
11
11
|
|
|
12
|
-
function optionValue(entry) {
|
|
13
|
-
if (typeof entry === "string") return entry;
|
|
14
|
-
return entry && (entry.value || entry.id) || "";
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function optionLabel(entry) {
|
|
18
|
-
if (typeof entry === "string") return entry;
|
|
19
|
-
return entry && (entry.displayName || entry.name || entry.value || entry.id) || "";
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function fillModels(select, vendor, options) {
|
|
23
|
-
var models = (options.modelsByVendor && options.modelsByVendor[vendor]) || [];
|
|
24
|
-
select.innerHTML = "";
|
|
25
|
-
var automatic = document.createElement("option");
|
|
26
|
-
automatic.value = "";
|
|
27
|
-
automatic.textContent = "Automatic";
|
|
28
|
-
select.appendChild(automatic);
|
|
29
|
-
for (var i = 0; i < models.length; i++) {
|
|
30
|
-
var option = document.createElement("option");
|
|
31
|
-
option.value = optionValue(models[i]);
|
|
32
|
-
option.textContent = optionLabel(models[i]);
|
|
33
|
-
select.appendChild(option);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
12
|
function closePairDialog() {
|
|
38
13
|
if (pairDialog) pairDialog.remove();
|
|
39
14
|
pairDialog = null;
|
|
40
15
|
}
|
|
41
16
|
|
|
42
|
-
function buildVendorSelect(installed, preferred) {
|
|
43
|
-
var select = document.createElement("select");
|
|
44
|
-
select.className = "wt-modal-input";
|
|
45
|
-
for (var i = 0; i < VENDOR_ORDER.length; i++) {
|
|
46
|
-
if (installed.indexOf(VENDOR_ORDER[i]) === -1) continue;
|
|
47
|
-
var option = document.createElement("option");
|
|
48
|
-
option.value = VENDOR_ORDER[i];
|
|
49
|
-
option.textContent = VENDOR_NAMES[VENDOR_ORDER[i]] || VENDOR_ORDER[i];
|
|
50
|
-
select.appendChild(option);
|
|
51
|
-
}
|
|
52
|
-
if (preferred && installed.indexOf(preferred) !== -1) select.value = preferred;
|
|
53
|
-
return select;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
17
|
// Effort levels are vendor- and model-specific (codex: minimal..xhigh,
|
|
57
18
|
// claude/kiro: low..max, plus per-model supportedEffortLevels overrides), so
|
|
58
19
|
// options are rebuilt whenever the role's vendor or model changes.
|
|
59
|
-
function fillEffortOptions(select, vendor, options, modelValue) {
|
|
60
|
-
var previous = select.value;
|
|
61
|
-
var models = (options.modelsByVendor && options.modelsByVendor[vendor]) || [];
|
|
62
|
-
var levels = effortLevelsFor(vendor, models, modelValue);
|
|
63
|
-
select.innerHTML = "";
|
|
64
|
-
var automatic = document.createElement("option");
|
|
65
|
-
automatic.value = "";
|
|
66
|
-
automatic.textContent = "Default";
|
|
67
|
-
select.appendChild(automatic);
|
|
68
|
-
for (var i = 0; i < levels.length; i++) {
|
|
69
|
-
var option = document.createElement("option");
|
|
70
|
-
option.value = levels[i];
|
|
71
|
-
option.textContent = effortDisplayName(levels[i]);
|
|
72
|
-
select.appendChild(option);
|
|
73
|
-
}
|
|
74
|
-
select.value = levels.indexOf(previous) !== -1 ? previous : "";
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function buildEffortSelect() {
|
|
78
|
-
var select = document.createElement("select");
|
|
79
|
-
select.className = "wt-modal-input";
|
|
80
|
-
return select;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
20
|
function fieldLabel(text, control) {
|
|
84
21
|
var label = document.createElement("label");
|
|
85
22
|
label.className = "wt-modal-label";
|
|
@@ -154,25 +91,25 @@ export function showPairDialog(options) {
|
|
|
154
91
|
: "One Driver plans and directs a visible Worker session.";
|
|
155
92
|
modal.appendChild(desc);
|
|
156
93
|
|
|
157
|
-
var driverVendor =
|
|
94
|
+
var driverVendor = buildAgentVendorSelect(installed, installed.indexOf("claude") !== -1 ? "claude" : installed[0]);
|
|
158
95
|
var workerDefault = options.lastVendor && options.lastVendor !== driverVendor.value ? options.lastVendor : (installed.indexOf("codex") !== -1 ? "codex" : installed[0]);
|
|
159
|
-
var workerVendor =
|
|
96
|
+
var workerVendor = buildAgentVendorSelect(installed, workerDefault);
|
|
160
97
|
var driverModel = document.createElement("select");
|
|
161
98
|
driverModel.className = "wt-modal-input";
|
|
162
99
|
var workerModel = document.createElement("select");
|
|
163
100
|
workerModel.className = "wt-modal-input";
|
|
164
|
-
var driverEffort =
|
|
165
|
-
var workerEffort =
|
|
166
|
-
function refreshDriverEffort() {
|
|
167
|
-
function refreshWorkerEffort() {
|
|
168
|
-
|
|
169
|
-
|
|
101
|
+
var driverEffort = buildAgentEffortSelect();
|
|
102
|
+
var workerEffort = buildAgentEffortSelect();
|
|
103
|
+
function refreshDriverEffort() { fillAgentEffort(driverEffort, driverVendor.value, options, driverModel.value); }
|
|
104
|
+
function refreshWorkerEffort() { fillAgentEffort(workerEffort, workerVendor.value, options, workerModel.value); }
|
|
105
|
+
fillAgentModels(driverModel, driverVendor.value, options);
|
|
106
|
+
fillAgentModels(workerModel, workerVendor.value, options);
|
|
170
107
|
refreshDriverEffort();
|
|
171
108
|
refreshWorkerEffort();
|
|
172
109
|
workerEffort.value = "medium";
|
|
173
110
|
if (workerEffort.value !== "medium") workerEffort.value = "";
|
|
174
|
-
driverVendor.addEventListener("change", function () {
|
|
175
|
-
workerVendor.addEventListener("change", function () {
|
|
111
|
+
driverVendor.addEventListener("change", function () { fillAgentModels(driverModel, driverVendor.value, options); refreshDriverEffort(); });
|
|
112
|
+
workerVendor.addEventListener("change", function () { fillAgentModels(workerModel, workerVendor.value, options); refreshWorkerEffort(); });
|
|
176
113
|
driverModel.addEventListener("change", refreshDriverEffort);
|
|
177
114
|
workerModel.addEventListener("change", refreshWorkerEffort);
|
|
178
115
|
|
|
@@ -318,7 +255,8 @@ export function syncPairChrome(host, split) {
|
|
|
318
255
|
setBtn.title = "Make this session the Driver; the other pane becomes its Worker";
|
|
319
256
|
setBtn.addEventListener("click", function () { sendSetPair(group.id, paneSessionId); });
|
|
320
257
|
var titleEl = header.querySelector(".split-pane-title");
|
|
321
|
-
|
|
258
|
+
var accessEl = header.querySelector(".split-pane-full-access");
|
|
259
|
+
header.insertBefore(setBtn, accessEl ? accessEl.nextSibling : (titleEl ? titleEl.nextSibling : null));
|
|
322
260
|
})(split.panes[ai].sessionId, headers[ai]);
|
|
323
261
|
}
|
|
324
262
|
return;
|
|
@@ -338,7 +276,8 @@ export function syncPairChrome(host, split) {
|
|
|
338
276
|
sendSetPair(group.id, isDriver ? null : sessionId);
|
|
339
277
|
});
|
|
340
278
|
var title = header.querySelector(".split-pane-title");
|
|
341
|
-
|
|
279
|
+
var access = header.querySelector(".split-pane-full-access");
|
|
280
|
+
header.insertBefore(badge, access ? access.nextSibling : (title ? title.nextSibling : null));
|
|
342
281
|
})(split.panes[pi].sessionId, headers[pi]);
|
|
343
282
|
}
|
|
344
283
|
var active = (store.get('splitDelegations') || {})[group.id];
|
|
@@ -231,6 +231,9 @@ function createPane(pane, index) {
|
|
|
231
231
|
}, "Skip Permissions", true);
|
|
232
232
|
});
|
|
233
233
|
header.appendChild(fullAccess);
|
|
234
|
+
// Permission state belongs to the session identity on the left. Keep it
|
|
235
|
+
// immediately after the title instead of grouping it with usage and close.
|
|
236
|
+
header.insertBefore(fullAccess, ctxChip);
|
|
234
237
|
|
|
235
238
|
var close = document.createElement("button");
|
|
236
239
|
close.type = "button";
|
|
@@ -817,8 +817,13 @@ function resolvePermissionIdentity(mateId, vendor) {
|
|
|
817
817
|
var vendorAvatars = {
|
|
818
818
|
claude: "/claude-code-avatar.png",
|
|
819
819
|
codex: "/codex-avatar.png",
|
|
820
|
-
|
|
820
|
+
antigravity: "/antigravity-avatar.png",
|
|
821
821
|
opencode: "/opencode-avatar.svg",
|
|
822
|
+
kimi: "/kimi-avatar.svg",
|
|
823
|
+
grok: "/grok-avatar.svg",
|
|
824
|
+
copilot: "/copilot-avatar.svg",
|
|
825
|
+
qwen: "/qwen-avatar.svg",
|
|
826
|
+
junie: "/junie-avatar.svg",
|
|
822
827
|
kiro: "/kiro-avatar.svg",
|
|
823
828
|
};
|
|
824
829
|
var vendorName = (vendor && VENDOR_NAMES[vendor]) || VENDOR_NAMES.claude;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export var VENDOR_ORDER = ["claude", "codex", "grok", "kimi", "copilot", "qwen", "junie", "antigravity", "opencode", "kiro"];
|
|
2
|
+
export var EXPERIMENTAL_VENDORS = ["grok", "kimi", "copilot", "qwen", "junie", "antigravity", "opencode"];
|
|
3
|
+
|
|
4
|
+
export function isExperimentalVendor(vendor) {
|
|
5
|
+
return EXPERIMENTAL_VENDORS.indexOf(vendor) !== -1;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function firstInstalledVendor(installedVendors) {
|
|
9
|
+
var installed = Array.isArray(installedVendors) ? installedVendors : [];
|
|
10
|
+
for (var i = 0; i < VENDOR_ORDER.length; i++) {
|
|
11
|
+
if (installed.indexOf(VENDOR_ORDER[i]) !== -1) return VENDOR_ORDER[i];
|
|
12
|
+
}
|
|
13
|
+
return "";
|
|
14
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { store } from './store.js';
|
|
2
|
+
import { firstInstalledVendor } from './vendor-priority.js';
|
|
3
|
+
|
|
4
|
+
export function selectDefaultVendorForBlankSession() {
|
|
5
|
+
var state = store.snap();
|
|
6
|
+
if (!state.activeSessionId || state.sessionHasHistory || state.sessionVendorBound || state.dmMode) return "";
|
|
7
|
+
var vendor = firstInstalledVendor(state.installedVendors);
|
|
8
|
+
if (!vendor) return "";
|
|
9
|
+
if (vendor === state.currentVendor) {
|
|
10
|
+
if (state.vendorSelectionLocked) store.set({ vendorSelectionLocked: false });
|
|
11
|
+
return vendor;
|
|
12
|
+
}
|
|
13
|
+
store.set({
|
|
14
|
+
currentVendor: vendor,
|
|
15
|
+
currentModel: "",
|
|
16
|
+
currentModels: [],
|
|
17
|
+
vendorSelectionLocked: false,
|
|
18
|
+
});
|
|
19
|
+
return vendor;
|
|
20
|
+
}
|
|
@@ -95,6 +95,7 @@ function statusLabel(status) {
|
|
|
95
95
|
if (status === "starting") return "Starting Worker";
|
|
96
96
|
if (status === "running") return "Worker running";
|
|
97
97
|
if (status === "completed") return "Completed";
|
|
98
|
+
if (status === "interrupted") return "Interrupted";
|
|
98
99
|
if (status === "declined") return "Continuing here";
|
|
99
100
|
if (status === "error") return "Needs attention";
|
|
100
101
|
return "Suggested by Fable";
|
|
@@ -103,8 +104,10 @@ function statusLabel(status) {
|
|
|
103
104
|
function applyState(card, msg) {
|
|
104
105
|
var status = msg.status || "pending";
|
|
105
106
|
card.dataset.status = status;
|
|
107
|
+
if (msg.autoApproved) card.dataset.autoApproved = "true";
|
|
108
|
+
var autoApproved = card.dataset.autoApproved === "true";
|
|
106
109
|
var badge = card.querySelector(".worker-proposal-status");
|
|
107
|
-
if (badge) badge.textContent = statusLabel(status);
|
|
110
|
+
if (badge) badge.textContent = statusLabel(status) + (autoApproved ? " · auto-approved" : "");
|
|
108
111
|
var error = card.querySelector(".worker-proposal-error");
|
|
109
112
|
if (error) {
|
|
110
113
|
error.textContent = msg.error || "";
|
|
@@ -116,6 +119,8 @@ function applyState(card, msg) {
|
|
|
116
119
|
preview.classList.remove("hidden");
|
|
117
120
|
}
|
|
118
121
|
setControlsDisabled(card, status !== "pending");
|
|
122
|
+
var actions = card.querySelector(".worker-proposal-actions");
|
|
123
|
+
if (actions) actions.classList.toggle("hidden", autoApproved);
|
|
119
124
|
}
|
|
120
125
|
|
|
121
126
|
function sendDecision(card, accepted) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function isExternalWorktree(project) {
|
|
2
|
+
return !!(project && project.isWorktree && project.worktreeExternal === true);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function externalWorktreeTooltip(name) {
|
|
6
|
+
return name + " — outside the main project folder";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function appendExternalWorktreeBadge(container, className) {
|
|
10
|
+
var badge = document.createElement("span");
|
|
11
|
+
badge.className = className;
|
|
12
|
+
badge.setAttribute("role", "img");
|
|
13
|
+
badge.setAttribute("aria-label", "Outside the main project folder");
|
|
14
|
+
badge.innerHTML = '<i data-lucide="external-link"></i>';
|
|
15
|
+
container.appendChild(badge);
|
|
16
|
+
return badge;
|
|
17
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Qwen Code">
|
|
2
|
+
<rect width="64" height="64" rx="14" fill="#6b4eff"/>
|
|
3
|
+
<path d="M32 12a20 20 0 1 0 12 36l7 5-3-11a20 20 0 0 0-16-30zm0 9a11 11 0 1 1-7.8 18.8A11 11 0 0 1 32 21z" fill="#fff"/>
|
|
4
|
+
</svg>
|
package/lib/public/style.css
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
@import url("css/base.css");
|
|
2
2
|
@import url("css/icon-strip.css");
|
|
3
|
-
@import url("css/title-bar.css");
|
|
3
|
+
@import url("css/title-bar.css?v=20260824");
|
|
4
4
|
@import url("css/pane.css");
|
|
5
5
|
@import url("css/worker-proposal.css");
|
|
6
|
+
@import url("css/session-actions.css");
|
|
6
7
|
@import url("css/sidebar.css");
|
|
7
8
|
@import url("css/overlays.css");
|
|
8
9
|
@import url("css/menus.css");
|
|
9
|
-
@import url("css/messages.css?v=
|
|
10
|
+
@import url("css/messages.css?v=20260824");
|
|
10
11
|
@import url("css/rewind.css");
|
|
11
12
|
@import url("css/input.css");
|
|
12
13
|
@import url("css/filebrowser.css");
|
|
@@ -35,3 +36,4 @@
|
|
|
35
36
|
@import url("css/debate.css");
|
|
36
37
|
@import url("css/notifications-center.css");
|
|
37
38
|
@import url("css/tui-attention.css");
|
|
39
|
+
@import url("css/pwa-mobile.css?v=20260824f");
|