clay-server 2.6.0 → 2.7.0
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/bin/cli.js +51 -3
- package/lib/config.js +8 -2
- package/lib/daemon.js +47 -5
- package/lib/ipc.js +12 -0
- package/lib/notes.js +1 -1
- package/lib/project.js +711 -2
- package/lib/public/app.js +693 -8
- package/lib/public/css/diff.css +12 -0
- package/lib/public/css/filebrowser.css +1 -1
- package/lib/public/css/loop.css +780 -0
- package/lib/public/css/rewind.css +23 -0
- package/lib/public/css/sidebar.css +1 -0
- package/lib/public/css/skills.css +59 -0
- package/lib/public/css/sticky-notes.css +486 -0
- package/lib/public/css/title-bar.css +83 -3
- package/lib/public/index.html +107 -3
- package/lib/public/modules/diff.js +3 -3
- package/lib/public/modules/filebrowser.js +169 -45
- package/lib/public/modules/input.js +4 -0
- package/lib/public/modules/qrcode.js +23 -26
- package/lib/public/modules/server-settings.js +40 -0
- package/lib/public/modules/sidebar.js +12 -0
- package/lib/public/modules/skills.js +84 -0
- package/lib/public/modules/sticky-notes.js +617 -52
- package/lib/public/modules/theme.js +9 -19
- package/lib/public/modules/tools.js +16 -2
- package/lib/public/style.css +1 -0
- package/lib/sdk-bridge.js +28 -0
- package/lib/sessions.js +2 -1
- package/package.json +1 -1
|
@@ -502,22 +502,13 @@ export function toggleDarkMode() {
|
|
|
502
502
|
updateToggleIcon();
|
|
503
503
|
}
|
|
504
504
|
|
|
505
|
-
// Update the toggle
|
|
505
|
+
// Update the toggle switch checkbox state
|
|
506
506
|
function updateToggleIcon() {
|
|
507
|
-
var
|
|
508
|
-
if (!
|
|
507
|
+
var checkbox = document.getElementById("theme-toggle-check");
|
|
508
|
+
if (!checkbox) return;
|
|
509
509
|
var mode = getEffectiveMode();
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
var existing = btn.querySelector(".lucide, [data-lucide]");
|
|
513
|
-
if (existing) {
|
|
514
|
-
var i = document.createElement("i");
|
|
515
|
-
i.setAttribute("data-lucide", iconName);
|
|
516
|
-
btn.replaceChild(i, existing);
|
|
517
|
-
if (window.lucide && window.lucide.createIcons) {
|
|
518
|
-
window.lucide.createIcons();
|
|
519
|
-
}
|
|
520
|
-
}
|
|
510
|
+
// checked = light mode (thumb slides right, covering moon)
|
|
511
|
+
checkbox.checked = (mode === "light");
|
|
521
512
|
}
|
|
522
513
|
|
|
523
514
|
// --- Theme picker UI ---
|
|
@@ -687,11 +678,10 @@ export function initTheme() {
|
|
|
687
678
|
// Load all themes from server, then apply properly
|
|
688
679
|
loadThemes();
|
|
689
680
|
|
|
690
|
-
// Wire up title bar toggle
|
|
691
|
-
var
|
|
692
|
-
if (
|
|
693
|
-
|
|
694
|
-
e.stopPropagation();
|
|
681
|
+
// Wire up title bar toggle switch
|
|
682
|
+
var toggleCheck = document.getElementById("theme-toggle-check");
|
|
683
|
+
if (toggleCheck) {
|
|
684
|
+
toggleCheck.addEventListener("change", function () {
|
|
695
685
|
toggleDarkMode();
|
|
696
686
|
});
|
|
697
687
|
}
|
|
@@ -189,6 +189,13 @@ export function renderAskUserQuestion(toolId, input) {
|
|
|
189
189
|
var qDiv = document.createElement("div");
|
|
190
190
|
qDiv.className = "ask-user-question";
|
|
191
191
|
|
|
192
|
+
if (q.header) {
|
|
193
|
+
var qHeader = document.createElement("div");
|
|
194
|
+
qHeader.className = "ask-user-question-header";
|
|
195
|
+
qHeader.textContent = q.header;
|
|
196
|
+
qDiv.appendChild(qHeader);
|
|
197
|
+
}
|
|
198
|
+
|
|
192
199
|
var qText = document.createElement("div");
|
|
193
200
|
qText.className = "ask-user-question-text";
|
|
194
201
|
qText.textContent = q.question || "";
|
|
@@ -208,6 +215,12 @@ export function renderAskUserQuestion(toolId, input) {
|
|
|
208
215
|
(opt.description ? '<div class="option-desc"></div>' : '');
|
|
209
216
|
btn.querySelector(".option-label").textContent = opt.label;
|
|
210
217
|
if (opt.description) btn.querySelector(".option-desc").textContent = opt.description;
|
|
218
|
+
if (opt.markdown) {
|
|
219
|
+
var pre = document.createElement("pre");
|
|
220
|
+
pre.className = "option-markdown";
|
|
221
|
+
pre.textContent = opt.markdown;
|
|
222
|
+
btn.appendChild(pre);
|
|
223
|
+
}
|
|
211
224
|
|
|
212
225
|
btn.addEventListener("click", function () {
|
|
213
226
|
if (container.classList.contains("answered")) return;
|
|
@@ -267,8 +280,9 @@ export function renderAskUserQuestion(toolId, input) {
|
|
|
267
280
|
container.appendChild(qDiv);
|
|
268
281
|
});
|
|
269
282
|
|
|
270
|
-
//
|
|
271
|
-
|
|
283
|
+
// Submit button: show for multi-question or any multi-select question
|
|
284
|
+
var hasMultiSelect = questions.some(function (q) { return q.multiSelect; });
|
|
285
|
+
if (questions.length > 1 || hasMultiSelect) {
|
|
272
286
|
var submitBtn = document.createElement("button");
|
|
273
287
|
submitBtn.className = "ask-user-submit";
|
|
274
288
|
submitBtn.textContent = "Submit";
|
package/lib/public/style.css
CHANGED
package/lib/sdk-bridge.js
CHANGED
|
@@ -479,6 +479,17 @@ function createSDKBridge(opts) {
|
|
|
479
479
|
// --- SDK query lifecycle ---
|
|
480
480
|
|
|
481
481
|
function handleCanUseTool(session, toolName, input, opts) {
|
|
482
|
+
// Ralph Loop: auto-approve all tools, deny interactive ones
|
|
483
|
+
if (session.loop && session.loop.active) {
|
|
484
|
+
if (toolName === "AskUserQuestion") {
|
|
485
|
+
return Promise.resolve({ behavior: "deny", message: "Autonomous mode. Make your own decision." });
|
|
486
|
+
}
|
|
487
|
+
if (toolName === "EnterPlanMode") {
|
|
488
|
+
return Promise.resolve({ behavior: "deny", message: "Do not enter plan mode. Execute directly." });
|
|
489
|
+
}
|
|
490
|
+
return Promise.resolve({ behavior: "allow", updatedInput: input });
|
|
491
|
+
}
|
|
492
|
+
|
|
482
493
|
// AskUserQuestion: wait for user answers via WebSocket
|
|
483
494
|
if (toolName === "AskUserQuestion") {
|
|
484
495
|
return new Promise(function(resolve) {
|
|
@@ -666,6 +677,15 @@ function createSDKBridge(opts) {
|
|
|
666
677
|
session.pendingPermissions = {};
|
|
667
678
|
session.pendingAskUser = {};
|
|
668
679
|
}
|
|
680
|
+
// Ralph Loop: notify completion so loop orchestrator can proceed
|
|
681
|
+
if (session.onQueryComplete) {
|
|
682
|
+
console.log("[sdk-bridge] Calling onQueryComplete for session " + session.localId + " (title: " + (session.title || "?") + ")");
|
|
683
|
+
try {
|
|
684
|
+
session.onQueryComplete(session);
|
|
685
|
+
} catch (err) {
|
|
686
|
+
console.error("[sdk-bridge] onQueryComplete error:", err.message || err);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
669
689
|
}
|
|
670
690
|
|
|
671
691
|
async function getOrCreateRewindQuery(session) {
|
|
@@ -808,6 +828,14 @@ function createSDKBridge(opts) {
|
|
|
808
828
|
return;
|
|
809
829
|
}
|
|
810
830
|
|
|
831
|
+
// For single-turn sessions (Ralph Loop), end the message queue so the SDK
|
|
832
|
+
// query finishes after processing the one message. Without this, the query
|
|
833
|
+
// stream stays open forever waiting for more messages, and onQueryComplete
|
|
834
|
+
// never fires.
|
|
835
|
+
if (session.singleTurn) {
|
|
836
|
+
session.messageQueue.end();
|
|
837
|
+
}
|
|
838
|
+
|
|
811
839
|
session.streamPromise = processQueryStream(session).catch(function(err) {
|
|
812
840
|
});
|
|
813
841
|
}
|
package/lib/sessions.js
CHANGED
|
@@ -178,6 +178,7 @@ function createSessionManager(opts) {
|
|
|
178
178
|
active: s.localId === activeSessionId,
|
|
179
179
|
isProcessing: s.isProcessing,
|
|
180
180
|
lastActivity: s.lastActivity || s.createdAt || 0,
|
|
181
|
+
loop: s.loop || null,
|
|
181
182
|
};
|
|
182
183
|
}),
|
|
183
184
|
});
|
|
@@ -254,7 +255,7 @@ function createSessionManager(opts) {
|
|
|
254
255
|
if (!session) return;
|
|
255
256
|
|
|
256
257
|
activeSessionId = localId;
|
|
257
|
-
send({ type: "session_switched", id: localId, cliSessionId: session.cliSessionId || null });
|
|
258
|
+
send({ type: "session_switched", id: localId, cliSessionId: session.cliSessionId || null, loop: session.loop || null });
|
|
258
259
|
broadcastSessionList();
|
|
259
260
|
replayHistory(session);
|
|
260
261
|
|