clay-server 4.0.0-beta.9 → 4.0.1-beta.1
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/capsule-display-floor.js +51 -0
- package/lib/capsule-frame-server.js +255 -0
- package/lib/capsule-mate-turn.js +105 -0
- package/lib/capsule-pig-logic.js +300 -0
- package/lib/capsule-server-runtimes.js +39 -0
- package/lib/capsules/pig/display.js +198 -0
- package/lib/capsules/pig/manifest.json +9 -0
- package/lib/capsules/pig/ui.json +84 -0
- package/lib/config.js +25 -1
- package/lib/daemon-projects.js +13 -8
- package/lib/daemon.js +127 -14
- package/lib/git-cli.js +95 -1
- package/lib/knowledge-import.js +436 -0
- package/lib/knowledge-record-store.js +188 -0
- package/lib/knowledge-search.js +240 -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/migrate-single-user.js +2 -0
- package/lib/notes-lifecycle.js +149 -0
- package/lib/notes.js +60 -3
- package/lib/os-users.js +3 -1
- package/lib/project-capsule-catalog.js +9 -1
- package/lib/project-capsule-turn.js +96 -0
- package/lib/project-connection.js +15 -1
- package/lib/project-file-history.js +223 -0
- package/lib/project-file-watch.js +77 -49
- package/lib/project-filesystem.js +31 -220
- package/lib/project-http.js +15 -1
- package/lib/project-knowledge.js +22 -0
- package/lib/project-log-context.js +172 -0
- package/lib/project-log-feedback-delivery.js +118 -0
- package/lib/project-logs-comments.js +137 -0
- package/lib/project-logs-context-state.js +42 -0
- package/lib/project-logs-mcp-server.js +328 -0
- package/lib/project-logs-query.js +185 -0
- package/lib/project-logs-root.js +75 -0
- package/lib/project-logs-schema.js +259 -0
- package/lib/project-logs-service.js +463 -0
- package/lib/project-logs-snapshot.js +205 -0
- package/lib/project-logs-store.js +495 -0
- package/lib/project-logs-versioning.js +132 -0
- package/lib/project-logs.js +400 -0
- package/lib/project-mate-interaction.js +14 -0
- package/lib/project-mate-knowledge.js +110 -0
- package/lib/project-memory.js +22 -0
- package/lib/project-message-delivery.js +70 -0
- package/lib/project-pair-lifecycle.js +460 -0
- package/lib/project-request-access.js +66 -0
- package/lib/project-session-handoff.js +1 -1
- package/lib/project-session-notes.js +64 -13
- package/lib/project-session-pair.js +159 -146
- package/lib/project-session-spawn.js +1 -1
- package/lib/project-sessions.js +71 -16
- package/lib/project-user-message.js +53 -4
- package/lib/project-worker-permission.js +430 -0
- package/lib/project-worker-proposal.js +208 -62
- package/lib/project.js +191 -6
- package/lib/public/app.js +64 -35
- package/lib/public/css/admin.css +2 -2
- package/lib/public/css/capsule-ui.css +38 -0
- package/lib/public/css/command-palette.css +45 -9
- package/lib/public/css/git-placard.css +154 -0
- package/lib/public/css/home-hub.css +4 -0
- package/lib/public/css/home-session-actions.css +66 -0
- package/lib/public/css/home-sidebar.css +66 -0
- package/lib/public/css/input.css +84 -3
- package/lib/public/css/messages.css +40 -1
- package/lib/public/css/mobile-nav.css +80 -0
- package/lib/public/css/notifications-center.css +67 -0
- package/lib/public/css/pane.css +97 -10
- package/lib/public/css/project-logs.css +198 -0
- package/lib/public/css/scheduler.css +1 -1
- package/lib/public/css/session-actions.css +16 -101
- package/lib/public/css/sidebar.css +103 -0
- package/lib/public/css/sticky-notes.css +237 -229
- package/lib/public/css/worker-proposal.css +36 -3
- package/lib/public/index.html +43 -11
- package/lib/public/modules/admin.js +8 -8
- package/lib/public/modules/app-connection.js +124 -6
- package/lib/public/modules/app-home-hub.js +12 -8
- package/lib/public/modules/app-message-cards.js +2 -1
- package/lib/public/modules/app-message-router.js +1 -1
- package/lib/public/modules/app-messages.js +92 -11
- package/lib/public/modules/app-misc.js +2 -14
- package/lib/public/modules/app-notifications.js +11 -7
- package/lib/public/modules/app-panels.js +3 -2
- package/lib/public/modules/app-projects.js +56 -18
- package/lib/public/modules/app-rendering.js +1 -0
- package/lib/public/modules/capsule-preference.js +44 -0
- package/lib/public/modules/chat-bubble-renderer.js +1 -1
- package/lib/public/modules/clay-log-links.js +70 -0
- package/lib/public/modules/command-palette.js +52 -15
- package/lib/public/modules/context-sources.js +0 -3
- package/lib/public/modules/git-agent-sessions.js +85 -0
- package/lib/public/modules/git-panel.js +111 -84
- package/lib/public/modules/git-placard.js +161 -0
- package/lib/public/modules/home-chat-empty-state.js +39 -0
- package/lib/public/modules/home-chat-identity.js +9 -0
- package/lib/public/modules/home-conversations-sheet.js +102 -48
- package/lib/public/modules/home-mate-chat.js +15 -35
- package/lib/public/modules/home-session-actions.js +6 -0
- package/lib/public/modules/home-sidebar-chat-list.js +101 -41
- package/lib/public/modules/home-sidebar.js +7 -0
- package/lib/public/modules/home-surface-boot.js +7 -3
- package/lib/public/modules/home-tool-frame.js +182 -0
- package/lib/public/modules/home-tools.js +138 -1
- package/lib/public/modules/input.js +38 -7
- package/lib/public/modules/markdown.js +2 -0
- package/lib/public/modules/mate-sidebar.js +0 -8
- package/lib/public/modules/message-delivery.js +97 -0
- package/lib/public/modules/paste-modal.js +84 -0
- package/lib/public/modules/project-activation.js +45 -0
- package/lib/public/modules/project-logs-render.js +405 -0
- package/lib/public/modules/project-logs.js +461 -0
- package/lib/public/modules/project-removal-target.js +26 -0
- package/lib/public/modules/scheduler.js +17 -3
- package/lib/public/modules/search-clay-chat.js +47 -6
- package/lib/public/modules/search-clay-controls.js +86 -0
- package/lib/public/modules/session-actions.js +29 -105
- package/lib/public/modules/session-hierarchy.js +54 -0
- package/lib/public/modules/sidebar-mobile.js +40 -15
- package/lib/public/modules/sidebar-session-hierarchy.js +214 -0
- package/lib/public/modules/sidebar-sessions.js +77 -11
- package/lib/public/modules/sidebar.js +17 -5
- package/lib/public/modules/split-group-helpers.js +8 -0
- package/lib/public/modules/split-pair-ui.js +15 -4
- package/lib/public/modules/split-view.js +5 -2
- package/lib/public/modules/split-worker-runtime.js +24 -0
- package/lib/public/modules/sticky-note-markdown.js +5 -0
- package/lib/public/modules/sticky-notes-browser.js +326 -0
- package/lib/public/modules/sticky-notes-card.js +360 -0
- package/lib/public/modules/sticky-notes-editor.js +291 -0
- package/lib/public/modules/sticky-notes-shared.js +90 -0
- package/lib/public/modules/sticky-notes.js +170 -946
- package/lib/public/modules/thinking-lifecycle.js +175 -0
- package/lib/public/modules/thinking-summary.js +28 -0
- package/lib/public/modules/thinking-view.js +75 -0
- package/lib/public/modules/tool-palette-order.js +143 -0
- package/lib/public/modules/tool-palette-overlays.js +159 -0
- package/lib/public/modules/tool-palette.js +21 -188
- package/lib/public/modules/tools.js +31 -123
- package/lib/public/modules/update-snooze.js +169 -0
- package/lib/public/modules/user-settings.js +4 -0
- package/lib/public/modules/worker-pane-lock.js +176 -0
- package/lib/public/modules/worker-proposal-state.js +16 -0
- package/lib/public/modules/worker-proposal.js +49 -20
- package/lib/public/style.css +3 -1
- package/lib/sdk-bridge.js +136 -47
- package/lib/sdk-message-processor.js +36 -7
- package/lib/server-experimental-settings.js +49 -0
- package/lib/server-global-ws.js +11 -0
- package/lib/server-home-chat-events.js +34 -1
- package/lib/server-home-chat.js +62 -4
- package/lib/server-home-clay-entry.js +1 -1
- package/lib/server-home-clay-session-links.js +34 -5
- package/lib/server-settings.js +5 -0
- package/lib/server-tools.js +127 -9
- package/lib/server.js +137 -22
- package/lib/session-driver-eligibility.js +38 -0
- package/lib/session-driver-orchestration.js +31 -0
- package/lib/session-hygiene.js +3 -0
- package/lib/session-notes-mcp-server.js +25 -5
- package/lib/session-pair-factory.js +247 -0
- package/lib/session-pair-mcp-server.js +46 -8
- package/lib/session-pair-prompts.js +79 -0
- package/lib/session-pair-turn-control.js +153 -0
- package/lib/session-provenance.js +119 -0
- package/lib/session-spawn-mcp-server.js +1 -1
- package/lib/session-split-groups.js +4 -1
- package/lib/session-title-policy.js +60 -0
- package/lib/session-visibility.js +41 -0
- package/lib/sessions.js +57 -10
- package/lib/tools-registry.js +89 -10
- package/lib/update-snooze.js +437 -0
- package/lib/users-experimental-preferences.js +30 -0
- package/lib/users-permissions.js +6 -6
- package/lib/users.js +22 -16
- package/lib/workspace-query-access.js +102 -0
- package/lib/workspace-query-service.js +24 -17
- package/lib/worktree.js +25 -38
- package/lib/ws-schema.js +44 -7
- package/lib/yoke/adapters/claude-worker.js +16 -6
- package/lib/yoke/adapters/claude.js +12 -0
- package/lib/yoke/adapters/codex.js +24 -14
- package/lib/yoke/vendor-registry.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// Driver-operated Split Worker surface.
|
|
2
|
+
//
|
|
3
|
+
// A configured Split Worker executes work its Driver delegated, so its pane is
|
|
4
|
+
// an execution surface rather than a chat the person types into. This module
|
|
5
|
+
// takes the composer's footprint away and replaces it with one compact,
|
|
6
|
+
// non-interactive status line.
|
|
7
|
+
//
|
|
8
|
+
// What stays, deliberately: the transcript, streaming status, tool and
|
|
9
|
+
// permission progress, scrolling, and the stop control — the human keeps their
|
|
10
|
+
// emergency brake. What goes: the text input, attachments, send, the composer
|
|
11
|
+
// context row, and any Worker-local permission-mode affordance.
|
|
12
|
+
//
|
|
13
|
+
// The role is read from pair state only (`splitGroups` + the displayed
|
|
14
|
+
// session), which is server-broadcast and therefore correct across reconnect,
|
|
15
|
+
// project switch, session switch, dissolve, replacement and role change. There
|
|
16
|
+
// is no second copy of the role and nothing in localStorage. A plain ad-hoc
|
|
17
|
+
// side-by-side split has no pair roles, so it is never locked and keeps its
|
|
18
|
+
// composer.
|
|
19
|
+
//
|
|
20
|
+
// Accessibility: locked controls are removed from the tab order with `disabled`
|
|
21
|
+
// and `tabindex="-1"`, and the composer region is `aria-hidden` while the
|
|
22
|
+
// status line carries the explanation, so a screen reader is told the pane is
|
|
23
|
+
// Driver-controlled instead of finding focusable inputs that do nothing.
|
|
24
|
+
|
|
25
|
+
import { store } from './store.js';
|
|
26
|
+
|
|
27
|
+
var STATUS_ID = "worker-pane-status";
|
|
28
|
+
var LOCK_CLASS = "worker-pane-locked";
|
|
29
|
+
|
|
30
|
+
// Every interactive composer affordance. Queried lazily: a pane iframe and the
|
|
31
|
+
// main window share this markup, and some ids are mobile-only.
|
|
32
|
+
var LOCKED_CONTROL_IDS = [
|
|
33
|
+
"input",
|
|
34
|
+
"send-btn",
|
|
35
|
+
"attach-file-btn",
|
|
36
|
+
"attach-image-btn",
|
|
37
|
+
"input-more-btn",
|
|
38
|
+
"shell-command-btn",
|
|
39
|
+
"stt-btn",
|
|
40
|
+
"schedule-btn",
|
|
41
|
+
"ask-mate-btn",
|
|
42
|
+
"context-sources-add",
|
|
43
|
+
"composer-add-worker-btn",
|
|
44
|
+
"composer-handoff-btn",
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
function lockedControls() {
|
|
48
|
+
var found = [];
|
|
49
|
+
for (var i = 0; i < LOCKED_CONTROL_IDS.length; i++) {
|
|
50
|
+
var el = document.getElementById(LOCKED_CONTROL_IDS[i]);
|
|
51
|
+
if (el) found.push(el);
|
|
52
|
+
}
|
|
53
|
+
return found;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// The configured Worker of a live pair, for the session actually on screen.
|
|
57
|
+
// Returns false for an ad-hoc split, for the Driver, and for any ordinary
|
|
58
|
+
// session, so the composer is only ever taken away in the one real case.
|
|
59
|
+
export function isDriverOperatedView(state) {
|
|
60
|
+
var snapshot = state || store.snap();
|
|
61
|
+
var sessionId = snapshot.paneMode && snapshot.paneSessionId
|
|
62
|
+
? snapshot.paneSessionId
|
|
63
|
+
: snapshot.activeSessionId;
|
|
64
|
+
if (!sessionId) return false;
|
|
65
|
+
var groups = snapshot.splitGroups || [];
|
|
66
|
+
for (var i = 0; i < groups.length; i++) {
|
|
67
|
+
var pair = groups[i] && groups[i].pair;
|
|
68
|
+
if (!pair) continue;
|
|
69
|
+
if (pair.workerId === sessionId) return true;
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function ensureStatusLine(inputArea) {
|
|
75
|
+
var existing = document.getElementById(STATUS_ID);
|
|
76
|
+
if (existing) return existing;
|
|
77
|
+
var line = document.createElement("div");
|
|
78
|
+
line.id = STATUS_ID;
|
|
79
|
+
line.className = "worker-pane-status";
|
|
80
|
+
// A status region, not a live region: it states a standing condition rather
|
|
81
|
+
// than announcing a change, so it should not interrupt.
|
|
82
|
+
line.setAttribute("role", "status");
|
|
83
|
+
var mark = document.createElement("span");
|
|
84
|
+
mark.className = "worker-pane-status-mark";
|
|
85
|
+
mark.setAttribute("aria-hidden", "true");
|
|
86
|
+
var label = document.createElement("span");
|
|
87
|
+
label.className = "worker-pane-status-label";
|
|
88
|
+
label.textContent = "Controlled by Driver";
|
|
89
|
+
line.appendChild(mark);
|
|
90
|
+
line.appendChild(label);
|
|
91
|
+
inputArea.appendChild(line);
|
|
92
|
+
return line;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function applyLock(locked) {
|
|
96
|
+
var inputArea = document.getElementById("input-area");
|
|
97
|
+
var inputWrapper = document.getElementById("input-wrapper");
|
|
98
|
+
if (!inputArea) return;
|
|
99
|
+
|
|
100
|
+
document.body.classList.toggle(LOCK_CLASS, locked);
|
|
101
|
+
|
|
102
|
+
if (inputWrapper) {
|
|
103
|
+
// Hidden from assistive tech as well as sight; the status line speaks for
|
|
104
|
+
// the region instead.
|
|
105
|
+
if (locked) inputWrapper.setAttribute("aria-hidden", "true");
|
|
106
|
+
else inputWrapper.removeAttribute("aria-hidden");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
var controls = lockedControls();
|
|
110
|
+
for (var i = 0; i < controls.length; i++) {
|
|
111
|
+
var el = controls[i];
|
|
112
|
+
if (locked) {
|
|
113
|
+
if (el.dataset.workerLockPrev === undefined) {
|
|
114
|
+
el.dataset.workerLockPrev = el.disabled ? "1" : "0";
|
|
115
|
+
}
|
|
116
|
+
el.disabled = true;
|
|
117
|
+
el.setAttribute("tabindex", "-1");
|
|
118
|
+
} else if (el.dataset.workerLockPrev !== undefined) {
|
|
119
|
+
// Restore exactly what was there before the lock, so an independently
|
|
120
|
+
// disabled send button stays disabled when the pair dissolves.
|
|
121
|
+
el.disabled = el.dataset.workerLockPrev === "1";
|
|
122
|
+
el.removeAttribute("tabindex");
|
|
123
|
+
delete el.dataset.workerLockPrev;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
var status = document.getElementById(STATUS_ID);
|
|
128
|
+
if (locked) {
|
|
129
|
+
status = ensureStatusLine(inputArea);
|
|
130
|
+
status.classList.add("visible");
|
|
131
|
+
} else if (status) {
|
|
132
|
+
status.classList.remove("visible");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Skip permissions and any other Worker-local permission-mode affordance are
|
|
137
|
+
// the Driver's to set, so they are removed from this pane only. The Driver pane
|
|
138
|
+
// and ordinary sessions are untouched.
|
|
139
|
+
function applyPermissionChrome(locked) {
|
|
140
|
+
var ids = ["skip-perms-pill", "config-chip-wrap"];
|
|
141
|
+
for (var i = 0; i < ids.length; i++) {
|
|
142
|
+
var el = document.getElementById(ids[i]);
|
|
143
|
+
if (!el) continue;
|
|
144
|
+
if (locked) {
|
|
145
|
+
if (el.dataset.workerLockHidden === undefined) {
|
|
146
|
+
el.dataset.workerLockHidden = el.classList.contains("hidden") ? "1" : "0";
|
|
147
|
+
}
|
|
148
|
+
el.classList.add("hidden");
|
|
149
|
+
el.setAttribute("aria-hidden", "true");
|
|
150
|
+
} else if (el.dataset.workerLockHidden !== undefined) {
|
|
151
|
+
if (el.dataset.workerLockHidden === "0") el.classList.remove("hidden");
|
|
152
|
+
el.removeAttribute("aria-hidden");
|
|
153
|
+
delete el.dataset.workerLockHidden;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function syncWorkerPaneLock(state) {
|
|
159
|
+
var locked = isDriverOperatedView(state);
|
|
160
|
+
applyLock(locked);
|
|
161
|
+
applyPermissionChrome(locked);
|
|
162
|
+
return locked;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function initWorkerPaneLock() {
|
|
166
|
+
syncWorkerPaneLock();
|
|
167
|
+
// Pair state is the source of truth, so every input that could change the
|
|
168
|
+
// role re-runs the same resolution: a dissolve, a replacement, a role swap,
|
|
169
|
+
// switching to another session, or a reconnect that reloads the groups.
|
|
170
|
+
store.subscribe(function (state, prev) {
|
|
171
|
+
if (state.splitGroups === prev.splitGroups
|
|
172
|
+
&& state.activeSessionId === prev.activeSessionId
|
|
173
|
+
&& state.paneSessionId === prev.paneSessionId) return;
|
|
174
|
+
syncWorkerPaneLock(state);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function workerProposalSelection(msg) {
|
|
2
|
+
var hasSelection = typeof msg.selectedVendor === "string" ||
|
|
3
|
+
typeof msg.selectedModel === "string" || typeof msg.selectedEffort === "string";
|
|
4
|
+
return {
|
|
5
|
+
selected: hasSelection,
|
|
6
|
+
vendor: hasSelection ? (msg.selectedVendor || "") : (msg.recommendedVendor || ""),
|
|
7
|
+
model: hasSelection ? (msg.selectedModel || "") : (msg.recommendedModel || ""),
|
|
8
|
+
effort: hasSelection ? (msg.selectedEffort || "") : (msg.recommendedEffort || "medium"),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function syncWorkerProposalSelection(msg, sync) {
|
|
13
|
+
var selection = workerProposalSelection(msg);
|
|
14
|
+
if (selection.selected && typeof sync === "function") sync(selection);
|
|
15
|
+
return selection;
|
|
16
|
+
}
|
|
@@ -2,6 +2,7 @@ import { getWs } from './ws-ref.js';
|
|
|
2
2
|
import { addToMessages, scrollToBottom, VENDOR_AVATARS, VENDOR_NAMES } from './app-rendering.js';
|
|
3
3
|
import { effortLevelsFor, effortDisplayName } from './app-panels.js';
|
|
4
4
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
5
|
+
import { workerProposalSelection, syncWorkerProposalSelection } from './worker-proposal-state.js';
|
|
5
6
|
|
|
6
7
|
function optionValue(entry) {
|
|
7
8
|
if (typeof entry === "string") return entry;
|
|
@@ -27,7 +28,7 @@ function planSteps(plan) {
|
|
|
27
28
|
}).filter(Boolean).slice(0, 8);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
function buildVendorSelect(msg) {
|
|
31
|
+
function buildVendorSelect(msg, preferred) {
|
|
31
32
|
var select = document.createElement("select");
|
|
32
33
|
select.className = "worker-proposal-select worker-proposal-vendor";
|
|
33
34
|
var installed = (msg.options && msg.options.installedVendors) || [];
|
|
@@ -37,7 +38,7 @@ function buildVendorSelect(msg) {
|
|
|
37
38
|
option.textContent = VENDOR_NAMES[installed[i]] || installed[i];
|
|
38
39
|
select.appendChild(option);
|
|
39
40
|
}
|
|
40
|
-
if (installed.indexOf(
|
|
41
|
+
if (installed.indexOf(preferred) !== -1) select.value = preferred;
|
|
41
42
|
return select;
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -98,29 +99,38 @@ function statusLabel(status) {
|
|
|
98
99
|
if (status === "interrupted") return "Interrupted";
|
|
99
100
|
if (status === "declined") return "Continuing here";
|
|
100
101
|
if (status === "error") return "Needs attention";
|
|
101
|
-
return "
|
|
102
|
+
return "Awaiting your choice";
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function decisionLabel(status, autoAccepted) {
|
|
106
|
+
if (autoAccepted) return "Driver recommendation auto-accepted under Full auto";
|
|
107
|
+
if (status === "pending") return "Runtime choice remains with you";
|
|
108
|
+
if (status === "declined") return "Runtime proposal declined by user";
|
|
109
|
+
return "Runtime configuration accepted by user";
|
|
102
110
|
}
|
|
103
111
|
|
|
104
112
|
function applyState(card, msg) {
|
|
105
113
|
var status = msg.status || "pending";
|
|
106
114
|
card.dataset.status = status;
|
|
107
|
-
if (msg.autoApproved) card.dataset.
|
|
108
|
-
|
|
115
|
+
if (msg.autoAccepted || msg.autoApproved) card.dataset.autoAccepted = "true";
|
|
116
|
+
if (msg.autoAccepted === false || msg.autoApproved === false) card.dataset.autoAccepted = "false";
|
|
117
|
+
var autoAccepted = card.dataset.autoAccepted === "true";
|
|
118
|
+
syncWorkerProposalSelection(msg, card._syncWorkerProposalSelection);
|
|
109
119
|
var badge = card.querySelector(".worker-proposal-status");
|
|
110
|
-
if (badge) badge.textContent = statusLabel(status) + (
|
|
120
|
+
if (badge) badge.textContent = statusLabel(status) + (autoAccepted ? " · auto-accepted" : "");
|
|
121
|
+
var decision = card.querySelector(".worker-proposal-decision");
|
|
122
|
+
if (decision) {
|
|
123
|
+
decision.textContent = decisionLabel(status, autoAccepted);
|
|
124
|
+
decision.classList.toggle("automatic", autoAccepted);
|
|
125
|
+
}
|
|
111
126
|
var error = card.querySelector(".worker-proposal-error");
|
|
112
127
|
if (error) {
|
|
113
128
|
error.textContent = msg.error || "";
|
|
114
129
|
error.classList.toggle("hidden", !msg.error);
|
|
115
130
|
}
|
|
116
|
-
var preview = card.querySelector(".worker-proposal-result");
|
|
117
|
-
if (preview && msg.resultPreview) {
|
|
118
|
-
preview.textContent = msg.resultPreview;
|
|
119
|
-
preview.classList.remove("hidden");
|
|
120
|
-
}
|
|
121
131
|
setControlsDisabled(card, status !== "pending");
|
|
122
132
|
var actions = card.querySelector(".worker-proposal-actions");
|
|
123
|
-
if (actions) actions.classList.toggle("hidden",
|
|
133
|
+
if (actions) actions.classList.toggle("hidden", autoAccepted);
|
|
124
134
|
}
|
|
125
135
|
|
|
126
136
|
function sendDecision(card, accepted) {
|
|
@@ -150,10 +160,12 @@ export function renderWorkerProposal(msg) {
|
|
|
150
160
|
card.className = "worker-proposal-card";
|
|
151
161
|
card.dataset.proposalId = msg.proposalId;
|
|
152
162
|
card.dataset.status = msg.status || "pending";
|
|
163
|
+
var runtimeSelection = workerProposalSelection(msg);
|
|
153
164
|
|
|
154
165
|
var header = document.createElement("div");
|
|
155
166
|
header.className = "worker-proposal-header";
|
|
156
|
-
|
|
167
|
+
var replacing = msg.action === "replace";
|
|
168
|
+
header.innerHTML = '<div class="worker-proposal-mark">' + iconHtml("git-branch") + '</div><div class="worker-proposal-heading"><span class="worker-proposal-kicker">DRIVER / SPLIT WORKER</span><strong>' + (replacing ? "Configure a replacement Split Worker" : "Configure a Split Worker") + '</strong></div><span class="worker-proposal-status"></span>';
|
|
157
169
|
card.appendChild(header);
|
|
158
170
|
|
|
159
171
|
var summary = document.createElement("p");
|
|
@@ -173,12 +185,24 @@ export function renderWorkerProposal(msg) {
|
|
|
173
185
|
card.appendChild(plan);
|
|
174
186
|
}
|
|
175
187
|
|
|
188
|
+
if (msg.recommendationRationale) {
|
|
189
|
+
var rationale = document.createElement("div");
|
|
190
|
+
rationale.className = "worker-proposal-rationale";
|
|
191
|
+
var rationaleLabel = document.createElement("span");
|
|
192
|
+
rationaleLabel.textContent = "Driver's recommendation rationale";
|
|
193
|
+
var rationaleText = document.createElement("p");
|
|
194
|
+
rationaleText.textContent = msg.recommendationRationale;
|
|
195
|
+
rationale.appendChild(rationaleLabel);
|
|
196
|
+
rationale.appendChild(rationaleText);
|
|
197
|
+
card.appendChild(rationale);
|
|
198
|
+
}
|
|
199
|
+
|
|
176
200
|
var config = document.createElement("div");
|
|
177
201
|
config.className = "worker-proposal-config";
|
|
178
202
|
var vendorField = document.createElement("label");
|
|
179
203
|
vendorField.className = "worker-proposal-field worker-proposal-vendor-field";
|
|
180
204
|
vendorField.innerHTML = '<span>Worker</span><span class="worker-proposal-vendor-control"><img alt=""></span>';
|
|
181
|
-
var vendorSelect = buildVendorSelect(msg);
|
|
205
|
+
var vendorSelect = buildVendorSelect(msg, runtimeSelection.vendor);
|
|
182
206
|
vendorField.querySelector(".worker-proposal-vendor-control").appendChild(vendorSelect);
|
|
183
207
|
config.appendChild(vendorField);
|
|
184
208
|
var modelField = document.createElement("label");
|
|
@@ -194,6 +218,10 @@ export function renderWorkerProposal(msg) {
|
|
|
194
218
|
config.appendChild(effortField);
|
|
195
219
|
card.appendChild(config);
|
|
196
220
|
|
|
221
|
+
var decision = document.createElement("div");
|
|
222
|
+
decision.className = "worker-proposal-decision";
|
|
223
|
+
card.appendChild(decision);
|
|
224
|
+
|
|
197
225
|
function syncVendor(preferredModel, preferredEffort) {
|
|
198
226
|
var vendor = vendorSelect.value;
|
|
199
227
|
var avatar = vendorField.querySelector("img");
|
|
@@ -201,31 +229,32 @@ export function renderWorkerProposal(msg) {
|
|
|
201
229
|
fillModels(modelSelect, vendor, msg, preferredModel);
|
|
202
230
|
fillEffort(card, vendor, modelSelect.value, msg, preferredEffort);
|
|
203
231
|
}
|
|
232
|
+
card._syncWorkerProposalSelection = function (selection) {
|
|
233
|
+
if (selection.vendor && vendorSelect.value !== selection.vendor) vendorSelect.value = selection.vendor;
|
|
234
|
+
syncVendor(selection.model, selection.effort);
|
|
235
|
+
};
|
|
204
236
|
vendorSelect.addEventListener("change", function () { syncVendor("", "medium"); });
|
|
205
237
|
modelSelect.addEventListener("change", function () {
|
|
206
238
|
var active = card.querySelector(".worker-proposal-effort-btn.active");
|
|
207
239
|
fillEffort(card, vendorSelect.value, modelSelect.value, msg, active ? active.dataset.effort : "medium");
|
|
208
240
|
});
|
|
209
|
-
syncVendor(
|
|
241
|
+
syncVendor(runtimeSelection.model, runtimeSelection.effort);
|
|
210
242
|
|
|
211
243
|
var error = document.createElement("div");
|
|
212
244
|
error.className = "worker-proposal-error hidden";
|
|
213
245
|
card.appendChild(error);
|
|
214
|
-
var result = document.createElement("div");
|
|
215
|
-
result.className = "worker-proposal-result hidden";
|
|
216
|
-
card.appendChild(result);
|
|
217
246
|
|
|
218
247
|
var actions = document.createElement("div");
|
|
219
248
|
actions.className = "worker-proposal-actions";
|
|
220
249
|
var decline = document.createElement("button");
|
|
221
250
|
decline.type = "button";
|
|
222
251
|
decline.className = "worker-proposal-action secondary";
|
|
223
|
-
decline.textContent = "Continue here";
|
|
252
|
+
decline.textContent = replacing ? "Keep current Worker" : "Continue here";
|
|
224
253
|
decline.addEventListener("click", function () { sendDecision(card, false); });
|
|
225
254
|
var accept = document.createElement("button");
|
|
226
255
|
accept.type = "button";
|
|
227
256
|
accept.className = "worker-proposal-action primary";
|
|
228
|
-
accept.innerHTML = iconHtml("panel-right-open") + "<span>Run with Split Worker</span>";
|
|
257
|
+
accept.innerHTML = iconHtml("panel-right-open") + "<span>" + (replacing ? "Replace Split Worker" : "Run with Split Worker") + "</span>";
|
|
229
258
|
accept.addEventListener("click", function () { sendDecision(card, true); });
|
|
230
259
|
actions.appendChild(decline);
|
|
231
260
|
actions.appendChild(accept);
|
package/lib/public/style.css
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
@import url("css/input.css?v=20260828-composer-depth1");
|
|
15
15
|
@import url("css/filebrowser.css?v=20260829-terminal-canvas1");
|
|
16
16
|
@import url("css/git-panel.css");
|
|
17
|
+
@import url("css/git-placard.css");
|
|
17
18
|
@import url("css/diff.css");
|
|
18
19
|
@import url("css/highlight.css");
|
|
19
20
|
@import url("css/server-settings.css");
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
@import url("css/mobile-nav.css?v=20260407");
|
|
23
24
|
@import url("css/loop.css");
|
|
24
25
|
@import url("css/scheduler.css");
|
|
26
|
+
@import url("css/project-logs.css");
|
|
25
27
|
@import url("css/scheduler-modal.css");
|
|
26
28
|
@import url("css/home-hub.css");
|
|
27
29
|
@import url("css/home-sidebar.css");
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
@import url("css/session-search.css");
|
|
40
42
|
@import url("css/tooltip.css");
|
|
41
43
|
@import url("css/mates.css?v=20260407");
|
|
42
|
-
@import url("css/command-palette.css?v=
|
|
44
|
+
@import url("css/command-palette.css?v=20260910-ask-clay-controls1");
|
|
43
45
|
@import url("css/mention.css");
|
|
44
46
|
@import url("css/debate.css");
|
|
45
47
|
@import url("css/home-debate-planning.css");
|