clay-server 4.0.0-beta.2 → 4.0.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/background-task-timing.js +105 -0
- 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 +14 -1
- 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-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 +58 -13
- package/lib/project-user-message.js +53 -4
- package/lib/project-vendor-login.js +20 -3
- package/lib/project-worker-permission.js +430 -0
- package/lib/project-worker-proposal.js +208 -62
- package/lib/project.js +178 -6
- package/lib/public/app.js +58 -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 +19 -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 +163 -28
- package/lib/public/css/mobile-nav.css +80 -0
- package/lib/public/css/notifications-center.css +67 -0
- package/lib/public/css/pane.css +52 -0
- 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 +34 -1
- package/lib/public/index.html +45 -11
- package/lib/public/modules/admin.js +8 -8
- package/lib/public/modules/app-connection.js +109 -4
- package/lib/public/modules/app-home-hub.js +19 -7
- package/lib/public/modules/app-message-cards.js +2 -1
- package/lib/public/modules/app-messages.js +84 -7
- 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 +46 -4
- package/lib/public/modules/app-projects.js +13 -8
- package/lib/public/modules/app-rendering.js +1 -0
- package/lib/public/modules/background-tasks-ui.js +139 -16
- 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-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-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/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-view.js +5 -2
- 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/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 +21 -1
- 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 -12
- package/lib/public/style.css +3 -1
- package/lib/sdk-bridge.js +132 -46
- package/lib/sdk-message-processor.js +60 -14
- package/lib/server-experimental-settings.js +49 -0
- package/lib/server-global-ws.js +11 -0
- package/lib/server-home-chat-events.js +31 -1
- package/lib/server-home-chat.js +27 -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 +124 -18
- 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 +39 -0
- package/lib/sessions.js +61 -11
- 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 +2 -2
- 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 +38 -7
- package/lib/yoke/adapters/claude-worker.js +16 -6
- package/lib/yoke/adapters/claude.js +81 -4
- package/lib/yoke/adapters/codex.js +63 -15
- package/lib/yoke/codex-background-tasks.js +8 -2
- package/lib/yoke/vendor-registry.js +1 -1
- package/package.json +3 -3
package/lib/project.js
CHANGED
|
@@ -9,6 +9,7 @@ var runtimeEnv = require("./runtime-env");
|
|
|
9
9
|
var { createTerminalManager } = require("./terminal-manager");
|
|
10
10
|
var { createNotesManager } = require("./notes");
|
|
11
11
|
var { fetchLatestVersion, fetchVersion, isNewer } = require("./updater");
|
|
12
|
+
var updateSnooze = require("./update-snooze");
|
|
12
13
|
var { execFileSync, spawn } = require("child_process");
|
|
13
14
|
var usersModule = require("./users");
|
|
14
15
|
var { resolveOsUserInfo, fsAsUser, grantProjectAccess } = require("./os-users");
|
|
@@ -42,6 +43,7 @@ var { attachEmail: attachEmailModule } = require("./project-email");
|
|
|
42
43
|
var { attachSessionSpawn } = require("./project-session-spawn");
|
|
43
44
|
var { attachDelegatedSession } = require("./project-delegated-session");
|
|
44
45
|
var { attachDelegatedFollowUp } = require("./project-delegated-follow-up");
|
|
46
|
+
var { attachCapsuleTurn } = require("./project-capsule-turn");
|
|
45
47
|
var workspaceSessionRef = require("./workspace-query-service").sessionRef;
|
|
46
48
|
var { attachSessionPair } = require("./project-session-pair");
|
|
47
49
|
var { attachSessionHandoff } = require("./project-session-handoff");
|
|
@@ -49,8 +51,12 @@ var { attachSessionNotes, composeSystemPrompts } = require("./project-session-no
|
|
|
49
51
|
var { attachSessionDocument } = require("./project-session-document");
|
|
50
52
|
var { attachCapsuleCatalog } = require("./project-capsule-catalog");
|
|
51
53
|
var { attachProjectWorkspaceQuery } = require("./project-workspace-query");
|
|
54
|
+
var { attachProjectLogs } = require("./project-logs");
|
|
55
|
+
var { attachProjectLogFeedbackDelivery } = require("./project-log-feedback-delivery");
|
|
56
|
+
var { attachProjectMateKnowledge } = require("./project-mate-knowledge");
|
|
52
57
|
var { attachSplitGroups } = require("./session-split-groups");
|
|
53
58
|
var toolControlMcp = require("./tool-control-mcp-server");
|
|
59
|
+
var capsuleFloor = require("./capsule-display-floor");
|
|
54
60
|
var toolLlm = require("./tool-llm");
|
|
55
61
|
// project-notifications is attached globally in server.js, passed via opts.notificationsModule
|
|
56
62
|
|
|
@@ -61,6 +67,10 @@ function createMateToolControlMcp(adapter, config) {
|
|
|
61
67
|
var manifests = config.list(config.userId) || [];
|
|
62
68
|
var tools = [];
|
|
63
69
|
for (var i = 0; i < manifests.length; i++) {
|
|
70
|
+
// Skills go dark when the declarative Display floor does, so a Capsule
|
|
71
|
+
// the human cannot operate is never listed to a Mate either. The guard
|
|
72
|
+
// validates the Capsule's own Display tree, not a claim about it.
|
|
73
|
+
if (!capsuleFloor.hasUsableFloor(manifests[i])) continue;
|
|
64
74
|
tools.push({
|
|
65
75
|
id: manifests[i].id,
|
|
66
76
|
name: manifests[i].name,
|
|
@@ -205,6 +215,7 @@ function createProjectContext(opts) {
|
|
|
205
215
|
var updateChannel = opts.updateChannel || "stable";
|
|
206
216
|
var osUsers = opts.osUsers || false;
|
|
207
217
|
var projectOwnerId = opts.projectOwnerId || null;
|
|
218
|
+
var projectKnowledgeId = opts.projectKnowledgeId || null;
|
|
208
219
|
var worktreeMeta = opts.worktreeMeta || null; // { parentSlug, branch, external }
|
|
209
220
|
var isMate = opts.isMate || false;
|
|
210
221
|
var mateId = opts.mateId || (isMate ? path.basename(cwd) : null);
|
|
@@ -395,6 +406,49 @@ function createProjectContext(opts) {
|
|
|
395
406
|
}
|
|
396
407
|
}
|
|
397
408
|
|
|
409
|
+
// Update version metadata goes only to admin-grade connections, and only to
|
|
410
|
+
// those not currently snoozing this exact version. Both decisions come from
|
|
411
|
+
// update-snooze.js; this loop owns nothing but the client set.
|
|
412
|
+
function broadcastUpdateAvailable(version) {
|
|
413
|
+
if (!version) return;
|
|
414
|
+
var now = Date.now();
|
|
415
|
+
var payload = JSON.stringify({ type: "update_available", version: version });
|
|
416
|
+
for (var ws of clients) {
|
|
417
|
+
if (ws.readyState !== 1) continue;
|
|
418
|
+
if (!updateSnooze.isUpdateAdmin(ws, usersModule)) continue;
|
|
419
|
+
var key = updateSnooze.userKeyFor(ws, usersModule);
|
|
420
|
+
if (updateSnooze.isSnoozed(key, version, now)) continue;
|
|
421
|
+
ws.send(payload);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// The install lifecycle frame. Every client needs it, because the daemon is
|
|
426
|
+
// about to restart and the UI blocks the screen — but only admin-grade
|
|
427
|
+
// connections get the version with it. Non-admins get the same frame minus
|
|
428
|
+
// the metadata, so behaviour is unchanged for them and nothing leaks.
|
|
429
|
+
function broadcastUpdateStarted(version) {
|
|
430
|
+
var withVersion = JSON.stringify({ type: "update_started", version: version || "" });
|
|
431
|
+
var withoutVersion = JSON.stringify({ type: "update_started" });
|
|
432
|
+
for (var ws of clients) {
|
|
433
|
+
if (ws.readyState !== 1) continue;
|
|
434
|
+
ws.send(updateSnooze.isUpdateAdmin(ws, usersModule) ? withVersion : withoutVersion);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Tell every live connection of one user that a snooze took effect, so the
|
|
439
|
+
// banner clears on their other devices too rather than only where it was
|
|
440
|
+
// dismissed. Scoped by the same server-derived key the snooze was stored
|
|
441
|
+
// under, never by anything in a payload.
|
|
442
|
+
function sendToUpdateUser(userKey, obj) {
|
|
443
|
+
if (!userKey) return;
|
|
444
|
+
var data = JSON.stringify(obj);
|
|
445
|
+
for (var ws of clients) {
|
|
446
|
+
if (ws.readyState !== 1) continue;
|
|
447
|
+
if (updateSnooze.userKeyFor(ws, usersModule) !== userKey) continue;
|
|
448
|
+
ws.send(data);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
398
452
|
function broadcastClientCount() {
|
|
399
453
|
var msg = { type: "client_count", count: clients.size };
|
|
400
454
|
if (usersModule.isMultiUser()) {
|
|
@@ -624,6 +678,31 @@ function createProjectContext(opts) {
|
|
|
624
678
|
isMate: isMate,
|
|
625
679
|
mateId: mateId,
|
|
626
680
|
});
|
|
681
|
+
var _logFeedbackDelivery = attachProjectLogFeedbackDelivery({
|
|
682
|
+
sm: sm,
|
|
683
|
+
getSdk: function () { return sdk; },
|
|
684
|
+
onProcessingChanged: onProcessingChanged,
|
|
685
|
+
getLinuxUserForSession: getLinuxUserForSession,
|
|
686
|
+
});
|
|
687
|
+
var _projectLogs = attachProjectLogs({
|
|
688
|
+
service: opts.projectLogsService || null,
|
|
689
|
+
sm: sm,
|
|
690
|
+
projectSlug: slug,
|
|
691
|
+
getProjectOwnerId: function () { return projectOwnerId; },
|
|
692
|
+
isMate: isMate,
|
|
693
|
+
mateId: mateId,
|
|
694
|
+
sendTo: sendTo,
|
|
695
|
+
getClients: function () { return clients; },
|
|
696
|
+
onFeedback: _logFeedbackDelivery.deliver,
|
|
697
|
+
});
|
|
698
|
+
var _mateKnowledge = attachProjectMateKnowledge({
|
|
699
|
+
service: opts.mateKnowledgeService || null,
|
|
700
|
+
sm: sm,
|
|
701
|
+
projectSlug: slug,
|
|
702
|
+
getProjectOwnerId: function () { return projectOwnerId; },
|
|
703
|
+
isMate: isMate,
|
|
704
|
+
mateId: mateId,
|
|
705
|
+
});
|
|
627
706
|
|
|
628
707
|
// The SDK bridge is created after local MCP servers. Session spawning uses
|
|
629
708
|
// a getter so tool handlers see the initialized bridge when they run.
|
|
@@ -739,6 +818,27 @@ function createProjectContext(opts) {
|
|
|
739
818
|
}
|
|
740
819
|
}
|
|
741
820
|
|
|
821
|
+
// Project Logs. Project sessions get the project-scoped set; Mate projects
|
|
822
|
+
// get the read-only cross-project set only when the Mate registry confirms
|
|
823
|
+
// authoritative builtin Clay.
|
|
824
|
+
try {
|
|
825
|
+
var projectLogsMcpConfig = _projectLogs.createMcpServer(adapter, null);
|
|
826
|
+
if (projectLogsMcpConfig) servers[projectLogsMcpConfig.name || "clay-logs"] = projectLogsMcpConfig;
|
|
827
|
+
} catch (e) {
|
|
828
|
+
console.error("[project] Failed to create clay-logs MCP server:", e.message);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
// Mate Knowledge. Mate projects only; the registry decides whether this is
|
|
832
|
+
// one Mate's own scope or authoritative Clay's cross-Mate read view.
|
|
833
|
+
if (isMate) {
|
|
834
|
+
try {
|
|
835
|
+
var mateKnowledgeMcpConfig = _mateKnowledge.createMcpServer(adapter, null);
|
|
836
|
+
if (mateKnowledgeMcpConfig) servers[mateKnowledgeMcpConfig.name || "clay-knowledge"] = mateKnowledgeMcpConfig;
|
|
837
|
+
} catch (e) {
|
|
838
|
+
console.error("[project] Failed to create clay-knowledge MCP server:", e.message);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
742
842
|
// Session-bound access to the source of a handoff (main projects only).
|
|
743
843
|
if (!isMate) {
|
|
744
844
|
try {
|
|
@@ -903,6 +1003,24 @@ function createProjectContext(opts) {
|
|
|
903
1003
|
}
|
|
904
1004
|
continue;
|
|
905
1005
|
}
|
|
1006
|
+
if (name === "clay-logs" && forSession) {
|
|
1007
|
+
try {
|
|
1008
|
+
var boundLogs = _projectLogs.createMcpServer(adapter, forSession);
|
|
1009
|
+
if (boundLogs) { filtered[name] = boundLogs; hasAny = true; }
|
|
1010
|
+
} catch (e) {
|
|
1011
|
+
console.error("[project] Failed to bind clay-logs MCP server:", e.message);
|
|
1012
|
+
}
|
|
1013
|
+
continue;
|
|
1014
|
+
}
|
|
1015
|
+
if (name === "clay-knowledge" && forSession) {
|
|
1016
|
+
try {
|
|
1017
|
+
var boundKnowledge = _mateKnowledge.createMcpServer(adapter, forSession);
|
|
1018
|
+
if (boundKnowledge) { filtered[name] = boundKnowledge; hasAny = true; }
|
|
1019
|
+
} catch (e) {
|
|
1020
|
+
console.error("[project] Failed to bind clay-knowledge MCP server:", e.message);
|
|
1021
|
+
}
|
|
1022
|
+
continue;
|
|
1023
|
+
}
|
|
906
1024
|
if (name === "clay-tools" && forSession) {
|
|
907
1025
|
try {
|
|
908
1026
|
var boundToolControl = createToolControlMcpServer();
|
|
@@ -992,6 +1110,9 @@ function createProjectContext(opts) {
|
|
|
992
1110
|
clayPort: serverPort,
|
|
993
1111
|
clayTls: serverTls,
|
|
994
1112
|
clayAuthToken: serverAuthToken,
|
|
1113
|
+
getWorkerPermissionRouter: function () {
|
|
1114
|
+
return isMate ? null : _sessionPair.workerPermission;
|
|
1115
|
+
},
|
|
995
1116
|
onProcessingChanged: onProcessingChanged,
|
|
996
1117
|
onTurnDone: function (session, preview) {
|
|
997
1118
|
if (isMate) digestDmTurn(session, preview);
|
|
@@ -1021,6 +1142,8 @@ function createProjectContext(opts) {
|
|
|
1021
1142
|
_sessionHandoff.getSystemPrompt(session),
|
|
1022
1143
|
_sessionDocument.getSystemPrompt(session),
|
|
1023
1144
|
_capsuleCatalog.getSystemPrompt(session),
|
|
1145
|
+
_projectLogs.getSystemPrompt(session),
|
|
1146
|
+
_mateKnowledge.getSystemPrompt(session),
|
|
1024
1147
|
]);
|
|
1025
1148
|
},
|
|
1026
1149
|
getRuntimeEnv: getRuntimeEnvForSession,
|
|
@@ -1035,7 +1158,9 @@ function createProjectContext(opts) {
|
|
|
1035
1158
|
.concat(_debateProposal.getToolDefs(session))
|
|
1036
1159
|
.concat(_mateCreationProposal.getToolDefs(session))
|
|
1037
1160
|
.concat(_workspaceQuery.getDynamicToolDefs(session))
|
|
1038
|
-
.concat(_workspaceQuery.getHistoryDynamicToolDefs(session))
|
|
1161
|
+
.concat(_workspaceQuery.getHistoryDynamicToolDefs(session))
|
|
1162
|
+
.concat(_projectLogs.getDynamicToolDefs(session))
|
|
1163
|
+
.concat(_mateKnowledge.getDynamicToolDefs(session));
|
|
1039
1164
|
},
|
|
1040
1165
|
});
|
|
1041
1166
|
|
|
@@ -1081,7 +1206,7 @@ function createProjectContext(opts) {
|
|
|
1081
1206
|
fetchVersion(updateChannel).then(function (v) {
|
|
1082
1207
|
if (v && isNewer(v, currentVersion)) {
|
|
1083
1208
|
latestVersion = v;
|
|
1084
|
-
if (broadcast)
|
|
1209
|
+
if (broadcast) broadcastUpdateAvailable(v);
|
|
1085
1210
|
}
|
|
1086
1211
|
}).catch(function (e) {
|
|
1087
1212
|
console.error("[project] Background version check failed:", e.message || e);
|
|
@@ -1169,6 +1294,12 @@ function createProjectContext(opts) {
|
|
|
1169
1294
|
}
|
|
1170
1295
|
|
|
1171
1296
|
function handleMessage(ws, msg) {
|
|
1297
|
+
// --- Keep-alive (delegated to project-connection.js) ---
|
|
1298
|
+
// Answered before any routing so a ping can never be forwarded elsewhere.
|
|
1299
|
+
// _connection is assigned later in this factory than the other modules, so
|
|
1300
|
+
// the reference is guarded rather than assumed.
|
|
1301
|
+
if (_connection && _connection.handleKeepaliveMessage(ws, msg)) return;
|
|
1302
|
+
|
|
1172
1303
|
if (ws._clayHomeDebateSlug && ws._clayHomeDebateSlug !== slug && /^debate_(hand_raise|comment|stop|conclude_response|user_floor_response)$/.test(msg.type || "") && opts.getProject) {
|
|
1173
1304
|
var homeDebateCtx = opts.getProject(ws._clayHomeDebateSlug);
|
|
1174
1305
|
if (homeDebateCtx) homeDebateCtx.handleMessage(ws, msg);
|
|
@@ -1188,11 +1319,11 @@ function createProjectContext(opts) {
|
|
|
1188
1319
|
if (typeof opts.onDmMessage === "function") opts.onDmMessage(ws, msg);
|
|
1189
1320
|
return;
|
|
1190
1321
|
}
|
|
1191
|
-
if (msg.type === "home_clay_ask" || msg.type === "home_clay_session_resolve") {
|
|
1322
|
+
if (msg.type === "home_clay_ask" || msg.type === "home_clay_session_resolve" || msg.type === "home_clay_log_resolve") {
|
|
1192
1323
|
if (typeof opts.onDmMessage === "function") opts.onDmMessage(ws, msg, slug);
|
|
1193
1324
|
return;
|
|
1194
1325
|
}
|
|
1195
|
-
if (msg.type === "project_assignment_response" || msg.type === "dm_open" || msg.type === "dm_send" || msg.type === "dm_list" || msg.type === "dm_typing" || msg.type === "dm_add_favorite" || msg.type === "dm_remove_favorite" || msg.type === "mate_create" || msg.type === "mate_list" || msg.type === "mate_delete" || msg.type === "mate_update" || msg.type === "mate_readd_builtin" || msg.type === "mate_list_available_builtins" || msg.type === "email_accounts_list" || msg.type === "email_account_add" || msg.type === "email_account_remove" || msg.type === "email_account_test" || msg.type === "home_debates_list" || msg.type === "home_mate_present" || msg.type === "home_mate_open" || msg.type === "home_mate_sessions_list" || msg.type === "home_mate_session_open" || msg.type === "home_mate_send" || msg.type === "home_mate_new_session" || msg.type === "home_mate_debate_plan" || msg.type === "home_debate_proposal_response" || msg.type === "home_mate_creation_plan" || msg.type === "home_mate_creation_proposal_response" || msg.type === "home_mate_close" || msg.type === "home_mate_memory_list" || msg.type === "home_mate_knowledge_list" || msg.type === "home_mate_models_get" || msg.type === "home_mate_model_set" || msg.type === "home_dock_get" || msg.type === "home_dock_set" || msg.type === "home_surface_get" || msg.type === "home_surface_set" || msg.type === "tools_list" || msg.type === "tool_get" || msg.type === "tool_install" || msg.type === "tool_remove" || msg.type === "tool_storage_op" || msg.type === "tool_llm_op" || msg.type === "tool_llm_config_get" || msg.type === "tool_control_response" || msg.type === "tool_source_get" || msg.type === "tool_mate_access_set") {
|
|
1326
|
+
if (msg.type === "project_assignment_response" || msg.type === "dm_open" || msg.type === "dm_send" || msg.type === "dm_list" || msg.type === "dm_typing" || msg.type === "dm_add_favorite" || msg.type === "dm_remove_favorite" || msg.type === "mate_create" || msg.type === "mate_list" || msg.type === "mate_delete" || msg.type === "mate_update" || msg.type === "mate_readd_builtin" || msg.type === "mate_list_available_builtins" || msg.type === "email_accounts_list" || msg.type === "email_account_add" || msg.type === "email_account_remove" || msg.type === "email_account_test" || msg.type === "home_debates_list" || msg.type === "home_mate_present" || msg.type === "home_mate_open" || msg.type === "home_mate_sessions_list" || msg.type === "home_mate_session_open" || msg.type === "home_mate_send" || msg.type === "home_mate_new_session" || msg.type === "home_mate_debate_plan" || msg.type === "home_debate_proposal_response" || msg.type === "home_mate_creation_plan" || msg.type === "home_mate_creation_proposal_response" || msg.type === "home_mate_close" || msg.type === "home_mate_memory_list" || msg.type === "home_mate_knowledge_list" || msg.type === "home_mate_models_get" || msg.type === "home_mate_model_set" || msg.type === "home_dock_get" || msg.type === "home_dock_set" || msg.type === "home_surface_get" || msg.type === "home_surface_set" || msg.type === "tools_list" || msg.type === "tool_get" || msg.type === "tool_install" || msg.type === "tool_remove" || msg.type === "tool_storage_op" || msg.type === "tool_llm_op" || msg.type === "tool_llm_config_get" || msg.type === "tool_control_response" || msg.type === "tool_source_get" || msg.type === "tool_mate_access_set" || msg.type === "tool_server_control" || msg.type === "tool_frame_url") {
|
|
1196
1327
|
if (typeof opts.onDmMessage === "function") {
|
|
1197
1328
|
opts.onDmMessage(ws, msg, slug);
|
|
1198
1329
|
}
|
|
@@ -1266,6 +1397,9 @@ function createProjectContext(opts) {
|
|
|
1266
1397
|
// --- Knowledge file management (delegated to project-knowledge.js) ---
|
|
1267
1398
|
if (_knowledge.handleKnowledgeMessage(ws, msg)) return;
|
|
1268
1399
|
|
|
1400
|
+
// --- Project Logs (delegated to project-logs.js) ---
|
|
1401
|
+
if (_projectLogs.handleLogsMessage(ws, msg)) return;
|
|
1402
|
+
|
|
1269
1403
|
// --- Notifications (delegated to project-notifications.js) ---
|
|
1270
1404
|
if (_notifications.handleNotificationMessage(ws, msg)) return;
|
|
1271
1405
|
|
|
@@ -1468,6 +1602,9 @@ function createProjectContext(opts) {
|
|
|
1468
1602
|
send: send,
|
|
1469
1603
|
sendTo: sendTo,
|
|
1470
1604
|
sendToAdmins: sendToAdmins,
|
|
1605
|
+
broadcastUpdateAvailable: broadcastUpdateAvailable,
|
|
1606
|
+
broadcastUpdateStarted: broadcastUpdateStarted,
|
|
1607
|
+
sendToUpdateUser: sendToUpdateUser,
|
|
1471
1608
|
sendToSession: sendToSession,
|
|
1472
1609
|
sendToSessionOthers: sendToSessionOthers,
|
|
1473
1610
|
opts: opts,
|
|
@@ -1477,6 +1614,7 @@ function createProjectContext(opts) {
|
|
|
1477
1614
|
matesModule: matesModule,
|
|
1478
1615
|
pushModule: pushModule,
|
|
1479
1616
|
getSessionForWs: getSessionForWs,
|
|
1617
|
+
onHumanPairStop: function (session) { return _sessionPair.handleHumanStop(session); },
|
|
1480
1618
|
getLinuxUserForSession: getLinuxUserForSession,
|
|
1481
1619
|
ensureProjectAccessForSession: ensureProjectAccessForSession,
|
|
1482
1620
|
getOsUserInfoForWs: getOsUserInfoForWs,
|
|
@@ -1530,6 +1668,16 @@ function createProjectContext(opts) {
|
|
|
1530
1668
|
return _models.resolveConfiguredModel({ _clayUser: user || null }, "standard");
|
|
1531
1669
|
},
|
|
1532
1670
|
});
|
|
1671
|
+
var _capsuleTurn = attachCapsuleTurn({
|
|
1672
|
+
sm: sm,
|
|
1673
|
+
getSdk: function () { return sdk; },
|
|
1674
|
+
getLinuxUserForSession: getLinuxUserForSession,
|
|
1675
|
+
isMultiUser: function () { return usersModule.isMultiUser(); },
|
|
1676
|
+
resolveModel: function (principal) {
|
|
1677
|
+
var user = principal && principal.userId ? usersModule.findUserById(principal.userId) : null;
|
|
1678
|
+
return _models.resolveConfiguredModel({ _clayUser: user || null }, "standard");
|
|
1679
|
+
},
|
|
1680
|
+
});
|
|
1533
1681
|
var _delegatedFollowUp = attachDelegatedFollowUp({
|
|
1534
1682
|
sm: sm,
|
|
1535
1683
|
getSdk: function () { return sdk; },
|
|
@@ -1546,6 +1694,13 @@ function createProjectContext(opts) {
|
|
|
1546
1694
|
|
|
1547
1695
|
// --- User message handler (delegated to project-user-message.js) ---
|
|
1548
1696
|
var _userMessage = attachUserMessage({
|
|
1697
|
+
// Exact live pair state decides whether a session is Driver-operated; the
|
|
1698
|
+
// handler never infers the role from the message.
|
|
1699
|
+
isDriverOperatedSession: function (session) {
|
|
1700
|
+
if (isMate || !_sessionPair.workerPermission) return false;
|
|
1701
|
+
return _sessionPair.workerPermission.isDriverOperated(session);
|
|
1702
|
+
},
|
|
1703
|
+
beginHumanPairTurn: function (session) { return _sessionPair.beginHumanTurn(session); },
|
|
1549
1704
|
cwd: cwd,
|
|
1550
1705
|
slug: slug,
|
|
1551
1706
|
isMate: isMate,
|
|
@@ -1610,6 +1765,7 @@ function createProjectContext(opts) {
|
|
|
1610
1765
|
getOsUserInfoForWs: getOsUserInfoForWs,
|
|
1611
1766
|
getOsUserInfoForLinuxUser: getOsUserInfoForLinuxUser,
|
|
1612
1767
|
getLinuxUserForSession: getLinuxUserForSession,
|
|
1768
|
+
refreshVendorAuthEverywhere: opts.refreshVendorAuthEverywhere,
|
|
1613
1769
|
});
|
|
1614
1770
|
|
|
1615
1771
|
// --- Filesystem handler (delegated to project-filesystem.js) ---
|
|
@@ -1733,6 +1889,10 @@ function createProjectContext(opts) {
|
|
|
1733
1889
|
for (var wqti = 0; wqti < workspaceTools.length; wqti++) tools.push(workspaceTools[wqti]);
|
|
1734
1890
|
var historyTools = _workspaceQuery.getHistoryBridgeTools(boundSession, normalizeToolSchema);
|
|
1735
1891
|
for (var cht = 0; cht < historyTools.length; cht++) tools.push(historyTools[cht]);
|
|
1892
|
+
var logsTools = _projectLogs.getBridgeTools(boundSession, normalizeToolSchema);
|
|
1893
|
+
for (var plti = 0; plti < logsTools.length; plti++) tools.push(logsTools[plti]);
|
|
1894
|
+
var knowledgeTools = _mateKnowledge.getBridgeTools(boundSession, normalizeToolSchema);
|
|
1895
|
+
for (var mkti = 0; mkti < knowledgeTools.length; mkti++) tools.push(knowledgeTools[mkti]);
|
|
1736
1896
|
}
|
|
1737
1897
|
|
|
1738
1898
|
if (sessionOnly) return Promise.resolve(tools);
|
|
@@ -1748,7 +1908,7 @@ function createProjectContext(opts) {
|
|
|
1748
1908
|
// Debate tools were added above only when this request had an
|
|
1749
1909
|
// exact session. Never duplicate them or advertise the static,
|
|
1750
1910
|
// intentionally unbound proposal server.
|
|
1751
|
-
if (inAppNames[i] === "clay-debate" || inAppNames[i] === "clay-mate-creation" || inAppNames[i] === "clay-workspace" || inAppNames[i] === "clay-history") continue;
|
|
1911
|
+
if (inAppNames[i] === "clay-debate" || inAppNames[i] === "clay-mate-creation" || inAppNames[i] === "clay-workspace" || inAppNames[i] === "clay-history" || inAppNames[i] === "clay-logs" || inAppNames[i] === "clay-knowledge") continue;
|
|
1752
1912
|
extractServerTools(inAppNames[i], localMcp[inAppNames[i]]);
|
|
1753
1913
|
}
|
|
1754
1914
|
}
|
|
@@ -1811,7 +1971,13 @@ function createProjectContext(opts) {
|
|
|
1811
1971
|
if (boundSession && serverName === "clay-history") {
|
|
1812
1972
|
return _workspaceQuery.callHistoryBridgeTool(boundSession, toolName, args);
|
|
1813
1973
|
}
|
|
1814
|
-
if (
|
|
1974
|
+
if (boundSession && serverName === "clay-logs") {
|
|
1975
|
+
return _projectLogs.callBridgeTool(boundSession, toolName, args);
|
|
1976
|
+
}
|
|
1977
|
+
if (boundSession && serverName === "clay-knowledge") {
|
|
1978
|
+
return _mateKnowledge.callBridgeTool(boundSession, toolName, args);
|
|
1979
|
+
}
|
|
1980
|
+
if (serverName === "clay-sessions" || serverName === "clay-notes" || serverName === "clay-handoff" || serverName === "clay-documents" || serverName === "clay-debate" || serverName === "clay-mate-creation" || serverName === "clay-workspace" || serverName === "clay-history" || serverName === "clay-logs" || serverName === "clay-knowledge") {
|
|
1815
1981
|
return Promise.reject(new Error("Session-bound tool requires a valid Clay session: " + serverName + "/" + toolName));
|
|
1816
1982
|
}
|
|
1817
1983
|
if (sessionOnly) return Promise.reject(new Error("Session tool not found: " + serverName + "/" + toolName));
|
|
@@ -2023,6 +2189,7 @@ function createProjectContext(opts) {
|
|
|
2023
2189
|
isProcessing: hasProcessing,
|
|
2024
2190
|
pendingPermissions: pendingPermCount,
|
|
2025
2191
|
projectOwnerId: projectOwnerId,
|
|
2192
|
+
projectKnowledgeId: projectKnowledgeId,
|
|
2026
2193
|
};
|
|
2027
2194
|
if (isMate) {
|
|
2028
2195
|
status.isMate = true;
|
|
@@ -2032,6 +2199,9 @@ function createProjectContext(opts) {
|
|
|
2032
2199
|
status.isWorktree = true;
|
|
2033
2200
|
status.parentSlug = worktreeMeta.parentSlug;
|
|
2034
2201
|
status.branch = worktreeMeta.branch;
|
|
2202
|
+
status.changeSetId = worktreeMeta.changeSetId || null;
|
|
2203
|
+
status.baseCommit = worktreeMeta.baseCommit || null;
|
|
2204
|
+
status.headCommit = worktreeMeta.headCommit || null;
|
|
2035
2205
|
status.worktreeExternal = worktreeMeta.external === true;
|
|
2036
2206
|
}
|
|
2037
2207
|
if (usersModule.isMultiUser()) {
|
|
@@ -2130,6 +2300,7 @@ function createProjectContext(opts) {
|
|
|
2130
2300
|
createDelegatedSession: _delegatedSession.createDelegatedSession,
|
|
2131
2301
|
inspectDelegatedFollowUp: _delegatedFollowUp.inspectDelegatedFollowUp,
|
|
2132
2302
|
dispatchDelegatedFollowUp: _delegatedFollowUp.dispatchDelegatedFollowUp,
|
|
2303
|
+
deliverCapsuleTurn: _capsuleTurn.deliverCapsuleTurn,
|
|
2133
2304
|
unregisterHomeDebateClient: function (ws) { homeDebateClients.delete(ws); },
|
|
2134
2305
|
handleHomeDebateProposalResponse: function (ws, msg, session) { return _debateProposal.handleHomeMessage(ws, msg, session); },
|
|
2135
2306
|
handleHomeMateCreationProposalResponse: function (ws, msg, session) { return _mateCreationProposal.handleHomeMessage(ws, msg, session); },
|
|
@@ -2141,6 +2312,7 @@ function createProjectContext(opts) {
|
|
|
2141
2312
|
listKnowledgeFiles: _knowledge.listKnowledgeFiles,
|
|
2142
2313
|
refreshCapsuleCatalog: _capsuleCatalog.refreshSessions,
|
|
2143
2314
|
getNotificationsModule: function () { return _notifications; },
|
|
2315
|
+
refreshVendorAuth: _vendorLogin.refreshVendorAuth,
|
|
2144
2316
|
getSchedules: _loop.getSchedules,
|
|
2145
2317
|
importSchedule: _loop.importSchedule,
|
|
2146
2318
|
removeSchedule: _loop.removeSchedule,
|
package/lib/public/app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { avatarUrl, userAvatarUrl, mateAvatarUrl } from './modules/avatar.js';
|
|
2
|
-
import { showToast,
|
|
2
|
+
import { showToast, escapeHtml } from './modules/utils.js';
|
|
3
3
|
import { refreshIcons, iconHtml } from './modules/icons.js';
|
|
4
4
|
import { renderMarkdown, highlightCodeBlocks, renderMermaidBlocks, closeMermaidModal, parseEmojis } from './modules/markdown.js';
|
|
5
5
|
import { initSidebar, updatePageTitle, spawnDustParticles } from './modules/sidebar.js';
|
|
@@ -27,9 +27,11 @@ import { initInput, clearPendingImages, handleInputSync, autoResize, builtinComm
|
|
|
27
27
|
import { initQrCode, triggerShare } from './modules/qrcode.js';
|
|
28
28
|
import { initFileBrowser, loadRootDirectory, refreshTree, handleFsList, handleFsRead, handleDirChanged, refreshIfOpen, handleFileChanged, handleFileHistory, handleGitDiff, handleFileAt, getPendingNavigate, closeFileViewer, resetFileBrowser } from './modules/filebrowser.js';
|
|
29
29
|
import { initGitPanel } from './modules/git-panel.js';
|
|
30
|
+
import { initWorkerPaneLock } from './modules/worker-pane-lock.js';
|
|
30
31
|
import { initTerminal, openTerminal, closeTerminal, resetTerminals, handleTermList, handleTermCreated, handleTermOutput, handleTermResized, handleTermExited, handleTermClosed, sendTerminalCommand } from './modules/terminal.js';
|
|
31
32
|
import { initContextSources, updateTerminalList, updateBrowserTabList, handleContextSourcesState, getActiveSources, hasActiveSources } from './modules/context-sources.js';
|
|
32
|
-
import { initStickyNotes, handleNotesList, handleNoteCreated, handleNoteUpdated, handleNoteDeleted,
|
|
33
|
+
import { initStickyNotes, handleNotesList, handleNoteCreated, handleNoteUpdated, handleNoteDeleted, hideNotes, showNotes, isNotesVisible, createNote, setBrowserRefresh } from './modules/sticky-notes.js';
|
|
34
|
+
import { initNotesBrowser, openNotesBrowser, closeNotesBrowser, isNotesBrowserOpen, renderNotesBrowser, registerExclusiveClosers } from './modules/sticky-notes-browser.js';
|
|
33
35
|
import { initTheme, getThemeColor, getComputedVar, onThemeChange, getCurrentTheme, getChatLayout } from './modules/theme.js';
|
|
34
36
|
import { initTools, resetToolState, saveToolState, restoreToolState, renderAskUserQuestion, markAskUserAnswered, renderPermissionRequest, markPermissionResolved, markPermissionCancelled, renderElicitationRequest, markElicitationResolved, renderPlanBanner, renderPlanCard, handleTodoWrite, handleTaskCreate, handleTaskUpdate, startThinking, appendThinking, stopThinking, resetThinkingGroup, createToolItem, updateToolExecuting, updateToolResult, markAllToolsDone, addTurnMeta, resetTurnMetaCost, enableMainInput, getTools, getPlanContent, setPlanContent, isPlanFilePath, getTodoTools, updateSubagentActivity, addSubagentToolEntry, markSubagentDone, updateSubagentProgress, initSubagentStop, closeToolGroup, removeToolFromGroup } from './modules/tools.js';
|
|
35
37
|
import { initServerSettings, updateSettingsStats, updateDaemonConfig, handleSetPinResult, handleKeepAwakeChanged, handleAutoContinueChanged, handleRestartResult, handleShutdownResult, handleSharedEnv, handleSharedEnvSaved, handleGlobalClaudeMdRead, handleGlobalClaudeMdWrite } from './modules/server-settings.js';
|
|
@@ -42,6 +44,7 @@ import { initSTT } from './modules/stt.js';
|
|
|
42
44
|
import { initProfile, getProfileLang } from './modules/profile.js';
|
|
43
45
|
import { initUserSettings } from './modules/user-settings.js';
|
|
44
46
|
import { initToolPalettes } from './modules/tool-palette.js';
|
|
47
|
+
import { initProjectLogs, closeProjectLogs } from './modules/project-logs.js';
|
|
45
48
|
import { initProjectSwitcher } from './modules/project-switcher.js';
|
|
46
49
|
import { initSplitView } from './modules/split-view.js';
|
|
47
50
|
import { initPaneBridge } from './modules/pane-bridge.js';
|
|
@@ -64,7 +67,8 @@ import { initCursors, handleRemoteCursorMove as _curHandleRemoteCursorMove, hand
|
|
|
64
67
|
import { initFavicon, updateFavicon as _favUpdateFavicon, setSendBtnMode as _favSetSendBtnMode, blinkIO as _favBlinkIO, blinkSessionDot as _favBlinkSessionDot, updateCrossProjectBlink as _favUpdateCrossProjectBlink, startUrgentBlink as _favStartUrgentBlink, stopUrgentBlink as _favStopUrgentBlink, setActivity as _favSetActivity } from './modules/app-favicon.js';
|
|
65
68
|
import { initHeader, closeSessionInfoPopover as _hdrCloseSessionInfoPopover, updateHistorySentinel as _hdrUpdateHistorySentinel, requestMoreHistory as _hdrRequestMoreHistory, prependOlderHistory as _hdrPrependOlderHistory } from './modules/app-header.js';
|
|
66
69
|
import { initSessionActions } from './modules/session-actions.js';
|
|
67
|
-
import { initMisc, flushPendingExtMessages, showImageModal as _miscShowImageModal, closeImageModal as _miscCloseImageModal,
|
|
70
|
+
import { initMisc, flushPendingExtMessages, showImageModal as _miscShowImageModal, closeImageModal as _miscCloseImageModal, showConfirm as _miscShowConfirm, hideConfirm as _miscHideConfirm, showForceChangePinOverlay as _miscShowForceChangePinOverlay, sendExtensionCommand as _miscSendExtensionCommand, handleExtensionResult as _miscHandleExtensionResult } from './modules/app-misc.js';
|
|
71
|
+
import { showPasteModal } from './modules/paste-modal.js';
|
|
68
72
|
import { initSkillInstall, requireSkills as _siRequireSkills, handleSkillInstallWs as _siHandleSkillInstallWs } from './modules/app-skills-install.js';
|
|
69
73
|
import { initDebateUi, showDebateConcludeConfirm as _debShowDebateConcludeConfirm, exitDebateConcludeMode as _debExitDebateConcludeMode, handleDebateConcludeSend as _debHandleDebateConcludeSend, showDebateEndedMode as _debShowDebateEndedMode, exitDebateEndedMode as _debExitDebateEndedMode, showDebateUserFloor as _debShowDebateUserFloor, exitDebateFloorMode as _debExitDebateFloorMode, handleDebateFloorSend as _debHandleDebateFloorSend, renderDebateUserFloorDone as _debRenderDebateUserFloorDone, showDebateSticky as _debShowDebateSticky, showDebateBottomBar as _debShowDebateBottomBar, removeDebateBottomBar as _debRemoveDebateBottomBar, sendDebateStickyComment as _debSendDebateStickyComment, updateDebateRound as _debUpdateDebateRound } from './modules/app-debate-ui.js';
|
|
70
74
|
import { initLoopUi, updateLoopInputVisibility as _loopUpdateLoopInputVisibility, updateLoopButton as _loopUpdateLoopButton, showLoopBanner as _loopShowLoopBanner, updateLoopBanner as _loopUpdateLoopBanner, updateRalphBars as _loopUpdateRalphBars, showRalphCraftingBar as _loopShowRalphCraftingBar, showRalphApprovalBar as _loopShowRalphApprovalBar, updateRalphApprovalStatus as _loopUpdateRalphApprovalStatus, openRalphPreviewModal as _loopOpenRalphPreviewModal, showExecModal as _loopShowExecModal, closeExecModal as _loopCloseExecModal, updateExecModalStatus as _loopUpdateExecModalStatus } from './modules/app-loop-ui.js';
|
|
@@ -203,16 +207,6 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
203
207
|
}
|
|
204
208
|
|
|
205
209
|
// Modal close handlers (replaces inline onclick)
|
|
206
|
-
$("paste-modal").querySelector(".confirm-backdrop").addEventListener("click", function() {
|
|
207
|
-
$("paste-modal").classList.add("hidden");
|
|
208
|
-
});
|
|
209
|
-
$("paste-modal").querySelector(".paste-modal-close").addEventListener("click", function() {
|
|
210
|
-
$("paste-modal").classList.add("hidden");
|
|
211
|
-
});
|
|
212
|
-
$("paste-modal").querySelector(".paste-modal-copy").addEventListener("click", function() {
|
|
213
|
-
var body = $("paste-modal-body");
|
|
214
|
-
if (body) copyToClipboard(body.textContent, "Copied to clipboard");
|
|
215
|
-
});
|
|
216
210
|
$("mermaid-modal").querySelector(".confirm-backdrop").addEventListener("click", closeMermaidModal);
|
|
217
211
|
$("mermaid-modal").querySelector(".mermaid-modal-btn[title='Close']").addEventListener("click", closeMermaidModal);
|
|
218
212
|
$("image-modal").querySelector(".confirm-backdrop").addEventListener("click", closeImageModal);
|
|
@@ -260,9 +254,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
260
254
|
// --- Header session rename, session info popover -> modules/app-header.js
|
|
261
255
|
function closeSessionInfoPopover() { _hdrCloseSessionInfoPopover(); }
|
|
262
256
|
|
|
263
|
-
// ---
|
|
264
|
-
function showPasteModal(text) { _miscShowPasteModal(text); }
|
|
265
|
-
function closePasteModal() { _miscClosePasteModal(); }
|
|
257
|
+
// --- Confirmation modal -> modules/app-misc.js
|
|
266
258
|
function showConfirm(text, onConfirm, okLabel, destructive) { _miscShowConfirm(text, onConfirm, okLabel, destructive); }
|
|
267
259
|
function hideConfirm() { _miscHideConfirm(); }
|
|
268
260
|
|
|
@@ -297,6 +289,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
297
289
|
isHeadlessMode: false,
|
|
298
290
|
savedMainSlug: null,
|
|
299
291
|
connected: false,
|
|
292
|
+
pendingOutboundMessages: [],
|
|
300
293
|
homeChatMateId: null,
|
|
301
294
|
homeChatSessionId: null,
|
|
302
295
|
homeChatSessionModel: null,
|
|
@@ -327,7 +320,27 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
327
320
|
dockWidth: null,
|
|
328
321
|
dockHasActivity: false,
|
|
329
322
|
dockActivityToolId: null,
|
|
323
|
+
projectLogsOpen: false,
|
|
324
|
+
projectLogsWide: false,
|
|
325
|
+
projectLogsFullscreen: false,
|
|
326
|
+
projectLogsEntries: [],
|
|
327
|
+
projectLogsSelectedRef: null,
|
|
328
|
+
projectLogsView: 'list',
|
|
329
|
+
projectLogsCategory: '',
|
|
330
|
+
projectLogsContextMode: '',
|
|
331
|
+
projectLogsIsWorktree: false,
|
|
332
|
+
projectLogsListScroll: 0,
|
|
333
|
+
projectLogsListRequestId: null,
|
|
334
|
+
projectLogsReadRequestId: null,
|
|
335
|
+
projectLogsCommentRequestId: null,
|
|
336
|
+
projectLogsCommentStatusEl: null,
|
|
337
|
+
projectLogsDeleteRequestId: null,
|
|
338
|
+
projectLogsCanDelete: false,
|
|
339
|
+
projectLogsUnread: 0,
|
|
340
|
+
projectLogsSeenRevisions: {},
|
|
330
341
|
installedTools: [],
|
|
342
|
+
capsulesEnabled: false,
|
|
343
|
+
capsulesPreferenceLoaded: false,
|
|
331
344
|
homeToolRegistryLoaded: false,
|
|
332
345
|
toolScanErrors: [],
|
|
333
346
|
|
|
@@ -480,6 +493,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
480
493
|
// buttons exist in the DOM when sidebar.js (and later terminal.js /
|
|
481
494
|
// mcp-ui.js / etc.) attach click handlers by ID.
|
|
482
495
|
initToolPalettes();
|
|
496
|
+
initProjectLogs();
|
|
483
497
|
initSidebar(sidebarCtx);
|
|
484
498
|
var wsGetter = function () { return _getWsRef(); };
|
|
485
499
|
initMateSidebar(wsGetter);
|
|
@@ -772,7 +786,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
772
786
|
if (isHomeHubVisible()) hideHomeHub();
|
|
773
787
|
if (newSlug && newSlug !== store.get('currentSlug')) {
|
|
774
788
|
resetFileBrowser();
|
|
775
|
-
|
|
789
|
+
closeNotesBrowser();
|
|
776
790
|
if (isSchedulerOpen()) closeScheduler();
|
|
777
791
|
resetScheduler(newSlug);
|
|
778
792
|
store.set({ currentSlug: newSlug });
|
|
@@ -944,8 +958,8 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
944
958
|
if (!_perms.fileBrowser) {
|
|
945
959
|
var fbBtn = document.getElementById("file-browser-btn");
|
|
946
960
|
if (fbBtn) fbBtn.style.display = "none";
|
|
947
|
-
var
|
|
948
|
-
if (
|
|
961
|
+
var gitPlacardEl = document.getElementById("git-placard");
|
|
962
|
+
if (gitPlacardEl) gitPlacardEl.style.display = "none";
|
|
949
963
|
}
|
|
950
964
|
if (!_perms.skills) {
|
|
951
965
|
var sBtn = document.getElementById("skills-btn");
|
|
@@ -954,10 +968,10 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
954
968
|
if (msBtn) msBtn.style.display = "none";
|
|
955
969
|
}
|
|
956
970
|
if (!_perms.scheduledTasks) {
|
|
957
|
-
var schBtn = document.getElementById("scheduler-btn");
|
|
971
|
+
var schBtn = document.getElementById("home-scheduler-btn");
|
|
958
972
|
if (schBtn) schBtn.style.display = "none";
|
|
959
|
-
var
|
|
960
|
-
if (
|
|
973
|
+
var schToolBtn = document.getElementById("scheduler-btn");
|
|
974
|
+
if (schToolBtn) schToolBtn.style.display = "none";
|
|
961
975
|
}
|
|
962
976
|
if (!_perms.createProject) {
|
|
963
977
|
var addProjBtn = document.getElementById("icon-strip-add");
|
|
@@ -1036,6 +1050,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1036
1050
|
fileViewerEl: $("file-viewer"),
|
|
1037
1051
|
});
|
|
1038
1052
|
initGitPanel();
|
|
1053
|
+
initWorkerPaneLock();
|
|
1039
1054
|
|
|
1040
1055
|
// --- Terminal ---
|
|
1041
1056
|
initTerminal({
|
|
@@ -1088,17 +1103,24 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1088
1103
|
}
|
|
1089
1104
|
|
|
1090
1105
|
// --- Sticky Notes ---
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1106
|
+
// The canvas reads the socket from ws-ref and the connection flag from the
|
|
1107
|
+
// store directly, so it needs no injected context.
|
|
1108
|
+
initStickyNotes();
|
|
1109
|
+
initNotesBrowser();
|
|
1110
|
+
// The browser refreshes from note messages without the canvas module having
|
|
1111
|
+
// to import it, which would be a cycle.
|
|
1112
|
+
setBrowserRefresh(function () { if (isNotesBrowserOpen()) renderNotesBrowser(); });
|
|
1113
|
+
// Opening the browser claims the single right workbench slot. Registered here
|
|
1114
|
+
// so the browser module never imports the other tools.
|
|
1115
|
+
registerExclusiveClosers([closeProjectLogs, closeScheduler, closeFileViewer, closeTerminal]);
|
|
1095
1116
|
|
|
1096
1117
|
// --- Sticky Notes sidebar button (create new note) ---
|
|
1097
1118
|
var stickyNotesSidebarBtn = $("sticky-notes-sidebar-btn");
|
|
1098
1119
|
if (stickyNotesSidebarBtn) {
|
|
1099
1120
|
stickyNotesSidebarBtn.addEventListener("click", function () {
|
|
1121
|
+
closeProjectLogs();
|
|
1100
1122
|
if (isSchedulerOpen()) closeScheduler();
|
|
1101
|
-
if (
|
|
1123
|
+
if (isNotesBrowserOpen()) closeNotesBrowser();
|
|
1102
1124
|
showNotes();
|
|
1103
1125
|
createNote();
|
|
1104
1126
|
});
|
|
@@ -1109,22 +1131,23 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1109
1131
|
if (stickyNotesBadge) {
|
|
1110
1132
|
stickyNotesBadge.addEventListener("click", function (e) {
|
|
1111
1133
|
e.stopPropagation();
|
|
1134
|
+
closeProjectLogs();
|
|
1112
1135
|
if (isSchedulerOpen()) closeScheduler();
|
|
1113
|
-
if (
|
|
1114
|
-
|
|
1136
|
+
if (isNotesBrowserOpen()) {
|
|
1137
|
+
closeNotesBrowser();
|
|
1115
1138
|
} else {
|
|
1116
|
-
|
|
1139
|
+
openNotesBrowser();
|
|
1117
1140
|
}
|
|
1118
1141
|
});
|
|
1119
1142
|
}
|
|
1120
1143
|
|
|
1121
|
-
// Close
|
|
1144
|
+
// Close the notes browser / scheduler panel when switching to other sidebar panels
|
|
1122
1145
|
var fileBrowserBtn = $("file-browser-btn");
|
|
1123
|
-
var
|
|
1146
|
+
var gitPlacardMoreBtn = $("git-placard-more");
|
|
1124
1147
|
var terminalSidebarBtn = $("terminal-sidebar-btn");
|
|
1125
|
-
if (fileBrowserBtn) fileBrowserBtn.addEventListener("click", function () { if (
|
|
1126
|
-
if (
|
|
1127
|
-
if (terminalSidebarBtn) terminalSidebarBtn.addEventListener("click", function () { if (
|
|
1148
|
+
if (fileBrowserBtn) fileBrowserBtn.addEventListener("click", function () { closeProjectLogs(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
|
|
1149
|
+
if (gitPlacardMoreBtn) gitPlacardMoreBtn.addEventListener("click", function () { closeProjectLogs(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
|
|
1150
|
+
if (terminalSidebarBtn) terminalSidebarBtn.addEventListener("click", function () { closeProjectLogs(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
|
|
1128
1151
|
|
|
1129
1152
|
// --- Ralph Loop UI (delegated to app-loop-ui.js + app-loop-wizard.js) ---
|
|
1130
1153
|
function updateLoopInputVisibility(loop) { _loopUpdateLoopInputVisibility(loop); }
|
package/lib/public/css/admin.css
CHANGED
|
@@ -651,7 +651,7 @@
|
|
|
651
651
|
}
|
|
652
652
|
|
|
653
653
|
/* --- Session visibility indicator --- */
|
|
654
|
-
.session-
|
|
654
|
+
.session-shared-icon {
|
|
655
655
|
display: inline-flex;
|
|
656
656
|
align-items: center;
|
|
657
657
|
margin-right: 4px;
|
|
@@ -659,7 +659,7 @@
|
|
|
659
659
|
vertical-align: middle;
|
|
660
660
|
}
|
|
661
661
|
|
|
662
|
-
.session-
|
|
662
|
+
.session-shared-icon svg {
|
|
663
663
|
width: 12px;
|
|
664
664
|
height: 12px;
|
|
665
665
|
}
|