@oar-sh/oar 0.9.15 → 0.9.17
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/.github/extensions/web-relay/polling/polling-loop.mjs +14 -87
- package/CHANGELOG.md +305 -0
- package/README.md +12 -11
- package/package.json +2 -1
- package/server/claude-worker/claude-attachments.mjs +7 -4
- package/server/claude-worker/claude-remote-relay-tool.mjs +36 -1
- package/server/claude-worker/claude-sdk-adapter.mjs +167 -9
- package/server/claude-worker/claude-session-process.mjs +131 -33
- package/server/claude-worker/claude-session-worker-main.mjs +266 -0
- package/server/claude-worker/claude-session-worker.mjs +2 -253
- package/server/claude-worker/claude-turn-failure.mjs +8 -0
- package/server/claude-worker/claude-turn-publisher.mjs +282 -13
- package/server/claude-worker/claude-usage-totals.mjs +108 -0
- package/server/claude-worker/sdk-message-normalizer.mjs +55 -0
- package/server/copilot-worker/copilot-sdk-adapter.mjs +18 -4
- package/server/copilot-worker/copilot-sdk-session-process.mjs +73 -7
- package/server/db-schema.mjs +115 -0
- package/server/deepseek-worker/deepseek-claude-backend.mjs +433 -0
- package/server/deepseek-worker/deepseek-session-worker.mjs +37 -0
- package/server/migrations/0019-relay-event-subscription-options.mjs +106 -0
- package/server/migrations/0020-conversation-may-create-sessions.mjs +67 -0
- package/server/migrations/0021-conversation-group-agent-marks.mjs +77 -0
- package/server/migrations/0022-relay-schedules.mjs +142 -0
- package/server/migrations/0023-relay-asks.mjs +141 -0
- package/server/migrations/0024-deepseek-usage-totals.mjs +151 -0
- package/server/migrations/0025-deepseek-usage-requests-daily.mjs +179 -0
- package/server/migrations/0026-deepseek-usage-served-models.mjs +222 -0
- package/server/migrations/0027-deepseek-usage-checkpoint-runs.mjs +101 -0
- package/server/migrations/0028-deepseek-usage-checkpoint-request-runs.mjs +99 -0
- package/server/migrations/0029-deepseek-balance-rises.mjs +99 -0
- package/server/migrations/0030-deepseek-usage-actuals.mjs +123 -0
- package/server/public/app/api-client.js +53 -0
- package/server/public/app/ask-user-view.js +3 -0
- package/server/public/app/bootstrap.js +162 -16
- package/server/public/app/context-tier-options.mjs +4 -0
- package/server/public/app/context-usage-view.mjs +17 -0
- package/server/public/app/conversation-group-order.mjs +35 -0
- package/server/public/app/conversation-provider-indicator.mjs +7 -0
- package/server/public/app/conversation-view.js +2 -0
- package/server/public/app/deepseek-settings-ui.js +342 -0
- package/server/public/app/inbox-ui.js +367 -0
- package/server/public/app/inbox-view.mjs +370 -0
- package/server/public/app/journal-view.js +54 -5
- package/server/public/app/model-selector-options.mjs +11 -0
- package/server/public/app/model-vision-support.mjs +2 -0
- package/server/public/app/no-conversation-state.mjs +1 -1
- package/server/public/app/plan-usage-view.mjs +165 -13
- package/server/public/app/provider-readiness.mjs +4 -1
- package/server/public/app/relay-error-ctas.mjs +8 -0
- package/server/public/app/relay-event-subscriptions-ui.js +4 -2
- package/server/public/app/relay-event-view.mjs +33 -7
- package/server/public/app/relay-schedule-view.mjs +119 -0
- package/server/public/app/relay-schedules-ui.js +172 -0
- package/server/public/app/settings-modal.js +11 -0
- package/server/public/app/settings-tabs.js +1 -1
- package/server/public/app/socket-handlers.js +37 -3
- package/server/public/app/store.js +18 -5
- package/server/public/index.html +567 -35
- package/server/relay-tools.md +18 -3
- package/server/repositories/conversation-group-repository.mjs +110 -17
- package/server/repositories/remote-relay-repository.mjs +20 -2
- package/server/repositories/session-repository.mjs +7 -1
- package/server/routes/ask-user-routes.mjs +57 -3
- package/server/routes/cache-routes.mjs +6 -0
- package/server/routes/conversation-group-routes.mjs +19 -3
- package/server/routes/deepseek-usage-import-routes.mjs +72 -0
- package/server/routes/messages-routes.mjs +195 -18
- package/server/routes/relay-ask-routes.mjs +387 -0
- package/server/routes/relay-event-routes.mjs +3 -1
- package/server/routes/relay-schedule-routes.mjs +57 -0
- package/server/routes/sessions-routes.mjs +932 -97
- package/server/server-runtime.mjs +203 -11
- package/server/services/about-service.mjs +1 -0
- package/server/services/cache-rebuild-service.mjs +19 -2
- package/server/services/claude-session-leftovers.mjs +226 -0
- package/server/services/conversation-preferences-service.mjs +17 -0
- package/server/services/deepseek-balance-service.mjs +102 -0
- package/server/services/deepseek-settings-service.mjs +380 -0
- package/server/services/deepseek-usage-import.mjs +471 -0
- package/server/services/model-variant-catalog-service.mjs +1 -0
- package/server/services/plan-usage-contract.mjs +100 -5
- package/server/services/plan-usage-deepseek.mjs +931 -0
- package/server/services/plan-usage-service.mjs +431 -0
- package/server/services/provider-model-selection.mjs +1 -0
- package/server/services/provider-reasoning-effort.mjs +15 -2
- package/server/services/relay-ask-link-service.mjs +174 -0
- package/server/services/relay-ask-service.mjs +604 -0
- package/server/services/relay-event-service.mjs +589 -73
- package/server/services/relay-schedule-service.mjs +596 -0
- package/server/services/remote-relay-caller-context.mjs +89 -20
- package/server/services/remote-relay-dispatcher.mjs +958 -31
- package/server/services/session-worker-launch-service.mjs +233 -82
- package/server/services/worker-secret-redaction.mjs +318 -0
- package/shared/context-window-fallbacks.mjs +3 -0
- package/shared/deepseek-api.mjs +137 -0
- package/shared/deepseek-models.mjs +114 -0
- package/shared/deepseek-pricing.mjs +146 -0
- package/shared/host-claude-session-env.mjs +101 -0
- package/shared/model-id.mjs +7 -0
- package/shared/preview-tool-core.mjs +1 -1
- package/shared/provider-routing.mjs +2 -2
- package/shared/relay-asks.mjs +145 -0
- package/shared/relay-events.mjs +268 -18
- package/shared/relay-schedules.mjs +128 -0
- package/shared/remote-relay-contract.mjs +554 -26
- package/shared/remote-relay-tool-core.mjs +16 -5
- package/shared/steer-settle-failure.mjs +1 -0
- package/shared/worker-runtime/direct-openai-image.mjs +128 -0
- package/shared/worker-runtime/worker-log-file.mjs +60 -0
package/server/public/index.html
CHANGED
|
@@ -295,6 +295,16 @@
|
|
|
295
295
|
--provider-cursor: #a78bfa;
|
|
296
296
|
--provider-grok: #e879f9;
|
|
297
297
|
--provider-claude-cloud: #7dd3fc;
|
|
298
|
+
/* DeepSeek's blue, toward indigo so it reads apart from Copilot's. */
|
|
299
|
+
--provider-deepseek: #8b9dff;
|
|
300
|
+
/* The usage charts' series, in a fixed order (blue, orange, green,
|
|
301
|
+
amber; grey for "other"), stepped for the dark surface and checked
|
|
302
|
+
for colour-vision deficiency and contrast against it. */
|
|
303
|
+
--plan-usage-series-1: #3987e5;
|
|
304
|
+
--plan-usage-series-2: #d95926;
|
|
305
|
+
--plan-usage-series-3: #199e70;
|
|
306
|
+
--plan-usage-series-4: #c98500;
|
|
307
|
+
--plan-usage-series-5: #8b949e;
|
|
298
308
|
--viewport-top-offset: 0px;
|
|
299
309
|
--header-safe-top: max(env(safe-area-inset-top, 0px), var(--viewport-top-offset, 0px));
|
|
300
310
|
--chat-header-top-base-desktop: 14px;
|
|
@@ -359,6 +369,13 @@
|
|
|
359
369
|
--provider-cursor: #6b3fd4;
|
|
360
370
|
--provider-grok: #a21caf;
|
|
361
371
|
--provider-claude-cloud: #0369a1;
|
|
372
|
+
--provider-deepseek: #3b5bdb;
|
|
373
|
+
/* The same series order, stepped for the white surface. */
|
|
374
|
+
--plan-usage-series-1: #2a78d6;
|
|
375
|
+
--plan-usage-series-2: #eb6834;
|
|
376
|
+
--plan-usage-series-3: #1baf7a;
|
|
377
|
+
--plan-usage-series-4: #eda100;
|
|
378
|
+
--plan-usage-series-5: #656d76;
|
|
362
379
|
--inline-code-bg: #eff1f3;
|
|
363
380
|
}
|
|
364
381
|
:root {
|
|
@@ -788,6 +805,151 @@
|
|
|
788
805
|
}
|
|
789
806
|
.status-empty { color: var(--muted); text-align: center; }
|
|
790
807
|
|
|
808
|
+
/* The Inbox: the sidebar button with its count, the view in the
|
|
809
|
+
transcript's place (status-view's frame), and the card a question that
|
|
810
|
+
does not block shows in its session. Every text in it is an agent's,
|
|
811
|
+
set as plain text. */
|
|
812
|
+
#inbox-btn {
|
|
813
|
+
flex: 0 0 auto;
|
|
814
|
+
display: inline-flex;
|
|
815
|
+
align-items: center;
|
|
816
|
+
gap: 6px;
|
|
817
|
+
min-width: 72px;
|
|
818
|
+
padding: 10px 12px;
|
|
819
|
+
background: var(--bg3);
|
|
820
|
+
color: var(--text);
|
|
821
|
+
border: 1px solid var(--border);
|
|
822
|
+
border-radius: 8px;
|
|
823
|
+
cursor: pointer;
|
|
824
|
+
font-weight: 600;
|
|
825
|
+
font-size: var(--fs-meta-md);
|
|
826
|
+
white-space: nowrap;
|
|
827
|
+
}
|
|
828
|
+
#inbox-btn:hover, #inbox-btn[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }
|
|
829
|
+
.inbox-count {
|
|
830
|
+
min-width: 18px;
|
|
831
|
+
padding: 1px 6px;
|
|
832
|
+
border-radius: 999px;
|
|
833
|
+
background: var(--accent);
|
|
834
|
+
color: var(--bg);
|
|
835
|
+
font-size: var(--fs-meta-xs);
|
|
836
|
+
font-variant-numeric: tabular-nums;
|
|
837
|
+
text-align: center;
|
|
838
|
+
}
|
|
839
|
+
.inbox-count:empty { display: none; }
|
|
840
|
+
body.inbox-view-active #input-area { display: none; }
|
|
841
|
+
body.inbox-view-active #pending-question-banner { display: none; }
|
|
842
|
+
.inbox-view { display: grid; gap: 14px; padding: 4px 0 24px; }
|
|
843
|
+
.inbox-filter { display: flex; gap: 6px; flex-wrap: wrap; }
|
|
844
|
+
.inbox-filter-option {
|
|
845
|
+
padding: 6px 12px;
|
|
846
|
+
border: 1px solid var(--border);
|
|
847
|
+
border-radius: 999px;
|
|
848
|
+
background: var(--bg2);
|
|
849
|
+
color: var(--text);
|
|
850
|
+
cursor: pointer;
|
|
851
|
+
font-size: var(--fs-meta-sm);
|
|
852
|
+
}
|
|
853
|
+
.inbox-filter-option.active { border-color: var(--accent); color: var(--accent); }
|
|
854
|
+
.inbox-relay { display: grid; gap: 10px; }
|
|
855
|
+
.inbox-relay-name { margin: 6px 0 0; font-size: var(--fs-meta-md); color: var(--muted); font-weight: 600; }
|
|
856
|
+
.inbox-relay-unreachable, .inbox-empty { margin: 0; color: var(--muted); font-size: var(--fs-meta-sm); }
|
|
857
|
+
.inbox-divider {
|
|
858
|
+
margin-top: 6px;
|
|
859
|
+
padding-top: 8px;
|
|
860
|
+
border-top: 1px dashed var(--border);
|
|
861
|
+
color: var(--muted);
|
|
862
|
+
font-size: var(--fs-meta-xs);
|
|
863
|
+
text-transform: uppercase;
|
|
864
|
+
letter-spacing: 0.04em;
|
|
865
|
+
}
|
|
866
|
+
.inbox-item {
|
|
867
|
+
display: grid;
|
|
868
|
+
gap: 8px;
|
|
869
|
+
min-width: 0;
|
|
870
|
+
padding: 12px 14px;
|
|
871
|
+
border: 1px solid var(--border);
|
|
872
|
+
border-radius: 10px;
|
|
873
|
+
background: var(--bg2);
|
|
874
|
+
}
|
|
875
|
+
.inbox-item[data-status="answered"], .inbox-item[data-status="dismissed"] { opacity: 0.75; }
|
|
876
|
+
.inbox-item-head { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; color: var(--muted); font-size: var(--fs-meta-xs); }
|
|
877
|
+
.inbox-item-kind { font-weight: 600; color: var(--accent); }
|
|
878
|
+
.inbox-item-urgent { color: var(--danger); font-weight: 600; text-transform: uppercase; }
|
|
879
|
+
.inbox-item-relay { padding: 0 6px; border: 1px solid var(--border); border-radius: 999px; }
|
|
880
|
+
.inbox-item-session { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; font-size: var(--fs-meta-sm); }
|
|
881
|
+
.inbox-open-session {
|
|
882
|
+
padding: 0;
|
|
883
|
+
border: 0;
|
|
884
|
+
background: none;
|
|
885
|
+
color: var(--accent);
|
|
886
|
+
cursor: pointer;
|
|
887
|
+
font: inherit;
|
|
888
|
+
text-align: left;
|
|
889
|
+
text-decoration: underline;
|
|
890
|
+
}
|
|
891
|
+
.inbox-open-there { color: var(--accent); }
|
|
892
|
+
.inbox-item-asker { color: var(--muted); }
|
|
893
|
+
.inbox-item-header { font-weight: 600; font-size: var(--fs-meta-sm); }
|
|
894
|
+
.inbox-item-question, .inbox-item-recommendation { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
895
|
+
.inbox-item-recommendation { color: var(--muted); font-size: var(--fs-meta-sm); }
|
|
896
|
+
.inbox-item-detail summary { cursor: pointer; color: var(--muted); font-size: var(--fs-meta-sm); }
|
|
897
|
+
.inbox-item-detail-text {
|
|
898
|
+
margin: 6px 0 0;
|
|
899
|
+
padding: 8px 10px;
|
|
900
|
+
max-height: 320px;
|
|
901
|
+
overflow: auto;
|
|
902
|
+
border-radius: 8px;
|
|
903
|
+
background: var(--bg3);
|
|
904
|
+
white-space: pre-wrap;
|
|
905
|
+
overflow-wrap: anywhere;
|
|
906
|
+
font-size: var(--fs-meta-sm);
|
|
907
|
+
}
|
|
908
|
+
.inbox-item-outcome { color: var(--success); font-size: var(--fs-meta-sm); overflow-wrap: anywhere; }
|
|
909
|
+
.inbox-item-options, .inbox-item-actions { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
910
|
+
.inbox-item-reply { display: grid; gap: 8px; }
|
|
911
|
+
.inbox-answer-text {
|
|
912
|
+
width: 100%;
|
|
913
|
+
box-sizing: border-box;
|
|
914
|
+
padding: 8px 10px;
|
|
915
|
+
border: 1px solid var(--border);
|
|
916
|
+
border-radius: 8px;
|
|
917
|
+
background: var(--bg);
|
|
918
|
+
color: var(--text);
|
|
919
|
+
font: inherit;
|
|
920
|
+
resize: vertical;
|
|
921
|
+
}
|
|
922
|
+
.inbox-choice, .inbox-answer, .inbox-dismiss, .inbox-open-session-button, .inbox-open-there-button {
|
|
923
|
+
min-height: 36px;
|
|
924
|
+
padding: 6px 14px;
|
|
925
|
+
border: 1px solid var(--border);
|
|
926
|
+
border-radius: 8px;
|
|
927
|
+
background: var(--bg3);
|
|
928
|
+
color: var(--text);
|
|
929
|
+
cursor: pointer;
|
|
930
|
+
font: inherit;
|
|
931
|
+
text-decoration: none;
|
|
932
|
+
display: inline-flex;
|
|
933
|
+
align-items: center;
|
|
934
|
+
gap: 6px;
|
|
935
|
+
}
|
|
936
|
+
.inbox-choice.recommended { border-color: var(--accent); }
|
|
937
|
+
.inbox-recommended-tag { color: var(--accent); font-size: var(--fs-meta-xs); }
|
|
938
|
+
.inbox-answer { border-color: var(--accent); color: var(--accent); }
|
|
939
|
+
.inbox-dismiss { color: var(--muted); }
|
|
940
|
+
.inbox-view button:disabled, .relay-ask-container button:disabled { opacity: 0.5; cursor: wait; }
|
|
941
|
+
.relay-ask-container { max-width: 760px; }
|
|
942
|
+
/* The phone: one column, buttons the full width. */
|
|
943
|
+
@media (max-width: 680px) {
|
|
944
|
+
#inbox-btn { min-width: 64px; padding: 9px 10px; }
|
|
945
|
+
.inbox-item-options, .inbox-item-actions { flex-direction: column; }
|
|
946
|
+
.inbox-choice, .inbox-answer, .inbox-dismiss, .inbox-open-session-button, .inbox-open-there-button {
|
|
947
|
+
width: 100%;
|
|
948
|
+
justify-content: center;
|
|
949
|
+
}
|
|
950
|
+
.inbox-item { padding: 12px; }
|
|
951
|
+
}
|
|
952
|
+
|
|
791
953
|
#conv-list { flex: 1; overflow-y: auto; padding: 0 8px 8px; }
|
|
792
954
|
.conv-list-footer {
|
|
793
955
|
padding: 10px 12px 6px;
|
|
@@ -842,6 +1004,7 @@
|
|
|
842
1004
|
.conv-provider-indicator[data-provider="claude"] { color: var(--provider-claude); }
|
|
843
1005
|
.conv-provider-indicator[data-provider="cursor"] { color: var(--provider-cursor); }
|
|
844
1006
|
.conv-provider-indicator[data-provider="grok"] { color: var(--provider-grok); }
|
|
1007
|
+
.conv-provider-indicator[data-provider="deepseek"] { color: var(--provider-deepseek); }
|
|
845
1008
|
.conv-provider-indicator[data-provider="claude-cloud"] { color: var(--provider-claude-cloud); }
|
|
846
1009
|
.conv-item.worker-ui-offline .conv-title,
|
|
847
1010
|
#chat-title[data-ui-state="offline"] { color: var(--conversation-title-offline); }
|
|
@@ -1310,6 +1473,74 @@
|
|
|
1310
1473
|
font-size: var(--fs-meta-md);
|
|
1311
1474
|
width: min(260px, 100%);
|
|
1312
1475
|
}
|
|
1476
|
+
/* The DeepSeek tab's key, base URL and monthly budget take the text
|
|
1477
|
+
inputs' look (an input left to the browser is a white box in dark). */
|
|
1478
|
+
#settings-provider-panel-deepseek input[type="password"],
|
|
1479
|
+
#settings-provider-panel-deepseek input[type="url"],
|
|
1480
|
+
#settings-provider-panel-deepseek input[type="number"] {
|
|
1481
|
+
background: var(--bg);
|
|
1482
|
+
color: var(--text);
|
|
1483
|
+
border: 1px solid var(--border);
|
|
1484
|
+
border-radius: 6px;
|
|
1485
|
+
padding: 6px 12px;
|
|
1486
|
+
outline: none;
|
|
1487
|
+
font-size: var(--fs-meta-md);
|
|
1488
|
+
width: min(360px, 100%);
|
|
1489
|
+
}
|
|
1490
|
+
/* A select is as wide as its longest option (the commit attribution's
|
|
1491
|
+
runs to ~290 px): kept inside the panel on a narrow phone. */
|
|
1492
|
+
#settings-provider-panel-deepseek select {
|
|
1493
|
+
max-width: 100%;
|
|
1494
|
+
}
|
|
1495
|
+
/* "No longer used" under the starting balance: the warning look of the
|
|
1496
|
+
composer's model banner, apart from the help text above it. */
|
|
1497
|
+
#deepseek-starting-balance-status {
|
|
1498
|
+
background: var(--bg2);
|
|
1499
|
+
background: color-mix(in srgb, var(--warn) 14%, var(--bg2));
|
|
1500
|
+
border: 1px solid var(--warn);
|
|
1501
|
+
color: var(--warn);
|
|
1502
|
+
border-radius: 8px;
|
|
1503
|
+
padding: 6px 10px;
|
|
1504
|
+
margin-top: 6px;
|
|
1505
|
+
}
|
|
1506
|
+
/* Import usage export: the two file pickers in the panel's colours, their
|
|
1507
|
+
button drawn like the panel's other buttons. */
|
|
1508
|
+
.deepseek-usage-import {
|
|
1509
|
+
margin-top: 14px;
|
|
1510
|
+
padding-top: 12px;
|
|
1511
|
+
border-top: 1px solid var(--border);
|
|
1512
|
+
display: flex;
|
|
1513
|
+
flex-direction: column;
|
|
1514
|
+
gap: 6px;
|
|
1515
|
+
min-width: 0;
|
|
1516
|
+
}
|
|
1517
|
+
.deepseek-usage-import-files {
|
|
1518
|
+
display: grid;
|
|
1519
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
1520
|
+
gap: 6px 10px;
|
|
1521
|
+
align-items: center;
|
|
1522
|
+
}
|
|
1523
|
+
.deepseek-usage-import input[type="file"] {
|
|
1524
|
+
color: var(--text);
|
|
1525
|
+
font-size: var(--fs-meta-md);
|
|
1526
|
+
min-width: 0;
|
|
1527
|
+
max-width: 100%;
|
|
1528
|
+
}
|
|
1529
|
+
.deepseek-usage-import input[type="file"]::file-selector-button {
|
|
1530
|
+
border: 1px solid var(--border);
|
|
1531
|
+
background: var(--bg2);
|
|
1532
|
+
color: var(--text);
|
|
1533
|
+
border-radius: 8px;
|
|
1534
|
+
height: 30px;
|
|
1535
|
+
padding: 0 10px;
|
|
1536
|
+
margin-right: 8px;
|
|
1537
|
+
font: inherit;
|
|
1538
|
+
cursor: pointer;
|
|
1539
|
+
}
|
|
1540
|
+
.deepseek-usage-import-status:empty { display: none; }
|
|
1541
|
+
@media (max-width: 520px) {
|
|
1542
|
+
.deepseek-usage-import-files { grid-template-columns: minmax(0, 1fr); }
|
|
1543
|
+
}
|
|
1313
1544
|
.settings-row input[type="checkbox"] {
|
|
1314
1545
|
width: 18px;
|
|
1315
1546
|
height: 18px;
|
|
@@ -2508,6 +2739,9 @@
|
|
|
2508
2739
|
.ctx-attribution-select { font-size: var(--fs-meta-sm); max-width: 100%; }
|
|
2509
2740
|
.ctx-attribution-note { margin-top: 6px; font-size: var(--fs-meta-sm); color: var(--muted); line-height: 1.4; overflow-wrap: anywhere; }
|
|
2510
2741
|
.ctx-attribution-note code { font-size: inherit; }
|
|
2742
|
+
.ctx-agent-sessions { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 6px; }
|
|
2743
|
+
.ctx-agent-sessions-row { display: flex; align-items: flex-start; gap: 8px; font-size: 0.85rem; cursor: pointer; }
|
|
2744
|
+
.ctx-agent-sessions-row input { margin-top: 2px; }
|
|
2511
2745
|
.ctx-thinking {
|
|
2512
2746
|
margin-top: 14px;
|
|
2513
2747
|
padding-top: 12px;
|
|
@@ -2715,6 +2949,25 @@
|
|
|
2715
2949
|
padding: 2px 0;
|
|
2716
2950
|
}
|
|
2717
2951
|
.plan-usage-details summary:hover { color: var(--text); }
|
|
2952
|
+
/* A card's figures (plan-usage-view.mjs renderFact): label and hint on the
|
|
2953
|
+
left, the value on the right, one row each. */
|
|
2954
|
+
.plan-usage-facts {
|
|
2955
|
+
display: grid;
|
|
2956
|
+
gap: 8px;
|
|
2957
|
+
margin: 12px 0 0;
|
|
2958
|
+
padding-top: 10px;
|
|
2959
|
+
border-top: 1px solid var(--border);
|
|
2960
|
+
}
|
|
2961
|
+
.plan-usage-fact {
|
|
2962
|
+
display: flex;
|
|
2963
|
+
align-items: baseline;
|
|
2964
|
+
justify-content: space-between;
|
|
2965
|
+
gap: 12px;
|
|
2966
|
+
font-size: 0.84rem;
|
|
2967
|
+
}
|
|
2968
|
+
.plan-usage-fact dt { display: flex; flex-direction: column; gap: 1px; min-width: 0; font-weight: 500; }
|
|
2969
|
+
.plan-usage-fact-hint { font-size: 0.72rem; font-weight: 400; color: var(--muted); }
|
|
2970
|
+
.plan-usage-fact dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
2718
2971
|
.plan-usage-detail-note {
|
|
2719
2972
|
font-size: 0.74rem;
|
|
2720
2973
|
color: var(--muted);
|
|
@@ -2724,14 +2977,22 @@
|
|
|
2724
2977
|
.plan-usage-detail-table { width: 100%; border-collapse: collapse; margin-top: 6px; }
|
|
2725
2978
|
.plan-usage-detail-table td { padding: 5px 2px; border-bottom: 1px solid var(--border); }
|
|
2726
2979
|
.plan-usage-detail-table tr:last-child td { border-bottom: none; }
|
|
2727
|
-
|
|
2728
|
-
|
|
2980
|
+
/* The label cell stays a table cell (a flex cell does not stretch to the
|
|
2981
|
+
row, and its border then steps against the value's): the hint goes
|
|
2982
|
+
under the label as a block. */
|
|
2983
|
+
.plan-usage-detail-hint { display: block; margin-top: 2px; font-size: 0.7rem; color: var(--muted); }
|
|
2729
2984
|
.plan-usage-detail-value {
|
|
2730
2985
|
text-align: right;
|
|
2731
2986
|
font-variant-numeric: tabular-nums;
|
|
2732
2987
|
white-space: nowrap;
|
|
2733
2988
|
vertical-align: top;
|
|
2734
2989
|
}
|
|
2990
|
+
/* On a phone a long value (tokens by model) wraps instead of pushing the
|
|
2991
|
+
card wider than the screen. */
|
|
2992
|
+
@media (max-width: 520px) {
|
|
2993
|
+
.plan-usage-details .plan-usage-detail-value { white-space: normal; }
|
|
2994
|
+
}
|
|
2995
|
+
.plan-usage-detail-part { white-space: nowrap; }
|
|
2735
2996
|
.plan-usage-card-foot {
|
|
2736
2997
|
display: flex;
|
|
2737
2998
|
align-items: center;
|
|
@@ -2744,6 +3005,145 @@
|
|
|
2744
3005
|
}
|
|
2745
3006
|
.plan-usage-link { color: var(--accent); text-decoration: none; }
|
|
2746
3007
|
.plan-usage-link:hover { text-decoration: underline; }
|
|
3008
|
+
/* Usage charts (plan-usage-view.mjs renderChart): stacked columns and
|
|
3009
|
+
bars from the theme's series colours; text stays in the text colours. */
|
|
3010
|
+
.plan-usage-chart {
|
|
3011
|
+
margin: 12px 0 0;
|
|
3012
|
+
padding-top: 10px;
|
|
3013
|
+
border-top: 1px solid var(--border);
|
|
3014
|
+
}
|
|
3015
|
+
.plan-usage-chart-head {
|
|
3016
|
+
display: flex;
|
|
3017
|
+
align-items: baseline;
|
|
3018
|
+
justify-content: space-between;
|
|
3019
|
+
gap: 10px;
|
|
3020
|
+
flex-wrap: wrap;
|
|
3021
|
+
margin-bottom: 8px;
|
|
3022
|
+
}
|
|
3023
|
+
.plan-usage-chart-label { font-size: 0.88rem; font-weight: 600; }
|
|
3024
|
+
.plan-usage-chart-summary { font-size: 0.82rem; color: var(--text); font-variant-numeric: tabular-nums; }
|
|
3025
|
+
.plan-usage-chart-columns {
|
|
3026
|
+
position: relative;
|
|
3027
|
+
display: grid;
|
|
3028
|
+
grid-template-columns: repeat(var(--plan-usage-columns, 30), minmax(0, 1fr));
|
|
3029
|
+
gap: 2px;
|
|
3030
|
+
height: 72px;
|
|
3031
|
+
padding-bottom: 18px;
|
|
3032
|
+
border-bottom: 1px solid var(--border);
|
|
3033
|
+
}
|
|
3034
|
+
.plan-usage-chart-col {
|
|
3035
|
+
position: relative;
|
|
3036
|
+
display: flex;
|
|
3037
|
+
align-items: flex-end;
|
|
3038
|
+
min-width: 0;
|
|
3039
|
+
height: 100%;
|
|
3040
|
+
border-radius: 2px;
|
|
3041
|
+
outline: none;
|
|
3042
|
+
}
|
|
3043
|
+
.plan-usage-chart-col:hover, .plan-usage-chart-col:focus-visible { background: var(--bg3); }
|
|
3044
|
+
.plan-usage-chart-col:focus-visible { box-shadow: 0 0 0 2px var(--accent); }
|
|
3045
|
+
.plan-usage-chart-stack {
|
|
3046
|
+
display: flex;
|
|
3047
|
+
flex-direction: column-reverse;
|
|
3048
|
+
width: 100%;
|
|
3049
|
+
height: 100%;
|
|
3050
|
+
justify-content: flex-start;
|
|
3051
|
+
}
|
|
3052
|
+
.plan-usage-chart-col-empty .plan-usage-chart-stack::before {
|
|
3053
|
+
content: '';
|
|
3054
|
+
display: block;
|
|
3055
|
+
height: 2px;
|
|
3056
|
+
background: var(--border);
|
|
3057
|
+
}
|
|
3058
|
+
.plan-usage-chart-columns .plan-usage-chart-seg {
|
|
3059
|
+
display: block;
|
|
3060
|
+
width: 100%;
|
|
3061
|
+
min-height: 2px;
|
|
3062
|
+
margin-top: 2px;
|
|
3063
|
+
}
|
|
3064
|
+
.plan-usage-chart-columns .plan-usage-chart-seg:last-child { border-radius: 4px 4px 0 0; }
|
|
3065
|
+
.plan-usage-chart-axis {
|
|
3066
|
+
position: absolute;
|
|
3067
|
+
left: 0;
|
|
3068
|
+
right: 0;
|
|
3069
|
+
bottom: 0;
|
|
3070
|
+
display: flex;
|
|
3071
|
+
justify-content: space-between;
|
|
3072
|
+
font-size: 0.68rem;
|
|
3073
|
+
color: var(--muted);
|
|
3074
|
+
}
|
|
3075
|
+
.plan-usage-chart-bars { display: flex; flex-direction: column; gap: 8px; }
|
|
3076
|
+
.plan-usage-chart-row {
|
|
3077
|
+
position: relative;
|
|
3078
|
+
display: grid;
|
|
3079
|
+
grid-template-columns: minmax(80px, 1fr) 3fr auto;
|
|
3080
|
+
align-items: center;
|
|
3081
|
+
gap: 10px;
|
|
3082
|
+
font-size: 0.82rem;
|
|
3083
|
+
border-radius: 4px;
|
|
3084
|
+
outline: none;
|
|
3085
|
+
}
|
|
3086
|
+
.plan-usage-chart-row:focus-visible { box-shadow: 0 0 0 2px var(--accent); }
|
|
3087
|
+
/* A model's name wraps on a narrow screen rather than being cut. */
|
|
3088
|
+
.plan-usage-chart-row-label { min-width: 0; line-height: 1.25; overflow-wrap: anywhere; }
|
|
3089
|
+
.plan-usage-chart-row-value { font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
3090
|
+
.plan-usage-chart-bar {
|
|
3091
|
+
display: flex;
|
|
3092
|
+
gap: 2px;
|
|
3093
|
+
height: 14px;
|
|
3094
|
+
border-radius: 4px;
|
|
3095
|
+
overflow: hidden;
|
|
3096
|
+
background: var(--bg3);
|
|
3097
|
+
}
|
|
3098
|
+
.plan-usage-chart-bar .plan-usage-chart-seg { display: block; height: 100%; min-width: 2px; }
|
|
3099
|
+
.plan-usage-chart-bar .plan-usage-chart-seg:first-child { border-radius: 4px 0 0 4px; }
|
|
3100
|
+
.plan-usage-chart-bar .plan-usage-chart-seg:last-child { border-radius: 0 4px 4px 0; }
|
|
3101
|
+
.plan-usage-chart-tip {
|
|
3102
|
+
display: none;
|
|
3103
|
+
position: absolute;
|
|
3104
|
+
bottom: calc(100% + 4px);
|
|
3105
|
+
left: 50%;
|
|
3106
|
+
transform: translateX(-50%);
|
|
3107
|
+
z-index: 2;
|
|
3108
|
+
max-width: 260px;
|
|
3109
|
+
padding: 4px 8px;
|
|
3110
|
+
border: 1px solid var(--border);
|
|
3111
|
+
border-radius: 6px;
|
|
3112
|
+
background: var(--bg2);
|
|
3113
|
+
color: var(--text);
|
|
3114
|
+
font-size: 0.74rem;
|
|
3115
|
+
line-height: 1.4;
|
|
3116
|
+
white-space: normal;
|
|
3117
|
+
text-align: center;
|
|
3118
|
+
pointer-events: none;
|
|
3119
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
|
|
3120
|
+
}
|
|
3121
|
+
.plan-usage-chart-col:hover .plan-usage-chart-tip,
|
|
3122
|
+
.plan-usage-chart-col:focus .plan-usage-chart-tip,
|
|
3123
|
+
.plan-usage-chart-row:hover .plan-usage-chart-tip,
|
|
3124
|
+
.plan-usage-chart-row:focus .plan-usage-chart-tip { display: block; }
|
|
3125
|
+
.plan-usage-chart-col .plan-usage-chart-tip { width: 180px; }
|
|
3126
|
+
.plan-usage-chart-col:first-child .plan-usage-chart-tip,
|
|
3127
|
+
.plan-usage-chart-col:nth-child(-n+6) .plan-usage-chart-tip { left: 0; transform: none; text-align: left; }
|
|
3128
|
+
.plan-usage-chart-col:nth-last-child(-n+7):not(.plan-usage-chart-axis) .plan-usage-chart-tip { left: auto; right: 0; transform: none; text-align: right; }
|
|
3129
|
+
.plan-usage-chart-legend {
|
|
3130
|
+
display: flex;
|
|
3131
|
+
flex-wrap: wrap;
|
|
3132
|
+
gap: 4px 14px;
|
|
3133
|
+
margin: 8px 0 0;
|
|
3134
|
+
padding: 0;
|
|
3135
|
+
list-style: none;
|
|
3136
|
+
font-size: 0.74rem;
|
|
3137
|
+
color: var(--muted);
|
|
3138
|
+
}
|
|
3139
|
+
.plan-usage-chart-legend li { display: inline-flex; align-items: center; gap: 5px; }
|
|
3140
|
+
.plan-usage-chart-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; }
|
|
3141
|
+
/* A table wider than a narrow screen scrolls inside the card. */
|
|
3142
|
+
.plan-usage-chart-table { margin-top: 6px; font-size: 0.78rem; max-width: 100%; overflow-x: auto; }
|
|
3143
|
+
.plan-usage-chart-table summary { cursor: pointer; color: var(--muted); padding: 2px 0; }
|
|
3144
|
+
.plan-usage-chart-table summary:hover { color: var(--text); }
|
|
3145
|
+
.plan-usage-chart-table th { text-align: left; font-weight: 500; color: var(--muted); padding: 4px 2px; border-bottom: 1px solid var(--border); }
|
|
3146
|
+
.plan-usage-chart-table thead th:not(:first-child) { text-align: right; }
|
|
2747
3147
|
/* About OAR: the plan-usage cards and tables, stacked. */
|
|
2748
3148
|
.about-modal { display: flex; flex-direction: column; gap: 12px; }
|
|
2749
3149
|
.about-section .plan-usage-card-head { margin-bottom: 4px; }
|
|
@@ -3038,6 +3438,7 @@
|
|
|
3038
3438
|
#model-lock-note[data-provider="claude"] { color: var(--provider-claude); }
|
|
3039
3439
|
#model-lock-note[data-provider="cursor"] { color: var(--provider-cursor); }
|
|
3040
3440
|
#model-lock-note[data-provider="grok"] { color: var(--provider-grok); }
|
|
3441
|
+
#model-lock-note[data-provider="deepseek"] { color: var(--provider-deepseek); }
|
|
3041
3442
|
#model-lock-note[data-provider="claude-cloud"] { color: var(--provider-claude-cloud); }
|
|
3042
3443
|
/* Claude Cloud conversations (claude-cloud-conversation-ui.js): where the
|
|
3043
3444
|
session runs and what it pushed, above the composer like the lock note.
|
|
@@ -3789,11 +4190,17 @@
|
|
|
3789
4190
|
font-size: var(--fs-meta-xs); line-height: 1.2; color: var(--muted); position: relative;
|
|
3790
4191
|
}
|
|
3791
4192
|
#chat-title-relay-events[hidden] { display: none; }
|
|
4193
|
+
#chat-title-relay-schedules {
|
|
4194
|
+
display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 2px;
|
|
4195
|
+
font-size: var(--fs-meta-xs); line-height: 1.2; color: var(--muted); position: relative;
|
|
4196
|
+
}
|
|
4197
|
+
#chat-title-relay-schedules[hidden] { display: none; }
|
|
3792
4198
|
.relay-watch-panel[hidden] { display: none; }
|
|
3793
4199
|
.relay-watch-chip {
|
|
3794
4200
|
font: inherit; color: var(--accent); background: transparent; cursor: pointer;
|
|
3795
4201
|
border: 1px solid var(--border); border-radius: 10px; padding: 2px 8px;
|
|
3796
4202
|
}
|
|
4203
|
+
.relay-watch-hint { font-size: var(--fs-meta-xs); color: var(--muted); }
|
|
3797
4204
|
.relay-watch-panel {
|
|
3798
4205
|
position: fixed; top: 0; left: 0; z-index: 60; overflow-y: auto; box-sizing: border-box;
|
|
3799
4206
|
min-width: min(260px, calc(100vw - 16px)); max-width: min(calc(100vw - 16px), 480px);
|
|
@@ -3809,11 +4216,13 @@
|
|
|
3809
4216
|
.relay-watch-item:last-child { border-bottom: none; }
|
|
3810
4217
|
.relay-watch-what { color: var(--text, inherit); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
3811
4218
|
.relay-watch-events { grid-column: 1; font-size: var(--fs-ui-chip); }
|
|
3812
|
-
.relay-watch-unsubscribe
|
|
4219
|
+
.relay-watch-unsubscribe,
|
|
4220
|
+
.relay-schedule-cancel {
|
|
3813
4221
|
grid-column: 2; grid-row: 1 / span 2; font: inherit; cursor: pointer;
|
|
3814
4222
|
color: var(--danger); background: transparent; border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px;
|
|
3815
4223
|
}
|
|
3816
|
-
.conv-watched-badge
|
|
4224
|
+
.conv-watched-badge,
|
|
4225
|
+
.conv-scheduled-badge {
|
|
3817
4226
|
flex: 0 0 auto; font-size: var(--fs-ui-chip); color: var(--accent);
|
|
3818
4227
|
border: 1px solid var(--border); border-radius: 8px; padding: 0 5px;
|
|
3819
4228
|
}
|
|
@@ -6233,37 +6642,51 @@
|
|
|
6233
6642
|
.conv-item.conv-drag-ghost { margin: -18px 0 0; }
|
|
6234
6643
|
.conv-item.conv-drop-before::before,
|
|
6235
6644
|
.conv-item.conv-drop-after::after { height: 4px; }
|
|
6645
|
+
/* Two rows on a phone: ☰, the title and the buttons on the first; the
|
|
6646
|
+
origin line, the chips and the folder on a second row across the whole
|
|
6647
|
+
header. The title column dissolves (display: contents) so its lines
|
|
6648
|
+
become the header's own flex items; ::after breaks the row after the
|
|
6649
|
+
buttons. The row gap is 0 and the second row's items carry their own
|
|
6650
|
+
top margin, so a header with nothing below the title stays one row. */
|
|
6236
6651
|
#chat-header {
|
|
6237
6652
|
padding: var(--chat-header-top-pad-mobile) 10px 10px;
|
|
6238
|
-
gap:
|
|
6239
|
-
flex-wrap:
|
|
6653
|
+
gap: 0 8px;
|
|
6654
|
+
flex-wrap: wrap;
|
|
6240
6655
|
align-items: center;
|
|
6241
6656
|
position: relative;
|
|
6242
6657
|
z-index: 30;
|
|
6243
6658
|
}
|
|
6244
|
-
#chat-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
align-items: flex-start;
|
|
6250
|
-
gap: 6px;
|
|
6251
|
-
}
|
|
6252
|
-
#chat-title-slot {
|
|
6253
|
-
display: flex;
|
|
6254
|
-
flex-direction: column;
|
|
6255
|
-
flex: 1 1 auto;
|
|
6256
|
-
width: auto;
|
|
6257
|
-
margin: 0;
|
|
6258
|
-
min-width: 0;
|
|
6659
|
+
#chat-header::after {
|
|
6660
|
+
content: '';
|
|
6661
|
+
order: 4;
|
|
6662
|
+
flex: 0 0 100%;
|
|
6663
|
+
height: 0;
|
|
6259
6664
|
}
|
|
6665
|
+
#chat-title-wrap,
|
|
6666
|
+
#chat-title-slot { display: contents; }
|
|
6260
6667
|
#chat-title-primary {
|
|
6261
|
-
|
|
6668
|
+
order: 2;
|
|
6669
|
+
flex: 1 1 0;
|
|
6262
6670
|
min-width: 0;
|
|
6263
6671
|
}
|
|
6672
|
+
#chat-title-origin,
|
|
6673
|
+
#chat-title-relay-events,
|
|
6674
|
+
#chat-title-relay-schedules,
|
|
6675
|
+
#chat-title-cwd,
|
|
6676
|
+
#chat-title-session-usage {
|
|
6677
|
+
order: 5;
|
|
6678
|
+
flex: 0 1 auto;
|
|
6679
|
+
max-width: 100%;
|
|
6680
|
+
margin-top: 4px;
|
|
6681
|
+
}
|
|
6682
|
+
#chat-title-relay-events,
|
|
6683
|
+
#chat-title-relay-schedules { flex-shrink: 0; }
|
|
6684
|
+
#chat-title-relay-events .relay-watch-chip,
|
|
6685
|
+
#chat-title-relay-events .conv-watched-badge,
|
|
6686
|
+
#chat-title-relay-schedules .relay-watch-chip { white-space: nowrap; }
|
|
6687
|
+
#chat-title-primary { display: block; }
|
|
6264
6688
|
#chat-title-cwd {
|
|
6265
6689
|
display: block;
|
|
6266
|
-
margin-top: 1px;
|
|
6267
6690
|
font-size: clamp(0.62rem, 2vw, 0.7rem);
|
|
6268
6691
|
line-height: 1.2;
|
|
6269
6692
|
min-width: 0;
|
|
@@ -6273,7 +6696,6 @@
|
|
|
6273
6696
|
}
|
|
6274
6697
|
#chat-title-session-usage {
|
|
6275
6698
|
display: block;
|
|
6276
|
-
margin-top: 1px;
|
|
6277
6699
|
font-size: clamp(0.62rem, 2vw, 0.7rem);
|
|
6278
6700
|
line-height: 1.2;
|
|
6279
6701
|
min-width: 0;
|
|
@@ -6281,10 +6703,7 @@
|
|
|
6281
6703
|
overflow: hidden;
|
|
6282
6704
|
text-overflow: ellipsis;
|
|
6283
6705
|
}
|
|
6284
|
-
#chat-title-origin {
|
|
6285
|
-
margin-top: 1px;
|
|
6286
|
-
font-size: clamp(0.62rem, 2vw, 0.7rem);
|
|
6287
|
-
}
|
|
6706
|
+
#chat-title-origin { font-size: clamp(0.62rem, 2vw, 0.7rem); }
|
|
6288
6707
|
#chat-header-actions {
|
|
6289
6708
|
margin-left: auto;
|
|
6290
6709
|
}
|
|
@@ -6293,6 +6712,7 @@
|
|
|
6293
6712
|
flex: 0 0 auto;
|
|
6294
6713
|
}
|
|
6295
6714
|
#chat-title-editor {
|
|
6715
|
+
order: 2;
|
|
6296
6716
|
flex: 1 0 100%;
|
|
6297
6717
|
width: 100%;
|
|
6298
6718
|
flex-wrap: wrap;
|
|
@@ -6301,9 +6721,6 @@
|
|
|
6301
6721
|
body.chat-title-editing #chat-header-actions {
|
|
6302
6722
|
align-self: flex-start;
|
|
6303
6723
|
}
|
|
6304
|
-
body.chat-title-editing #chat-title-wrap {
|
|
6305
|
-
z-index: 40;
|
|
6306
|
-
}
|
|
6307
6724
|
body.chat-title-editing #chat-title-editor {
|
|
6308
6725
|
position: fixed;
|
|
6309
6726
|
left: 10px;
|
|
@@ -6348,7 +6765,6 @@
|
|
|
6348
6765
|
color: var(--relay-tone-tunnelled);
|
|
6349
6766
|
text-shadow: 0 0 8px rgba(210, 153, 34, 0.35);
|
|
6350
6767
|
}
|
|
6351
|
-
#chat-title-wrap { order: 2; }
|
|
6352
6768
|
#chat-header-actions { order: 3; }
|
|
6353
6769
|
#chat-title { font-size: clamp(0.92rem, 3vw, 0.98rem); }
|
|
6354
6770
|
#chat-title-input,
|
|
@@ -6621,13 +7037,20 @@
|
|
|
6621
7037
|
flex: 0 0 auto;
|
|
6622
7038
|
min-width: 40px;
|
|
6623
7039
|
}
|
|
6624
|
-
/* About OAR: the same, with Refresh
|
|
6625
|
-
|
|
7040
|
+
/* About OAR, Plan usage and Settings: the same, with Refresh (where
|
|
7041
|
+
there is one) beside the close button, and the title cut with an
|
|
7042
|
+
ellipsis if it must be. */
|
|
7043
|
+
#summary-modal[data-kind="about"] .summary-header-actions,
|
|
7044
|
+
#summary-modal[data-kind="usage"] .summary-header-actions,
|
|
7045
|
+
#settings-modal .summary-header-actions {
|
|
6626
7046
|
width: auto;
|
|
6627
7047
|
flex: 0 0 auto;
|
|
6628
7048
|
}
|
|
6629
7049
|
#summary-modal[data-kind="about"] .summary-header-actions .summary-btn,
|
|
6630
|
-
#summary-modal[data-kind="about"] .summary-header-actions .summary-close
|
|
7050
|
+
#summary-modal[data-kind="about"] .summary-header-actions .summary-close,
|
|
7051
|
+
#summary-modal[data-kind="usage"] .summary-header-actions .summary-btn,
|
|
7052
|
+
#summary-modal[data-kind="usage"] .summary-header-actions .summary-close,
|
|
7053
|
+
#settings-modal .summary-header-actions .summary-close {
|
|
6631
7054
|
flex: 0 0 auto;
|
|
6632
7055
|
min-width: 40px;
|
|
6633
7056
|
}
|
|
@@ -6876,6 +7299,7 @@
|
|
|
6876
7299
|
<span id="cli-dot" title="CLI status"></span>
|
|
6877
7300
|
<button id="new-conv-btn" onclick="newConversation()">+ New Chat</button>
|
|
6878
7301
|
<button id="status-btn" type="button" onclick="window.toggleStatusView()">Status</button>
|
|
7302
|
+
<button id="inbox-btn" type="button" onclick="window.toggleInboxView()" aria-label="Inbox" aria-pressed="false">Inbox<span id="inbox-count" class="inbox-count"></span></button>
|
|
6879
7303
|
<div id="sidebar-actions">
|
|
6880
7304
|
<button id="install-btn" class="header-icon-btn" onclick="promptInstallApp()" title="Install app to home screen" aria-label="Install app">⬇</button>
|
|
6881
7305
|
</div>
|
|
@@ -7453,6 +7877,16 @@
|
|
|
7453
7877
|
tabindex="-1"
|
|
7454
7878
|
data-settings-provider-tab="cursor"
|
|
7455
7879
|
>Cursor</button>
|
|
7880
|
+
<button
|
|
7881
|
+
id="settings-provider-tab-deepseek"
|
|
7882
|
+
class="settings-tab settings-subtab"
|
|
7883
|
+
type="button"
|
|
7884
|
+
role="tab"
|
|
7885
|
+
aria-selected="false"
|
|
7886
|
+
aria-controls="settings-provider-panel-deepseek"
|
|
7887
|
+
tabindex="-1"
|
|
7888
|
+
data-settings-provider-tab="deepseek"
|
|
7889
|
+
>DeepSeek</button>
|
|
7456
7890
|
</div>
|
|
7457
7891
|
<div
|
|
7458
7892
|
id="settings-provider-panel-copilot"
|
|
@@ -7890,6 +8324,104 @@
|
|
|
7890
8324
|
<div class="settings-help">Unlocks the live percentage bars on Check Usage: "Plan usage (total)", "Auto + Composer" and "API". Detected automatically from this machine's Cursor IDE login when one exists; paste the <code>WorkosCursorSessionToken</code> cookie from a logged-in cursor.com tab (DevTools → Application → Cookies) only for headless relay hosts or to use a different account. Headless hosts can also set <code>CURSOR_SESSION_TOKEN</code> in the relay environment. Tokens stay on the relay.</div>
|
|
7891
8325
|
</div>
|
|
7892
8326
|
</div>
|
|
8327
|
+
<div
|
|
8328
|
+
id="settings-provider-panel-deepseek"
|
|
8329
|
+
class="settings-panel"
|
|
8330
|
+
role="tabpanel"
|
|
8331
|
+
tabindex="0"
|
|
8332
|
+
aria-labelledby="settings-provider-tab-deepseek"
|
|
8333
|
+
data-settings-provider-panel="deepseek"
|
|
8334
|
+
hidden
|
|
8335
|
+
>
|
|
8336
|
+
<div class="settings-row settings-row-column" style="margin-top: 12px; margin-bottom: 0;">
|
|
8337
|
+
<label for="deepseek-api-key-input">DeepSeek</label>
|
|
8338
|
+
<div class="settings-row" style="width: 100%; margin-bottom: 8px;">
|
|
8339
|
+
<label for="deepseek-enabled-toggle">Enable DeepSeek for New Chat model selection</label>
|
|
8340
|
+
<input id="deepseek-enabled-toggle" type="checkbox" onchange="toggleDeepSeekProvider(this.checked)" disabled>
|
|
8341
|
+
</div>
|
|
8342
|
+
<input
|
|
8343
|
+
id="deepseek-api-key-input"
|
|
8344
|
+
type="password"
|
|
8345
|
+
autocomplete="off"
|
|
8346
|
+
placeholder="DeepSeek API key…"
|
|
8347
|
+
aria-label="DeepSeek API key"
|
|
8348
|
+
>
|
|
8349
|
+
<label for="deepseek-model-select" style="margin-top: 8px;">Default model</label>
|
|
8350
|
+
<select id="deepseek-model-select" aria-label="DeepSeek default model">
|
|
8351
|
+
<option value="deepseek-flash">deepseek-flash</option>
|
|
8352
|
+
<option value="deepseek-v4-pro">deepseek-v4-pro</option>
|
|
8353
|
+
</select>
|
|
8354
|
+
<label for="deepseek-attribution-select" style="margin-top: 8px;">Commit attribution</label>
|
|
8355
|
+
<select id="deepseek-attribution-select" aria-label="DeepSeek commit attribution">
|
|
8356
|
+
<option value="oar">OAR: Co-authored-by: Open Agent Relay (DeepSeek …)</option>
|
|
8357
|
+
<option value="off">Off: no attribution</option>
|
|
8358
|
+
</select>
|
|
8359
|
+
<label for="deepseek-monthly-budget-input" style="margin-top: 8px;">Monthly budget (optional)</label>
|
|
8360
|
+
<input
|
|
8361
|
+
id="deepseek-monthly-budget-input"
|
|
8362
|
+
type="number"
|
|
8363
|
+
inputmode="decimal"
|
|
8364
|
+
min="0"
|
|
8365
|
+
step="0.01"
|
|
8366
|
+
autocomplete="off"
|
|
8367
|
+
placeholder="No budget bar"
|
|
8368
|
+
aria-label="DeepSeek monthly budget"
|
|
8369
|
+
>
|
|
8370
|
+
<label for="deepseek-monthly-budget-currency-select" style="margin-top: 8px;">Budget currency</label>
|
|
8371
|
+
<select id="deepseek-monthly-budget-currency-select" aria-label="DeepSeek monthly budget currency">
|
|
8372
|
+
<option value="USD">USD ($)</option>
|
|
8373
|
+
<option value="CNY">CNY (¥)</option>
|
|
8374
|
+
<option value="">The balance's currency (may change)</option>
|
|
8375
|
+
</select>
|
|
8376
|
+
<div class="settings-help">The usage card shows this relay's estimated DeepSeek spend of the calendar month (UTC) against the budget, in the budget's currency, amber near the budget and red over it. Leave the amount empty for no budget bar.</div>
|
|
8377
|
+
<label for="deepseek-starting-balance-input" style="margin-top: 8px;">Starting balance (optional)</label>
|
|
8378
|
+
<input
|
|
8379
|
+
id="deepseek-starting-balance-input"
|
|
8380
|
+
type="number"
|
|
8381
|
+
inputmode="decimal"
|
|
8382
|
+
min="0"
|
|
8383
|
+
step="0.01"
|
|
8384
|
+
autocomplete="off"
|
|
8385
|
+
placeholder="The balance after the last top-up"
|
|
8386
|
+
aria-label="DeepSeek starting balance"
|
|
8387
|
+
aria-describedby="deepseek-starting-balance-help"
|
|
8388
|
+
>
|
|
8389
|
+
<div id="deepseek-starting-balance-help" class="settings-help">The usage card's balance bar measures what is left against this amount, in the balance's currency, for example your first top-up. Leave it empty to measure from the balance after the last top-up this relay has seen (before it has seen one, the highest balance it has read).</div>
|
|
8390
|
+
<div id="deepseek-starting-balance-status" class="settings-help" hidden></div>
|
|
8391
|
+
<details id="deepseek-advanced" style="margin-top: 8px;">
|
|
8392
|
+
<summary>Advanced</summary>
|
|
8393
|
+
<label for="deepseek-base-url-input" style="margin-top: 8px;">Base URL</label>
|
|
8394
|
+
<input
|
|
8395
|
+
id="deepseek-base-url-input"
|
|
8396
|
+
type="url"
|
|
8397
|
+
autocomplete="off"
|
|
8398
|
+
placeholder="https://api.deepseek.com"
|
|
8399
|
+
aria-label="DeepSeek base URL"
|
|
8400
|
+
>
|
|
8401
|
+
<div class="settings-help">Leave empty for DeepSeek's own API. Another address must use https (http only on this machine, for a local proxy); the key is sent there and nowhere else.</div>
|
|
8402
|
+
</details>
|
|
8403
|
+
<div id="deepseek-settings-status" class="settings-help settings-provider-status">Loading DeepSeek settings…</div>
|
|
8404
|
+
<div style="display: flex; gap: 8px; margin-top: 8px;">
|
|
8405
|
+
<button id="deepseek-save-btn" type="button" class="summary-btn" onclick="saveDeepSeekSettings()">Save DeepSeek settings</button>
|
|
8406
|
+
<button id="deepseek-remove-btn" type="button" class="summary-btn" onclick="removeDeepSeekSettings()">Remove saved key</button>
|
|
8407
|
+
</div>
|
|
8408
|
+
<div class="settings-help">DeepSeek chats run Claude Code on the relay host against DeepSeek's Anthropic-compatible API, with all four modes, tools and question cards. The key is stored on the relay host and never sent to browsers; saving it lists DeepSeek's models. Turns are billed to the DeepSeek account the key belongs to.</div>
|
|
8409
|
+
<div id="deepseek-usage-import" class="deepseek-usage-import" role="group" aria-labelledby="deepseek-usage-import-title">
|
|
8410
|
+
<label id="deepseek-usage-import-title">Import usage export</label>
|
|
8411
|
+
<div class="settings-help">DeepSeek's usage page exports two files for a period, amount and cost. Imported here, their figures for the saved key replace the estimate on the usage card for the days they cover; the other days stay estimated.</div>
|
|
8412
|
+
<div class="deepseek-usage-import-files">
|
|
8413
|
+
<label for="deepseek-usage-amount-input" class="settings-help">Amount file</label>
|
|
8414
|
+
<input id="deepseek-usage-amount-input" type="file" accept=".csv,text/csv" aria-label="DeepSeek usage export: amount file">
|
|
8415
|
+
<label for="deepseek-usage-cost-input" class="settings-help">Cost file</label>
|
|
8416
|
+
<input id="deepseek-usage-cost-input" type="file" accept=".csv,text/csv" aria-label="DeepSeek usage export: cost file">
|
|
8417
|
+
</div>
|
|
8418
|
+
<div>
|
|
8419
|
+
<button id="deepseek-usage-import-btn" type="button" class="summary-btn" onclick="importDeepSeekUsageExport()">Import usage export</button>
|
|
8420
|
+
</div>
|
|
8421
|
+
<div id="deepseek-usage-import-status" class="settings-help settings-provider-status deepseek-usage-import-status" role="status" aria-live="polite"></div>
|
|
8422
|
+
</div>
|
|
8423
|
+
</div>
|
|
8424
|
+
</div>
|
|
7893
8425
|
</div>
|
|
7894
8426
|
<div
|
|
7895
8427
|
id="settings-panel-relays"
|