clay-server 2.33.0-beta.1 → 2.33.0-beta.3
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/project-connection.js +1 -0
- package/lib/project-sessions.js +12 -0
- package/lib/project.js +38 -5
- package/lib/public/css/debate.css +0 -29
- package/lib/public/css/mobile-nav.css +17 -0
- package/lib/public/css/notifications-center.css +30 -17
- package/lib/public/css/overlays.css +7 -1
- package/lib/public/css/sidebar.css +65 -39
- package/lib/public/index.html +0 -2
- package/lib/public/modules/app-messages.js +11 -1
- package/lib/public/modules/app-panels.js +1 -1
- package/lib/public/modules/app-rate-limit.js +33 -6
- package/lib/public/modules/app-rendering.js +1 -1
- package/lib/public/modules/sidebar-mobile.js +41 -3
- package/lib/public/modules/sidebar-sessions.js +68 -4
- package/lib/public/modules/sidebar.js +7 -4
- package/lib/public/modules/tool-palette.js +3 -1
- package/lib/public/modules/tools.js +47 -26
- package/lib/sdk-bridge.js +59 -7
- package/lib/sdk-message-processor.js +55 -1
- package/lib/sessions.js +15 -0
- package/lib/ws-schema.js +1 -0
- package/lib/yoke/adapters/codex.js +145 -9
- package/lib/yoke/index.js +5 -1
- package/package.json +1 -1
package/lib/project-sessions.js
CHANGED
|
@@ -124,6 +124,18 @@ function attachSessions(ctx) {
|
|
|
124
124
|
return true;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
if (msg.type === "set_session_bookmark") {
|
|
128
|
+
if (typeof msg.sessionId === "number") {
|
|
129
|
+
var bookmarkTarget = sm.sessions.get(msg.sessionId);
|
|
130
|
+
if (!bookmarkTarget) return true;
|
|
131
|
+
if (usersModule.isMultiUser() && ws._clayUser) {
|
|
132
|
+
if (!usersModule.canAccessSession(ws._clayUser.id, bookmarkTarget, { visibility: "public" })) return true;
|
|
133
|
+
}
|
|
134
|
+
sm.setSessionBookmarked(msg.sessionId, !!msg.bookmarked);
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
|
|
127
139
|
if (msg.type === "transfer_project_owner") {
|
|
128
140
|
// Home directory projects: ownership is permanently locked
|
|
129
141
|
if (osUsers && osUsers.length > 0 && /^\/home\/[^/]+\//.test(cwd)) {
|
package/lib/project.js
CHANGED
|
@@ -779,11 +779,44 @@ function createProjectContext(opts) {
|
|
|
779
779
|
|
|
780
780
|
// --- Vendor model switching ---
|
|
781
781
|
if (msg.type === "get_vendor_models") {
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
782
|
+
(async function() {
|
|
783
|
+
if (msg.vendor) {
|
|
784
|
+
try {
|
|
785
|
+
var vendorAdapter = adapters[msg.vendor] || null;
|
|
786
|
+
if (!vendorAdapter) {
|
|
787
|
+
vendorAdapter = await yoke.lazyCreateAdapter(adapters, msg.vendor, {
|
|
788
|
+
cwd: cwd,
|
|
789
|
+
clayPort: serverPort,
|
|
790
|
+
clayTls: serverTls,
|
|
791
|
+
clayAuthToken: serverAuthToken,
|
|
792
|
+
slug: slug,
|
|
793
|
+
});
|
|
794
|
+
} else if ((!sm.modelsByVendor || !sm.modelsByVendor[msg.vendor]) && typeof vendorAdapter.init === "function") {
|
|
795
|
+
await vendorAdapter.init({
|
|
796
|
+
cwd: cwd,
|
|
797
|
+
clayPort: serverPort,
|
|
798
|
+
clayTls: serverTls,
|
|
799
|
+
clayAuthToken: serverAuthToken,
|
|
800
|
+
slug: slug,
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
if (vendorAdapter) {
|
|
804
|
+
sm.availableVendors = Object.keys(adapters);
|
|
805
|
+
sm.modelsByVendor = sm.modelsByVendor || {};
|
|
806
|
+
if (!sm.modelsByVendor[msg.vendor] && typeof vendorAdapter.supportedModels === "function") {
|
|
807
|
+
sm.modelsByVendor[msg.vendor] = await vendorAdapter.supportedModels();
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
} catch (e) {
|
|
811
|
+
console.error("[project] get_vendor_models lazy init failed for " + msg.vendor + ":", e.message || e);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
var vendorModels = (sm.modelsByVendor && sm.modelsByVendor[msg.vendor]) || [];
|
|
815
|
+
var firstModel = vendorModels[0] || "";
|
|
816
|
+
// model value can be string or {value, displayName} object
|
|
817
|
+
var defaultModel = typeof firstModel === "string" ? firstModel : (firstModel.value || "");
|
|
818
|
+
sendTo(ws, { type: "model_info", model: defaultModel, models: vendorModels, vendor: msg.vendor, availableVendors: sm.availableVendors || [], installedVendors: sm.installedVendors || [] });
|
|
819
|
+
})();
|
|
787
820
|
return;
|
|
788
821
|
}
|
|
789
822
|
|
|
@@ -88,35 +88,6 @@
|
|
|
88
88
|
height: 12px;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
/* --- Debate pill button in mate sidebar (matches .new-ralph-pill) --- */
|
|
92
|
-
.mate-debate-pill {
|
|
93
|
-
display: inline-flex;
|
|
94
|
-
align-items: center;
|
|
95
|
-
justify-content: center;
|
|
96
|
-
gap: 3px;
|
|
97
|
-
height: 22px;
|
|
98
|
-
padding: 0 8px;
|
|
99
|
-
border: 1px solid var(--accent);
|
|
100
|
-
border-radius: 6px;
|
|
101
|
-
background: var(--accent-12, rgba(108, 92, 231, 0.12));
|
|
102
|
-
color: var(--accent);
|
|
103
|
-
font-size: 10px;
|
|
104
|
-
font-weight: 700;
|
|
105
|
-
font-family: inherit;
|
|
106
|
-
letter-spacing: 0.2px;
|
|
107
|
-
cursor: pointer;
|
|
108
|
-
white-space: nowrap;
|
|
109
|
-
transition: background 0.15s, color 0.15s;
|
|
110
|
-
}
|
|
111
|
-
.mate-debate-pill .lucide {
|
|
112
|
-
width: 10px;
|
|
113
|
-
height: 10px;
|
|
114
|
-
}
|
|
115
|
-
.mate-debate-pill:hover {
|
|
116
|
-
background: var(--accent);
|
|
117
|
-
color: #fff;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
91
|
/* --- Debate header badges (inline with session title) --- */
|
|
121
92
|
.debate-header-badge {
|
|
122
93
|
display: inline-flex;
|
|
@@ -518,11 +518,28 @@
|
|
|
518
518
|
|
|
519
519
|
.mobile-session-title {
|
|
520
520
|
flex: 1;
|
|
521
|
+
display: inline-flex;
|
|
522
|
+
align-items: center;
|
|
523
|
+
gap: 6px;
|
|
521
524
|
overflow: hidden;
|
|
522
525
|
text-overflow: ellipsis;
|
|
523
526
|
white-space: nowrap;
|
|
524
527
|
}
|
|
525
528
|
|
|
529
|
+
.mobile-session-bookmark {
|
|
530
|
+
display: inline-flex;
|
|
531
|
+
align-items: center;
|
|
532
|
+
color: var(--accent, #ff7b54);
|
|
533
|
+
flex-shrink: 0;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
.mobile-session-bookmark .lucide,
|
|
537
|
+
.mobile-session-bookmark svg {
|
|
538
|
+
width: 13px;
|
|
539
|
+
height: 13px;
|
|
540
|
+
display: block;
|
|
541
|
+
}
|
|
542
|
+
|
|
526
543
|
.mobile-session-processing {
|
|
527
544
|
width: 7px;
|
|
528
545
|
height: 7px;
|
|
@@ -51,22 +51,27 @@
|
|
|
51
51
|
align-items: center;
|
|
52
52
|
gap: 4px;
|
|
53
53
|
padding: 3px 10px;
|
|
54
|
-
background:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
background:
|
|
55
|
+
linear-gradient(180deg, rgba(255,255,255,0.14), rgba(255,255,255,0.04)),
|
|
56
|
+
rgba(var(--overlay-rgb), 0.06);
|
|
57
|
+
backdrop-filter: blur(10px) saturate(1.1);
|
|
58
|
+
-webkit-backdrop-filter: blur(10px) saturate(1.1);
|
|
59
|
+
border: 1px solid rgba(255,255,255,0.18);
|
|
58
60
|
border-radius: 999px;
|
|
59
61
|
font-family: inherit;
|
|
60
62
|
font-size: 11px;
|
|
61
63
|
font-weight: 500;
|
|
62
64
|
color: var(--text-muted);
|
|
63
65
|
cursor: pointer;
|
|
64
|
-
box-shadow: 0
|
|
65
|
-
transition: color 0.15s, background 0.15s;
|
|
66
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,0.18);
|
|
67
|
+
transition: color 0.15s, background 0.15s, border-color 0.15s;
|
|
66
68
|
}
|
|
67
69
|
.notif-banner-clear-all:hover {
|
|
68
70
|
color: var(--text);
|
|
69
|
-
background:
|
|
71
|
+
background:
|
|
72
|
+
linear-gradient(180deg, rgba(255,255,255,0.18), rgba(255,255,255,0.06)),
|
|
73
|
+
rgba(var(--overlay-rgb), 0.08);
|
|
74
|
+
border-color: rgba(255,255,255,0.24);
|
|
70
75
|
}
|
|
71
76
|
.notif-banner-clear-all .lucide {
|
|
72
77
|
width: 12px;
|
|
@@ -79,17 +84,19 @@
|
|
|
79
84
|
align-items: center;
|
|
80
85
|
gap: 10px;
|
|
81
86
|
padding: 10px 14px;
|
|
82
|
-
background:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
background:
|
|
88
|
+
linear-gradient(180deg, rgba(255,255,255,0.16), rgba(255,255,255,0.04)),
|
|
89
|
+
rgba(var(--overlay-rgb), 0.07);
|
|
90
|
+
backdrop-filter: blur(10px) saturate(1.08);
|
|
91
|
+
-webkit-backdrop-filter: blur(10px) saturate(1.08);
|
|
92
|
+
border: 1px solid rgba(255,255,255,0.2);
|
|
93
|
+
border-radius: 16px;
|
|
94
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,0.2);
|
|
88
95
|
pointer-events: auto;
|
|
89
96
|
cursor: pointer;
|
|
90
97
|
opacity: 0;
|
|
91
98
|
transform: translateY(-100%);
|
|
92
|
-
transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
99
|
+
transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.18s ease, box-shadow 0.18s ease;
|
|
93
100
|
}
|
|
94
101
|
.notif-banner.show {
|
|
95
102
|
opacity: 1;
|
|
@@ -99,6 +106,10 @@
|
|
|
99
106
|
opacity: 0;
|
|
100
107
|
transform: translateY(-100%);
|
|
101
108
|
}
|
|
109
|
+
.notif-banner:hover {
|
|
110
|
+
border-color: rgba(255,255,255,0.28);
|
|
111
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,0.24);
|
|
112
|
+
}
|
|
102
113
|
|
|
103
114
|
.notif-banner-icon {
|
|
104
115
|
flex-shrink: 0;
|
|
@@ -107,9 +118,11 @@
|
|
|
107
118
|
display: flex;
|
|
108
119
|
align-items: center;
|
|
109
120
|
justify-content: center;
|
|
110
|
-
background:
|
|
111
|
-
border
|
|
121
|
+
background: linear-gradient(180deg, rgba(255,255,255,0.18), rgba(255,255,255,0.04));
|
|
122
|
+
border: 1px solid rgba(255,255,255,0.16);
|
|
123
|
+
border-radius: 10px;
|
|
112
124
|
color: var(--text-muted);
|
|
125
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,0.18);
|
|
113
126
|
}
|
|
114
127
|
.notif-banner-icon .lucide { width: 16px; height: 16px; }
|
|
115
128
|
.notif-banner-emoji { font-size: 18px; line-height: 1; }
|
|
@@ -215,7 +228,7 @@
|
|
|
215
228
|
.notif-banner:hover .notif-banner-close { opacity: 1; }
|
|
216
229
|
.notif-banner-close:hover {
|
|
217
230
|
color: var(--text);
|
|
218
|
-
background: rgba(
|
|
231
|
+
background: rgba(255,255,255,0.12);
|
|
219
232
|
}
|
|
220
233
|
.notif-banner-close .lucide { width: 12px; height: 12px; }
|
|
221
234
|
|
|
@@ -46,6 +46,13 @@
|
|
|
46
46
|
.usage-check-link:hover {
|
|
47
47
|
background: color-mix(in srgb, var(--text-dimmer) 16%, transparent);
|
|
48
48
|
}
|
|
49
|
+
.usage-check-vendor-icon {
|
|
50
|
+
width: 14px;
|
|
51
|
+
height: 14px;
|
|
52
|
+
border-radius: 4px;
|
|
53
|
+
object-fit: cover;
|
|
54
|
+
flex: 0 0 auto;
|
|
55
|
+
}
|
|
49
56
|
.usage-check-link .lucide {
|
|
50
57
|
width: 12px;
|
|
51
58
|
height: 12px;
|
|
@@ -1258,4 +1265,3 @@ button.top-bar-pill.pill-accent:hover { background: color-mix(in srgb, var(--acc
|
|
|
1258
1265
|
margin-top: 1.2rem;
|
|
1259
1266
|
letter-spacing: 0.03em;
|
|
1260
1267
|
}
|
|
1261
|
-
|
|
@@ -603,7 +603,7 @@
|
|
|
603
603
|
gap: 2px;
|
|
604
604
|
}
|
|
605
605
|
|
|
606
|
-
.session-list-header-actions button
|
|
606
|
+
.session-list-header-actions button {
|
|
607
607
|
display: flex;
|
|
608
608
|
align-items: center;
|
|
609
609
|
justify-content: center;
|
|
@@ -618,8 +618,8 @@
|
|
|
618
618
|
transition: color 0.15s, background 0.15s;
|
|
619
619
|
}
|
|
620
620
|
|
|
621
|
-
.session-list-header-actions button
|
|
622
|
-
.session-list-header-actions button:
|
|
621
|
+
.session-list-header-actions button .lucide { width: 14px; height: 14px; }
|
|
622
|
+
.session-list-header-actions button:hover { color: var(--text); background: var(--sidebar-hover); }
|
|
623
623
|
|
|
624
624
|
/* --- Session search --- */
|
|
625
625
|
#session-search {
|
|
@@ -810,6 +810,64 @@
|
|
|
810
810
|
box-shadow: 0 0 4px var(--success);
|
|
811
811
|
}
|
|
812
812
|
|
|
813
|
+
.session-bookmark-btn {
|
|
814
|
+
display: flex;
|
|
815
|
+
width: 20px;
|
|
816
|
+
height: 20px;
|
|
817
|
+
border-radius: 6px;
|
|
818
|
+
border: none;
|
|
819
|
+
background: transparent;
|
|
820
|
+
color: var(--text-dimmer);
|
|
821
|
+
cursor: pointer;
|
|
822
|
+
align-items: center;
|
|
823
|
+
justify-content: center;
|
|
824
|
+
padding: 0;
|
|
825
|
+
margin-right: 2px;
|
|
826
|
+
flex-shrink: 0;
|
|
827
|
+
opacity: 0;
|
|
828
|
+
transition: opacity 0.2s ease, color 0.15s, background 0.15s;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
.session-bookmark-btn.hover {
|
|
832
|
+
position: absolute;
|
|
833
|
+
right: 30px;
|
|
834
|
+
top: 50%;
|
|
835
|
+
transform: translateY(-50%);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
.session-bookmark-btn.inline {
|
|
839
|
+
margin-right: 2px;
|
|
840
|
+
flex-shrink: 0;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
.session-bookmark-btn .lucide,
|
|
844
|
+
.session-bookmark-btn svg {
|
|
845
|
+
width: 13px;
|
|
846
|
+
height: 13px;
|
|
847
|
+
display: block;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
.session-item:hover .session-bookmark-btn.hover,
|
|
851
|
+
.session-item:focus-within .session-bookmark-btn.hover,
|
|
852
|
+
.session-bookmark-btn.bookmarked {
|
|
853
|
+
opacity: 1;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
.session-bookmark-btn:hover {
|
|
857
|
+
color: var(--accent);
|
|
858
|
+
background: rgba(var(--overlay-rgb), 0.06);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
.session-bookmark-btn.bookmarked {
|
|
862
|
+
color: var(--accent);
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
.session-bookmark-btn.bookmarked .lucide,
|
|
866
|
+
.session-bookmark-btn.bookmarked svg {
|
|
867
|
+
fill: currentColor;
|
|
868
|
+
stroke: currentColor;
|
|
869
|
+
}
|
|
870
|
+
|
|
813
871
|
/* Session unread badge */
|
|
814
872
|
.session-unread-badge {
|
|
815
873
|
position: absolute;
|
|
@@ -832,6 +890,10 @@
|
|
|
832
890
|
z-index: 2;
|
|
833
891
|
}
|
|
834
892
|
|
|
893
|
+
.session-item .session-item-text {
|
|
894
|
+
padding-right: 28px;
|
|
895
|
+
}
|
|
896
|
+
|
|
835
897
|
.session-unread-badge.has-unread {
|
|
836
898
|
display: flex;
|
|
837
899
|
}
|
|
@@ -1216,41 +1278,6 @@
|
|
|
1216
1278
|
margin-left: 12px;
|
|
1217
1279
|
}
|
|
1218
1280
|
|
|
1219
|
-
/* --- New Ralph Loop pill button --- */
|
|
1220
|
-
.new-ralph-pill {
|
|
1221
|
-
display: inline-flex;
|
|
1222
|
-
align-items: center;
|
|
1223
|
-
justify-content: center;
|
|
1224
|
-
gap: 3px;
|
|
1225
|
-
height: 22px;
|
|
1226
|
-
padding: 0 8px;
|
|
1227
|
-
border: 1px solid var(--accent);
|
|
1228
|
-
border-radius: 6px;
|
|
1229
|
-
background: var(--accent-12, rgba(108, 92, 231, 0.12));
|
|
1230
|
-
color: var(--accent);
|
|
1231
|
-
font-size: 10px;
|
|
1232
|
-
font-weight: 700;
|
|
1233
|
-
font-family: inherit;
|
|
1234
|
-
letter-spacing: 0.2px;
|
|
1235
|
-
cursor: pointer;
|
|
1236
|
-
white-space: nowrap;
|
|
1237
|
-
transition: background 0.15s, color 0.15s;
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
.new-ralph-pill .lucide {
|
|
1241
|
-
width: 10px;
|
|
1242
|
-
height: 10px;
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
|
-
.new-ralph-pill + button {
|
|
1246
|
-
margin-left: 4px;
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
.new-ralph-pill:hover {
|
|
1250
|
-
background: var(--accent);
|
|
1251
|
-
color: #fff;
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
1281
|
@media (hover: none) {
|
|
1255
1282
|
.session-more-btn { opacity: 1; }
|
|
1256
1283
|
.msg-copy-hint { opacity: 1; }
|
|
@@ -1719,4 +1746,3 @@
|
|
|
1719
1746
|
50% { opacity: 0.18; }
|
|
1720
1747
|
100% { opacity: 0.1; }
|
|
1721
1748
|
}
|
|
1722
|
-
|
package/lib/public/index.html
CHANGED
|
@@ -200,7 +200,6 @@
|
|
|
200
200
|
<div class="session-list-header">
|
|
201
201
|
<span>Sessions</span>
|
|
202
202
|
<div class="session-list-header-actions">
|
|
203
|
-
<button id="new-ralph-btn" type="button" class="new-ralph-pill" data-tip="New Loop"><i data-lucide="repeat"></i> Loop</button>
|
|
204
203
|
<button id="new-session-btn" type="button" data-tip="New session"><i data-lucide="plus"></i></button>
|
|
205
204
|
<button id="resume-session-btn" type="button" data-tip="Import CLI session"><i data-lucide="import"></i></button>
|
|
206
205
|
<button id="search-session-btn" type="button" data-tip="Search sessions"><i data-lucide="search"></i></button>
|
|
@@ -270,7 +269,6 @@
|
|
|
270
269
|
<div id="mate-sidebar-conversations">
|
|
271
270
|
<div class="mate-sidebar-sessions-header">
|
|
272
271
|
<span>Conversations</span>
|
|
273
|
-
<button id="mate-debate-btn" class="mate-debate-pill" title="New Debate"><i data-lucide="mic"></i> Debate</button>
|
|
274
272
|
<div class="mate-sidebar-actions">
|
|
275
273
|
<button id="mate-search-session-btn" type="button" title="Search sessions"><i data-lucide="search"></i></button>
|
|
276
274
|
<button id="mate-new-session-btn" type="button" title="New session"><i data-lucide="plus"></i></button>
|
|
@@ -337,7 +337,12 @@ export function processMessage(msg) {
|
|
|
337
337
|
case "model_info": {
|
|
338
338
|
var _modelVal = msg.model;
|
|
339
339
|
if (_modelVal && typeof _modelVal === "object") _modelVal = _modelVal.value || _modelVal.displayName || "";
|
|
340
|
-
var _miUpdate = {
|
|
340
|
+
var _miUpdate = { currentModels: msg.models || [] };
|
|
341
|
+
if (Object.prototype.hasOwnProperty.call(msg, "model")) {
|
|
342
|
+
_miUpdate.currentModel = _modelVal || "";
|
|
343
|
+
} else {
|
|
344
|
+
_miUpdate.currentModel = store.get('currentModel');
|
|
345
|
+
}
|
|
341
346
|
if (msg.vendor) _miUpdate.currentVendor = msg.vendor;
|
|
342
347
|
if (msg.availableVendors) _miUpdate.availableVendors = msg.availableVendors;
|
|
343
348
|
if (msg.installedVendors) _miUpdate.installedVendors = msg.installedVendors;
|
|
@@ -573,6 +578,11 @@ export function processMessage(msg) {
|
|
|
573
578
|
}
|
|
574
579
|
break;
|
|
575
580
|
|
|
581
|
+
case "plan_content":
|
|
582
|
+
setPlanContent(msg.content || "");
|
|
583
|
+
renderPlanCard(msg.content || "");
|
|
584
|
+
break;
|
|
585
|
+
|
|
576
586
|
case "context_preview":
|
|
577
587
|
// Show a Context Card with tab screenshot between user message and assistant response
|
|
578
588
|
if (msg.tab) {
|
|
@@ -410,7 +410,7 @@ export function initPanels() {
|
|
|
410
410
|
if (vendor === (store.get('currentVendor') || "claude")) return;
|
|
411
411
|
var installed = store.get('installedVendors') || [];
|
|
412
412
|
if (installed.indexOf(vendor) === -1) return;
|
|
413
|
-
store.set({ currentVendor: vendor });
|
|
413
|
+
store.set({ currentVendor: vendor, currentModel: "", currentModels: [] });
|
|
414
414
|
var ws = getWs();
|
|
415
415
|
if (ws) ws.send(JSON.stringify({ type: "set_vendor", vendor: vendor }));
|
|
416
416
|
}
|
|
@@ -22,6 +22,23 @@ var fastModeIndicatorEl = null;
|
|
|
22
22
|
|
|
23
23
|
// --- Internal helpers ---
|
|
24
24
|
|
|
25
|
+
function getVendorUsageMeta(vendor) {
|
|
26
|
+
if (vendor === "codex") {
|
|
27
|
+
return {
|
|
28
|
+
icon: "/codex-avatar.png",
|
|
29
|
+
alt: "Codex",
|
|
30
|
+
href: "https://chatgpt.com/admin/usage",
|
|
31
|
+
title: "Check usage on ChatGPT",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
icon: "/claude-code-avatar.png",
|
|
36
|
+
alt: "Claude Code",
|
|
37
|
+
href: "https://claude.ai/settings/usage",
|
|
38
|
+
title: "Check usage on claude.ai",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
25
42
|
function rateLimitTypeLabel(type) {
|
|
26
43
|
if (!type) return "Usage";
|
|
27
44
|
var labels = {
|
|
@@ -159,7 +176,13 @@ function tickRateLimitUsage() {
|
|
|
159
176
|
|
|
160
177
|
// --- Exported functions ---
|
|
161
178
|
|
|
162
|
-
export function initRateLimit() {
|
|
179
|
+
export function initRateLimit() {
|
|
180
|
+
store.subscribe(function(state, prev) {
|
|
181
|
+
if (state.currentVendor !== prev.currentVendor && state.currentVendor && state.currentVendor !== "claude") {
|
|
182
|
+
clearScheduleDelay();
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
163
186
|
|
|
164
187
|
export function handleRateLimitEvent(msg) {
|
|
165
188
|
var isRejected = msg.status === "rejected";
|
|
@@ -180,7 +203,7 @@ export function handleRateLimitEvent(msg) {
|
|
|
180
203
|
if (rateLimitResetTimer) clearTimeout(rateLimitResetTimer);
|
|
181
204
|
// Auto-switch input to schedule mode: any message typed will be queued for after reset
|
|
182
205
|
var delayUntilReset = msg.resetsAt - Date.now();
|
|
183
|
-
if (delayUntilReset > 0) {
|
|
206
|
+
if (delayUntilReset > 0 && (store.get('currentVendor') || "claude") === "claude") {
|
|
184
207
|
setScheduleDelayMs(delayUntilReset + 60000); // +1min buffer after reset
|
|
185
208
|
}
|
|
186
209
|
rateLimitResetTimer = setTimeout(function () {
|
|
@@ -210,11 +233,8 @@ export function updateRateLimitUsage(msg) {
|
|
|
210
233
|
rateLimitUsageEl = document.createElement("a");
|
|
211
234
|
rateLimitUsageEl.id = "rate-limit-usage-link";
|
|
212
235
|
rateLimitUsageEl.className = "top-bar-pill pill-dim usage-check-link";
|
|
213
|
-
var vendor = store.get('currentVendor') || "claude";
|
|
214
|
-
rateLimitUsageEl.href = vendor === "codex" ? "https://chatgpt.com/admin/usage" : "https://claude.ai/settings/usage";
|
|
215
236
|
rateLimitUsageEl.target = "_blank";
|
|
216
237
|
rateLimitUsageEl.rel = "noopener";
|
|
217
|
-
rateLimitUsageEl.title = vendor === "codex" ? "Check usage on ChatGPT" : "Check usage on claude.ai";
|
|
218
238
|
var ref = document.getElementById("skip-perms-pill");
|
|
219
239
|
topBarActions.insertBefore(rateLimitUsageEl, ref);
|
|
220
240
|
}
|
|
@@ -231,7 +251,14 @@ export function updateRateLimitUsage(msg) {
|
|
|
231
251
|
}
|
|
232
252
|
|
|
233
253
|
var label = parts.length > 0 ? parts.join(" · ") : "Check usage";
|
|
234
|
-
|
|
254
|
+
var vendor = store.get('currentVendor') || "claude";
|
|
255
|
+
var meta = getVendorUsageMeta(vendor);
|
|
256
|
+
rateLimitUsageEl.href = meta.href;
|
|
257
|
+
rateLimitUsageEl.title = meta.title;
|
|
258
|
+
rateLimitUsageEl.innerHTML =
|
|
259
|
+
'<img src="' + meta.icon + '" class="usage-check-vendor-icon" alt="' + meta.alt + '">' +
|
|
260
|
+
'<span>' + label + '</span>' +
|
|
261
|
+
iconHtml("external-link");
|
|
235
262
|
refreshIcons();
|
|
236
263
|
|
|
237
264
|
// Start or stop live countdown tick
|
|
@@ -496,7 +496,7 @@ export function addAuthRequiredMessage(msg) {
|
|
|
496
496
|
div.className = "auth-required-msg";
|
|
497
497
|
|
|
498
498
|
var vendor = msg.vendor || "claude";
|
|
499
|
-
var loginCmd = msg.loginCommand || (vendor === "codex" ? "codex login" : "claude login");
|
|
499
|
+
var loginCmd = msg.loginCommand || (vendor === "codex" ? "codex login --device-auth" : "claude login");
|
|
500
500
|
var vendorName = msg.text || "Claude Code is not logged in.";
|
|
501
501
|
|
|
502
502
|
var header = document.createElement("div");
|
|
@@ -389,7 +389,13 @@ function createMobileSessionItem(s) {
|
|
|
389
389
|
|
|
390
390
|
var titleSpan = document.createElement("span");
|
|
391
391
|
titleSpan.className = "mobile-session-title";
|
|
392
|
-
|
|
392
|
+
if (s.bookmarked) {
|
|
393
|
+
var bookmarkIcon = document.createElement("span");
|
|
394
|
+
bookmarkIcon.className = "mobile-session-bookmark";
|
|
395
|
+
bookmarkIcon.innerHTML = iconHtml("star");
|
|
396
|
+
titleSpan.appendChild(bookmarkIcon);
|
|
397
|
+
}
|
|
398
|
+
titleSpan.appendChild(document.createTextNode(s.title || "New Session"));
|
|
393
399
|
el.appendChild(titleSpan);
|
|
394
400
|
|
|
395
401
|
// Unread badge (right side)
|
|
@@ -758,12 +764,37 @@ function renderMobileSessionsInto(container) {
|
|
|
758
764
|
|
|
759
765
|
// Sort by lastActivity descending
|
|
760
766
|
items.sort(function (a, b) {
|
|
767
|
+
var aBookmarked = !!(a.type === "loop" ? false : a.data && a.data.bookmarked);
|
|
768
|
+
var bBookmarked = !!(b.type === "loop" ? false : b.data && b.data.bookmarked);
|
|
769
|
+
if (aBookmarked !== bBookmarked) return aBookmarked ? -1 : 1;
|
|
761
770
|
return (b.lastActivity || 0) - (a.lastActivity || 0);
|
|
762
771
|
});
|
|
763
772
|
|
|
764
|
-
var
|
|
773
|
+
var bookmarkedItems = [];
|
|
774
|
+
var regularItems = [];
|
|
765
775
|
for (var n = 0; n < items.length; n++) {
|
|
766
776
|
var item = items[n];
|
|
777
|
+
if (item.type === "session" && item.data && item.data.bookmarked) {
|
|
778
|
+
bookmarkedItems.push(item);
|
|
779
|
+
} else {
|
|
780
|
+
regularItems.push(item);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (bookmarkedItems.length > 0) {
|
|
785
|
+
var bookmarkedHeader = document.createElement("div");
|
|
786
|
+
bookmarkedHeader.className = "mobile-sheet-group";
|
|
787
|
+
bookmarkedHeader.textContent = "Bookmarked";
|
|
788
|
+
container.appendChild(bookmarkedHeader);
|
|
789
|
+
|
|
790
|
+
for (var bi = 0; bi < bookmarkedItems.length; bi++) {
|
|
791
|
+
container.appendChild(createMobileSessionItem(bookmarkedItems[bi].data));
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
var currentGroup = "";
|
|
796
|
+
for (var ri = 0; ri < regularItems.length; ri++) {
|
|
797
|
+
var item = regularItems[ri];
|
|
767
798
|
var group = getDateGroup(item.lastActivity || 0);
|
|
768
799
|
if (group !== currentGroup) {
|
|
769
800
|
currentGroup = group;
|
|
@@ -929,6 +960,7 @@ function renderSheetSearch(listEl) {
|
|
|
929
960
|
function renderSearchResults(container, query) {
|
|
930
961
|
container.innerHTML = "";
|
|
931
962
|
var sorted = getCachedSessions().slice().sort(function (a, b) {
|
|
963
|
+
if (!!a.bookmarked !== !!b.bookmarked) return a.bookmarked ? -1 : 1;
|
|
932
964
|
return (b.lastActivity || 0) - (a.lastActivity || 0);
|
|
933
965
|
});
|
|
934
966
|
|
|
@@ -945,7 +977,13 @@ function renderSearchResults(container, query) {
|
|
|
945
977
|
|
|
946
978
|
var titleSpan = document.createElement("span");
|
|
947
979
|
titleSpan.className = "mobile-session-title";
|
|
948
|
-
|
|
980
|
+
if (s.bookmarked) {
|
|
981
|
+
var bookmarkIcon = document.createElement("span");
|
|
982
|
+
bookmarkIcon.className = "mobile-session-bookmark";
|
|
983
|
+
bookmarkIcon.innerHTML = iconHtml("star");
|
|
984
|
+
titleSpan.appendChild(bookmarkIcon);
|
|
985
|
+
}
|
|
986
|
+
titleSpan.appendChild(document.createTextNode(title));
|
|
949
987
|
el.appendChild(titleSpan);
|
|
950
988
|
|
|
951
989
|
if (s.isProcessing) {
|