@oar-sh/oar 0.9.10 → 0.9.12
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/CHANGELOG.md +440 -1
- package/README.md +156 -972
- package/package.json +13 -13
- package/server/README.md +112 -25
- package/server/claude-worker/claude-remote-relay-tool.mjs +2 -0
- package/server/claude-worker/claude-sdk-adapter.mjs +57 -4
- package/server/claude-worker/claude-session-process.mjs +217 -11
- package/server/claude-worker/claude-session-worker.mjs +26 -1
- package/server/claude-worker/task-output-discovery.mjs +126 -0
- package/server/copilot-worker/copilot-sdk-session-process.mjs +235 -14
- package/server/copilot-worker/copilot-sdk-session-worker.mjs +8 -0
- package/server/copilot-worker/copilot-shell-output-mirror.mjs +94 -0
- package/server/copilot-worker/copilot-task-settle.mjs +96 -0
- package/server/db-schema.mjs +68 -2
- package/server/grok-worker/acp-client.mjs +2 -1
- package/server/grok-worker/acp-host-services.mjs +46 -6
- package/server/grok-worker/grok-background-tasks.mjs +241 -0
- package/server/grok-worker/grok-sdk-adapter.mjs +3 -1
- package/server/grok-worker/grok-session-worker.mjs +33 -1
- package/server/grok-worker/grok-turn-runner.mjs +11 -0
- package/server/migrations/0013-previews.mjs +130 -0
- package/server/migrations/0014-conversation-groups.mjs +89 -0
- package/server/migrations/0015-conversation-group-position.mjs +76 -0
- package/server/migrations/0016-share-access-log.mjs +110 -0
- package/server/migrations/0017-conversation-history-indexes.mjs +89 -0
- package/server/public/app/about-ui.js +73 -0
- package/server/public/app/about-view.mjs +234 -0
- package/server/public/app/action-confirmations.js +31 -14
- package/server/public/app/agent-exchange-fold-view.mjs +40 -101
- package/server/public/app/api-client.js +264 -16
- package/server/public/app/ask-user-view.js +17 -15
- package/server/public/app/background-tasks-view.mjs +285 -16
- package/server/public/app/bootstrap.js +253 -37
- package/server/public/app/chat-actions-menu-state.mjs +20 -10
- package/server/public/app/claude-background-command-limit-options.mjs +21 -0
- package/server/public/app/context-menu.mjs +90 -6
- package/server/public/app/conversation-group-drag.mjs +191 -0
- package/server/public/app/conversation-group-order.mjs +265 -0
- package/server/public/app/conversation-group-state.mjs +100 -0
- package/server/public/app/conversation-list-drag.mjs +449 -0
- package/server/public/app/conversation-payload-cache.mjs +357 -0
- package/server/public/app/conversation-turn-state.mjs +81 -0
- package/server/public/app/conversation-view.js +567 -94
- package/server/public/app/conversation-window-retention.mjs +96 -0
- package/server/public/app/cwd-picker.js +1 -1
- package/server/public/app/hidden-messages-view.mjs +312 -0
- package/server/public/app/host-suspend-ui.js +7 -1
- package/server/public/app/journal-view.js +1033 -82
- package/server/public/app/preview-cards.mjs +117 -31
- package/server/public/app/preview-command.mjs +10 -1
- package/server/public/app/relay-board-view.js +19 -6
- package/server/public/app/relay-prompt-sanitizer.mjs +11 -4
- package/server/public/app/relay-restart-error.mjs +16 -0
- package/server/public/app/settings-modal.js +150 -10
- package/server/public/app/settings-tabs.js +1 -1
- package/server/public/app/share-format.mjs +49 -0
- package/server/public/app/share-preview-marks.mjs +167 -0
- package/server/public/app/share-state.js +109 -0
- package/server/public/app/shared-conversations-settings.js +480 -0
- package/server/public/app/socket-handlers.js +138 -20
- package/server/public/app/store.js +121 -30
- package/server/public/app/subagent-row.mjs +3 -3
- package/server/public/app/subagent-viewer.mjs +37 -7
- package/server/public/app/task-console-render.mjs +237 -0
- package/server/public/app/task-console-watch.mjs +42 -0
- package/server/public/app/task-console.mjs +630 -0
- package/server/public/app/task-output-text.mjs +234 -0
- package/server/public/app/thinking-follow.js +0 -4
- package/server/public/app/transcript-island.mjs +73 -0
- package/server/public/app/transcript-jump-bottom-view.mjs +230 -26
- package/server/public/app/transcript-jump-bottom.mjs +170 -22
- package/server/public/app/transcript-reading-anchor.mjs +256 -0
- package/server/public/app/transcript-reload-freshness.mjs +17 -1
- package/server/public/app/transcript-viewport-anchor.mjs +159 -0
- package/server/public/index.html +625 -21
- package/server/relay-tools.md +3 -1
- package/server/relay.mjs +2 -1
- package/server/repositories/conversation-group-repository.mjs +444 -0
- package/server/repositories/message-repository.mjs +9 -0
- package/server/repositories/question-repository.mjs +4 -0
- package/server/repositories/session-repository.mjs +12 -37
- package/server/repositories/share-repository.mjs +322 -0
- package/server/repositories/share-visibility-statements.mjs +10 -0
- package/server/routes/about-routes.mjs +15 -0
- package/server/routes/cache-routes.mjs +4 -0
- package/server/routes/conversation-group-routes.mjs +171 -0
- package/server/routes/messages-routes.mjs +433 -68
- package/server/routes/preview-routes.mjs +9 -1
- package/server/routes/sessions-routes.mjs +901 -253
- package/server/server-runtime.mjs +392 -99
- package/server/services/about-service.mjs +461 -0
- package/server/services/background-task-store.mjs +365 -0
- package/server/services/background-work-view.mjs +228 -0
- package/server/services/cache-rebuild-service.mjs +30 -0
- package/server/services/cli-process-runner.mjs +4 -21
- package/server/services/conversation-history-page.mjs +199 -0
- package/server/services/delete-archive-service.mjs +4 -1
- package/server/services/detached-worker-watch-service.mjs +150 -0
- package/server/services/hidden-message-list.mjs +21 -0
- package/server/services/host-suspend-command.mjs +2 -1
- package/server/services/message-pin-list.mjs +1 -1
- package/server/services/preview-health-probe.mjs +8 -1
- package/server/services/preview-proxy-server.mjs +8 -4
- package/server/services/preview-registry-service.mjs +676 -26
- package/server/services/preview-static-handler.mjs +40 -7
- package/server/services/preview-store.mjs +274 -0
- package/server/services/rate-limit-service.mjs +12 -1
- package/server/services/relay-auth.mjs +183 -0
- package/server/services/relay-cli-launcher-service.mjs +3 -1
- package/server/services/relay-event-service.mjs +17 -0
- package/server/services/relay-prompt-sanitizer.mjs +11 -4
- package/server/services/remote-relay-dispatcher.mjs +187 -7
- package/server/services/request-boundary.mjs +183 -0
- package/server/services/session-activity-tracker.mjs +231 -19
- package/server/services/session-worker-launch-service.mjs +190 -6
- package/server/services/session-worker-process-service.mjs +10 -6
- package/server/services/share-access-log-service.mjs +123 -0
- package/server/services/share-path-redaction.mjs +424 -0
- package/server/services/status-event-service.mjs +7 -3
- package/server/services/task-output-rooms.mjs +259 -0
- package/server/services/task-output-service.mjs +562 -0
- package/server/services/tunnel-worker-path-guard.mjs +24 -41
- package/server/services/windows-autostart-service.mjs +6 -1
- package/server/services/windows-boot-autostart-service.mjs +207 -23
- package/shared/claude-background-command-limit.mjs +83 -0
- package/shared/preview-tool-core.mjs +15 -5
- package/shared/remote-relay-contract.mjs +35 -3
- package/shared/share-path-privacy.mjs +30 -0
- package/shared/task-output-text.mjs +737 -0
- package/shared/windows-system-tools.mjs +106 -0
- package/shared/worker-runtime/background-task-digest.mjs +30 -0
- package/shared/worker-runtime/heartbeat.mjs +24 -0
- package/shared/worker-runtime/kept-posts.mjs +83 -0
- package/shared/worker-runtime/task-output-spool.mjs +181 -0
- package/shared/worker-runtime/worker-websocket-link.mjs +47 -15
package/server/public/index.html
CHANGED
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
if (sharedIdx >= 0) {
|
|
30
30
|
return path.slice(0, sharedIdx).replace(/\/+$/, '');
|
|
31
31
|
}
|
|
32
|
+
const previewIdx = path.indexOf('/share-preview/');
|
|
33
|
+
if (previewIdx >= 0) {
|
|
34
|
+
return path.slice(0, previewIdx).replace(/\/+$/, '');
|
|
35
|
+
}
|
|
32
36
|
return path.replace(/\/+$/, '');
|
|
33
37
|
};
|
|
34
38
|
const __APP_BASE = typeof __APP_CONFIG?.basePath === 'string' && __APP_CONFIG.basePath.trim()
|
|
@@ -276,6 +280,7 @@
|
|
|
276
280
|
--warn: #d29922;
|
|
277
281
|
--conversation-title-offline: #f0f6fc;
|
|
278
282
|
--conversation-title-ready: #3fb950;
|
|
283
|
+
--conversation-title-idle: #238636;
|
|
279
284
|
--conversation-title-question: #f85149;
|
|
280
285
|
--conversation-title-error: #d29922;
|
|
281
286
|
/* Relay reachability tones, shared by the sidebar dot and the mobile
|
|
@@ -343,6 +348,8 @@
|
|
|
343
348
|
--warn: #9a6700;
|
|
344
349
|
--conversation-title-offline: #1F2328;
|
|
345
350
|
--conversation-title-ready: #1a7f37;
|
|
351
|
+
/* Muted, not darker: a darker green would stand out more on white. */
|
|
352
|
+
--conversation-title-idle: #4c8b5c;
|
|
346
353
|
--conversation-title-question: #cf222e;
|
|
347
354
|
--conversation-title-error: #9a6700;
|
|
348
355
|
--provider-github: #0969da;
|
|
@@ -526,6 +533,31 @@
|
|
|
526
533
|
opacity: 0;
|
|
527
534
|
pointer-events: none;
|
|
528
535
|
}
|
|
536
|
+
/* "Preview as shared": what a viewer gets instead of a path, and what still
|
|
537
|
+
looks like one (share-preview-marks.mjs). */
|
|
538
|
+
mark.share-preview-redacted,
|
|
539
|
+
mark.share-preview-suspect {
|
|
540
|
+
color: inherit;
|
|
541
|
+
border-radius: 3px;
|
|
542
|
+
padding: 0 2px;
|
|
543
|
+
}
|
|
544
|
+
mark.share-preview-redacted {
|
|
545
|
+
background: rgba(63, 185, 80, 0.18);
|
|
546
|
+
box-shadow: inset 0 -1px 0 rgba(63, 185, 80, 0.65);
|
|
547
|
+
}
|
|
548
|
+
mark.share-preview-suspect {
|
|
549
|
+
background: rgba(210, 153, 34, 0.2);
|
|
550
|
+
box-shadow: inset 0 -2px 0 rgba(210, 153, 34, 0.9);
|
|
551
|
+
}
|
|
552
|
+
#share-preview-banner {
|
|
553
|
+
display: none;
|
|
554
|
+
padding: 6px 12px;
|
|
555
|
+
font-size: var(--fs-meta-sm);
|
|
556
|
+
color: var(--muted);
|
|
557
|
+
border-bottom: 1px solid var(--border);
|
|
558
|
+
background: var(--bg2);
|
|
559
|
+
}
|
|
560
|
+
body.share-preview-mode #share-preview-banner { display: block; }
|
|
529
561
|
body.shared-reader-mode #sidebar,
|
|
530
562
|
body.shared-reader-mode #sidebar-resizer,
|
|
531
563
|
body.shared-reader-mode #sidebar-overlay,
|
|
@@ -586,7 +618,8 @@
|
|
|
586
618
|
.header-icon-count:empty { display: none; }
|
|
587
619
|
/* The display rule above outranks the UA [hidden] rule, same trap as the
|
|
588
620
|
other [hidden] overrides in this file. */
|
|
589
|
-
#pinned-messages-btn[hidden]
|
|
621
|
+
#pinned-messages-btn[hidden],
|
|
622
|
+
#hidden-messages-btn[hidden] { display: none; }
|
|
590
623
|
/* Same trap: without this the ⋯ trigger stays drawn as a dead button. */
|
|
591
624
|
#chat-actions-menu-btn[hidden] { display: none; }
|
|
592
625
|
#cli-dot {
|
|
@@ -660,7 +693,8 @@
|
|
|
660
693
|
/* The display rule above outranks the UA [hidden] rule, same trap as the
|
|
661
694
|
other [hidden] overrides in this file. */
|
|
662
695
|
#conv-filter-clear[hidden] { display: none; }
|
|
663
|
-
#conv-filter-status
|
|
696
|
+
#conv-filter-status,
|
|
697
|
+
#conv-list-announce {
|
|
664
698
|
position: absolute;
|
|
665
699
|
width: 1px;
|
|
666
700
|
height: 1px;
|
|
@@ -811,17 +845,17 @@
|
|
|
811
845
|
.conv-provider-indicator[data-provider="claude-cloud"] { color: var(--provider-claude-cloud); }
|
|
812
846
|
.conv-item.worker-ui-offline .conv-title,
|
|
813
847
|
#chat-title[data-ui-state="offline"] { color: var(--conversation-title-offline); }
|
|
848
|
+
/* Ready and idle: the darker green. Ready and working (a turn or
|
|
849
|
+
background work): the bright one. :where() keeps the working rule as
|
|
850
|
+
specific as the others, so an archived row stays muted. */
|
|
814
851
|
.conv-item.worker-ui-ready .conv-title,
|
|
815
|
-
#chat-title[data-ui-state="ready"] { color: var(--conversation-title-
|
|
852
|
+
#chat-title[data-ui-state="ready"] { color: var(--conversation-title-idle); }
|
|
853
|
+
.conv-item.worker-ui-ready:where(.conv-working) .conv-title,
|
|
854
|
+
#chat-title[data-ui-state="ready"][data-working] { color: var(--conversation-title-ready); }
|
|
816
855
|
.conv-item.worker-ui-question .conv-title,
|
|
817
856
|
#chat-title[data-ui-state="question"] { color: var(--conversation-title-question); }
|
|
818
857
|
.conv-item.worker-ui-error .conv-title,
|
|
819
858
|
#chat-title[data-ui-state="error"] { color: var(--conversation-title-error); }
|
|
820
|
-
.conv-processing-dots {
|
|
821
|
-
display: inline-block;
|
|
822
|
-
min-width: 1.8ch;
|
|
823
|
-
letter-spacing: 0.02em;
|
|
824
|
-
}
|
|
825
859
|
.conv-delete {
|
|
826
860
|
position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
|
|
827
861
|
background: none; border: none; color: var(--muted); cursor: pointer; font-size: var(--fs-ui-icon);
|
|
@@ -906,6 +940,118 @@
|
|
|
906
940
|
font-weight: 600;
|
|
907
941
|
vertical-align: middle;
|
|
908
942
|
}
|
|
943
|
+
/* ── Session groups in the sidebar ──
|
|
944
|
+
A head row (the session that created the others, or a line of its own for
|
|
945
|
+
a hand-made or headless group) with a fold button and a pill that sums up
|
|
946
|
+
the members; the members indented under it while the group is open. */
|
|
947
|
+
.conv-group-fold {
|
|
948
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
949
|
+
width: 20px; height: 20px; margin: 0 2px 0 -4px; padding: 0;
|
|
950
|
+
border: none; border-radius: 6px; background: transparent; color: var(--muted);
|
|
951
|
+
font: inherit; font-size: var(--fs-meta-md); line-height: 1; cursor: pointer; vertical-align: middle;
|
|
952
|
+
}
|
|
953
|
+
.conv-group-fold:hover { background: var(--bg3); color: var(--text); }
|
|
954
|
+
.conv-item.conv-group-synthetic { cursor: default; }
|
|
955
|
+
.conv-item.conv-group-synthetic .conv-title { color: var(--text); font-weight: 600; }
|
|
956
|
+
.conv-item.conv-group-synthetic.worker-ui-question .conv-title { color: var(--conversation-title-question); }
|
|
957
|
+
.conv-item.conv-group-member {
|
|
958
|
+
margin-left: 14px;
|
|
959
|
+
border-left: 2px solid color-mix(in srgb, var(--accent) 45%, transparent);
|
|
960
|
+
border-top-left-radius: 0; border-bottom-left-radius: 0;
|
|
961
|
+
}
|
|
962
|
+
/* The head row keeps its title and meta line clear of the archive and
|
|
963
|
+
delete icons (absolute, at the row's right), so nothing sits under them
|
|
964
|
+
on hover; a synthetic head has no icons. The margin is outside the
|
|
965
|
+
rectangles, so a measurement sees the clearance. */
|
|
966
|
+
.conv-item.conv-group-head:not(.conv-group-synthetic) .conv-title,
|
|
967
|
+
.conv-item.conv-group-head:not(.conv-group-synthetic) .conv-meta {
|
|
968
|
+
padding-right: 0;
|
|
969
|
+
margin-right: 48px;
|
|
970
|
+
}
|
|
971
|
+
/* In a head row's meta line the date gives way first and completely, then
|
|
972
|
+
the pill shortens with an ellipsis (its full text is its title), and the
|
|
973
|
+
provider chip always stays inside. Both shrink factors are 1 or more:
|
|
974
|
+
a factor below 1 that is left alone shrinks only that share of the
|
|
975
|
+
overflow, which is how the chip once left the row. */
|
|
976
|
+
.conv-item.conv-group-head .conv-meta-primary { flex: 0 1000 auto; }
|
|
977
|
+
.conv-group-summary {
|
|
978
|
+
display: inline-block; flex: 0 1 auto; min-width: 2.5em;
|
|
979
|
+
padding: 0 6px; border-radius: 999px;
|
|
980
|
+
border: 1px solid color-mix(in srgb, currentColor 40%, transparent);
|
|
981
|
+
background: color-mix(in srgb, currentColor 12%, transparent);
|
|
982
|
+
color: var(--muted); font-size: var(--fs-ui-chip); font-weight: 600; line-height: 1.3;
|
|
983
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: middle;
|
|
984
|
+
}
|
|
985
|
+
.conv-group-summary-running { color: var(--conversation-title-ready); }
|
|
986
|
+
.conv-group-summary-waiting { color: var(--conversation-title-question); cursor: pointer; }
|
|
987
|
+
.conv-group-summary-error { color: var(--conversation-title-error); }
|
|
988
|
+
.conv-group-summary[data-open-waiting]:hover { border-color: currentColor; }
|
|
989
|
+
/* Drag and drop (conversation-list-drag.mjs): a long press lifts a row, the
|
|
990
|
+
dragged row stays dimmed in place while a ghost follows the pointer, a
|
|
991
|
+
line shows where it lands, the target group is tinted, and a loose row
|
|
992
|
+
that would make a new group with it is highlighted. */
|
|
993
|
+
.conv-item.conv-drag-lifted {
|
|
994
|
+
background: var(--bg3);
|
|
995
|
+
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
|
|
996
|
+
transform: scale(1.02);
|
|
997
|
+
transition: transform 0.12s ease-out, box-shadow 0.12s ease-out;
|
|
998
|
+
z-index: 1;
|
|
999
|
+
}
|
|
1000
|
+
#conv-list.conv-list-dragging { cursor: grabbing; }
|
|
1001
|
+
#conv-list.conv-list-dragging .conv-item { cursor: grabbing; }
|
|
1002
|
+
#conv-list.conv-list-dragging .conv-item:hover:not(.conv-drop-group):not(.conv-drop-new-group) { background: transparent; }
|
|
1003
|
+
.conv-item.conv-drag-source { opacity: 0.35; }
|
|
1004
|
+
.conv-item.conv-drag-ghost {
|
|
1005
|
+
position: fixed; z-index: 12900; margin: 0; pointer-events: none;
|
|
1006
|
+
background: var(--bg2); border-color: var(--accent);
|
|
1007
|
+
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45); opacity: 0.95;
|
|
1008
|
+
cursor: grabbing; will-change: transform;
|
|
1009
|
+
}
|
|
1010
|
+
.conv-item.conv-drop-group {
|
|
1011
|
+
background: color-mix(in srgb, var(--accent) 10%, transparent);
|
|
1012
|
+
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent);
|
|
1013
|
+
}
|
|
1014
|
+
.conv-item.conv-drop-new-group,
|
|
1015
|
+
.conv-item.conv-drop-inside {
|
|
1016
|
+
background: color-mix(in srgb, var(--accent) 16%, transparent);
|
|
1017
|
+
border-color: var(--accent);
|
|
1018
|
+
}
|
|
1019
|
+
.conv-item.conv-drop-before::before,
|
|
1020
|
+
.conv-item.conv-drop-after::after {
|
|
1021
|
+
content: ''; position: absolute; left: 4px; right: 4px; height: 3px;
|
|
1022
|
+
border-radius: 2px; background: var(--accent); pointer-events: none;
|
|
1023
|
+
}
|
|
1024
|
+
.conv-item.conv-drop-before::before { top: -3px; }
|
|
1025
|
+
.conv-item.conv-drop-after::after { bottom: -3px; }
|
|
1026
|
+
.conv-item.conv-drop-flash { animation: conv-drop-flash 1.1s ease-out; }
|
|
1027
|
+
@keyframes conv-drop-flash {
|
|
1028
|
+
0%, 30% { background: color-mix(in srgb, var(--accent) 28%, transparent); }
|
|
1029
|
+
100% { background: transparent; }
|
|
1030
|
+
}
|
|
1031
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1032
|
+
.conv-item.conv-drag-lifted { transform: none; transition: none; }
|
|
1033
|
+
.conv-item.conv-drop-flash { animation: none; outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
1034
|
+
}
|
|
1035
|
+
/* The group picker and the rename form (inside the summary modal). */
|
|
1036
|
+
.conv-group-choices { display: flex; flex-direction: column; gap: 6px; max-height: 40vh; overflow-y: auto; }
|
|
1037
|
+
.conv-group-choice {
|
|
1038
|
+
display: flex; align-items: baseline; justify-content: space-between; gap: 10px; width: 100%;
|
|
1039
|
+
padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg3); color: var(--text);
|
|
1040
|
+
font: inherit; font-size: var(--fs-meta-md); text-align: left; cursor: pointer;
|
|
1041
|
+
}
|
|
1042
|
+
.conv-group-choice:hover:not([disabled]), .conv-group-choice:focus-visible { border-color: var(--accent); outline: none; }
|
|
1043
|
+
.conv-group-choice[disabled] { opacity: 0.6; cursor: default; }
|
|
1044
|
+
.conv-group-choice-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1045
|
+
.conv-group-choice-count { flex: 0 0 auto; color: var(--muted); font-size: var(--fs-meta-xs); }
|
|
1046
|
+
.conv-group-picker-empty { color: var(--muted); font-size: var(--fs-meta-md); margin: 0 0 6px; }
|
|
1047
|
+
.conv-group-form { margin-top: 14px; }
|
|
1048
|
+
.conv-group-form-label { display: block; color: var(--muted); font-size: var(--fs-meta-xs); margin-bottom: 4px; }
|
|
1049
|
+
.conv-group-form-row { display: flex; gap: 8px; align-items: center; }
|
|
1050
|
+
.conv-group-input {
|
|
1051
|
+
flex: 1 1 auto; min-width: 0; width: 100%; padding: 7px 10px;
|
|
1052
|
+
border: 1px solid var(--border); border-radius: 8px; background: var(--bg); color: var(--text); font: inherit;
|
|
1053
|
+
}
|
|
1054
|
+
.conv-group-input:focus { outline: none; border-color: var(--accent); }
|
|
909
1055
|
/* ── Main Chat ── */
|
|
910
1056
|
#main {
|
|
911
1057
|
/* Containing block for #transcript-separator-rail. Safe to add: every
|
|
@@ -2229,9 +2375,42 @@
|
|
|
2229
2375
|
text-align: center;
|
|
2230
2376
|
}
|
|
2231
2377
|
.jump-to-bottom-badge[hidden] { display: none; }
|
|
2378
|
+
/* Something new landed below a reader who is scrolled up: the accent
|
|
2379
|
+
colour, and a count or (news without a row to count) a dot. */
|
|
2380
|
+
#jump-to-bottom-btn[data-state="new"] { border-color: var(--accent); color: var(--accent); }
|
|
2381
|
+
.jump-to-bottom-badge.jump-to-bottom-badge-dot {
|
|
2382
|
+
top: -3px;
|
|
2383
|
+
right: -3px;
|
|
2384
|
+
min-width: 12px;
|
|
2385
|
+
width: 12px;
|
|
2386
|
+
height: 12px;
|
|
2387
|
+
padding: 0;
|
|
2388
|
+
border-radius: 50%;
|
|
2389
|
+
border: 2px solid var(--bg2);
|
|
2390
|
+
}
|
|
2391
|
+
/* A question, an approval or a board waits below: the button is filled. */
|
|
2392
|
+
#jump-to-bottom-btn[data-state="question"] {
|
|
2393
|
+
border-color: var(--warn);
|
|
2394
|
+
background: var(--warn);
|
|
2395
|
+
color: #000;
|
|
2396
|
+
animation: jump-to-bottom-attention 1.6s ease-out 2;
|
|
2397
|
+
}
|
|
2398
|
+
:root[data-theme="light"] #jump-to-bottom-btn[data-state="question"] { color: #fff; }
|
|
2399
|
+
#jump-to-bottom-btn[data-state="question"] .jump-to-bottom-badge {
|
|
2400
|
+
background: var(--bg2);
|
|
2401
|
+
color: var(--warn);
|
|
2402
|
+
border: 1px solid var(--warn);
|
|
2403
|
+
line-height: 16px;
|
|
2404
|
+
font-size: 12px;
|
|
2405
|
+
}
|
|
2406
|
+
@keyframes jump-to-bottom-attention {
|
|
2407
|
+
0% { box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35), 0 0 0 0 var(--warn); }
|
|
2408
|
+
100% { box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35), 0 0 0 12px transparent; }
|
|
2409
|
+
}
|
|
2232
2410
|
@media (prefers-reduced-motion: reduce) {
|
|
2233
2411
|
#jump-to-bottom-btn,
|
|
2234
2412
|
#jump-to-bottom-btn.visible { transition: none; }
|
|
2413
|
+
#jump-to-bottom-btn[data-state="question"] { animation: none; }
|
|
2235
2414
|
}
|
|
2236
2415
|
/* ── Context usage modal ── */
|
|
2237
2416
|
.ctx-usage-model {
|
|
@@ -2565,6 +2744,25 @@
|
|
|
2565
2744
|
}
|
|
2566
2745
|
.plan-usage-link { color: var(--accent); text-decoration: none; }
|
|
2567
2746
|
.plan-usage-link:hover { text-decoration: underline; }
|
|
2747
|
+
/* About OAR: the plan-usage cards and tables, stacked. */
|
|
2748
|
+
.about-modal { display: flex; flex-direction: column; gap: 12px; }
|
|
2749
|
+
.about-section .plan-usage-card-head { margin-bottom: 4px; }
|
|
2750
|
+
.about-section code { font-size: 0.82rem; }
|
|
2751
|
+
.about-usage-provider { font-size: 0.82rem; font-weight: 600; margin-top: 8px; }
|
|
2752
|
+
.about-usage-provider:first-child { margin-top: 0; }
|
|
2753
|
+
.about-state { font-weight: 600; }
|
|
2754
|
+
.about-state[data-state="online"] { color: var(--success); }
|
|
2755
|
+
.about-state[data-state="offline"] { color: var(--warn); }
|
|
2756
|
+
.about-state[data-state="idle"] { color: var(--muted); }
|
|
2757
|
+
.about-inline-button {
|
|
2758
|
+
background: none;
|
|
2759
|
+
border: none;
|
|
2760
|
+
padding: 0;
|
|
2761
|
+
font: inherit;
|
|
2762
|
+
cursor: pointer;
|
|
2763
|
+
text-align: left;
|
|
2764
|
+
}
|
|
2765
|
+
.about-links { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; font-size: 0.86rem; padding: 2px 0 4px; }
|
|
2568
2766
|
@media (prefers-reduced-motion: reduce) {
|
|
2569
2767
|
.plan-usage-bar-fill { transition: none; }
|
|
2570
2768
|
}
|
|
@@ -3184,6 +3382,166 @@
|
|
|
3184
3382
|
.subagent-viewer-dialog { width: 100%; height: 100%; border: 0; border-radius: 0; }
|
|
3185
3383
|
#subagent-viewer-body { padding: 8px 10px 28px; }
|
|
3186
3384
|
}
|
|
3385
|
+
/* The task console: a shell or Monitor task's output (task-console.mjs).
|
|
3386
|
+
Same shell as the sub-agent viewer; the 16 terminal colours follow the
|
|
3387
|
+
theme so red and green stay readable on Day and Night. */
|
|
3388
|
+
:root {
|
|
3389
|
+
--tc-ansi-0: #484f58;
|
|
3390
|
+
--tc-ansi-1: #ff7b72;
|
|
3391
|
+
--tc-ansi-2: #3fb950;
|
|
3392
|
+
--tc-ansi-3: #d29922;
|
|
3393
|
+
--tc-ansi-4: #58a6ff;
|
|
3394
|
+
--tc-ansi-5: #bc8cff;
|
|
3395
|
+
--tc-ansi-6: #39c5cf;
|
|
3396
|
+
--tc-ansi-7: #b1bac4;
|
|
3397
|
+
--tc-ansi-8: #6e7681;
|
|
3398
|
+
--tc-ansi-9: #ffa198;
|
|
3399
|
+
--tc-ansi-10: #56d364;
|
|
3400
|
+
--tc-ansi-11: #e3b341;
|
|
3401
|
+
--tc-ansi-12: #79c0ff;
|
|
3402
|
+
--tc-ansi-13: #d2a8ff;
|
|
3403
|
+
--tc-ansi-14: #56d4dd;
|
|
3404
|
+
--tc-ansi-15: #f0f6fc;
|
|
3405
|
+
}
|
|
3406
|
+
:root[data-theme="light"] {
|
|
3407
|
+
--tc-ansi-0: #24292f;
|
|
3408
|
+
--tc-ansi-1: #cf222e;
|
|
3409
|
+
--tc-ansi-2: #116329;
|
|
3410
|
+
--tc-ansi-3: #4d2d00;
|
|
3411
|
+
--tc-ansi-4: #0969da;
|
|
3412
|
+
--tc-ansi-5: #8250df;
|
|
3413
|
+
--tc-ansi-6: #1b7c83;
|
|
3414
|
+
--tc-ansi-7: #6e7781;
|
|
3415
|
+
--tc-ansi-8: #57606a;
|
|
3416
|
+
--tc-ansi-9: #a40e26;
|
|
3417
|
+
--tc-ansi-10: #1a7f37;
|
|
3418
|
+
--tc-ansi-11: #633c01;
|
|
3419
|
+
--tc-ansi-12: #218bff;
|
|
3420
|
+
--tc-ansi-13: #a475f9;
|
|
3421
|
+
--tc-ansi-14: #3192aa;
|
|
3422
|
+
--tc-ansi-15: #8c959f;
|
|
3423
|
+
}
|
|
3424
|
+
#task-console-modal {
|
|
3425
|
+
position: fixed; inset: 0; z-index: 10900; display: none;
|
|
3426
|
+
align-items: center; justify-content: center;
|
|
3427
|
+
background: rgba(0, 0, 0, 0.68); padding: 18px;
|
|
3428
|
+
}
|
|
3429
|
+
#task-console-modal.visible { display: flex; }
|
|
3430
|
+
#task-console-title { flex: 1; min-width: 0; margin: 0; font-size: 1.05rem; font-weight: 600; overflow-wrap: anywhere; }
|
|
3431
|
+
.task-console-meta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--muted); font-size: var(--fs-meta-sm); }
|
|
3432
|
+
#task-console-meta { overflow-wrap: anywhere; }
|
|
3433
|
+
.tc-stall { color: var(--muted); }
|
|
3434
|
+
.tc-stall-warn { color: var(--warn); font-weight: 600; }
|
|
3435
|
+
#task-console-chip { cursor: pointer; font: inherit; }
|
|
3436
|
+
#task-console-failure {
|
|
3437
|
+
background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer;
|
|
3438
|
+
font-size: var(--fs-meta-sm); text-decoration: underline; text-underline-offset: 3px;
|
|
3439
|
+
}
|
|
3440
|
+
#task-console-stop:hover:not(:disabled) { border-color: #f85149; color: #f85149; }
|
|
3441
|
+
#task-console-scroll {
|
|
3442
|
+
flex: 1; overflow: auto; overscroll-behavior: contain; padding: 8px 14px 28px;
|
|
3443
|
+
background: var(--bg);
|
|
3444
|
+
}
|
|
3445
|
+
#task-console-earlier {
|
|
3446
|
+
display: block; margin: 0 auto 8px; border: 1px solid var(--border); background: var(--bg2);
|
|
3447
|
+
color: var(--text); border-radius: 999px; padding: 3px 14px; font-size: var(--fs-meta-sm); cursor: pointer;
|
|
3448
|
+
}
|
|
3449
|
+
#task-console-earlier:disabled { opacity: 0.6; cursor: default; }
|
|
3450
|
+
#task-console-earlier[hidden] { display: none; }
|
|
3451
|
+
#task-console-body {
|
|
3452
|
+
margin: 0; font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
3453
|
+
font-size: var(--fs-meta-sm); line-height: 1.45; color: var(--text);
|
|
3454
|
+
white-space: pre-wrap; overflow-wrap: anywhere;
|
|
3455
|
+
}
|
|
3456
|
+
.tc-line { min-height: 1.45em; }
|
|
3457
|
+
.tc-line-partial { opacity: 0.85; }
|
|
3458
|
+
.tc-line-target { background: rgba(248, 81, 73, 0.16); border-radius: 3px; }
|
|
3459
|
+
.tc-line-count {
|
|
3460
|
+
display: inline-block; margin-left: 8px; padding: 0 6px; border-radius: 999px;
|
|
3461
|
+
border: 1px solid var(--border); color: var(--muted); font-size: 0.85em; user-select: none;
|
|
3462
|
+
}
|
|
3463
|
+
.tc-bold { font-weight: 700; }
|
|
3464
|
+
.tc-dim { opacity: 0.65; }
|
|
3465
|
+
.tc-italic { font-style: italic; }
|
|
3466
|
+
.tc-underline { text-decoration: underline; }
|
|
3467
|
+
.tc-fg-0 { color: var(--tc-ansi-0); }
|
|
3468
|
+
.tc-fg-1 { color: var(--tc-ansi-1); }
|
|
3469
|
+
.tc-fg-2 { color: var(--tc-ansi-2); }
|
|
3470
|
+
.tc-fg-3 { color: var(--tc-ansi-3); }
|
|
3471
|
+
.tc-fg-4 { color: var(--tc-ansi-4); }
|
|
3472
|
+
.tc-fg-5 { color: var(--tc-ansi-5); }
|
|
3473
|
+
.tc-fg-6 { color: var(--tc-ansi-6); }
|
|
3474
|
+
.tc-fg-7 { color: var(--tc-ansi-7); }
|
|
3475
|
+
.tc-fg-8 { color: var(--tc-ansi-8); }
|
|
3476
|
+
.tc-fg-9 { color: var(--tc-ansi-9); }
|
|
3477
|
+
.tc-fg-10 { color: var(--tc-ansi-10); }
|
|
3478
|
+
.tc-fg-11 { color: var(--tc-ansi-11); }
|
|
3479
|
+
.tc-fg-12 { color: var(--tc-ansi-12); }
|
|
3480
|
+
.tc-fg-13 { color: var(--tc-ansi-13); }
|
|
3481
|
+
.tc-fg-14 { color: var(--tc-ansi-14); }
|
|
3482
|
+
.tc-fg-15 { color: var(--tc-ansi-15); }
|
|
3483
|
+
.tc-bg-0 { background: var(--tc-ansi-0); }
|
|
3484
|
+
.tc-bg-1 { background: var(--tc-ansi-1); }
|
|
3485
|
+
.tc-bg-2 { background: var(--tc-ansi-2); }
|
|
3486
|
+
.tc-bg-3 { background: var(--tc-ansi-3); }
|
|
3487
|
+
.tc-bg-4 { background: var(--tc-ansi-4); }
|
|
3488
|
+
.tc-bg-5 { background: var(--tc-ansi-5); }
|
|
3489
|
+
.tc-bg-6 { background: var(--tc-ansi-6); }
|
|
3490
|
+
.tc-bg-7 { background: var(--tc-ansi-7); }
|
|
3491
|
+
.tc-bg-8 { background: var(--tc-ansi-8); }
|
|
3492
|
+
.tc-bg-9 { background: var(--tc-ansi-9); }
|
|
3493
|
+
.tc-bg-10 { background: var(--tc-ansi-10); }
|
|
3494
|
+
.tc-bg-11 { background: var(--tc-ansi-11); }
|
|
3495
|
+
.tc-bg-12 { background: var(--tc-ansi-12); }
|
|
3496
|
+
.tc-bg-13 { background: var(--tc-ansi-13); }
|
|
3497
|
+
.tc-bg-14 { background: var(--tc-ansi-14); }
|
|
3498
|
+
.tc-bg-15 { background: var(--tc-ansi-15); }
|
|
3499
|
+
#task-console-status { color: var(--muted); padding: 10px 0; font-size: var(--fs-meta-sm); }
|
|
3500
|
+
#task-console-status[hidden] { display: none; }
|
|
3501
|
+
#task-console-jump {
|
|
3502
|
+
position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%);
|
|
3503
|
+
border: 1px solid var(--accent); background: var(--bg3); color: var(--accent);
|
|
3504
|
+
border-radius: 999px; padding: 5px 14px; font-size: var(--fs-meta-sm); cursor: pointer;
|
|
3505
|
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
|
|
3506
|
+
}
|
|
3507
|
+
#task-console-jump[hidden] { display: none; }
|
|
3508
|
+
/* Rows in the composer panel: the console opener, the health hints, the
|
|
3509
|
+
ended rows. */
|
|
3510
|
+
.bg-task-desc.task-console-open {
|
|
3511
|
+
display: block; -webkit-line-clamp: unset; background: none; border: 0; padding: 0; margin: 0;
|
|
3512
|
+
font: inherit; color: var(--text); text-align: left; cursor: pointer;
|
|
3513
|
+
text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 3px;
|
|
3514
|
+
}
|
|
3515
|
+
.bg-task-desc.task-console-open:hover, .bg-task-desc.task-console-open:focus-visible {
|
|
3516
|
+
color: var(--accent); text-decoration-color: currentColor; outline: none;
|
|
3517
|
+
}
|
|
3518
|
+
.bg-task-desc-no-output { cursor: help; }
|
|
3519
|
+
.bg-task-steps { color: var(--muted); flex-shrink: 0; font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
3520
|
+
.bg-task-stall { color: var(--muted); flex-shrink: 0; white-space: nowrap; }
|
|
3521
|
+
.bg-task-stall[hidden] { display: none; }
|
|
3522
|
+
.bg-task-stall-warn { color: var(--warn); font-weight: 600; }
|
|
3523
|
+
.bg-task-chip {
|
|
3524
|
+
flex-shrink: 0; border: 1px solid var(--success); color: var(--success); background: transparent;
|
|
3525
|
+
border-radius: 999px; padding: 0 7px; font-size: var(--fs-meta-sm); white-space: nowrap;
|
|
3526
|
+
font-variant-numeric: tabular-nums;
|
|
3527
|
+
}
|
|
3528
|
+
.bg-task-chip[hidden] { display: none; }
|
|
3529
|
+
.bg-task-chip-fail { border-color: var(--danger); color: var(--danger); }
|
|
3530
|
+
.bg-task-row-ended { opacity: 0.62; }
|
|
3531
|
+
.bg-task-row-ended:hover, .bg-task-row-ended:focus-within { opacity: 0.9; }
|
|
3532
|
+
.bg-task-outcome { flex-shrink: 0; font-weight: 700; }
|
|
3533
|
+
.bg-task-outcome-ok { color: var(--success); }
|
|
3534
|
+
.bg-task-outcome-fail { color: var(--danger); }
|
|
3535
|
+
.bg-task-dismiss {
|
|
3536
|
+
flex-shrink: 0; background: transparent; border: 1px solid var(--border); color: var(--muted);
|
|
3537
|
+
border-radius: 8px; width: 26px; height: 24px; line-height: 1; cursor: pointer; font-size: 1rem;
|
|
3538
|
+
}
|
|
3539
|
+
.bg-task-dismiss:hover { color: var(--text); border-color: var(--text); }
|
|
3540
|
+
@media (max-width: 680px) {
|
|
3541
|
+
#task-console-modal { padding: 0; }
|
|
3542
|
+
#task-console-modal .subagent-viewer-dialog { width: 100%; height: 100%; border: 0; border-radius: 0; }
|
|
3543
|
+
#task-console-scroll { padding: 8px 10px 28px; }
|
|
3544
|
+
}
|
|
3187
3545
|
/* Preview cards: same row grammar as a background task, with a link-shaped
|
|
3188
3546
|
primary action. Shared by the composer panel and the settings list. */
|
|
3189
3547
|
.preview-row {
|
|
@@ -3213,6 +3571,32 @@
|
|
|
3213
3571
|
.preview-close:hover:not(:disabled) { border-color: #f85149; color: #f85149; }
|
|
3214
3572
|
.preview-close:disabled { opacity: 0.5; cursor: default; }
|
|
3215
3573
|
#settings-previews-empty { color: var(--muted); font-size: var(--fs-meta-sm); }
|
|
3574
|
+
/* Settings → Sharing: one row per shared conversation, the preview row's
|
|
3575
|
+
grammar, with its access log folded underneath. */
|
|
3576
|
+
#settings-shares-list { width: 100%; }
|
|
3577
|
+
.share-row { margin-top: 8px; padding: 6px 8px; border-radius: 8px; background: var(--bg2); }
|
|
3578
|
+
.share-row-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
|
|
3579
|
+
.share-row-main { flex: 1 1 220px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
|
|
3580
|
+
.share-row-title {
|
|
3581
|
+
background: none; border: 0; padding: 0; text-align: left; cursor: pointer;
|
|
3582
|
+
color: var(--text); font: inherit; overflow-wrap: anywhere;
|
|
3583
|
+
}
|
|
3584
|
+
.share-row-title:hover { color: var(--accent); text-decoration: underline; }
|
|
3585
|
+
.share-row-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
|
3586
|
+
.share-row-actions button {
|
|
3587
|
+
flex-shrink: 0; background: transparent; border: 1px solid var(--border);
|
|
3588
|
+
color: var(--text); border-radius: 8px; padding: 3px 10px; cursor: pointer;
|
|
3589
|
+
font-size: var(--fs-meta-sm); line-height: 1.5;
|
|
3590
|
+
}
|
|
3591
|
+
.share-row-actions button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
|
|
3592
|
+
.share-row-actions button.share-stop:hover:not(:disabled) { border-color: #f85149; color: #f85149; }
|
|
3593
|
+
.share-row-actions button:disabled { opacity: 0.5; cursor: default; }
|
|
3594
|
+
.share-opens { margin-top: 6px; border-top: 1px solid var(--border); padding-top: 4px; }
|
|
3595
|
+
.share-open { padding: 4px 0; font-size: var(--fs-meta-sm); border-bottom: 1px solid var(--border); }
|
|
3596
|
+
.share-open:last-child { border-bottom: 0; }
|
|
3597
|
+
.share-open-meta { color: var(--text); }
|
|
3598
|
+
.share-open-agent { color: var(--muted); overflow-wrap: anywhere; }
|
|
3599
|
+
#settings-shares-empty { color: var(--muted); font-size: var(--fs-meta-sm); }
|
|
3216
3600
|
/* Remote relays (Settings → Relays, the @mention popup): a health dot —
|
|
3217
3601
|
online green, unreachable/refused red, never checked grey. */
|
|
3218
3602
|
.remote-relay-dot {
|
|
@@ -3332,17 +3716,15 @@
|
|
|
3332
3716
|
.relay-event-line.relay-event-error,
|
|
3333
3717
|
.relay-event-line.relay-event-task-failed,
|
|
3334
3718
|
.relay-event-line.relay-event-stalled { color: var(--text, inherit); }
|
|
3335
|
-
/* Agent exchanges: an agent's prompt
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
and the
|
|
3339
|
-
|
|
3340
|
-
bubble's width. */
|
|
3719
|
+
/* Agent exchanges: an agent's prompt folded into one row in the event
|
|
3720
|
+
rows' look (agent-exchange-fold-view.mjs). The row is the first child of
|
|
3721
|
+
the prompt's own node; closed, the prompt's bubble is hidden. The reply
|
|
3722
|
+
and the live bubble are never part of it. The prompt's node spans the
|
|
3723
|
+
pane for the row; its bubble keeps a user bubble's width. */
|
|
3341
3724
|
.msg.agent-exchange-head { align-self: stretch; max-width: 100%; }
|
|
3342
3725
|
.msg.agent-exchange-head > .msg-bubble { max-width: 82%; }
|
|
3343
3726
|
.msg.agent-exchange-head.agent-exchange-closed > .msg-bubble,
|
|
3344
|
-
.msg.agent-exchange-head.agent-exchange-closed > .msg-label
|
|
3345
|
-
#messages > .msg.agent-exchange-member.agent-exchange-closed { display: none; }
|
|
3727
|
+
.msg.agent-exchange-head.agent-exchange-closed > .msg-label { display: none; }
|
|
3346
3728
|
.agent-exchange-row {
|
|
3347
3729
|
align-self: stretch; min-width: 0;
|
|
3348
3730
|
border: 1px dashed var(--border); border-left: 3px solid var(--accent);
|
|
@@ -3719,7 +4101,19 @@
|
|
|
3719
4101
|
.file-preview-markdown p { margin-bottom: 0.55em; }
|
|
3720
4102
|
.file-preview-markdown h1, .file-preview-markdown h2, .file-preview-markdown h3 { margin: 0.6em 0 0.35em; }
|
|
3721
4103
|
.file-preview-markdown ul, .file-preview-markdown ol { margin-left: 1.3em; margin-bottom: 0.55em; }
|
|
3722
|
-
|
|
4104
|
+
/* A table wider than the text scrolls sideways in its own box, as code
|
|
4105
|
+
does: the body itself never scrolls sideways, and the gallery swipe
|
|
4106
|
+
knows to leave a sideways scroller alone. */
|
|
4107
|
+
.file-preview-markdown table {
|
|
4108
|
+
display: block;
|
|
4109
|
+
width: max-content;
|
|
4110
|
+
max-width: 100%;
|
|
4111
|
+
overflow-x: auto;
|
|
4112
|
+
-webkit-overflow-scrolling: touch;
|
|
4113
|
+
border-collapse: collapse;
|
|
4114
|
+
margin: 0.55em 0;
|
|
4115
|
+
font-size: 0.88em;
|
|
4116
|
+
}
|
|
3723
4117
|
.file-preview-markdown th, .file-preview-markdown td { border: 1px solid var(--border); padding: 6px 9px; }
|
|
3724
4118
|
.file-preview-markdown th { background: var(--bg3); }
|
|
3725
4119
|
.file-preview-markdown img { display: block; max-width: 100%; height: auto; }
|
|
@@ -4763,6 +5157,44 @@
|
|
|
4763
5157
|
font-size: var(--fs-meta-sm);
|
|
4764
5158
|
padding: 8px 6px;
|
|
4765
5159
|
}
|
|
5160
|
+
/* Hidden messages list (kind 'hidden-messages'): the pin list's rows, with
|
|
5161
|
+
Unhide as a word where the pin list has 🗑, and Unhide all above. */
|
|
5162
|
+
.hidden-row-unhide {
|
|
5163
|
+
appearance: none;
|
|
5164
|
+
border: 0;
|
|
5165
|
+
border-left: 1px solid var(--border);
|
|
5166
|
+
background: transparent;
|
|
5167
|
+
color: var(--muted);
|
|
5168
|
+
cursor: pointer;
|
|
5169
|
+
flex: 0 0 auto;
|
|
5170
|
+
min-width: 44px;
|
|
5171
|
+
min-height: 44px;
|
|
5172
|
+
padding: 0 12px;
|
|
5173
|
+
font: inherit;
|
|
5174
|
+
font-size: var(--fs-meta-sm);
|
|
5175
|
+
}
|
|
5176
|
+
.hidden-row-unhide:hover:not(:disabled) {
|
|
5177
|
+
color: var(--accent);
|
|
5178
|
+
background: var(--bg2);
|
|
5179
|
+
}
|
|
5180
|
+
.hidden-row-unhide:disabled { cursor: wait; opacity: 0.55; }
|
|
5181
|
+
.hidden-list-actions,
|
|
5182
|
+
.hidden-unhide-all-confirm {
|
|
5183
|
+
margin-bottom: 10px;
|
|
5184
|
+
}
|
|
5185
|
+
.hidden-list-actions {
|
|
5186
|
+
display: flex;
|
|
5187
|
+
justify-content: flex-end;
|
|
5188
|
+
}
|
|
5189
|
+
.hidden-unhide-all-confirm {
|
|
5190
|
+
border: 1px solid var(--border);
|
|
5191
|
+
border-radius: 10px;
|
|
5192
|
+
padding: 10px 12px;
|
|
5193
|
+
}
|
|
5194
|
+
.hidden-unhide-all-confirm p {
|
|
5195
|
+
margin: 0 0 8px;
|
|
5196
|
+
font-size: var(--fs-meta-sm);
|
|
5197
|
+
}
|
|
4766
5198
|
|
|
4767
5199
|
#git-changes-modal,
|
|
4768
5200
|
#git-diff-modal {
|
|
@@ -5755,6 +6187,14 @@
|
|
|
5755
6187
|
}
|
|
5756
6188
|
.conv-meta { font-size: var(--fs-meta-sm); margin-top: 5px; }
|
|
5757
6189
|
.conv-delete { opacity: 1; right: 4px; font-size: var(--fs-ui-icon); }
|
|
6190
|
+
/* Session groups on a phone: a shallower indent, and a fold target that
|
|
6191
|
+
is easy to hit without stealing the row's width. */
|
|
6192
|
+
.conv-item.conv-group-member { margin-left: 10px; }
|
|
6193
|
+
.conv-group-fold { width: 24px; height: 24px; margin-left: -6px; }
|
|
6194
|
+
/* The finger covers the row it lifts: the ghost sits a little higher. */
|
|
6195
|
+
.conv-item.conv-drag-ghost { margin: -18px 0 0; }
|
|
6196
|
+
.conv-item.conv-drop-before::before,
|
|
6197
|
+
.conv-item.conv-drop-after::after { height: 4px; }
|
|
5758
6198
|
#chat-header {
|
|
5759
6199
|
padding: var(--chat-header-top-pad-mobile) 10px 10px;
|
|
5760
6200
|
gap: 6px 8px;
|
|
@@ -6125,10 +6565,31 @@
|
|
|
6125
6565
|
}
|
|
6126
6566
|
/* The pin list has one action, Close: the full-width action row above
|
|
6127
6567
|
would leave its title no room. Title left, close button right. */
|
|
6128
|
-
#summary-modal[data-kind="pinned-messages"] .summary-header-actions
|
|
6568
|
+
#summary-modal[data-kind="pinned-messages"] .summary-header-actions,
|
|
6569
|
+
#summary-modal[data-kind="hidden-messages"] .summary-header-actions {
|
|
6129
6570
|
width: auto;
|
|
6130
6571
|
}
|
|
6131
|
-
#summary-modal[data-kind="pinned-messages"] .summary-header-actions .summary-close
|
|
6572
|
+
#summary-modal[data-kind="pinned-messages"] .summary-header-actions .summary-close,
|
|
6573
|
+
#summary-modal[data-kind="hidden-messages"] .summary-header-actions .summary-close {
|
|
6574
|
+
flex: 0 0 auto;
|
|
6575
|
+
min-width: 40px;
|
|
6576
|
+
}
|
|
6577
|
+
/* The session-group picker, rename and confirmations: the same layout,
|
|
6578
|
+
so their title ("Add to group", the chat's name) stays readable. */
|
|
6579
|
+
#summary-modal[data-kind^="group-"] .summary-header-actions {
|
|
6580
|
+
width: auto;
|
|
6581
|
+
}
|
|
6582
|
+
#summary-modal[data-kind^="group-"] .summary-header-actions .summary-close {
|
|
6583
|
+
flex: 0 0 auto;
|
|
6584
|
+
min-width: 40px;
|
|
6585
|
+
}
|
|
6586
|
+
/* About OAR: the same, with Refresh beside the close button. */
|
|
6587
|
+
#summary-modal[data-kind="about"] .summary-header-actions {
|
|
6588
|
+
width: auto;
|
|
6589
|
+
flex: 0 0 auto;
|
|
6590
|
+
}
|
|
6591
|
+
#summary-modal[data-kind="about"] .summary-header-actions .summary-btn,
|
|
6592
|
+
#summary-modal[data-kind="about"] .summary-header-actions .summary-close {
|
|
6132
6593
|
flex: 0 0 auto;
|
|
6133
6594
|
min-width: 40px;
|
|
6134
6595
|
}
|
|
@@ -6389,6 +6850,7 @@
|
|
|
6389
6850
|
</div>
|
|
6390
6851
|
<div id="conv-archived-banner" hidden>Archived conversations <button type="button" class="conv-archived-back" onclick="toggleArchivedConversations()">Back to the list</button></div>
|
|
6391
6852
|
<div id="conv-list"></div>
|
|
6853
|
+
<div id="conv-list-announce" role="status" aria-live="polite"></div>
|
|
6392
6854
|
</div>
|
|
6393
6855
|
<div id="sidebar-resizer" role="separator" aria-orientation="vertical" aria-label="Resize conversations sidebar"></div>
|
|
6394
6856
|
|
|
@@ -6405,6 +6867,7 @@
|
|
|
6405
6867
|
</div>
|
|
6406
6868
|
<div id="chat-header-actions">
|
|
6407
6869
|
<button id="pinned-messages-btn" class="header-icon-btn has-count" type="button" title="Pinned messages" aria-label="Pinned messages" hidden>📍<span class="header-icon-count"></span></button>
|
|
6870
|
+
<button id="hidden-messages-btn" class="header-icon-btn has-count" type="button" title="Hidden from shared viewers" aria-label="Hidden from shared viewers" hidden>🙈<span class="header-icon-count"></span></button>
|
|
6408
6871
|
<button id="message-search-btn" class="header-icon-btn" onclick="openMessageSearchModal()" title="Search messages" aria-label="Search messages">🔍</button>
|
|
6409
6872
|
<button id="context-btn" class="header-icon-btn" onclick="showContext()" title="Check current context" aria-label="Check current context">🧠</button>
|
|
6410
6873
|
<div id="chat-actions-menu-wrap">
|
|
@@ -6413,11 +6876,14 @@
|
|
|
6413
6876
|
<div id="chat-menu-pwa-version" class="chat-actions-menu-meta chat-actions-menu-meta-stacked" aria-hidden="true"><span class="chat-actions-menu-meta-primary">PWA shell version</span><span class="chat-actions-menu-meta-secondary" id="chat-menu-pwa-version-value">v?</span></div>
|
|
6414
6877
|
<div id="chat-menu-queue-status" class="chat-actions-menu-meta chat-actions-menu-meta-stacked" aria-hidden="true"><div class="chat-actions-menu-meta-top"><span class="chat-actions-menu-meta-primary">Queue</span><button id="chat-menu-empty-queue" class="chat-actions-menu-meta-label" type="button">🚮 Empty queue</button></div><span class="chat-actions-menu-meta-secondary" id="chat-menu-queue-status-value">pending=?, processing=?, parked=?</span></div>
|
|
6415
6878
|
<button id="chat-menu-edit-title" class="chat-actions-menu-item" type="button" role="menuitem">✍️ Edit conversation title</button>
|
|
6416
|
-
<button id="chat-menu-
|
|
6879
|
+
<button id="chat-menu-theme-toggle" class="chat-actions-menu-item" type="button" role="menuitem" hidden>🌙/☀️ Day/Night mode</button>
|
|
6417
6880
|
<button id="chat-menu-usage" class="chat-actions-menu-item" type="button" role="menuitem">📊 Check Usage</button>
|
|
6418
6881
|
<button id="chat-menu-compact" class="chat-actions-menu-item" type="button" role="menuitem" hidden disabled aria-hidden="true" tabindex="-1" style="display:none">🗜️ Compact</button>
|
|
6419
6882
|
<button id="chat-menu-share-conversation" class="chat-actions-menu-item" type="button" role="menuitem">➡️ Share conversation</button>
|
|
6883
|
+
<button id="chat-menu-stop-sharing" class="chat-actions-menu-item" type="button" role="menuitem" hidden>⛔ Stop sharing</button>
|
|
6884
|
+
<button id="chat-menu-preview-shared" class="chat-actions-menu-item" type="button" role="menuitem">🔍 Preview as shared</button>
|
|
6420
6885
|
<button id="chat-menu-archive" class="chat-actions-menu-item" type="button" role="menuitem">🗄 Archive conversation</button>
|
|
6886
|
+
<button id="chat-menu-group" class="chat-actions-menu-item" type="button" role="menuitem">🧩 Session group…</button>
|
|
6421
6887
|
<button id="chat-menu-refresh-history" class="chat-actions-menu-item" type="button" role="menuitem" hidden disabled aria-hidden="true" tabindex="-1" style="display:none">🔄️ Refresh history</button>
|
|
6422
6888
|
<button id="chat-menu-inspect-tmux" class="chat-actions-menu-item" type="button" role="menuitem">🖥️ Inspect tmux console</button>
|
|
6423
6889
|
<button id="chat-menu-select-models" class="chat-actions-menu-item" type="button" role="menuitem">🤗 Select Models</button>
|
|
@@ -6425,6 +6891,7 @@
|
|
|
6425
6891
|
<button id="chat-menu-git-changes" class="chat-actions-menu-item" type="button" role="menuitem">🌿 Git changes</button>
|
|
6426
6892
|
<button id="chat-menu-open-cloud-session" class="chat-actions-menu-item" type="button" role="menuitem" hidden>☁️ Open on claude.ai</button>
|
|
6427
6893
|
<button id="chat-menu-settings" class="chat-actions-menu-item" type="button" role="menuitem">⚙️ Settings</button>
|
|
6894
|
+
<button id="chat-menu-about" class="chat-actions-menu-item" type="button" role="menuitem">ℹ️ About OAR</button>
|
|
6428
6895
|
<button id="chat-menu-restart-relay" class="chat-actions-menu-item" type="button" role="menuitem">🌄 Restart web relay</button>
|
|
6429
6896
|
<button id="chat-menu-suspend-host" class="chat-actions-menu-item" type="button" role="menuitem" onclick="openSuspendHostConfirmation()">💤 Suspend host</button>
|
|
6430
6897
|
<button id="chat-menu-kill-session" class="chat-actions-menu-item" type="button" role="menuitem">☠️ Kill session</button>
|
|
@@ -6445,6 +6912,7 @@
|
|
|
6445
6912
|
<div id="input-area">
|
|
6446
6913
|
<button id="jump-to-bottom-btn" type="button" title="Jump to the latest message" aria-label="Jump to the latest message"><span class="jump-to-bottom-icon" aria-hidden="true">⌄</span><span class="jump-to-bottom-badge" hidden></span></button>
|
|
6447
6914
|
<div id="offline-banner">⚠️ CLI is offline — messages will queue until it reconnects</div>
|
|
6915
|
+
<div id="share-preview-banner" role="note"></div>
|
|
6448
6916
|
<div id="model-banner"></div>
|
|
6449
6917
|
<div id="usage-limit-banner" role="status" aria-live="polite" hidden></div>
|
|
6450
6918
|
<div id="model-lock-note" hidden></div>
|
|
@@ -6627,6 +7095,16 @@
|
|
|
6627
7095
|
tabindex="-1"
|
|
6628
7096
|
data-settings-tab="previews"
|
|
6629
7097
|
>Previews</button>
|
|
7098
|
+
<button
|
|
7099
|
+
id="settings-tab-shares"
|
|
7100
|
+
class="settings-tab"
|
|
7101
|
+
type="button"
|
|
7102
|
+
role="tab"
|
|
7103
|
+
aria-selected="false"
|
|
7104
|
+
aria-controls="settings-panel-shares"
|
|
7105
|
+
tabindex="-1"
|
|
7106
|
+
data-settings-tab="shares"
|
|
7107
|
+
>Sharing</button>
|
|
6630
7108
|
<button
|
|
6631
7109
|
id="settings-tab-notifications"
|
|
6632
7110
|
class="settings-tab"
|
|
@@ -6679,6 +7157,33 @@
|
|
|
6679
7157
|
>
|
|
6680
7158
|
</div>
|
|
6681
7159
|
<div class="settings-help" style="margin-top: 6px;">Hide the menu action when host suspend is unsupported or not needed on this device.</div>
|
|
7160
|
+
<div class="settings-row" style="margin-top: 12px; margin-bottom: 0;">
|
|
7161
|
+
<label for="scroll-on-send-toggle">Jump to the end when I send a message</label>
|
|
7162
|
+
<input
|
|
7163
|
+
id="scroll-on-send-toggle"
|
|
7164
|
+
type="checkbox"
|
|
7165
|
+
onchange="updateScrollOnSendSetting(this.checked)"
|
|
7166
|
+
aria-label="Jump to the end when I send a message"
|
|
7167
|
+
checked
|
|
7168
|
+
>
|
|
7169
|
+
</div>
|
|
7170
|
+
<div class="settings-help" style="margin-top: 6px;">A conversation only scrolls by itself while you are at its end. Anywhere else it stays where you are reading, and the round button above the composer shows that something new or a question is waiting below. Your own message is the exception: sending one takes you to the end. Switch this off to stay put then too. Saved in this browser.</div>
|
|
7171
|
+
<div class="settings-row settings-row-column" style="margin-top: 12px; margin-bottom: 0;">
|
|
7172
|
+
<label for="conversation-window-retention-slider">Messages kept per conversation for switching back <span id="conversation-window-retention-value">200 messages</span></label>
|
|
7173
|
+
<input
|
|
7174
|
+
id="conversation-window-retention-slider"
|
|
7175
|
+
type="range"
|
|
7176
|
+
min="100"
|
|
7177
|
+
max="1100"
|
|
7178
|
+
step="100"
|
|
7179
|
+
value="200"
|
|
7180
|
+
aria-label="Messages kept per conversation for switching back"
|
|
7181
|
+
aria-valuetext="200 messages"
|
|
7182
|
+
oninput="previewConversationWindowRetention(this.value)"
|
|
7183
|
+
onchange="updateConversationWindowRetention(this.value)"
|
|
7184
|
+
>
|
|
7185
|
+
</div>
|
|
7186
|
+
<div class="settings-help" style="margin-top: 6px;">A conversation you switch away from and back to opens where you were reading, with the older messages you had loaded. This many are kept around that place for each of the last eight conversations; No limit keeps them all, at the cost of memory. Saved in this browser.</div>
|
|
6682
7187
|
<div class="settings-row settings-row-column" style="margin-top: 12px; margin-bottom: 0;">
|
|
6683
7188
|
<label for="turn-ceiling-slider">Max turn duration <span id="turn-ceiling-value">No limit</span></label>
|
|
6684
7189
|
<input
|
|
@@ -6709,6 +7214,21 @@
|
|
|
6709
7214
|
>
|
|
6710
7215
|
</div>
|
|
6711
7216
|
<div class="settings-help" style="margin-top: 6px;">How long background tasks may keep a session alive after its turn ends: backgrounded commands, subagents and monitors on Claude; background agents and detached shells on Copilot's SDK engine. When the limit is reached the tasks are stopped. Set to 0 for no limit — tasks then run until they finish or you stop them from the composer panel.</div>
|
|
7217
|
+
<div class="settings-row settings-row-column" style="margin-top: 12px; margin-bottom: 0;">
|
|
7218
|
+
<label for="task-stall-minutes-slider">Mark a background task as quiet after <span id="task-stall-minutes-value">10 min</span></label>
|
|
7219
|
+
<input
|
|
7220
|
+
id="task-stall-minutes-slider"
|
|
7221
|
+
type="range"
|
|
7222
|
+
min="1"
|
|
7223
|
+
max="120"
|
|
7224
|
+
step="1"
|
|
7225
|
+
value="10"
|
|
7226
|
+
aria-label="Minutes without output before a background task is marked as quiet"
|
|
7227
|
+
oninput="previewTaskStallMinutesSetting(this.value)"
|
|
7228
|
+
onchange="updateTaskStallMinutesSetting(this.value)"
|
|
7229
|
+
>
|
|
7230
|
+
</div>
|
|
7231
|
+
<div class="settings-help" style="margin-top: 6px;">A shell or Monitor task that has written no output for this long gets an amber "no output for N min" note in the composer panel and its console.</div>
|
|
6712
7232
|
<div class="settings-row" style="margin-top: 12px; margin-bottom: 0;">
|
|
6713
7233
|
<label for="subagent-record-retention-select">Keep sub-agent tool output</label>
|
|
6714
7234
|
<select id="subagent-record-retention-select" onchange="updateSubagentRecordRetentionSetting(this.value)" aria-label="Keep sub-agent tool output">
|
|
@@ -7046,6 +7566,18 @@
|
|
|
7046
7566
|
<option value="off">Off — no attribution</option>
|
|
7047
7567
|
</select>
|
|
7048
7568
|
<div id="claude-attribution-example" class="settings-help"></div>
|
|
7569
|
+
<label for="claude-background-command-limit-slider" style="margin-top: 8px;">Claude background command limit <span id="claude-background-command-limit-value">2 h</span></label>
|
|
7570
|
+
<input
|
|
7571
|
+
id="claude-background-command-limit-slider"
|
|
7572
|
+
type="range"
|
|
7573
|
+
min="30"
|
|
7574
|
+
max="480"
|
|
7575
|
+
step="30"
|
|
7576
|
+
value="120"
|
|
7577
|
+
aria-label="Claude background command limit in minutes"
|
|
7578
|
+
oninput="window.previewClaudeBackgroundCommandLimit?.(this.value)"
|
|
7579
|
+
>
|
|
7580
|
+
<div class="settings-help">How long a command Claude runs in the background may take before Claude Code stops it, unless Claude gives it its own timeout (up to 8 h). Commands in the foreground move to the background after 2 min. Applies to Claude sessions started after you save; a running session keeps its limit until it restarts.</div>
|
|
7049
7581
|
<div id="claude-settings-status" class="settings-help settings-provider-status">Loading Claude settings…</div>
|
|
7050
7582
|
<div style="display: flex; gap: 8px; margin-top: 8px;">
|
|
7051
7583
|
<button id="claude-save-btn" type="button" class="summary-btn" onclick="saveClaudeSettings()">Save Claude settings</button>
|
|
@@ -7436,7 +7968,52 @@
|
|
|
7436
7968
|
<label>Live previews</label>
|
|
7437
7969
|
<div id="settings-previews-list"></div>
|
|
7438
7970
|
<div id="settings-previews-empty" class="settings-help">Loading previews…</div>
|
|
7439
|
-
<div class="settings-help">Local dev servers published on the preview host. Previews never expire
|
|
7971
|
+
<div class="settings-help">Local dev servers and folders published on the preview host. Previews never expire and survive a relay restart — they live until you close them here or delete their conversation (a dev-server preview also ends when the machine reboots). Every link is public: anyone with the URL reaches the app without logging in.</div>
|
|
7972
|
+
</div>
|
|
7973
|
+
</div>
|
|
7974
|
+
<div
|
|
7975
|
+
id="settings-panel-shares"
|
|
7976
|
+
class="settings-panel"
|
|
7977
|
+
role="tabpanel"
|
|
7978
|
+
tabindex="0"
|
|
7979
|
+
aria-labelledby="settings-tab-shares"
|
|
7980
|
+
data-settings-panel="shares"
|
|
7981
|
+
hidden
|
|
7982
|
+
>
|
|
7983
|
+
<!-- One section per concern; further sharing settings (such as how
|
|
7984
|
+
paths show in a shared view) get their own section in here. -->
|
|
7985
|
+
<div id="shares-settings-sections" class="shares-settings-sections">
|
|
7986
|
+
<div id="shares-settings-section" class="settings-row settings-row-column" style="margin-top: 12px; margin-bottom: 0;">
|
|
7987
|
+
<label>Shared conversations</label>
|
|
7988
|
+
<div id="settings-shares-list"></div>
|
|
7989
|
+
<div id="settings-shares-empty" class="settings-help">Loading shared conversations…</div>
|
|
7990
|
+
<div class="settings-help">Every link is public: anyone with the URL can read the conversation without logging in, until you stop sharing it. Renew link gives the conversation a new link; the old one stops working at once and the access log carries over. Stop sharing ends the link and deletes its access log.</div>
|
|
7991
|
+
</div>
|
|
7992
|
+
<div id="shares-access-log-section" class="settings-row settings-row-column" style="margin-top: 16px; margin-bottom: 0;">
|
|
7993
|
+
<label>Access log</label>
|
|
7994
|
+
<div class="settings-row" style="width: 100%; margin-bottom: 0;">
|
|
7995
|
+
<label for="settings-shares-store-ip">Store viewer IP addresses</label>
|
|
7996
|
+
<input id="settings-shares-store-ip" type="checkbox" aria-label="Store viewer IP addresses" checked>
|
|
7997
|
+
</div>
|
|
7998
|
+
<div class="settings-help">Each open of a shared link is logged with its time, browser and country. Off: new entries keep no IP address (entries logged before keep theirs), and distinct viewers are still told apart by a keyed hash. The log is kept until you stop sharing the link or delete the conversation.</div>
|
|
7999
|
+
<div id="settings-shares-status" class="settings-help" role="status"></div>
|
|
8000
|
+
</div>
|
|
8001
|
+
<div id="shares-path-privacy-section" class="settings-row settings-row-column" style="margin-top: 16px; margin-bottom: 0;">
|
|
8002
|
+
<label id="settings-shares-path-privacy-label">Paths and file names</label>
|
|
8003
|
+
<div role="radiogroup" aria-labelledby="settings-shares-path-privacy-label" style="display: flex; flex-direction: column; gap: 4px;">
|
|
8004
|
+
<label style="font-weight: normal;">
|
|
8005
|
+
<input type="radio" name="settings-shares-path-privacy" value="show"> Show every path and file name
|
|
8006
|
+
</label>
|
|
8007
|
+
<label style="font-weight: normal;">
|
|
8008
|
+
<input type="radio" name="settings-shares-path-privacy" value="filename"> Hide the path, show the file name
|
|
8009
|
+
</label>
|
|
8010
|
+
<label style="font-weight: normal;">
|
|
8011
|
+
<input type="radio" name="settings-shares-path-privacy" value="hide"> Hide paths and file names
|
|
8012
|
+
</label>
|
|
8013
|
+
</div>
|
|
8014
|
+
<div class="settings-help">What every shared link shows of this relay's paths; your own view always shows everything. Free text (replies, thoughts, tool output) is filtered on a best-effort basis: check a conversation with ⋯ → Preview as shared.</div>
|
|
8015
|
+
<div id="settings-shares-path-privacy-status" class="settings-help" role="status"></div>
|
|
8016
|
+
</div>
|
|
7440
8017
|
</div>
|
|
7441
8018
|
</div>
|
|
7442
8019
|
<div
|
|
@@ -7658,6 +8235,33 @@
|
|
|
7658
8235
|
</div>
|
|
7659
8236
|
</div>
|
|
7660
8237
|
|
|
8238
|
+
<!-- Task console: a shell or Monitor task's output, live while it runs
|
|
8239
|
+
(task-console.mjs). -->
|
|
8240
|
+
<div id="task-console-modal" aria-hidden="true">
|
|
8241
|
+
<div class="subagent-viewer-dialog task-console-dialog" role="dialog" aria-modal="true" aria-labelledby="task-console-title">
|
|
8242
|
+
<div class="subagent-viewer-header">
|
|
8243
|
+
<div class="subagent-viewer-title-row">
|
|
8244
|
+
<span aria-hidden="true">⌨️</span>
|
|
8245
|
+
<h2 id="task-console-title">Task</h2>
|
|
8246
|
+
<button id="task-console-stop" class="subagent-viewer-btn" type="button" hidden>Stop</button>
|
|
8247
|
+
<button class="subagent-viewer-btn task-console-close" type="button" aria-label="Close">×</button>
|
|
8248
|
+
</div>
|
|
8249
|
+
<div class="task-console-meta-row">
|
|
8250
|
+
<span id="task-console-meta"></span>
|
|
8251
|
+
<span id="task-console-stall" class="tc-stall" hidden></span>
|
|
8252
|
+
<button id="task-console-chip" class="bg-task-chip" type="button" hidden></button>
|
|
8253
|
+
<button id="task-console-failure" type="button" hidden>first failure</button>
|
|
8254
|
+
</div>
|
|
8255
|
+
</div>
|
|
8256
|
+
<div id="task-console-scroll">
|
|
8257
|
+
<button id="task-console-earlier" type="button" hidden>Load earlier</button>
|
|
8258
|
+
<pre id="task-console-body"></pre>
|
|
8259
|
+
<div id="task-console-status" hidden></div>
|
|
8260
|
+
</div>
|
|
8261
|
+
<button id="task-console-jump" type="button" hidden>Jump to end ↓</button>
|
|
8262
|
+
</div>
|
|
8263
|
+
</div>
|
|
8264
|
+
|
|
7661
8265
|
<!-- Fullscreen file viewer. The content fills the screen; the chrome bars
|
|
7662
8266
|
float over it and a tap on the content shows or hides them. -->
|
|
7663
8267
|
<div id="file-preview-modal" aria-hidden="true">
|