@oar-sh/oar 0.9.21 → 0.9.22
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 +113 -0
- package/README.md +9 -9
- package/package.json +1 -1
- package/server/claude-cloud-worker/claude-cloud-session-worker.mjs +9 -1
- package/server/claude-worker/claude-sdk-adapter.mjs +149 -4
- package/server/claude-worker/claude-session-process.mjs +9 -4
- package/server/claude-worker/claude-session-worker-main.mjs +10 -1
- package/server/copilot-worker/copilot-sdk-session-process.mjs +1 -0
- package/server/copilot-worker/copilot-sdk-session-worker.mjs +10 -1
- package/server/cursor-worker/cursor-session-worker.mjs +9 -1
- package/server/db-schema.mjs +19 -0
- package/server/grok-worker/grok-background-tasks.mjs +1 -0
- package/server/grok-worker/grok-session-worker.mjs +10 -1
- package/server/grok-worker/grok-turn-runner.mjs +1 -0
- package/server/migrations/0037-relay-asks-queue-id.mjs +66 -0
- package/server/migrations/0038-turn-seq.mjs +92 -0
- package/server/public/app/activity-replay-state.mjs +160 -42
- package/server/public/app/api-client.js +7 -0
- package/server/public/app/ask-user-view.js +4 -3
- package/server/public/app/bootstrap.js +62 -4
- package/server/public/app/chat-actions-menu-state.mjs +2 -0
- package/server/public/app/context-usage-view.mjs +68 -0
- package/server/public/app/conversation-view.js +306 -49
- package/server/public/app/header-priority-actions.mjs +5 -1
- package/server/public/app/held-details.mjs +202 -0
- package/server/public/app/inbox-ui.js +70 -79
- package/server/public/app/inbox-view.mjs +35 -19
- package/server/public/app/journal-view.js +17 -0
- package/server/public/app/live-activity-cap.mjs +103 -0
- package/server/public/app/questions-panel-ui.js +634 -0
- package/server/public/app/questions-stub-view.mjs +40 -0
- package/server/public/app/questions-view.mjs +89 -0
- package/server/public/app/relay-board-view.js +12 -2
- package/server/public/app/relay-thoughts.mjs +15 -1
- package/server/public/app/session-history-ui.js +1 -0
- package/server/public/app/settings-modal.js +6 -0
- package/server/public/app/socket-handlers.js +42 -11
- package/server/public/app/stream-view-preference.mjs +60 -0
- package/server/public/app/subagent-fold.mjs +6 -3
- package/server/public/app/subagent-timeline-view.mjs +12 -5
- package/server/public/app/subagent-viewer.mjs +8 -6
- package/server/public/app/thoughts-preference.mjs +79 -0
- package/server/public/app/turn-stream-view.mjs +124 -0
- package/server/public/index.html +391 -214
- package/server/repositories/message-repository.mjs +10 -0
- package/server/repositories/question-repository.mjs +51 -7
- package/server/repositories/relay-turn-rows.mjs +56 -0
- package/server/routes/ask-user-routes.mjs +34 -5
- package/server/routes/messages-routes.mjs +35 -14
- package/server/routes/relay-ask-routes.mjs +15 -5
- package/server/routes/sessions-routes.mjs +76 -5
- package/server/server-runtime.mjs +178 -131
- package/server/services/cloudflared-tunnel-service.mjs +7 -0
- package/server/services/idle-timers.mjs +184 -0
- package/server/services/queue-wake-hook.mjs +145 -0
- package/server/services/queue-waker.mjs +127 -0
- package/server/services/relay-ask-service.mjs +64 -5
- package/server/services/relay-event-service.mjs +4 -1
- package/server/services/remote-relay-dispatcher.mjs +23 -4
- package/server/services/session-history-refresh-service.mjs +4 -0
- package/server/services/session-worker-supervisor-service.mjs +36 -0
- package/server/services/session-worker-websocket-service.mjs +143 -15
- package/server/services/ssh-tunnel-manager-service.mjs +7 -0
- package/shared/ask-user-bridge.mjs +9 -6
- package/shared/relay-asks.mjs +10 -0
- package/shared/relay-events.mjs +1 -0
- package/shared/worker-runtime/heartbeat.mjs +26 -0
- package/shared/worker-runtime/worker-keepalive.mjs +108 -0
- package/shared/worker-runtime/worker-websocket-link.mjs +21 -10
package/server/public/index.html
CHANGED
|
@@ -671,8 +671,11 @@
|
|
|
671
671
|
.header-icon-count:empty { display: none; }
|
|
672
672
|
/* The display rule above outranks the UA [hidden] rule, same trap as the
|
|
673
673
|
other [hidden] overrides in this file. */
|
|
674
|
+
#questions-btn[hidden],
|
|
674
675
|
#pinned-messages-btn[hidden],
|
|
675
676
|
#hidden-messages-btn[hidden] { display: none; }
|
|
677
|
+
/* 📓 with an urgent question waiting: the urgent count, in red. */
|
|
678
|
+
.header-icon-count.is-urgent { color: var(--danger); font-weight: 600; }
|
|
676
679
|
/* Same trap: without this the ︙ trigger stays drawn as a dead button. */
|
|
677
680
|
#chat-actions-menu-btn[hidden] { display: none; }
|
|
678
681
|
#cli-dot {
|
|
@@ -885,6 +888,7 @@
|
|
|
885
888
|
text-align: center;
|
|
886
889
|
}
|
|
887
890
|
.inbox-count:empty { display: none; }
|
|
891
|
+
.inbox-count.is-urgent { background: var(--danger); color: #fff; }
|
|
888
892
|
body.inbox-view-active #input-area { display: none; }
|
|
889
893
|
body.inbox-view-active #pending-question-banner { display: none; }
|
|
890
894
|
.inbox-view { display: grid; gap: calc(7px * var(--ui-scale)); padding: calc(4px * var(--ui-scale)) 0 calc(12px * var(--ui-scale)); }
|
|
@@ -941,7 +945,11 @@
|
|
|
941
945
|
.inbox-item-header { font-weight: 600; font-size: var(--fs-meta-sm); }
|
|
942
946
|
.inbox-item-question, .inbox-item-recommendation { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
943
947
|
.inbox-item-recommendation { color: var(--muted); font-size: var(--fs-meta-sm); }
|
|
944
|
-
|
|
948
|
+
/* A 28px tap row however small its text (the Inbox, 📓). */
|
|
949
|
+
.inbox-item-detail summary {
|
|
950
|
+
cursor: pointer; color: var(--muted); font-size: var(--fs-meta-sm);
|
|
951
|
+
min-height: calc(28px * var(--ui-scale)); line-height: calc(28px * var(--ui-scale)); width: fit-content;
|
|
952
|
+
}
|
|
945
953
|
.inbox-item-detail-text {
|
|
946
954
|
margin: calc(3px * var(--ui-scale)) 0 0;
|
|
947
955
|
padding: calc(4px * var(--ui-scale)) calc(6px * var(--ui-scale));
|
|
@@ -989,8 +997,21 @@
|
|
|
989
997
|
.inbox-recommended-tag { color: var(--accent); font-size: var(--fs-meta-xs); }
|
|
990
998
|
.inbox-answer { border-color: var(--accent); color: var(--accent); }
|
|
991
999
|
.inbox-dismiss { color: var(--muted); }
|
|
992
|
-
.inbox-view button:disabled
|
|
993
|
-
|
|
1000
|
+
.inbox-view button:disabled { opacity: 0.5; cursor: wait; }
|
|
1001
|
+
/* 📓 An ask's one-line stub in the bubble of the turn that asked it (or
|
|
1002
|
+
standing alone at the transcript's end); a tap opens 📓 at it. */
|
|
1003
|
+
.msg-ask-stubs { display: grid; justify-items: start; gap: calc(2px * var(--ui-scale)); margin-top: calc(4px * var(--ui-scale)); }
|
|
1004
|
+
.msg-ask-stub {
|
|
1005
|
+
min-height: calc(28px * var(--ui-scale)); padding: calc(2px * var(--ui-scale)) calc(8px * var(--ui-scale));
|
|
1006
|
+
border: 1px solid var(--border); border-radius: calc(8px * var(--ui-scale)); background: var(--bg2);
|
|
1007
|
+
color: var(--text); font: inherit; font-size: var(--fs-meta-sm); text-align: left; cursor: pointer;
|
|
1008
|
+
max-width: 100%; overflow-wrap: anywhere;
|
|
1009
|
+
}
|
|
1010
|
+
.msg-ask-stub:hover { border-color: var(--accent); }
|
|
1011
|
+
.msg-ask-stub-urgent { color: var(--danger); font-weight: 600; }
|
|
1012
|
+
.msg-ask-stub.is-closed { color: var(--muted); }
|
|
1013
|
+
.relay-ask-stub-container { align-self: flex-start; max-width: 82%; }
|
|
1014
|
+
.relay-ask-stub-container > .msg-ask-stubs { margin-top: 0; }
|
|
994
1015
|
/* The phone: one column, buttons the full width. */
|
|
995
1016
|
@media (max-width: 680px) {
|
|
996
1017
|
#inbox-btn { min-width: calc(64px * var(--ui-scale)); padding: calc(5px * var(--ui-scale)) calc(6px * var(--ui-scale)); }
|
|
@@ -1906,6 +1927,21 @@
|
|
|
1906
1927
|
.settings-gap-md { margin-top: calc(5px * var(--ui-scale)); margin-bottom: 0; }
|
|
1907
1928
|
.settings-gap-sm { margin-top: calc(4px * var(--ui-scale)); margin-bottom: 0; }
|
|
1908
1929
|
.settings-gap-xs { margin-top: calc(3px * var(--ui-scale)); margin-bottom: 0; }
|
|
1930
|
+
/* Settings → General in headed groups: a title row per section and a thin
|
|
1931
|
+
rule above every section after the first. The first row under a title
|
|
1932
|
+
drops its own gap; the title's margin already spaces it. */
|
|
1933
|
+
.settings-section + .settings-section {
|
|
1934
|
+
border-top: 1px solid var(--border);
|
|
1935
|
+
margin-top: calc(10px * var(--ui-scale));
|
|
1936
|
+
}
|
|
1937
|
+
.settings-section-title {
|
|
1938
|
+
font-size: var(--fs-meta-md);
|
|
1939
|
+
font-weight: 600;
|
|
1940
|
+
color: var(--muted);
|
|
1941
|
+
margin: calc(14px * var(--ui-scale)) 0 calc(6px * var(--ui-scale));
|
|
1942
|
+
}
|
|
1943
|
+
.settings-section:first-child .settings-section-title { margin-top: 0; }
|
|
1944
|
+
.settings-section-title + .settings-row { margin-top: 0; }
|
|
1909
1945
|
/* A row inside a column block: the block's full width; the lead row (the
|
|
1910
1946
|
provider's on/off toggle) keeps a small gap to the fields below. */
|
|
1911
1947
|
.settings-row-full { width: 100%; }
|
|
@@ -2845,15 +2881,25 @@
|
|
|
2845
2881
|
opacity: 0.92;
|
|
2846
2882
|
font-size: var(--fs-meta-md);
|
|
2847
2883
|
}
|
|
2884
|
+
/* The browser's own disclosure marker, the glyph of the Thoughts panel
|
|
2885
|
+
above the rows. */
|
|
2848
2886
|
.thinking-thought > summary {
|
|
2849
2887
|
cursor: pointer;
|
|
2850
|
-
list-
|
|
2888
|
+
display: list-item;
|
|
2889
|
+
list-style: disclosure-closed inside;
|
|
2851
2890
|
white-space: normal;
|
|
2852
2891
|
overflow-wrap: anywhere;
|
|
2853
2892
|
word-break: break-word;
|
|
2854
2893
|
}
|
|
2855
|
-
|
|
2856
|
-
|
|
2894
|
+
/* Open, the summary stays as a one-line fold header so the reader can fold
|
|
2895
|
+
the thought by hand ("Expand thoughts" opens them). */
|
|
2896
|
+
.thinking-thought[open] > summary {
|
|
2897
|
+
white-space: nowrap;
|
|
2898
|
+
overflow: hidden;
|
|
2899
|
+
text-overflow: ellipsis;
|
|
2900
|
+
opacity: 0.75;
|
|
2901
|
+
list-style-type: disclosure-open;
|
|
2902
|
+
}
|
|
2857
2903
|
.thinking-thought-body {
|
|
2858
2904
|
margin: calc(4px * var(--ui-scale)) 0 calc(3px * var(--ui-scale)) calc(11px * var(--ui-scale));
|
|
2859
2905
|
font-style: normal;
|
|
@@ -2887,6 +2933,36 @@
|
|
|
2887
2933
|
gap: calc(3px * var(--ui-scale));
|
|
2888
2934
|
min-width: 0;
|
|
2889
2935
|
}
|
|
2936
|
+
/* Stream view (turn-stream-view.mjs): a finished turn's thoughts, tool
|
|
2937
|
+
lines and reply as one list in the order they happened; in the live
|
|
2938
|
+
bubble, #thinking-stream-list holds the thoughts and tool lines. */
|
|
2939
|
+
.msg-turn-stream,
|
|
2940
|
+
.thinking-stream-list {
|
|
2941
|
+
display: flex;
|
|
2942
|
+
flex-direction: column;
|
|
2943
|
+
gap: calc(4px * var(--ui-scale));
|
|
2944
|
+
min-width: 0;
|
|
2945
|
+
}
|
|
2946
|
+
.thinking-stream-list { margin-bottom: calc(4px * var(--ui-scale)); font-size: var(--fs-meta-md); color: var(--muted); }
|
|
2947
|
+
.thinking-stream-list:empty { display: none; }
|
|
2948
|
+
.msg-stream-thought { min-width: 0; color: var(--muted); font-size: var(--fs-meta-sm); }
|
|
2949
|
+
.msg-stream-thought > summary {
|
|
2950
|
+
cursor: pointer;
|
|
2951
|
+
font-style: italic;
|
|
2952
|
+
white-space: nowrap;
|
|
2953
|
+
overflow: hidden;
|
|
2954
|
+
text-overflow: ellipsis;
|
|
2955
|
+
}
|
|
2956
|
+
.msg-stream-thought-body {
|
|
2957
|
+
margin: calc(3px * var(--ui-scale)) 0 calc(2px * var(--ui-scale)) calc(11px * var(--ui-scale));
|
|
2958
|
+
overflow-wrap: anywhere;
|
|
2959
|
+
word-break: break-word;
|
|
2960
|
+
}
|
|
2961
|
+
.msg-stream-thought-body > :first-child { margin-top: 0; }
|
|
2962
|
+
.msg-stream-thought-body > :last-child { margin-bottom: 0; }
|
|
2963
|
+
.msg-stream-omitted { color: var(--muted); font-size: var(--fs-meta-sm); font-style: italic; }
|
|
2964
|
+
.msg-stream-reply { min-width: 0; margin-top: calc(2px * var(--ui-scale)); }
|
|
2965
|
+
.msg-stream-reply > :first-child { margin-top: 0; }
|
|
2890
2966
|
.msg-thought-item {
|
|
2891
2967
|
color: var(--muted);
|
|
2892
2968
|
font-size: var(--fs-meta-sm);
|
|
@@ -3154,7 +3230,9 @@
|
|
|
3154
3230
|
font-size: 0.85rem;
|
|
3155
3231
|
}
|
|
3156
3232
|
.ctx-thinking-group { display: inline-flex; gap: 0; }
|
|
3157
|
-
.
|
|
3233
|
+
/* The 💭 Thoughts row (a setting of this browser) has the same look. */
|
|
3234
|
+
.ctx-thinking-btn,
|
|
3235
|
+
.ctx-thoughts-btn {
|
|
3158
3236
|
font-size: 0.78rem;
|
|
3159
3237
|
padding: calc(4px * var(--ui-scale)) calc(6px * var(--ui-scale));
|
|
3160
3238
|
border: 1px solid var(--border);
|
|
@@ -3162,10 +3240,14 @@
|
|
|
3162
3240
|
color: var(--muted);
|
|
3163
3241
|
cursor: pointer;
|
|
3164
3242
|
}
|
|
3165
|
-
.ctx-thinking-btn:first-child
|
|
3166
|
-
.ctx-
|
|
3167
|
-
.ctx-thinking-btn
|
|
3168
|
-
.ctx-
|
|
3243
|
+
.ctx-thinking-btn:first-child,
|
|
3244
|
+
.ctx-thoughts-btn:first-child { border-radius: calc(6px * var(--ui-scale)) 0 0 calc(6px * var(--ui-scale)); }
|
|
3245
|
+
.ctx-thinking-btn:last-child,
|
|
3246
|
+
.ctx-thoughts-btn:last-child { border-radius: 0 calc(6px * var(--ui-scale)) calc(6px * var(--ui-scale)) 0; }
|
|
3247
|
+
.ctx-thinking-btn + .ctx-thinking-btn,
|
|
3248
|
+
.ctx-thoughts-btn + .ctx-thoughts-btn { border-left: none; }
|
|
3249
|
+
.ctx-thinking-btn.is-active,
|
|
3250
|
+
.ctx-thoughts-btn.is-active {
|
|
3169
3251
|
background: var(--accent);
|
|
3170
3252
|
color: #fff;
|
|
3171
3253
|
border-color: var(--accent);
|
|
@@ -4811,6 +4893,47 @@
|
|
|
4811
4893
|
}
|
|
4812
4894
|
#chat-title-relay-schedules[hidden] { display: none; }
|
|
4813
4895
|
.relay-watch-panel[hidden] { display: none; }
|
|
4896
|
+
/* 📓 Questions: the conversation's asks, dropped down under 📓 (or ︙),
|
|
4897
|
+
placed by questions-panel-ui.js; on a phone a sheet under the header. */
|
|
4898
|
+
.questions-panel {
|
|
4899
|
+
position: fixed; top: 0; left: 0; z-index: 60; overflow-y: auto; overscroll-behavior: contain; box-sizing: border-box;
|
|
4900
|
+
width: min(calc(420px * var(--ui-scale)), calc(100vw - calc(16px * var(--ui-scale))));
|
|
4901
|
+
background: var(--bg2); border: 1px solid var(--border); border-radius: calc(8px * var(--ui-scale));
|
|
4902
|
+
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25); padding: calc(4px * var(--ui-scale)) calc(6px * var(--ui-scale)) calc(6px * var(--ui-scale));
|
|
4903
|
+
color: var(--text);
|
|
4904
|
+
}
|
|
4905
|
+
.questions-panel[hidden] { display: none; }
|
|
4906
|
+
.questions-panel-head {
|
|
4907
|
+
display: flex; align-items: center; justify-content: space-between; gap: calc(6px * var(--ui-scale));
|
|
4908
|
+
font-size: var(--fs-meta-md); font-weight: 600; padding: 0 0 calc(4px * var(--ui-scale));
|
|
4909
|
+
}
|
|
4910
|
+
.questions-panel-close {
|
|
4911
|
+
min-width: calc(28px * var(--ui-scale)); min-height: calc(28px * var(--ui-scale));
|
|
4912
|
+
font: inherit; color: var(--muted); background: transparent; border: 1px solid var(--border);
|
|
4913
|
+
border-radius: calc(6px * var(--ui-scale)); cursor: pointer;
|
|
4914
|
+
}
|
|
4915
|
+
.questions-panel-body { display: grid; gap: calc(6px * var(--ui-scale)); }
|
|
4916
|
+
.questions-panel-empty { margin: 0; color: var(--muted); font-size: var(--fs-meta-sm); }
|
|
4917
|
+
.questions-panel .inbox-item { background: var(--bg); }
|
|
4918
|
+
.questions-panel .inbox-item.questions-card-focus { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
|
|
4919
|
+
.questions-panel button:disabled { opacity: 0.5; cursor: wait; }
|
|
4920
|
+
#questions-panel-backdrop { display: none; }
|
|
4921
|
+
/* A phone, upright or sideways: full width under the header over a dimmed
|
|
4922
|
+
page; every button of a card half the width, one per row, left aligned,
|
|
4923
|
+
so the right half stays free to scroll. */
|
|
4924
|
+
.questions-panel.is-sheet {
|
|
4925
|
+
left: calc(8px * var(--ui-scale)); right: calc(8px * var(--ui-scale)); width: auto; z-index: 1200;
|
|
4926
|
+
}
|
|
4927
|
+
#questions-panel-backdrop:not([hidden]) {
|
|
4928
|
+
display: block; position: fixed; inset: 0; z-index: 1190; background: rgba(0, 0, 0, 0.42);
|
|
4929
|
+
}
|
|
4930
|
+
.questions-panel.is-sheet .inbox-item-options,
|
|
4931
|
+
.questions-panel.is-sheet .inbox-item-actions { flex-direction: column; align-items: flex-start; }
|
|
4932
|
+
.questions-panel.is-sheet .inbox-choice,
|
|
4933
|
+
.questions-panel.is-sheet .inbox-answer,
|
|
4934
|
+
.questions-panel.is-sheet .inbox-dismiss {
|
|
4935
|
+
width: 50%; min-width: calc(140px * var(--ui-scale)); justify-content: flex-start;
|
|
4936
|
+
}
|
|
4814
4937
|
.relay-watch-chip {
|
|
4815
4938
|
font: inherit; color: var(--accent); background: transparent; cursor: pointer;
|
|
4816
4939
|
border: 1px solid var(--border); border-radius: calc(10px * var(--ui-scale)); padding: calc(2px * var(--ui-scale)) calc(5px * var(--ui-scale));
|
|
@@ -8070,6 +8193,7 @@
|
|
|
8070
8193
|
</div>
|
|
8071
8194
|
<button id="pending-question-banner" onclick="openPendingQuestionFromBanner()" title="Open pending question"></button>
|
|
8072
8195
|
<div id="chat-header-actions">
|
|
8196
|
+
<button id="questions-btn" class="header-icon-btn has-count" type="button" title="Questions" aria-label="Questions" aria-haspopup="dialog" aria-expanded="false" aria-controls="questions-panel" hidden>📓<span class="header-icon-count"></span></button>
|
|
8073
8197
|
<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>
|
|
8074
8198
|
<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>
|
|
8075
8199
|
<button id="message-search-btn" class="header-icon-btn" onclick="openMessageSearchModal()" title="Search messages" aria-label="Search messages">🔍</button>
|
|
@@ -8086,6 +8210,7 @@
|
|
|
8086
8210
|
<button id="chat-menu-schedules" class="chat-actions-menu-item chat-menu-meta-chip" type="button" role="menuitem" hidden>⏰ Schedules…</button>
|
|
8087
8211
|
<button id="chat-menu-origin" class="chat-actions-menu-item chat-menu-meta-chip" type="button" role="menuitem" hidden>↗ Started by an agent</button>
|
|
8088
8212
|
<button id="chat-menu-edit-title" class="chat-actions-menu-item" type="button" role="menuitem">✍️ Edit conversation title</button>
|
|
8213
|
+
<button id="chat-menu-questions" class="chat-actions-menu-item chat-menu-twin" type="button" role="menuitem" hidden>📓 Questions</button>
|
|
8089
8214
|
<button id="chat-menu-pins" class="chat-actions-menu-item chat-menu-twin" type="button" role="menuitem" hidden>📍 Pinned messages</button>
|
|
8090
8215
|
<button id="chat-menu-hidden" class="chat-actions-menu-item chat-menu-twin" type="button" role="menuitem" hidden>🙈 Hidden from shared viewers</button>
|
|
8091
8216
|
<button id="chat-menu-search" class="chat-actions-menu-item chat-menu-twin" type="button" role="menuitem" hidden>🔍 Search messages</button>
|
|
@@ -8387,215 +8512,267 @@
|
|
|
8387
8512
|
aria-labelledby="settings-tab-general"
|
|
8388
8513
|
data-settings-panel="general"
|
|
8389
8514
|
>
|
|
8390
|
-
<
|
|
8391
|
-
<
|
|
8392
|
-
<
|
|
8393
|
-
<
|
|
8394
|
-
<
|
|
8395
|
-
|
|
8396
|
-
|
|
8397
|
-
|
|
8398
|
-
|
|
8399
|
-
<
|
|
8400
|
-
|
|
8401
|
-
|
|
8402
|
-
|
|
8403
|
-
<
|
|
8404
|
-
|
|
8405
|
-
|
|
8406
|
-
|
|
8407
|
-
|
|
8408
|
-
|
|
8409
|
-
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
|
|
8413
|
-
<
|
|
8414
|
-
<input
|
|
8415
|
-
id="scroll-on-send-toggle"
|
|
8416
|
-
type="checkbox"
|
|
8417
|
-
onchange="updateScrollOnSendSetting(this.checked)"
|
|
8418
|
-
aria-label="Jump to the end when I send a message"
|
|
8419
|
-
checked
|
|
8420
|
-
>
|
|
8421
|
-
</div>
|
|
8422
|
-
<div class="settings-help settings-gap-xs">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>
|
|
8423
|
-
<div class="settings-row settings-row-column settings-gap">
|
|
8424
|
-
<label for="conversation-window-retention-slider">Messages kept per conversation for switching back <span id="conversation-window-retention-value">200 messages</span></label>
|
|
8425
|
-
<input
|
|
8426
|
-
id="conversation-window-retention-slider"
|
|
8427
|
-
type="range"
|
|
8428
|
-
min="100"
|
|
8429
|
-
max="1100"
|
|
8430
|
-
step="100"
|
|
8431
|
-
value="200"
|
|
8432
|
-
aria-label="Messages kept per conversation for switching back"
|
|
8433
|
-
aria-valuetext="200 messages"
|
|
8434
|
-
oninput="previewConversationWindowRetention(this.value)"
|
|
8435
|
-
onchange="updateConversationWindowRetention(this.value)"
|
|
8436
|
-
>
|
|
8437
|
-
</div>
|
|
8438
|
-
<div class="settings-help settings-gap-xs">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>
|
|
8439
|
-
<div class="settings-row settings-row-column settings-gap">
|
|
8440
|
-
<label for="turn-ceiling-slider">Max turn duration <span id="turn-ceiling-value">No limit</span></label>
|
|
8441
|
-
<input
|
|
8442
|
-
id="turn-ceiling-slider"
|
|
8443
|
-
type="range"
|
|
8444
|
-
min="0"
|
|
8445
|
-
max="600"
|
|
8446
|
-
step="5"
|
|
8447
|
-
value="60"
|
|
8448
|
-
aria-label="Maximum turn duration in minutes"
|
|
8449
|
-
oninput="previewTurnCeilingSetting(this.value)"
|
|
8450
|
-
onchange="updateTurnCeilingSetting(this.value)"
|
|
8451
|
-
>
|
|
8452
|
-
</div>
|
|
8453
|
-
<div class="settings-help settings-gap-xs">A hard cap on how long one turn may run before the relay requeues it, counted from the start of the turn or from your last answer to one of its questions. Turns are already kept alive by worker heartbeats, and the relay never cuts off a turn waiting on your answer to a question — so this only catches a worker that has hung. Grok also enforces the limit itself, counted from the start of the prompt and without pausing for questions (remote relay approvals). Set to 0 for no limit.</div>
|
|
8454
|
-
<div class="settings-row settings-row-column settings-gap">
|
|
8455
|
-
<label for="background-task-timeout-slider">Background task timeout <span id="background-task-timeout-value">4 h</span></label>
|
|
8456
|
-
<input
|
|
8457
|
-
id="background-task-timeout-slider"
|
|
8458
|
-
type="range"
|
|
8459
|
-
min="0"
|
|
8460
|
-
max="600"
|
|
8461
|
-
step="5"
|
|
8462
|
-
value="240"
|
|
8463
|
-
aria-label="Background task timeout in minutes"
|
|
8464
|
-
oninput="previewBackgroundTaskTimeoutSetting(this.value)"
|
|
8465
|
-
onchange="updateBackgroundTaskTimeoutSetting(this.value)"
|
|
8466
|
-
>
|
|
8467
|
-
</div>
|
|
8468
|
-
<div class="settings-help settings-gap-xs">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>
|
|
8469
|
-
<div class="settings-row settings-row-column settings-gap">
|
|
8470
|
-
<label for="task-stall-minutes-slider">Mark a background task as quiet after <span id="task-stall-minutes-value">10 min</span></label>
|
|
8471
|
-
<input
|
|
8472
|
-
id="task-stall-minutes-slider"
|
|
8473
|
-
type="range"
|
|
8474
|
-
min="1"
|
|
8475
|
-
max="120"
|
|
8476
|
-
step="1"
|
|
8477
|
-
value="10"
|
|
8478
|
-
aria-label="Minutes without output before a background task is marked as quiet"
|
|
8479
|
-
oninput="previewTaskStallMinutesSetting(this.value)"
|
|
8480
|
-
onchange="updateTaskStallMinutesSetting(this.value)"
|
|
8481
|
-
>
|
|
8482
|
-
</div>
|
|
8483
|
-
<div class="settings-help settings-gap-xs">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>
|
|
8484
|
-
<div class="settings-row settings-gap">
|
|
8485
|
-
<label for="restart-resume-toggle">After a relay restart, tell interrupted sessions to carry on</label>
|
|
8486
|
-
<input
|
|
8487
|
-
id="restart-resume-toggle"
|
|
8488
|
-
type="checkbox"
|
|
8489
|
-
onchange="updateRestartResumeSettingFromToggle(this.checked)"
|
|
8490
|
-
aria-label="After a relay restart, tell interrupted sessions to carry on"
|
|
8491
|
-
>
|
|
8492
|
-
</div>
|
|
8493
|
-
<div class="settings-help settings-gap-xs">Most turns a restart interrupts run again by themselves. A turn that cannot (the agent had already taken the message, or had started on its own after a background task) just stops. With this on, such a session gets one relay note once the relay is back, saying when it restarted and asking the agent to check what it was doing and carry on. Your message is never sent again; idle, archived and usage-limit-paused sessions get nothing. Off by default; a setting of this relay.</div>
|
|
8494
|
-
<div class="settings-row settings-gap">
|
|
8495
|
-
<label for="relay-restart-max-wait-select">Ask after a queued relay restart has waited</label>
|
|
8496
|
-
<select id="relay-restart-max-wait-select" onchange="updateRelayRestartMaxWaitSetting(this.value)" aria-label="Ask after a queued relay restart has waited">
|
|
8497
|
-
<option value="5">5 min</option>
|
|
8498
|
-
<option value="10">10 min</option>
|
|
8499
|
-
<option value="15">15 min</option>
|
|
8500
|
-
<option value="30" selected>30 min</option>
|
|
8501
|
-
<option value="60">1 h</option>
|
|
8502
|
-
<option value="120">2 h</option>
|
|
8503
|
-
<option value="240">4 h</option>
|
|
8504
|
-
<option value="0">No limit</option>
|
|
8505
|
-
</select>
|
|
8506
|
-
</div>
|
|
8507
|
-
<div class="settings-help settings-gap-xs">A queued relay restart waits for the running turns, and new messages wait for the restart. After this long the banner asks whether to restart now, keep waiting or cancel; it never restarts while the turns run, and still restarts as soon as they end. No limit waits until the turns end.</div>
|
|
8508
|
-
<div class="settings-row settings-gap">
|
|
8509
|
-
<label for="subagent-record-retention-select">Keep sub-agent tool output</label>
|
|
8510
|
-
<select id="subagent-record-retention-select" onchange="updateSubagentRecordRetentionSetting(this.value)" aria-label="Keep sub-agent tool output">
|
|
8511
|
-
<option value="7">7 days</option>
|
|
8512
|
-
<option value="14">14 days</option>
|
|
8513
|
-
<option value="30">30 days</option>
|
|
8514
|
-
<option value="90" selected>90 days</option>
|
|
8515
|
-
<option value="0">Always</option>
|
|
8516
|
-
</select>
|
|
8517
|
-
</div>
|
|
8518
|
-
<div class="settings-help settings-gap-xs">A sub-agent's record keeps every tool call's full input and the first 4 KB of each result. After this many days the relay removes them from finished agents, once a day; the thoughts, the reply, notes and the one-line summary of each call stay. Always keeps everything.</div>
|
|
8519
|
-
<div id="windows-autostart-setting" hidden>
|
|
8515
|
+
<section class="settings-section" id="settings-section-appearance" aria-labelledby="settings-section-appearance-title">
|
|
8516
|
+
<h3 class="settings-section-title" id="settings-section-appearance-title">Appearance</h3>
|
|
8517
|
+
<div class="settings-row">
|
|
8518
|
+
<label for="theme-select">Theme</label>
|
|
8519
|
+
<select id="theme-select" onchange="updateTheme(this.value)">
|
|
8520
|
+
<option value="dark">Dark</option>
|
|
8521
|
+
<option value="light">Light</option>
|
|
8522
|
+
</select>
|
|
8523
|
+
</div>
|
|
8524
|
+
<div class="settings-row" style="margin-bottom: 0;">
|
|
8525
|
+
<label for="font-scale-select">Text scaling</label>
|
|
8526
|
+
<select id="font-scale-select" onchange="updateFontScaleFromSelect(this.value)" aria-label="Text scaling"></select>
|
|
8527
|
+
</div>
|
|
8528
|
+
<div class="settings-row settings-gap">
|
|
8529
|
+
<label for="thoughts-expanded-toggle">Expand thoughts while an agent works</label>
|
|
8530
|
+
<input
|
|
8531
|
+
id="thoughts-expanded-toggle"
|
|
8532
|
+
type="checkbox"
|
|
8533
|
+
onchange="updateThoughtsExpandedSetting(this.checked)"
|
|
8534
|
+
aria-label="Expand thoughts while an agent works"
|
|
8535
|
+
checked
|
|
8536
|
+
>
|
|
8537
|
+
</div>
|
|
8538
|
+
<div class="settings-help settings-gap-xs">Open thoughts in the live turn, in sub-agent bubbles and in the sub-agent viewer. Saved in this browser.</div>
|
|
8520
8539
|
<div class="settings-row settings-row-column settings-gap">
|
|
8521
|
-
<label>
|
|
8522
|
-
<
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8540
|
+
<label for="live-activity-cap-slider">Tool lines shown while an agent works <span id="live-activity-cap-value">50 lines</span></label>
|
|
8541
|
+
<input
|
|
8542
|
+
id="live-activity-cap-slider"
|
|
8543
|
+
type="range"
|
|
8544
|
+
min="10"
|
|
8545
|
+
max="510"
|
|
8546
|
+
step="10"
|
|
8547
|
+
value="50"
|
|
8548
|
+
aria-label="Tool lines shown while an agent works"
|
|
8549
|
+
aria-valuetext="50 lines"
|
|
8550
|
+
oninput="previewLiveActivityCap(this.value)"
|
|
8551
|
+
onchange="updateLiveActivityCap(this.value)"
|
|
8552
|
+
>
|
|
8553
|
+
</div>
|
|
8554
|
+
<div class="settings-help settings-gap-xs">Per agent: the main agent and each sub-agent keep this many of their newest tool lines in the live bubble. The relay keeps up to 500 per agent. Saved in this browser.</div>
|
|
8555
|
+
<div class="settings-row settings-gap">
|
|
8556
|
+
<label for="stream-view-toggle">Stream view: thoughts, tool calls and the reply in order</label>
|
|
8557
|
+
<input
|
|
8558
|
+
id="stream-view-toggle"
|
|
8559
|
+
type="checkbox"
|
|
8560
|
+
onchange="updateStreamViewSetting(this.checked)"
|
|
8561
|
+
aria-label="Stream view: thoughts, tool calls and the reply in order"
|
|
8562
|
+
>
|
|
8563
|
+
</div>
|
|
8564
|
+
<div class="settings-help settings-gap-xs">Turns recorded before this version keep the grouped layout. Saved in this browser.</div>
|
|
8565
|
+
<div class="settings-row settings-gap">
|
|
8566
|
+
<label for="show-suspend-host-toggle">Show Suspend host action</label>
|
|
8567
|
+
<input
|
|
8568
|
+
id="show-suspend-host-toggle"
|
|
8569
|
+
type="checkbox"
|
|
8570
|
+
onchange="updateShowSuspendHostSetting(this.checked)"
|
|
8571
|
+
aria-label="Show Suspend host action"
|
|
8572
|
+
checked
|
|
8573
|
+
>
|
|
8574
|
+
</div>
|
|
8575
|
+
<div class="settings-help settings-gap-xs">Shows or hides the menu action in this browser only. Suspend works only when the relay runs on Windows; a queued suspend still shows its banner here either way.</div>
|
|
8576
|
+
</section>
|
|
8577
|
+
<section class="settings-section" id="settings-section-reading" aria-labelledby="settings-section-reading-title">
|
|
8578
|
+
<h3 class="settings-section-title" id="settings-section-reading-title">Reading</h3>
|
|
8579
|
+
<div class="settings-row settings-gap">
|
|
8580
|
+
<label for="scroll-on-send-toggle">Jump to the end when I send a message</label>
|
|
8581
|
+
<input
|
|
8582
|
+
id="scroll-on-send-toggle"
|
|
8583
|
+
type="checkbox"
|
|
8584
|
+
onchange="updateScrollOnSendSetting(this.checked)"
|
|
8585
|
+
aria-label="Jump to the end when I send a message"
|
|
8586
|
+
checked
|
|
8587
|
+
>
|
|
8588
|
+
</div>
|
|
8589
|
+
<div class="settings-help settings-gap-xs">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>
|
|
8590
|
+
<div class="settings-row settings-row-column settings-gap">
|
|
8591
|
+
<label for="conversation-window-retention-slider">Messages kept per conversation for switching back <span id="conversation-window-retention-value">200 messages</span></label>
|
|
8592
|
+
<input
|
|
8593
|
+
id="conversation-window-retention-slider"
|
|
8594
|
+
type="range"
|
|
8595
|
+
min="100"
|
|
8596
|
+
max="1100"
|
|
8597
|
+
step="100"
|
|
8598
|
+
value="200"
|
|
8599
|
+
aria-label="Messages kept per conversation for switching back"
|
|
8600
|
+
aria-valuetext="200 messages"
|
|
8601
|
+
oninput="previewConversationWindowRetention(this.value)"
|
|
8602
|
+
onchange="updateConversationWindowRetention(this.value)"
|
|
8603
|
+
>
|
|
8604
|
+
</div>
|
|
8605
|
+
<div class="settings-help settings-gap-xs">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>
|
|
8606
|
+
</section>
|
|
8607
|
+
<section class="settings-section" id="settings-section-turns" aria-labelledby="settings-section-turns-title">
|
|
8608
|
+
<h3 class="settings-section-title" id="settings-section-turns-title">Turns and tasks</h3>
|
|
8609
|
+
<div class="settings-row settings-row-column settings-gap">
|
|
8610
|
+
<label for="turn-ceiling-slider">Max turn duration <span id="turn-ceiling-value">No limit</span></label>
|
|
8611
|
+
<input
|
|
8612
|
+
id="turn-ceiling-slider"
|
|
8613
|
+
type="range"
|
|
8614
|
+
min="0"
|
|
8615
|
+
max="600"
|
|
8616
|
+
step="5"
|
|
8617
|
+
value="60"
|
|
8618
|
+
aria-label="Maximum turn duration in minutes"
|
|
8619
|
+
oninput="previewTurnCeilingSetting(this.value)"
|
|
8620
|
+
onchange="updateTurnCeilingSetting(this.value)"
|
|
8621
|
+
>
|
|
8622
|
+
</div>
|
|
8623
|
+
<div class="settings-help settings-gap-xs">A hard cap on how long one turn may run before the relay requeues it, counted from the start of the turn or from your last answer to one of its questions. Turns are already kept alive by worker heartbeats, and the relay never cuts off a turn waiting on your answer to a question — so this only catches a worker that has hung. Grok also enforces the limit itself, counted from the start of the prompt and without pausing for questions (remote relay approvals). Set to 0 for no limit. A setting of this relay.</div>
|
|
8624
|
+
<div class="settings-row settings-row-column settings-gap">
|
|
8625
|
+
<label for="background-task-timeout-slider">Background task timeout <span id="background-task-timeout-value">4 h</span></label>
|
|
8626
|
+
<input
|
|
8627
|
+
id="background-task-timeout-slider"
|
|
8628
|
+
type="range"
|
|
8629
|
+
min="0"
|
|
8630
|
+
max="600"
|
|
8631
|
+
step="5"
|
|
8632
|
+
value="240"
|
|
8633
|
+
aria-label="Background task timeout in minutes"
|
|
8634
|
+
oninput="previewBackgroundTaskTimeoutSetting(this.value)"
|
|
8635
|
+
onchange="updateBackgroundTaskTimeoutSetting(this.value)"
|
|
8636
|
+
>
|
|
8637
|
+
</div>
|
|
8638
|
+
<div class="settings-help settings-gap-xs">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. A setting of this relay.</div>
|
|
8639
|
+
<div class="settings-row settings-row-column settings-gap">
|
|
8640
|
+
<label for="task-stall-minutes-slider">Mark a background task as quiet after <span id="task-stall-minutes-value">10 min</span></label>
|
|
8641
|
+
<input
|
|
8642
|
+
id="task-stall-minutes-slider"
|
|
8643
|
+
type="range"
|
|
8644
|
+
min="1"
|
|
8645
|
+
max="120"
|
|
8646
|
+
step="1"
|
|
8647
|
+
value="10"
|
|
8648
|
+
aria-label="Minutes without output before a background task is marked as quiet"
|
|
8649
|
+
oninput="previewTaskStallMinutesSetting(this.value)"
|
|
8650
|
+
onchange="updateTaskStallMinutesSetting(this.value)"
|
|
8651
|
+
>
|
|
8652
|
+
</div>
|
|
8653
|
+
<div class="settings-help settings-gap-xs">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. A setting of this relay.</div>
|
|
8654
|
+
<div class="settings-row settings-gap">
|
|
8655
|
+
<label for="subagent-record-retention-select">Keep sub-agent tool output</label>
|
|
8656
|
+
<select id="subagent-record-retention-select" onchange="updateSubagentRecordRetentionSetting(this.value)" aria-label="Keep sub-agent tool output">
|
|
8657
|
+
<option value="7">7 days</option>
|
|
8658
|
+
<option value="14">14 days</option>
|
|
8659
|
+
<option value="30">30 days</option>
|
|
8660
|
+
<option value="90" selected>90 days</option>
|
|
8661
|
+
<option value="0">Always</option>
|
|
8662
|
+
</select>
|
|
8663
|
+
</div>
|
|
8664
|
+
<div class="settings-help settings-gap-xs">A sub-agent's record keeps every tool call's full input and the first 4 KB of each result. After this many days the relay removes them from finished agents, once a day; the thoughts, the reply, notes and the one-line summary of each call stay. Always keeps everything. A setting of this relay.</div>
|
|
8665
|
+
</section>
|
|
8666
|
+
<section class="settings-section" id="settings-section-relay" aria-labelledby="settings-section-relay-title">
|
|
8667
|
+
<h3 class="settings-section-title" id="settings-section-relay-title">This relay</h3>
|
|
8668
|
+
<div class="settings-row settings-row-column settings-gap">
|
|
8669
|
+
<label for="pwa-app-name-input">Relay name</label>
|
|
8670
|
+
<input
|
|
8671
|
+
id="pwa-app-name-input"
|
|
8672
|
+
type="text"
|
|
8673
|
+
maxlength="60"
|
|
8674
|
+
placeholder="OAR"
|
|
8675
|
+
aria-label="Relay name"
|
|
8676
|
+
onchange="updatePwaAppName(this.value)"
|
|
8677
|
+
>
|
|
8678
|
+
<div class="settings-help">Shown to other relays and used as the installed app's name. On Android, a rename reaches an already-installed app after a short delay, with one confirmation prompt showing the new name. A setting of this relay.</div>
|
|
8679
|
+
</div>
|
|
8680
|
+
<div class="settings-row settings-gap">
|
|
8681
|
+
<label for="restart-resume-toggle">After a relay restart, tell interrupted sessions to carry on</label>
|
|
8682
|
+
<input
|
|
8683
|
+
id="restart-resume-toggle"
|
|
8684
|
+
type="checkbox"
|
|
8685
|
+
onchange="updateRestartResumeSettingFromToggle(this.checked)"
|
|
8686
|
+
aria-label="After a relay restart, tell interrupted sessions to carry on"
|
|
8687
|
+
>
|
|
8688
|
+
</div>
|
|
8689
|
+
<div class="settings-help settings-gap-xs">Most turns a restart interrupts run again by themselves. A turn that cannot (the agent had already taken the message, or had started on its own after a background task) just stops. With this on, such a session gets one relay note once the relay is back, saying when it restarted and asking the agent to check what it was doing and carry on. Your message is never sent again; idle, archived and usage-limit-paused sessions get nothing. Off by default; a setting of this relay.</div>
|
|
8690
|
+
<div class="settings-row settings-gap">
|
|
8691
|
+
<label for="relay-restart-max-wait-select">Ask after a queued relay restart has waited</label>
|
|
8692
|
+
<select id="relay-restart-max-wait-select" onchange="updateRelayRestartMaxWaitSetting(this.value)" aria-label="Ask after a queued relay restart has waited">
|
|
8693
|
+
<option value="5">5 min</option>
|
|
8694
|
+
<option value="10">10 min</option>
|
|
8695
|
+
<option value="15">15 min</option>
|
|
8696
|
+
<option value="30" selected>30 min</option>
|
|
8697
|
+
<option value="60">1 h</option>
|
|
8698
|
+
<option value="120">2 h</option>
|
|
8699
|
+
<option value="240">4 h</option>
|
|
8700
|
+
<option value="0">No limit</option>
|
|
8701
|
+
</select>
|
|
8702
|
+
</div>
|
|
8703
|
+
<div class="settings-help settings-gap-xs">A queued relay restart waits for the running turns, and new messages wait for the restart. After this long the banner asks whether to restart now, keep waiting or cancel; it never restarts while the turns run, and still restarts as soon as they end. No limit waits until the turns end. A setting of this relay.</div>
|
|
8704
|
+
<div class="settings-row settings-row-column settings-gap">
|
|
8705
|
+
<label for="default-session-workspace-root-input">Default CWD for new sessions</label>
|
|
8706
|
+
<input
|
|
8707
|
+
id="default-session-workspace-root-input"
|
|
8708
|
+
type="text"
|
|
8709
|
+
placeholder="Leave empty to use relay workspace root"
|
|
8710
|
+
aria-label="Default CWD for new sessions"
|
|
8711
|
+
onchange="updateDefaultSessionWorkspaceRootSetting(this.value)"
|
|
8712
|
+
>
|
|
8713
|
+
<div class="settings-help">Applies to newly created sessions. Leave blank to fallback to the relay workspace root. A setting of this relay.</div>
|
|
8714
|
+
</div>
|
|
8715
|
+
<div id="windows-autostart-setting" hidden>
|
|
8716
|
+
<div class="settings-row settings-row-column settings-gap">
|
|
8717
|
+
<label>Autostart (Windows)</label>
|
|
8718
|
+
<div role="radiogroup" aria-label="Windows autostart mode" class="settings-radio-stack">
|
|
8719
|
+
<label style="font-weight: normal;">
|
|
8720
|
+
<input type="radio" name="windows-autostart-mode" value="off" onchange="updateWindowsAutostartMode('off')"> Off
|
|
8721
|
+
</label>
|
|
8722
|
+
<label style="font-weight: normal;">
|
|
8723
|
+
<input type="radio" name="windows-autostart-mode" value="signin" onchange="updateWindowsAutostartMode('signin')"> At sign-in — visible terminal after you log on
|
|
8724
|
+
</label>
|
|
8725
|
+
<label style="font-weight: normal;">
|
|
8726
|
+
<input type="radio" name="windows-autostart-mode" value="boot" onchange="updateWindowsAutostartMode('boot')"> At system startup — headless, no logon needed
|
|
8727
|
+
</label>
|
|
8728
|
+
</div>
|
|
8729
|
+
</div>
|
|
8730
|
+
<div class="settings-help settings-gap-xs">System startup runs the relay as your user via a scheduled task (no password stored), reachable ~60 s after boot before anyone signs in. Switching modes asks for one admin confirmation on the PC itself. The task's identity has no network-share credentials — local files and the tunnel are unaffected.</div>
|
|
8731
|
+
<div id="windows-autostart-status" class="settings-help settings-gap-xs" hidden></div>
|
|
8732
|
+
<div id="windows-autostart-manual" class="settings-help settings-gap-xs" hidden>
|
|
8733
|
+
Run this from an elevated PowerShell instead:
|
|
8734
|
+
<code id="windows-autostart-manual-command" style="display: block; margin-top: calc(4px * var(--ui-scale)); user-select: all;"></code>
|
|
8532
8735
|
</div>
|
|
8533
8736
|
</div>
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
<
|
|
8537
|
-
|
|
8538
|
-
<
|
|
8737
|
+
</section>
|
|
8738
|
+
<section class="settings-section" id="settings-section-updates" aria-labelledby="settings-section-updates-title">
|
|
8739
|
+
<h3 class="settings-section-title" id="settings-section-updates-title">Updates</h3>
|
|
8740
|
+
<div class="settings-row settings-gap">
|
|
8741
|
+
<label for="update-auto-check-toggle">Check for updates automatically</label>
|
|
8742
|
+
<input
|
|
8743
|
+
id="update-auto-check-toggle"
|
|
8744
|
+
type="checkbox"
|
|
8745
|
+
onchange="updateAutoCheckSetting(this.checked)"
|
|
8746
|
+
aria-label="Check for updates automatically"
|
|
8747
|
+
>
|
|
8539
8748
|
</div>
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
<label for="pwa-app-name-input">Relay name</label>
|
|
8543
|
-
<input
|
|
8544
|
-
id="pwa-app-name-input"
|
|
8545
|
-
type="text"
|
|
8546
|
-
maxlength="60"
|
|
8547
|
-
placeholder="OAR"
|
|
8548
|
-
aria-label="Relay name"
|
|
8549
|
-
onchange="updatePwaAppName(this.value)"
|
|
8550
|
-
>
|
|
8551
|
-
<div class="settings-help">Shown to other relays and used as the installed app's name. On Android, a rename reaches an already-installed app after a short delay, with one confirmation prompt showing the new name.</div>
|
|
8552
|
-
</div>
|
|
8553
|
-
<div class="settings-row settings-gap">
|
|
8554
|
-
<label for="update-auto-check-toggle">Check for updates automatically</label>
|
|
8555
|
-
<input
|
|
8556
|
-
id="update-auto-check-toggle"
|
|
8557
|
-
type="checkbox"
|
|
8558
|
-
onchange="updateAutoCheckSetting(this.checked)"
|
|
8559
|
-
aria-label="Check for updates automatically"
|
|
8560
|
-
>
|
|
8561
|
-
</div>
|
|
8562
|
-
<div class="settings-help settings-gap-xs">Off by default — OAR sends no traffic anywhere unless you opt in. When enabled, the relay asks oar.sh for the latest version about twice a day. Manual checks below work regardless.</div>
|
|
8563
|
-
<div id="update-check-killed-help" class="settings-help settings-gap-xs" hidden>Update checks are disabled by OAR_NO_UPDATE_CHECK in this relay's environment.</div>
|
|
8564
|
-
<div class="settings-row settings-gap-xs">
|
|
8565
|
-
<button id="update-check-now-btn" class="chat-title-action-btn" type="button" onclick="checkForUpdatesNow()">Check for updates</button>
|
|
8566
|
-
<span id="update-last-checked" class="settings-help"></span>
|
|
8567
|
-
</div>
|
|
8568
|
-
<div id="update-available-card" class="settings-help settings-gap-xs" hidden>
|
|
8569
|
-
<span id="update-available-text"></span>
|
|
8570
|
-
<a id="update-notes-link" target="_blank" rel="noopener" hidden>release notes</a>
|
|
8749
|
+
<div class="settings-help settings-gap-xs">Off by default — OAR sends no traffic anywhere unless you opt in. When enabled, the relay asks oar.sh for the latest version about twice a day. Manual checks below work regardless. A setting of this relay.</div>
|
|
8750
|
+
<div id="update-check-killed-help" class="settings-help settings-gap-xs" hidden>Update checks are disabled by OAR_NO_UPDATE_CHECK in this relay's environment.</div>
|
|
8571
8751
|
<div class="settings-row settings-gap-xs">
|
|
8572
|
-
<button id="update-
|
|
8573
|
-
<
|
|
8752
|
+
<button id="update-check-now-btn" class="chat-title-action-btn" type="button" onclick="checkForUpdatesNow()">Check for updates</button>
|
|
8753
|
+
<span id="update-last-checked" class="settings-help"></span>
|
|
8574
8754
|
</div>
|
|
8575
|
-
<div id="update-
|
|
8576
|
-
|
|
8577
|
-
|
|
8578
|
-
|
|
8579
|
-
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
|
|
8584
|
-
<
|
|
8585
|
-
<
|
|
8586
|
-
<
|
|
8587
|
-
|
|
8588
|
-
|
|
8589
|
-
|
|
8590
|
-
<
|
|
8591
|
-
id="
|
|
8592
|
-
|
|
8593
|
-
|
|
8594
|
-
|
|
8595
|
-
|
|
8596
|
-
>
|
|
8597
|
-
<div class="settings-help">Applies to newly created sessions. Leave blank to fallback to the relay workspace root.</div>
|
|
8598
|
-
</div>
|
|
8755
|
+
<div id="update-available-card" class="settings-help settings-gap-xs" hidden>
|
|
8756
|
+
<span id="update-available-text"></span>
|
|
8757
|
+
<a id="update-notes-link" target="_blank" rel="noopener" hidden>release notes</a>
|
|
8758
|
+
<div class="settings-row settings-gap-xs">
|
|
8759
|
+
<button id="update-apply-btn" class="chat-title-action-btn" type="button" onclick="applyAvailableUpdate()">Update</button>
|
|
8760
|
+
<button id="update-dismiss-btn" class="chat-title-action-btn" type="button" onclick="dismissAvailableUpdate()">Dismiss</button>
|
|
8761
|
+
</div>
|
|
8762
|
+
<div id="update-git-hint" class="settings-gap-sm" hidden>This relay runs from a git checkout — pull and restart to update.</div>
|
|
8763
|
+
</div>
|
|
8764
|
+
<div id="update-install-status" class="settings-help settings-gap-xs" hidden></div>
|
|
8765
|
+
<button id="update-cancel-btn" class="chat-title-action-btn settings-gap-sm" type="button" onclick="cancelRunningUpdate()" hidden>Cancel update</button>
|
|
8766
|
+
<details id="update-install-log" class="cli-install-log" hidden>
|
|
8767
|
+
<summary>Update log</summary>
|
|
8768
|
+
<pre id="update-install-log-pre"></pre>
|
|
8769
|
+
</details>
|
|
8770
|
+
<div id="update-outcome" class="settings-help settings-gap-xs" hidden>
|
|
8771
|
+
<span id="update-outcome-text"></span>
|
|
8772
|
+
<pre id="update-outcome-log" hidden></pre>
|
|
8773
|
+
<button id="update-outcome-dismiss-btn" class="chat-title-action-btn" type="button" onclick="dismissUpdateOutcome()">Dismiss</button>
|
|
8774
|
+
</div>
|
|
8775
|
+
</section>
|
|
8599
8776
|
</div>
|
|
8600
8777
|
<div
|
|
8601
8778
|
id="settings-panel-providers"
|