clay-server 2.32.0-beta.6 → 2.32.0-beta.8
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/codex-defaults.js +18 -0
- package/lib/project-connection.js +5 -4
- package/lib/project-mate-interaction.js +30 -0
- package/lib/project-notifications.js +9 -0
- package/lib/project-sessions.js +7 -6
- package/lib/project.js +29 -9
- package/lib/public/app.js +5 -0
- package/lib/public/css/input.css +146 -3
- package/lib/public/css/notifications-center.css +7 -0
- package/lib/public/css/tooltip.css +47 -0
- package/lib/public/index.html +34 -4
- package/lib/public/modules/app-dm.js +5 -0
- package/lib/public/modules/app-messages.js +5 -4
- package/lib/public/modules/app-notifications.js +42 -26
- package/lib/public/modules/app-panels.js +3 -3
- package/lib/public/modules/context-sources.js +92 -27
- package/lib/public/modules/input.js +36 -0
- package/lib/public/modules/terminal.js +12 -0
- package/lib/public/modules/tools.js +4 -4
- package/lib/public/modules/tooltip.js +32 -5
- package/lib/sdk-bridge.js +7 -3
- package/lib/sdk-message-processor.js +9 -0
- package/lib/sessions.js +24 -2
- package/lib/yoke/adapters/claude.js +13 -0
- package/lib/yoke/adapters/codex.js +119 -8
- package/package.json +1 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
var CODEX_DEFAULTS = {
|
|
2
|
+
approval: "on-failure",
|
|
3
|
+
sandbox: "danger-full-access",
|
|
4
|
+
webSearch: "live",
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
function getCodexConfig(sm) {
|
|
8
|
+
return {
|
|
9
|
+
approval: (sm && sm.codexApproval) || CODEX_DEFAULTS.approval,
|
|
10
|
+
sandbox: (sm && sm.codexSandbox) || CODEX_DEFAULTS.sandbox,
|
|
11
|
+
webSearch: (sm && sm.codexWebSearch) || CODEX_DEFAULTS.webSearch,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
module.exports = {
|
|
16
|
+
CODEX_DEFAULTS: CODEX_DEFAULTS,
|
|
17
|
+
getCodexConfig: getCodexConfig,
|
|
18
|
+
};
|
|
@@ -3,6 +3,7 @@ var path = require("path");
|
|
|
3
3
|
var usersModule = require("./users");
|
|
4
4
|
var userPresence = require("./user-presence");
|
|
5
5
|
var emailAccounts = require("./email-accounts");
|
|
6
|
+
var { getCodexConfig } = require("./codex-defaults");
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Attach connection/disconnection handlers to a project context.
|
|
@@ -84,10 +85,9 @@ function attachConnection(ctx) {
|
|
|
84
85
|
var project = getProject();
|
|
85
86
|
var ownerLocked = !!(osUsers && osUsers.length > 0 && /^\/home\/[^/]+\//.test(cwd));
|
|
86
87
|
sendTo(ws, { type: "info", cwd: cwd, slug: slug, project: title || project, version: currentVersion, debug: !!debug, dangerouslySkipPermissions: dangerouslySkipPermissions, osUsers: osUsers, lanHost: lanHost, projectCount: _filteredProjects.length, projects: _filteredProjects, projectOwnerId: projectOwnerId, ownerLocked: ownerLocked });
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
88
|
+
// Update notifications are pushed on a scheduled interval (see
|
|
89
|
+
// scheduleUpdateBroadcast). We no longer push on connect to avoid
|
|
90
|
+
// re-triggering the banner on every page refresh.
|
|
91
91
|
if (sm.slashCommands) {
|
|
92
92
|
sendTo(ws, { type: "slash_commands", commands: sm.slashCommands });
|
|
93
93
|
}
|
|
@@ -96,6 +96,7 @@ function attachConnection(ctx) {
|
|
|
96
96
|
sendTo(ws, { type: "model_info", model: sm.currentModel, models: sm.availableModels || [], vendor: sm.defaultVendor || "claude", availableVendors: sm.availableVendors || [], installedVendors: sm.installedVendors || [] });
|
|
97
97
|
}
|
|
98
98
|
sendTo(ws, { type: "config_state", model: sm.currentModel || "", mode: sm.currentPermissionMode || "default", effort: sm.currentEffort || "medium", betas: sm.currentBetas || [], thinking: sm.currentThinking || "adaptive", thinkingBudget: sm.currentThinkingBudget || 10000 });
|
|
99
|
+
sendTo(ws, Object.assign({ type: "codex_config" }, getCodexConfig(sm)));
|
|
99
100
|
sendTo(ws, { type: "term_list", terminals: tm.list() });
|
|
100
101
|
// Context sources sent after session is resolved (per-session storage)
|
|
101
102
|
// Send email accounts list for context sources picker
|
|
@@ -4,6 +4,7 @@ var crypto = require("crypto");
|
|
|
4
4
|
|
|
5
5
|
function attachMateInteraction(ctx) {
|
|
6
6
|
var cwd = ctx.cwd;
|
|
7
|
+
var slug = ctx.slug || "";
|
|
7
8
|
var sm = ctx.sm;
|
|
8
9
|
var sdk = ctx.sdk;
|
|
9
10
|
var send = ctx.send;
|
|
@@ -21,6 +22,7 @@ function attachMateInteraction(ctx) {
|
|
|
21
22
|
var loadMateDigests = ctx.loadMateDigests;
|
|
22
23
|
var updateMemorySummary = ctx.updateMemorySummary;
|
|
23
24
|
var initMemorySummary = ctx.initMemorySummary;
|
|
25
|
+
var getNotificationsModule = ctx.getNotificationsModule || function () { return null; };
|
|
24
26
|
// checkForDmDebateBrief is accessed via ctx at call time because
|
|
25
27
|
// it comes from the debate module initialized after this one.
|
|
26
28
|
|
|
@@ -104,6 +106,30 @@ function attachMateInteraction(ctx) {
|
|
|
104
106
|
return lines.join("\n") + "\n\n";
|
|
105
107
|
}
|
|
106
108
|
|
|
109
|
+
function getHostMateId() {
|
|
110
|
+
if (typeof slug === "string" && slug.indexOf("mate-") === 0) {
|
|
111
|
+
return slug.substring(5) || null;
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function notifyMentionResponse(session, mentionMateId, mentionMateName, fullText) {
|
|
117
|
+
var notificationsModule = getNotificationsModule();
|
|
118
|
+
var hostMateId = getHostMateId();
|
|
119
|
+
var preview = (fullText || "").replace(/\s+/g, " ").trim();
|
|
120
|
+
if (preview.length > 140) preview = preview.substring(0, 140) + "...";
|
|
121
|
+
if (!notificationsModule || !hostMateId) return;
|
|
122
|
+
notificationsModule.notify("mention_response", {
|
|
123
|
+
title: (mentionMateName || "Mate") + " responded",
|
|
124
|
+
preview: preview,
|
|
125
|
+
slug: slug,
|
|
126
|
+
sessionId: session.localId,
|
|
127
|
+
mateId: hostMateId,
|
|
128
|
+
avatarMateId: mentionMateId || null,
|
|
129
|
+
ownerId: session.ownerId || null,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
107
133
|
// --- Shared digest worker: one reusable Haiku session for gate+digest ---
|
|
108
134
|
// Combines gate check and digest generation into a single prompt,
|
|
109
135
|
// processes jobs sequentially from a queue, reuses the session across calls.
|
|
@@ -557,6 +583,10 @@ function attachMateInteraction(ctx) {
|
|
|
557
583
|
sendToSession(session.localId, { type: "mention_done", mateId: msg.mateId });
|
|
558
584
|
send({ type: "mention_processing", mateId: msg.mateId, active: false });
|
|
559
585
|
|
|
586
|
+
if (isMate) {
|
|
587
|
+
notifyMentionResponse(session, msg.mateId, mateName, fullText);
|
|
588
|
+
}
|
|
589
|
+
|
|
560
590
|
// Check if the mate wrote a debate brief during this turn
|
|
561
591
|
ctx.checkForDmDebateBrief(session, msg.mateId, mateCtx);
|
|
562
592
|
|
|
@@ -60,6 +60,15 @@ var formatters = {
|
|
|
60
60
|
body: data.preview || "Sent you a message",
|
|
61
61
|
};
|
|
62
62
|
},
|
|
63
|
+
|
|
64
|
+
mention_response: function (data) {
|
|
65
|
+
return {
|
|
66
|
+
type: "mention_response",
|
|
67
|
+
title: data.title || "Mention response ready",
|
|
68
|
+
body: data.preview || "",
|
|
69
|
+
meta: { avatarMateId: data.avatarMateId || null },
|
|
70
|
+
};
|
|
71
|
+
},
|
|
63
72
|
};
|
|
64
73
|
|
|
65
74
|
// ========================================================
|
package/lib/project-sessions.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
var fs = require("fs");
|
|
2
2
|
var path = require("path");
|
|
3
3
|
var { execFileSync } = require("child_process");
|
|
4
|
+
var { CODEX_DEFAULTS, getCodexConfig } = require("./codex-defaults");
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Attach session management, config, project management, and mid-section
|
|
@@ -520,18 +521,18 @@ function attachSessions(ctx) {
|
|
|
520
521
|
|
|
521
522
|
// Codex-specific settings (stored on sessionManager, passed to adapter via adapterOptions)
|
|
522
523
|
if (msg.type === "set_codex_approval") {
|
|
523
|
-
sm.codexApproval = msg.approval ||
|
|
524
|
-
send({ type: "codex_config"
|
|
524
|
+
sm.codexApproval = msg.approval || CODEX_DEFAULTS.approval;
|
|
525
|
+
send(Object.assign({ type: "codex_config" }, getCodexConfig(sm)));
|
|
525
526
|
return true;
|
|
526
527
|
}
|
|
527
528
|
if (msg.type === "set_codex_sandbox") {
|
|
528
|
-
sm.codexSandbox = msg.sandbox ||
|
|
529
|
-
send({ type: "codex_config"
|
|
529
|
+
sm.codexSandbox = msg.sandbox || CODEX_DEFAULTS.sandbox;
|
|
530
|
+
send(Object.assign({ type: "codex_config" }, getCodexConfig(sm)));
|
|
530
531
|
return true;
|
|
531
532
|
}
|
|
532
533
|
if (msg.type === "set_codex_websearch") {
|
|
533
|
-
sm.codexWebSearch = msg.webSearch ||
|
|
534
|
-
send({ type: "codex_config"
|
|
534
|
+
sm.codexWebSearch = msg.webSearch || CODEX_DEFAULTS.webSearch;
|
|
535
|
+
send(Object.assign({ type: "codex_config" }, getCodexConfig(sm)));
|
|
535
536
|
return true;
|
|
536
537
|
}
|
|
537
538
|
|
package/lib/project.js
CHANGED
|
@@ -615,15 +615,33 @@ function createProjectContext(opts) {
|
|
|
615
615
|
var tm = createTerminalManager({ cwd: cwd, send: send, sendTo: sendTo });
|
|
616
616
|
var nm = createNotesManager({ cwd: cwd, send: send, sendTo: sendTo });
|
|
617
617
|
|
|
618
|
-
// Check for updates in background (admin only)
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
618
|
+
// Check for updates in background (admin only). The result is stored in
|
|
619
|
+
// latestVersion; broadcast is handled by the hourly scheduler below, so
|
|
620
|
+
// page refreshes don't re-trigger the banner.
|
|
621
|
+
function runVersionCheck(broadcast) {
|
|
622
|
+
fetchVersion(updateChannel).then(function (v) {
|
|
623
|
+
if (v && isNewer(v, currentVersion)) {
|
|
624
|
+
latestVersion = v;
|
|
625
|
+
if (broadcast) sendToAdmins({ type: "update_available", version: v });
|
|
626
|
+
}
|
|
627
|
+
}).catch(function (e) {
|
|
628
|
+
console.error("[project] Background version check failed:", e.message || e);
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
runVersionCheck(false);
|
|
632
|
+
|
|
633
|
+
// Push update_available on every hour boundary. Clients can dismiss the
|
|
634
|
+
// banner; the next hourly push acts as a fresh ping. This avoids needing
|
|
635
|
+
// any dismissed-state persistence.
|
|
636
|
+
function scheduleNextHourlyBroadcast() {
|
|
637
|
+
var now = Date.now();
|
|
638
|
+
var msUntilNextHour = 60 * 60 * 1000 - (now % (60 * 60 * 1000));
|
|
639
|
+
setTimeout(function tick() {
|
|
640
|
+
runVersionCheck(true);
|
|
641
|
+
setTimeout(tick, 60 * 60 * 1000);
|
|
642
|
+
}, msUntilNextHour);
|
|
643
|
+
}
|
|
644
|
+
scheduleNextHourlyBroadcast();
|
|
627
645
|
|
|
628
646
|
// --- WS connection handler (delegated to project-connection.js) ---
|
|
629
647
|
function handleConnection(ws, wsUser) {
|
|
@@ -850,6 +868,7 @@ function createProjectContext(opts) {
|
|
|
850
868
|
// so we use a lazy getter that resolves at call time.
|
|
851
869
|
var _mateInteraction = attachMateInteraction({
|
|
852
870
|
cwd: cwd,
|
|
871
|
+
slug: slug,
|
|
853
872
|
sm: sm,
|
|
854
873
|
sdk: sdk,
|
|
855
874
|
send: send,
|
|
@@ -867,6 +886,7 @@ function createProjectContext(opts) {
|
|
|
867
886
|
loadMateDigests: loadMateDigests,
|
|
868
887
|
updateMemorySummary: updateMemorySummary,
|
|
869
888
|
initMemorySummary: initMemorySummary,
|
|
889
|
+
getNotificationsModule: function () { return _notifications; },
|
|
870
890
|
get checkForDmDebateBrief() { return checkForDmDebateBrief; },
|
|
871
891
|
});
|
|
872
892
|
var handleMention = _mateInteraction.handleMention;
|
package/lib/public/app.js
CHANGED
|
@@ -309,6 +309,9 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
309
309
|
currentBetas: [],
|
|
310
310
|
currentThinking: "adaptive",
|
|
311
311
|
currentThinkingBudget: 10000,
|
|
312
|
+
codexApproval: null,
|
|
313
|
+
codexSandbox: null,
|
|
314
|
+
codexWebSearch: null,
|
|
312
315
|
ctxPopoverVisible: false,
|
|
313
316
|
headerContextEl: null,
|
|
314
317
|
// loop
|
|
@@ -782,6 +785,8 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
782
785
|
var _perms = store.get('permissions');
|
|
783
786
|
if (_perms) {
|
|
784
787
|
if (!_perms.terminal) {
|
|
788
|
+
var termBtn = document.getElementById("terminal-toggle-btn");
|
|
789
|
+
if (termBtn) termBtn.style.display = "none";
|
|
785
790
|
var termSideBtn = document.getElementById("terminal-sidebar-btn");
|
|
786
791
|
if (termSideBtn) termSideBtn.style.display = "none";
|
|
787
792
|
}
|
package/lib/public/css/input.css
CHANGED
|
@@ -827,7 +827,8 @@
|
|
|
827
827
|
|
|
828
828
|
#attach-file-btn,
|
|
829
829
|
#attach-image-btn,
|
|
830
|
-
#schedule-btn
|
|
830
|
+
#schedule-btn,
|
|
831
|
+
#input-more-btn {
|
|
831
832
|
width: 36px;
|
|
832
833
|
height: 36px;
|
|
833
834
|
border-radius: 50%;
|
|
@@ -844,11 +845,13 @@
|
|
|
844
845
|
|
|
845
846
|
#attach-file-btn .lucide,
|
|
846
847
|
#attach-image-btn .lucide,
|
|
847
|
-
#schedule-btn .lucide
|
|
848
|
+
#schedule-btn .lucide,
|
|
849
|
+
#input-more-btn .lucide { width: 20px; height: 20px; flex-shrink: 0; }
|
|
848
850
|
|
|
849
851
|
#attach-file-btn:hover,
|
|
850
852
|
#attach-image-btn:hover,
|
|
851
|
-
#schedule-btn:hover
|
|
853
|
+
#schedule-btn:hover,
|
|
854
|
+
#input-more-btn:hover { background: rgba(var(--overlay-rgb), 0.06); color: var(--text); }
|
|
852
855
|
|
|
853
856
|
#ask-mate-btn {
|
|
854
857
|
width: 36px;
|
|
@@ -1137,6 +1140,146 @@
|
|
|
1137
1140
|
body.keyboard-open #input-area {
|
|
1138
1141
|
padding-bottom: 8px;
|
|
1139
1142
|
}
|
|
1143
|
+
|
|
1144
|
+
/* Mobile visibility utilities for input toolbar */
|
|
1145
|
+
.desktop-only { display: none !important; }
|
|
1146
|
+
.mobile-only { display: inline-flex !important; }
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
/* Desktop: hide mobile-only, show desktop-only */
|
|
1150
|
+
@media (min-width: 769px) {
|
|
1151
|
+
.mobile-only { display: none !important; }
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
/* ==========================================================================
|
|
1155
|
+
Input More Bottom Sheet (mobile)
|
|
1156
|
+
========================================================================== */
|
|
1157
|
+
|
|
1158
|
+
#input-more-sheet {
|
|
1159
|
+
position: fixed;
|
|
1160
|
+
inset: 0;
|
|
1161
|
+
z-index: 10000;
|
|
1162
|
+
pointer-events: none;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
#input-more-sheet.hidden {
|
|
1166
|
+
display: none;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
.input-more-backdrop {
|
|
1170
|
+
position: absolute;
|
|
1171
|
+
inset: 0;
|
|
1172
|
+
background: rgba(0, 0, 0, 0.4);
|
|
1173
|
+
opacity: 0;
|
|
1174
|
+
transition: opacity 0.2s ease;
|
|
1175
|
+
pointer-events: auto;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
#input-more-sheet.open .input-more-backdrop {
|
|
1179
|
+
opacity: 1;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
.input-more-content {
|
|
1183
|
+
position: absolute;
|
|
1184
|
+
left: 0;
|
|
1185
|
+
right: 0;
|
|
1186
|
+
bottom: 0;
|
|
1187
|
+
background: var(--bg);
|
|
1188
|
+
border-top-left-radius: 16px;
|
|
1189
|
+
border-top-right-radius: 16px;
|
|
1190
|
+
padding: 8px 0 calc(var(--safe-bottom) + 16px);
|
|
1191
|
+
transform: translateY(100%);
|
|
1192
|
+
transition: transform 0.25s ease;
|
|
1193
|
+
pointer-events: auto;
|
|
1194
|
+
box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.15);
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
#input-more-sheet.open .input-more-content {
|
|
1198
|
+
transform: translateY(0);
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
.input-more-handle {
|
|
1202
|
+
width: 40px;
|
|
1203
|
+
height: 4px;
|
|
1204
|
+
border-radius: 2px;
|
|
1205
|
+
background: var(--border-subtle);
|
|
1206
|
+
margin: 8px auto 12px;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
.input-more-actions {
|
|
1210
|
+
display: grid;
|
|
1211
|
+
grid-template-columns: 1fr 1fr;
|
|
1212
|
+
gap: 8px;
|
|
1213
|
+
padding: 4px 16px 12px;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
.input-more-action {
|
|
1217
|
+
display: flex;
|
|
1218
|
+
flex-direction: column;
|
|
1219
|
+
align-items: center;
|
|
1220
|
+
justify-content: center;
|
|
1221
|
+
gap: 6px;
|
|
1222
|
+
padding: 16px 8px;
|
|
1223
|
+
background: var(--hover);
|
|
1224
|
+
border: 1px solid var(--border-subtle);
|
|
1225
|
+
border-radius: 10px;
|
|
1226
|
+
font-size: 13px;
|
|
1227
|
+
color: var(--text);
|
|
1228
|
+
cursor: pointer;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
.input-more-action:active {
|
|
1232
|
+
opacity: 0.7;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
.input-more-action .lucide {
|
|
1236
|
+
width: 22px;
|
|
1237
|
+
height: 22px;
|
|
1238
|
+
color: var(--text-secondary);
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
.input-more-divider {
|
|
1242
|
+
height: 1px;
|
|
1243
|
+
background: var(--border-subtle);
|
|
1244
|
+
margin: 0 16px;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
.input-more-section-label {
|
|
1248
|
+
display: flex;
|
|
1249
|
+
align-items: center;
|
|
1250
|
+
gap: 8px;
|
|
1251
|
+
padding: 14px 20px 6px;
|
|
1252
|
+
font-size: 13px;
|
|
1253
|
+
font-weight: 500;
|
|
1254
|
+
color: var(--text-secondary);
|
|
1255
|
+
text-transform: uppercase;
|
|
1256
|
+
letter-spacing: 0.04em;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
.input-more-section-label .lucide {
|
|
1260
|
+
width: 16px;
|
|
1261
|
+
height: 16px;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
.input-more-context-body {
|
|
1265
|
+
max-height: 50vh;
|
|
1266
|
+
overflow-y: auto;
|
|
1267
|
+
padding: 0 8px 8px;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
.input-more-context-body .context-picker-item {
|
|
1271
|
+
padding: 12px 16px;
|
|
1272
|
+
font-size: 15px;
|
|
1273
|
+
border-radius: 8px;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
.input-more-context-body .context-picker-item .lucide {
|
|
1277
|
+
width: 18px;
|
|
1278
|
+
height: 18px;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
.input-more-context-body .context-picker-section-label {
|
|
1282
|
+
padding: 10px 16px 4px;
|
|
1140
1283
|
}
|
|
1141
1284
|
|
|
1142
1285
|
/* ==========================================================================
|
|
@@ -81,6 +81,13 @@
|
|
|
81
81
|
}
|
|
82
82
|
.notif-banner-icon .lucide { width: 16px; height: 16px; }
|
|
83
83
|
.notif-banner-emoji { font-size: 18px; line-height: 1; }
|
|
84
|
+
.notif-banner-avatar {
|
|
85
|
+
width: 100%;
|
|
86
|
+
height: 100%;
|
|
87
|
+
object-fit: cover;
|
|
88
|
+
border-radius: 8px;
|
|
89
|
+
display: block;
|
|
90
|
+
}
|
|
84
91
|
|
|
85
92
|
.notif-banner-body {
|
|
86
93
|
flex: 1;
|
|
@@ -18,3 +18,50 @@
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
.tooltip.visible { opacity: 1; }
|
|
21
|
+
|
|
22
|
+
.tooltip.multi-line {
|
|
23
|
+
white-space: pre-line;
|
|
24
|
+
text-align: left;
|
|
25
|
+
max-width: 320px;
|
|
26
|
+
line-height: 1.5;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* Context sources tooltip */
|
|
30
|
+
.ctx-tip-header {
|
|
31
|
+
font-size: 11px;
|
|
32
|
+
font-weight: 600;
|
|
33
|
+
text-transform: uppercase;
|
|
34
|
+
letter-spacing: 0.04em;
|
|
35
|
+
color: var(--text-muted);
|
|
36
|
+
margin-bottom: 6px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.ctx-tip-row {
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
gap: 8px;
|
|
43
|
+
padding: 4px 0;
|
|
44
|
+
color: var(--text);
|
|
45
|
+
font-size: 12px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.ctx-tip-row .lucide {
|
|
49
|
+
width: 14px;
|
|
50
|
+
height: 14px;
|
|
51
|
+
flex-shrink: 0;
|
|
52
|
+
color: var(--text-secondary);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.ctx-tip-favicon {
|
|
56
|
+
width: 14px;
|
|
57
|
+
height: 14px;
|
|
58
|
+
flex-shrink: 0;
|
|
59
|
+
border-radius: 2px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.ctx-tip-row span {
|
|
63
|
+
overflow: hidden;
|
|
64
|
+
text-overflow: ellipsis;
|
|
65
|
+
white-space: nowrap;
|
|
66
|
+
max-width: 260px;
|
|
67
|
+
}
|
package/lib/public/index.html
CHANGED
|
@@ -352,6 +352,7 @@
|
|
|
352
352
|
<div class="status">
|
|
353
353
|
<button id="debate-pdf-btn" class="hidden" title="Export debate as PDF"><i data-lucide="download"></i></button>
|
|
354
354
|
<button id="find-in-session-btn" title="Search in session (Ctrl+F)"><i data-lucide="search"></i></button>
|
|
355
|
+
<button id="terminal-toggle-btn" title="Terminal"><i data-lucide="square-terminal"></i><span id="terminal-count" class="hidden"></span></button>
|
|
355
356
|
</div>
|
|
356
357
|
</div>
|
|
357
358
|
<div id="main-panels">
|
|
@@ -459,13 +460,14 @@
|
|
|
459
460
|
</div>
|
|
460
461
|
<div id="input-bottom">
|
|
461
462
|
<div id="attach-wrap">
|
|
462
|
-
<button id="
|
|
463
|
-
<button id="attach-
|
|
463
|
+
<button id="input-more-btn" type="button" aria-label="More options" title="More options" class="mobile-only"><i data-lucide="plus"></i></button>
|
|
464
|
+
<button id="attach-file-btn" type="button" aria-label="Attach file" title="Attach file" class="desktop-only"><i data-lucide="paperclip"></i></button>
|
|
465
|
+
<button id="attach-image-btn" type="button" aria-label="Attach image" title="Attach image" class="desktop-only"><i data-lucide="image"></i></button>
|
|
464
466
|
<button id="stt-btn" type="button" aria-label="Voice input" title="Voice input"><i data-lucide="mic"></i></button>
|
|
465
467
|
<button id="schedule-btn" type="button" aria-label="Schedule message" title="Schedule message"><i data-lucide="clock"></i></button>
|
|
466
468
|
<button id="ask-mate-btn" type="button" aria-label="Ask Mate" title="Ask a Mate for advice on this session"><i data-lucide="at-sign"></i></button>
|
|
467
|
-
<div id="context-sources-btn-wrap">
|
|
468
|
-
<button id="context-sources-add" type="button" title="Add context sources"><i data-lucide="
|
|
469
|
+
<div id="context-sources-btn-wrap" class="desktop-only">
|
|
470
|
+
<button id="context-sources-add" type="button" title="Add context sources"><i data-lucide="library"></i><span class="ctx-label">Context</span></button>
|
|
469
471
|
<div id="context-sources-picker" class="hidden">
|
|
470
472
|
<div class="context-picker-section" id="context-picker-email"></div>
|
|
471
473
|
<div class="context-picker-section" id="context-picker-terminals"></div>
|
|
@@ -542,6 +544,34 @@
|
|
|
542
544
|
</div>
|
|
543
545
|
</div>
|
|
544
546
|
</div>
|
|
547
|
+
<!-- Mobile input-more bottom sheet: attach / image + context sources -->
|
|
548
|
+
<div id="input-more-sheet" class="hidden">
|
|
549
|
+
<div class="input-more-backdrop"></div>
|
|
550
|
+
<div class="input-more-content">
|
|
551
|
+
<div class="input-more-handle"></div>
|
|
552
|
+
<div class="input-more-actions">
|
|
553
|
+
<button class="input-more-action" id="input-more-attach">
|
|
554
|
+
<i data-lucide="paperclip"></i>
|
|
555
|
+
<span>Attach file</span>
|
|
556
|
+
</button>
|
|
557
|
+
<button class="input-more-action" id="input-more-image">
|
|
558
|
+
<i data-lucide="image"></i>
|
|
559
|
+
<span>Image</span>
|
|
560
|
+
</button>
|
|
561
|
+
</div>
|
|
562
|
+
<div class="input-more-divider"></div>
|
|
563
|
+
<div class="input-more-section-label">
|
|
564
|
+
<i data-lucide="library"></i>
|
|
565
|
+
<span>Context sources</span>
|
|
566
|
+
</div>
|
|
567
|
+
<div class="input-more-context-body" id="input-more-context-body">
|
|
568
|
+
<div class="context-picker-section" id="context-picker-email-mobile"></div>
|
|
569
|
+
<div class="context-picker-section" id="context-picker-terminals-mobile"></div>
|
|
570
|
+
<div class="context-picker-section" id="context-picker-tabs-mobile"></div>
|
|
571
|
+
</div>
|
|
572
|
+
</div>
|
|
573
|
+
</div>
|
|
574
|
+
|
|
545
575
|
<!-- Mobile fullscreen sheet overlay (Projects / Sessions) -->
|
|
546
576
|
<div id="mobile-sheet" class="hidden">
|
|
547
577
|
<div class="mobile-sheet-backdrop"></div>
|
|
@@ -210,6 +210,8 @@ export function enterDmMode(key, targetUser, messages) {
|
|
|
210
210
|
// Close file viewer and terminal panel BEFORE switching WS (needs old WS still open)
|
|
211
211
|
try { closeFileViewer(); } catch(e) {}
|
|
212
212
|
closeTerminal();
|
|
213
|
+
var termBtn = document.getElementById("terminal-toggle-btn");
|
|
214
|
+
if (termBtn) termBtn.style.display = "none";
|
|
213
215
|
// Apply mate color to chat title bar and panels
|
|
214
216
|
var mateColor = (targetUser.profile && targetUser.profile.avatarColor) || targetUser.avatarColor || "#7c3aed";
|
|
215
217
|
document.body.style.setProperty("--mate-color", mateColor);
|
|
@@ -323,6 +325,9 @@ export function exitDmMode(skipProjectSwitch) {
|
|
|
323
325
|
hideKnowledge();
|
|
324
326
|
hideMemory();
|
|
325
327
|
if (isSchedulerOpen()) closeScheduler();
|
|
328
|
+
// Restore terminal button
|
|
329
|
+
var termBtn = document.getElementById("terminal-toggle-btn");
|
|
330
|
+
if (termBtn) termBtn.style.display = "";
|
|
326
331
|
// Reset DM header
|
|
327
332
|
var dmHeaderBar = document.getElementById("dm-header-bar");
|
|
328
333
|
if (dmHeaderBar) {
|
|
@@ -11,7 +11,7 @@ import { refreshIcons, iconHtml } from './icons.js';
|
|
|
11
11
|
import { renderMarkdown } from './markdown.js';
|
|
12
12
|
import { updatePageTitle } from './sidebar.js';
|
|
13
13
|
import { renderSessionList, updateSessionPresence, populateCliSessionList, handleSearchResults, updateSessionBadge } from './sidebar-sessions.js';
|
|
14
|
-
import { updateDmBadge, renderSidebarPresence, setMentionActive } from './sidebar-mates.js';
|
|
14
|
+
import { updateDmBadge, renderSidebarPresence, setMentionActive, renderUserStrip } from './sidebar-mates.js';
|
|
15
15
|
import { refreshMobileChatSheet } from './sidebar-mobile.js';
|
|
16
16
|
import { renderMateSessionList, handleMateSearchResults, updateMateSidebarProfile } from './mate-sidebar.js';
|
|
17
17
|
import { renderKnowledgeList, handleKnowledgeContent } from './mate-knowledge.js';
|
|
@@ -369,9 +369,9 @@ export function processMessage(msg) {
|
|
|
369
369
|
|
|
370
370
|
case "codex_config":
|
|
371
371
|
store.set({
|
|
372
|
-
codexApproval: msg.approval
|
|
373
|
-
codexSandbox: msg.sandbox
|
|
374
|
-
codexWebSearch: msg.webSearch
|
|
372
|
+
codexApproval: msg.approval,
|
|
373
|
+
codexSandbox: msg.sandbox,
|
|
374
|
+
codexWebSearch: msg.webSearch,
|
|
375
375
|
});
|
|
376
376
|
break;
|
|
377
377
|
|
|
@@ -1171,6 +1171,7 @@ export function processMessage(msg) {
|
|
|
1171
1171
|
|
|
1172
1172
|
case "projects_updated":
|
|
1173
1173
|
updateProjectList(msg);
|
|
1174
|
+
renderUserStrip();
|
|
1174
1175
|
break;
|
|
1175
1176
|
|
|
1176
1177
|
case "project_owner_changed":
|