clay-server 4.1.0-beta.13 → 4.1.0-beta.14
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/issues-mcp-server.js +1 -1
- package/lib/project-file-path.js +13 -0
- package/lib/project-file-watch.js +19 -8
- package/lib/project-filesystem.js +10 -16
- package/lib/project-http.js +19 -11
- package/lib/project-logs-mcp-server.js +8 -8
- package/lib/project.js +1 -0
- package/lib/public/app.js +12 -8
- package/lib/public/css/git-panel.css +13 -12
- package/lib/public/css/git-placard.css +4 -4
- package/lib/public/modules/app-rate-limit.js +148 -61
- package/lib/public/modules/filebrowser-tabs.js +1 -0
- package/lib/public/modules/filebrowser.js +45 -18
- package/lib/public/modules/issues.js +4 -6
- package/lib/public/modules/project-logs.js +4 -9
- package/lib/public/modules/right-workbench.js +44 -0
- package/lib/public/modules/scheduled-tasks.js +4 -5
- package/lib/public/modules/sidebar-mobile.js +2 -1
- package/lib/public/modules/sticky-notes-browser.js +4 -13
- package/lib/public/modules/terminal.js +4 -4
- package/lib/sdk-message-processor.js +6 -2
- package/lib/session-notes-mcp-server.js +2 -4
- package/lib/yoke/vendor-registry.js +1 -1
- package/package.json +1 -1
|
@@ -2,10 +2,7 @@ import { store } from './store.js';
|
|
|
2
2
|
import { getWs } from './ws-ref.js';
|
|
3
3
|
import { refreshIcons, iconHtml } from './icons.js';
|
|
4
4
|
import { showToast } from './utils.js';
|
|
5
|
-
import {
|
|
6
|
-
import { closeNotesBrowser } from './sticky-notes-browser.js';
|
|
7
|
-
import { closeFileViewer } from './filebrowser.js';
|
|
8
|
-
import { closeTerminal } from './terminal.js';
|
|
5
|
+
import { claimRightWorkbench, registerRightWorkbench, releaseRightWorkbench } from './right-workbench.js';
|
|
9
6
|
import { humanRecurrence } from './scheduled-task-recurrence.js';
|
|
10
7
|
import { humanScheduleRule } from './scheduled-task-schedule-rule.js';
|
|
11
8
|
import { readExecutionRuntime, renderExecutionRuntime } from './scheduled-task-engine.js';
|
|
@@ -320,7 +317,7 @@ export function openScheduledTasks() {
|
|
|
320
317
|
if (!canOpen()) { closeScheduledTasks(); return; }
|
|
321
318
|
ensurePanel();
|
|
322
319
|
if (!panel) return;
|
|
323
|
-
|
|
320
|
+
claimRightWorkbench("scheduled-tasks");
|
|
324
321
|
panel.classList.remove("hidden");
|
|
325
322
|
applyWindowState(store.get('scheduledTasksWide'), false);
|
|
326
323
|
store.set({ scheduledTasksOpen: true });
|
|
@@ -330,6 +327,7 @@ export function openScheduledTasks() {
|
|
|
330
327
|
}
|
|
331
328
|
|
|
332
329
|
export function closeScheduledTasks() {
|
|
330
|
+
releaseRightWorkbench("scheduled-tasks");
|
|
333
331
|
if (panel) panel.classList.add("hidden");
|
|
334
332
|
setCreateMenu(false);
|
|
335
333
|
applyWindowState(store.get('scheduledTasksWide'), false);
|
|
@@ -430,6 +428,7 @@ export function handleScheduledTaskSessionSwitched(msg) {
|
|
|
430
428
|
}
|
|
431
429
|
|
|
432
430
|
export function initScheduledTasks() {
|
|
431
|
+
registerRightWorkbench("scheduled-tasks", closeScheduledTasks);
|
|
433
432
|
var button = document.getElementById("scheduler-btn");
|
|
434
433
|
if (button) button.addEventListener("click", function () { if (isScheduledTasksOpen()) closeScheduledTasks(); else openScheduledTasks(); });
|
|
435
434
|
document.addEventListener("click", handleDocumentClick);
|
|
@@ -36,7 +36,7 @@ import { showHomeHub } from './app-home-hub.js';
|
|
|
36
36
|
import { openHomeChat } from './home-mate-chat.js';
|
|
37
37
|
import { openTerminal } from './terminal.js';
|
|
38
38
|
import { requestKnowledgeList } from './mate-knowledge.js';
|
|
39
|
-
import { loadRootDirectory } from './filebrowser.js';
|
|
39
|
+
import { loadRootDirectory, reopenFileViewer } from './filebrowser.js';
|
|
40
40
|
import {
|
|
41
41
|
prepareSidebarHierarchy,
|
|
42
42
|
renderMobileDriverHierarchy,
|
|
@@ -91,6 +91,7 @@ export function openMobileSheet(type) {
|
|
|
91
91
|
listEl.appendChild(fileTree);
|
|
92
92
|
fileTree.classList.remove("hidden");
|
|
93
93
|
}
|
|
94
|
+
reopenFileViewer();
|
|
94
95
|
loadRootDirectory();
|
|
95
96
|
} else if (type === "mate-knowledge") {
|
|
96
97
|
titleEl.textContent = "Knowledge";
|
|
@@ -14,6 +14,7 @@ import { renderMiniMarkdown, getTitle } from './sticky-note-markdown.js';
|
|
|
14
14
|
import { enhanceClayLogLinks } from './clay-log-links.js';
|
|
15
15
|
import { send } from './sticky-notes-shared.js';
|
|
16
16
|
import { listNoteData, focusNoteOnCanvas, hideNotes, showNotes } from './sticky-notes.js';
|
|
17
|
+
import { claimRightWorkbench, registerRightWorkbench, releaseRightWorkbench } from './right-workbench.js';
|
|
17
18
|
|
|
18
19
|
var panel = null;
|
|
19
20
|
var gridEl = null;
|
|
@@ -21,18 +22,6 @@ var tabsEl = null;
|
|
|
21
22
|
|
|
22
23
|
// Registered by app.js so this module never imports the other right-pane tools
|
|
23
24
|
// and cannot form an import cycle with them.
|
|
24
|
-
var exclusiveClosers = [];
|
|
25
|
-
|
|
26
|
-
export function registerExclusiveClosers(fns) {
|
|
27
|
-
exclusiveClosers = (fns || []).filter(function (fn) { return typeof fn === "function"; });
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function closeOtherRightTools() {
|
|
31
|
-
for (var i = 0; i < exclusiveClosers.length; i++) {
|
|
32
|
-
try { exclusiveClosers[i](); } catch (e) { /* a missing tool must not block opening */ }
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
25
|
function isClosed(data) {
|
|
37
26
|
if (!data) return false;
|
|
38
27
|
if (data.state === "closed") return true;
|
|
@@ -283,7 +272,7 @@ export function renderNotesBrowser() {
|
|
|
283
272
|
export function openNotesBrowser() {
|
|
284
273
|
ensurePanel();
|
|
285
274
|
if (!panel) return;
|
|
286
|
-
|
|
275
|
+
claimRightWorkbench("notes-browser");
|
|
287
276
|
// The floating canvas would otherwise sit on top of the pane.
|
|
288
277
|
hideNotes();
|
|
289
278
|
panel.classList.remove("hidden");
|
|
@@ -295,6 +284,7 @@ export function openNotesBrowser() {
|
|
|
295
284
|
}
|
|
296
285
|
|
|
297
286
|
export function closeNotesBrowser() {
|
|
287
|
+
releaseRightWorkbench("notes-browser");
|
|
298
288
|
if (!store.get('notesBrowserOpen')) return;
|
|
299
289
|
if (panel) panel.classList.add("hidden");
|
|
300
290
|
// Fullscreen is always dropped on close so the next open is a bounded pane.
|
|
@@ -311,6 +301,7 @@ export function isNotesBrowserOpen() {
|
|
|
311
301
|
}
|
|
312
302
|
|
|
313
303
|
export function initNotesBrowser() {
|
|
304
|
+
registerRightWorkbench("notes-browser", closeNotesBrowser);
|
|
314
305
|
document.addEventListener("keydown", function (e) {
|
|
315
306
|
if (e.key !== "Escape") return;
|
|
316
307
|
if (!store.get('notesBrowserOpen')) return;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
2
2
|
import { closeSidebar } from './sidebar.js';
|
|
3
|
-
import {
|
|
3
|
+
import { claimRightWorkbench, registerRightWorkbench, releaseRightWorkbench } from './right-workbench.js';
|
|
4
4
|
import { copyToClipboard } from './utils.js';
|
|
5
5
|
import { getTerminalTheme } from './theme.js';
|
|
6
6
|
import { getTerminalFontFamily, getTerminalFontSize, onTerminalFontChange } from './terminal-prefs.js';
|
|
7
7
|
import { createKeyToolbar } from './terminal-toolbar.js';
|
|
8
|
-
import { closeIssues } from './issues.js';
|
|
9
8
|
|
|
10
9
|
var ctx;
|
|
11
10
|
var tabs = new Map(); // termId -> { id, title, exited, xterm, fitAddon, bodyEl }
|
|
@@ -136,6 +135,7 @@ function createMultiLineLinkProvider(xterm) {
|
|
|
136
135
|
// --- Init ---
|
|
137
136
|
export function initTerminal(_ctx) {
|
|
138
137
|
ctx = _ctx;
|
|
138
|
+
registerRightWorkbench("terminal", closeTerminal);
|
|
139
139
|
|
|
140
140
|
// Close panel button
|
|
141
141
|
document.getElementById("terminal-close").addEventListener("click", function () {
|
|
@@ -193,8 +193,7 @@ export function openTerminal() {
|
|
|
193
193
|
var container = ctx.terminalContainerEl;
|
|
194
194
|
|
|
195
195
|
// Hide file viewer if open (also unwatches)
|
|
196
|
-
|
|
197
|
-
closeIssues();
|
|
196
|
+
claimRightWorkbench("terminal");
|
|
198
197
|
|
|
199
198
|
container.classList.remove("hidden");
|
|
200
199
|
isOpen = true;
|
|
@@ -224,6 +223,7 @@ export function openTerminal() {
|
|
|
224
223
|
|
|
225
224
|
// --- Close terminal panel (hide, detach, but keep PTYs alive) ---
|
|
226
225
|
export function closeTerminal() {
|
|
226
|
+
releaseRightWorkbench("terminal");
|
|
227
227
|
var container = ctx.terminalContainerEl;
|
|
228
228
|
container.classList.remove("panel-fullscreen");
|
|
229
229
|
container.classList.add("hidden");
|
|
@@ -778,10 +778,12 @@ function attachMessageProcessor(ctx) {
|
|
|
778
778
|
var info = parsed.rateLimitInfo;
|
|
779
779
|
console.log("[sdk-bridge] rate_limit_event for session " + session.localId + ": status=" + info.status + " resetsAt=" + info.resetsAt + " isUsingOverage=" + info.isUsingOverage + " isProcessing=" + session.isProcessing);
|
|
780
780
|
|
|
781
|
-
//
|
|
781
|
+
// Persist the scoped reset snapshot so reconnect/history restore can reproject it.
|
|
782
782
|
if (info.rateLimitType && info.resetsAt) {
|
|
783
|
-
|
|
783
|
+
sendAndRecord(session, {
|
|
784
784
|
type: "rate_limit_usage",
|
|
785
|
+
sessionId: session.localId,
|
|
786
|
+
vendor: session.vendor || "claude",
|
|
785
787
|
rateLimitType: info.rateLimitType,
|
|
786
788
|
resetsAt: info.resetsAt * 1000,
|
|
787
789
|
status: info.status,
|
|
@@ -792,6 +794,8 @@ function attachMessageProcessor(ctx) {
|
|
|
792
794
|
if (info.status === "allowed_warning" || info.status === "rejected") {
|
|
793
795
|
sendAndRecord(session, {
|
|
794
796
|
type: "rate_limit",
|
|
797
|
+
sessionId: session.localId,
|
|
798
|
+
vendor: session.vendor || "claude",
|
|
795
799
|
status: info.status,
|
|
796
800
|
resetsAt: info.resetsAt ? info.resetsAt * 1000 : null,
|
|
797
801
|
rateLimitType: info.rateLimitType || null,
|
|
@@ -4,10 +4,8 @@ var buildShape = require("./session-spawn-mcp-server").buildShape;
|
|
|
4
4
|
|
|
5
5
|
var MEMORY_CONTRACT =
|
|
6
6
|
"The sticky-note board persists across sessions and is a user-facing artifact shared with people and Clay agents, not private agent scratch space. " +
|
|
7
|
-
"Default to not writing. Create a note proactively only when the user explicitly asks to remember or track something, or when all of these are true: it will remain useful after the current task and session, it is not already adequately recorded in the repository or another note, and the user would likely be glad to find it on the board a week later. " +
|
|
8
|
-
"
|
|
9
|
-
"Important exception for deferred defects: while doing code or technical work, actively create a sticky note when you discover a concrete defect, regression risk, security issue, or data-loss risk that is outside the current session goal and will remain unfixed when the turn ends. Do not wait for the user to ask. For a Project Driver session with Issues authority, search, reuse, or create the Issue first and put the primary details there: observable evidence, affected component, impact, and next action. Then make the sticky note only a concise title, one-line actionable cue, and the actual opaque issue: reference; do not duplicate the full defect details in the note. If you lack Issues authority, route through an eligible Project Driver; never invent an issue reference or drop the alert. Check active notes first when a duplicate is plausible. Do not create defect notes for speculation, general cleanup ideas, or problems you fixed in the current session. " +
|
|
10
|
-
"Important exception for deferred proposals: when you propose work (a fix, follow-up, improvement, or next step) and the user defers it rather than declining it (\"let's do that later\", \"next time\", \"after this\"), actively create a sticky note before the topic moves on. Do not wait to be asked. Capture what was proposed, why it mattered, and the agreed timing if any. Deferred agreements scroll out of chat history quickly and are hard to track; the board is where they survive. If the user declines the idea outright, do not write a note. " +
|
|
7
|
+
"Default to not writing. Create a note proactively only when the user explicitly asks to remember or track something, or when all of these are true: it will remain useful after the current task and session, it is not already adequately recorded in the repository, an Issue, or another note, and the user would likely be glad to find it on the board a week later. " +
|
|
8
|
+
"Use Sticky Notes for preferences, reminders, undeveloped ideas, or an explicit request to remember something; they are not mandatory duplicates of Project Issues. For concrete actionable bugs, improvements, or deferred implementation, an authorized Project Driver should use Project Issues. If you lack Issues authority, route the work through an eligible Project Driver. Check active notes first when a duplicate is plausible. " +
|
|
11
9
|
"Never create a note merely because work is important, lengthy, spans agents or restarts, or might help another agent. Do not record completed work, implementation details, test results, investigation logs, transient blockers, conversation summaries, or announcements of your own activity. When uncertain, do not write. " +
|
|
12
10
|
"Updates are visible too: update only when durable state materially changes. " +
|
|
13
11
|
"A note is an attention item, so finishing it means closing it, never erasing it: call close_note once the thing it is asking for is done, and the note leaves the active board while the record stays and can be reopened. Do not turn a note into a completion log instead of closing it. " +
|
package/package.json
CHANGED