@oar-sh/oar 0.9.5 → 0.9.7

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.
Files changed (119) hide show
  1. package/.github/extensions/web-relay/polling/polling-loop.mjs +12 -32
  2. package/.github/extensions/web-relay/skills/question-bridge.mjs +14 -39
  3. package/CHANGELOG.md +340 -0
  4. package/README.md +196 -26
  5. package/package.json +2 -1
  6. package/server/README.md +174 -7
  7. package/server/claude-cloud-worker/claude-cloud-event-normalizer.mjs +340 -0
  8. package/server/claude-cloud-worker/claude-cloud-session-process.mjs +1325 -0
  9. package/server/claude-cloud-worker/claude-cloud-session-worker.mjs +155 -0
  10. package/server/claude-worker/claude-remote-relay-tool.mjs +2 -0
  11. package/server/claude-worker/claude-sdk-adapter.mjs +18 -2
  12. package/server/claude-worker/claude-session-process.mjs +151 -1
  13. package/server/claude-worker/claude-session-worker.mjs +6 -0
  14. package/server/claude-worker/claude-turn-failure.mjs +92 -0
  15. package/server/claude-worker/claude-turn-publisher.mjs +52 -3
  16. package/server/claude-worker/sdk-message-normalizer.mjs +13 -1
  17. package/server/copilot-worker/copilot-model-switch.mjs +29 -3
  18. package/server/copilot-worker/copilot-question-bridge.mjs +2 -4
  19. package/server/copilot-worker/copilot-runtime-tree.mjs +91 -0
  20. package/server/copilot-worker/copilot-sdk-adapter.mjs +48 -8
  21. package/server/copilot-worker/copilot-sdk-session-process.mjs +897 -166
  22. package/server/cursor-worker/cursor-sdk-adapter.mjs +80 -13
  23. package/server/cursor-worker/cursor-turn-runner.mjs +5 -2
  24. package/server/db-schema.mjs +24 -0
  25. package/server/grok-worker/acp-client.mjs +68 -12
  26. package/server/grok-worker/grok-sdk-adapter.mjs +4 -0
  27. package/server/grok-worker/grok-turn-runner.mjs +6 -2
  28. package/server/migrations/0006-workspace-root-settings.mjs +67 -0
  29. package/server/migrations/0007-claude-cloud.mjs +82 -0
  30. package/server/public/app/agent-sessions-settings-ui.js +197 -0
  31. package/server/public/app/agent-sessions-settings.mjs +134 -0
  32. package/server/public/app/api-client.js +160 -6
  33. package/server/public/app/attachments-view.js +20 -1
  34. package/server/public/app/attribution-control.mjs +46 -0
  35. package/server/public/app/bootstrap.js +347 -31
  36. package/server/public/app/claude-cloud-conversation-ui.js +110 -0
  37. package/server/public/app/claude-cloud-settings-ui.js +374 -0
  38. package/server/public/app/claude-cloud-ui.mjs +611 -0
  39. package/server/public/app/composer-control-state.mjs +15 -3
  40. package/server/public/app/context-menu.mjs +140 -0
  41. package/server/public/app/context-tier-options.mjs +4 -0
  42. package/server/public/app/conversation-origin-ui.js +27 -0
  43. package/server/public/app/conversation-provider-indicator.mjs +22 -4
  44. package/server/public/app/conversation-view.js +178 -8
  45. package/server/public/app/cwd-picker.js +12 -0
  46. package/server/public/app/journal-view.js +704 -28
  47. package/server/public/app/markdown-strikethrough.mjs +31 -0
  48. package/server/public/app/math-dollars.mjs +89 -0
  49. package/server/public/app/model-selector-options.mjs +1 -1
  50. package/server/public/app/plan-usage-view.mjs +36 -8
  51. package/server/public/app/relay-board-inline.mjs +70 -0
  52. package/server/public/app/relay-board-view.js +157 -61
  53. package/server/public/app/relay-error-ctas.mjs +28 -5
  54. package/server/public/app/remote-relay-origin-view.mjs +120 -4
  55. package/server/public/app/router.js +49 -12
  56. package/server/public/app/settings-modal.js +33 -2
  57. package/server/public/app/settings-tabs.js +1 -1
  58. package/server/public/app/socket-handlers.js +60 -0
  59. package/server/public/app/store.js +4 -1
  60. package/server/public/app/subagent-fold.mjs +61 -0
  61. package/server/public/app/usage-limit-ui.js +225 -0
  62. package/server/public/index.html +471 -8
  63. package/server/relay-tools.md +13 -1
  64. package/server/repositories/message-repository.mjs +10 -1
  65. package/server/repositories/question-repository.mjs +1 -0
  66. package/server/repositories/remote-relay-repository.mjs +72 -1
  67. package/server/repositories/session-repository.mjs +47 -1
  68. package/server/routes/claude-cloud-routes.mjs +140 -0
  69. package/server/routes/git-routes.mjs +37 -0
  70. package/server/routes/messages-routes.mjs +202 -26
  71. package/server/routes/relay-board-routes.mjs +56 -2
  72. package/server/routes/remote-relay-routes.mjs +15 -1
  73. package/server/routes/sessions-routes.mjs +538 -72
  74. package/server/server-runtime.mjs +291 -27
  75. package/server/services/claude-account-usage-service.mjs +176 -0
  76. package/server/services/claude-cloud-repo-service.mjs +408 -0
  77. package/server/services/claude-cloud-session-service.mjs +326 -0
  78. package/server/services/claude-cloud-settings-service.mjs +269 -0
  79. package/server/services/git-remote-service.mjs +115 -0
  80. package/server/services/plan-usage-claude-cloud.mjs +211 -0
  81. package/server/services/plan-usage-claude.mjs +202 -40
  82. package/server/services/plan-usage-contract.mjs +39 -3
  83. package/server/services/plan-usage-service.mjs +82 -2
  84. package/server/services/preview-proxy-server.mjs +64 -36
  85. package/server/services/process-list-service.mjs +122 -0
  86. package/server/services/provider-reasoning-effort.mjs +3 -0
  87. package/server/services/relay-console-log.mjs +199 -0
  88. package/server/services/remote-relay-caller-context.mjs +78 -19
  89. package/server/services/remote-relay-client.mjs +9 -0
  90. package/server/services/remote-relay-dispatcher.mjs +451 -39
  91. package/server/services/remote-relay-inbound.mjs +83 -1
  92. package/server/services/remote-relay-loopback.mjs +245 -0
  93. package/server/services/remote-relay-registry-service.mjs +52 -0
  94. package/server/services/session-worker-launch-service.mjs +100 -15
  95. package/server/services/session-worker-process-service.mjs +410 -138
  96. package/server/services/session-worker-registry-service.mjs +1 -1
  97. package/server/services/session-worker-stop-service.mjs +24 -13
  98. package/server/services/session-worker-supervisor-service.mjs +89 -2
  99. package/server/services/usage-limit-pause-service.mjs +443 -0
  100. package/server/services/worker-launch-note-service.mjs +151 -0
  101. package/shared/ask-user-bridge.mjs +14 -39
  102. package/shared/claude-attribution.mjs +117 -0
  103. package/shared/claude-cloud/api-client.mjs +809 -0
  104. package/shared/claude-cloud/base-url.mjs +47 -0
  105. package/shared/claude-cloud/credentials.mjs +221 -0
  106. package/shared/claude-cloud/repo-url.mjs +111 -0
  107. package/shared/claude-usage-limit.mjs +257 -0
  108. package/shared/control-poller.mjs +69 -20
  109. package/shared/failure-note-text.mjs +38 -0
  110. package/shared/provider-routing.mjs +4 -2
  111. package/shared/question-wait.mjs +108 -0
  112. package/shared/remote-relay-contract.mjs +167 -22
  113. package/shared/remote-relay-tool-core.mjs +11 -8
  114. package/shared/steer-settle-failure.mjs +17 -0
  115. package/shared/steer-settle-markers.mjs +8 -0
  116. package/shared/worker-runtime/process-tree.mjs +483 -0
  117. package/shared/worker-runtime/relay-errors.mjs +31 -0
  118. package/shared/worker-runtime/send-and-wait-errors.mjs +4 -4
  119. package/shared/worker-runtime/turn-liveness.mjs +249 -0
@@ -173,7 +173,7 @@
173
173
  </script>
174
174
  <title>OAR — Open Agent Relay</title>
175
175
  <script>document.write('<scr'+'ipt src="'+__APP_BASE+'/socket.io/socket.io.js"><\/scr'+'ipt>');</script>
176
- <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
176
+ <script src="https://cdn.jsdelivr.net/npm/marked@15.0.12/marked.min.js"></script>
177
177
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css">
178
178
  <script src="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.js"></script>
179
179
  <script src="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/contrib/mhchem.min.js"></script>
@@ -256,6 +256,7 @@
256
256
  --provider-claude: #e0855a;
257
257
  --provider-cursor: #a78bfa;
258
258
  --provider-grok: #e879f9;
259
+ --provider-claude-cloud: #7dd3fc;
259
260
  --viewport-top-offset: 0px;
260
261
  --header-safe-top: max(env(safe-area-inset-top, 0px), var(--viewport-top-offset, 0px));
261
262
  --chat-header-top-base-desktop: 14px;
@@ -317,6 +318,7 @@
317
318
  --provider-claude: #b4531f;
318
319
  --provider-cursor: #6b3fd4;
319
320
  --provider-grok: #a21caf;
321
+ --provider-claude-cloud: #0369a1;
320
322
  --inline-code-bg: #eff1f3;
321
323
  }
322
324
  :root {
@@ -541,7 +543,7 @@
541
543
  border-radius: 8px;
542
544
  background: var(--bg2);
543
545
  color: var(--text);
544
- padding: 0 38px 0 10px;
546
+ padding: 0 76px 0 10px;
545
547
  font-size: var(--fs-meta-md);
546
548
  }
547
549
  /* iOS Safari zooms the page on focus for inputs under 16px, and the mobile
@@ -724,6 +726,7 @@
724
726
  .conv-provider-indicator[data-provider="claude"] { color: var(--provider-claude); }
725
727
  .conv-provider-indicator[data-provider="cursor"] { color: var(--provider-cursor); }
726
728
  .conv-provider-indicator[data-provider="grok"] { color: var(--provider-grok); }
729
+ .conv-provider-indicator[data-provider="claude-cloud"] { color: var(--provider-claude-cloud); }
727
730
  .conv-item.worker-ui-offline .conv-title,
728
731
  #chat-title[data-ui-state="offline"] { color: var(--conversation-title-offline); }
729
732
  .conv-item.worker-ui-ready .conv-title,
@@ -744,6 +747,70 @@
744
747
  }
745
748
  .conv-item:hover .conv-delete { opacity: 1; }
746
749
  .conv-delete:hover { color: var(--danger); }
750
+ /* Archive / unarchive sits left of the bin, shown on hover like it. */
751
+ .conv-archive {
752
+ position: absolute; right: 34px; top: 50%; transform: translateY(-50%);
753
+ background: none; border: none; color: var(--muted); cursor: pointer; font-size: var(--fs-ui-icon);
754
+ opacity: 0; transition: opacity 0.15s; padding: 4px;
755
+ }
756
+ .conv-item:hover .conv-archive { opacity: 1; }
757
+ .conv-archive:hover { color: var(--text); }
758
+ .conv-item.archived .conv-title { color: var(--muted); }
759
+ /* The Archived view: a toggle in the filter row, a banner above the list. */
760
+ #conv-archived-toggle {
761
+ position: absolute;
762
+ top: 50%;
763
+ right: 46px;
764
+ transform: translateY(-50%);
765
+ height: 28px;
766
+ min-width: 28px;
767
+ padding: 0 6px;
768
+ border: 1px solid transparent;
769
+ border-radius: 6px;
770
+ background: transparent;
771
+ color: var(--muted);
772
+ cursor: pointer;
773
+ font-size: var(--fs-meta-md);
774
+ }
775
+ #conv-archived-toggle:hover { color: var(--text); border-color: var(--border); }
776
+ #conv-archived-toggle[aria-pressed="true"] { color: var(--accent); border-color: var(--accent); }
777
+ #conv-archived-banner {
778
+ display: flex; align-items: center; justify-content: space-between; gap: 8px;
779
+ margin: 0 16px 6px; padding: 6px 10px;
780
+ border: 1px solid var(--border); border-radius: 8px; background: var(--bg2);
781
+ font-size: var(--fs-meta-sm); color: var(--muted);
782
+ }
783
+ #conv-archived-banner[hidden] { display: none; }
784
+ .conv-archived-back {
785
+ border: 1px solid var(--border); border-radius: 6px; background: var(--bg3); color: var(--text);
786
+ font-size: var(--fs-meta-xs); padding: 2px 8px; cursor: pointer;
787
+ }
788
+ /* The conversation context menu (context-menu.mjs): right-click / long press. */
789
+ .context-menu {
790
+ position: fixed;
791
+ z-index: 1200;
792
+ min-width: 200px;
793
+ max-width: min(320px, calc(100vw - 8px));
794
+ padding: 4px;
795
+ display: flex;
796
+ flex-direction: column;
797
+ gap: 2px;
798
+ background: var(--bg2);
799
+ border: 1px solid var(--border);
800
+ border-radius: 10px;
801
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
802
+ }
803
+ .context-menu-item {
804
+ display: flex; align-items: center; gap: 8px; width: 100%; min-height: 34px;
805
+ border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--text);
806
+ padding: 0 10px; font: inherit; font-size: var(--fs-meta-md); text-align: left; cursor: pointer;
807
+ touch-action: manipulation; -webkit-tap-highlight-color: transparent;
808
+ }
809
+ .context-menu-item:hover, .context-menu-item:focus-visible { background: var(--bg3); border-color: var(--border); outline: none; }
810
+ .context-menu-item:disabled { opacity: 0.5; cursor: not-allowed; }
811
+ .context-menu-item-danger { color: var(--danger); }
812
+ .context-menu-sep { height: 1px; margin: 3px 6px; background: var(--border); }
813
+ #conv-list .conv-item { -webkit-touch-callout: none; user-select: none; -webkit-user-select: none; }
747
814
  .conv-open-questions {
748
815
  display: inline-flex;
749
816
  margin-left: 6px;
@@ -1434,6 +1501,17 @@
1434
1501
  overflow-wrap: normal;
1435
1502
  word-break: normal;
1436
1503
  }
1504
+ /* An inline formula breaks only between its terms: one long term is a box
1505
+ wider than the bubble and made the whole bubble scroll sideways. It
1506
+ scrolls inside itself instead. */
1507
+ .msg-bubble :not(.katex-display) > .katex {
1508
+ display: inline-block;
1509
+ max-width: 100%;
1510
+ overflow-x: auto;
1511
+ overflow-y: hidden;
1512
+ vertical-align: bottom;
1513
+ -webkit-overflow-scrolling: touch;
1514
+ }
1437
1515
  .katex-error {
1438
1516
  color: var(--danger);
1439
1517
  white-space: pre-wrap;
@@ -1451,6 +1529,7 @@
1451
1529
  .thinking-bubble a,
1452
1530
  .subagent-bubble a,
1453
1531
  .relay-question-card a,
1532
+ .relay-board-body a,
1454
1533
  .workspace-file-link {
1455
1534
  color: var(--bubble-link);
1456
1535
  text-decoration-thickness: 1.2px;
@@ -1460,6 +1539,7 @@
1460
1539
  .thinking-bubble a:visited,
1461
1540
  .subagent-bubble a:visited,
1462
1541
  .relay-question-card a:visited,
1542
+ .relay-board-body a:visited,
1463
1543
  .workspace-file-link:visited { color: var(--bubble-link); }
1464
1544
  .msg.user .msg-bubble code:not(pre code) {
1465
1545
  background: var(--user-bubble-chip-bg);
@@ -1701,6 +1781,44 @@
1701
1781
  margin-bottom: 6px;
1702
1782
  font-size: var(--fs-meta-sm);
1703
1783
  }
1784
+ .subagent-bubble-header {
1785
+ cursor: pointer;
1786
+ -webkit-tap-highlight-color: transparent;
1787
+ }
1788
+ .subagent-bubble-header:focus-visible {
1789
+ outline: 2px solid var(--accent-color);
1790
+ outline-offset: 2px;
1791
+ border-radius: 4px;
1792
+ }
1793
+ .subagent-bubble-fold {
1794
+ flex-shrink: 0;
1795
+ width: 1em;
1796
+ color: var(--muted);
1797
+ text-align: center;
1798
+ }
1799
+ .subagent-bubble-fold::before { content: '▾'; }
1800
+ .subagent-bubble.folded > .subagent-bubble-header > .subagent-bubble-fold::before { content: '▸'; }
1801
+ /* Folded: the header alone. What the run wrote, thought and did, and the
1802
+ runs it started, come back with a tap. */
1803
+ .subagent-bubble.folded > :not(.subagent-bubble-header) { display: none; }
1804
+ .subagent-bubble.folded > .subagent-bubble-header { margin-bottom: 0; }
1805
+ .subagent-stop-btn[hidden] { display: none; }
1806
+ /* The folded header's one line about the run. It takes the room the name
1807
+ and the controls leave and is cut with an ellipsis; on a narrow bubble
1808
+ that is little or nothing, and the name keeps its place. */
1809
+ .subagent-bubble-summary {
1810
+ display: none;
1811
+ flex: 1 1 0;
1812
+ min-width: 0;
1813
+ overflow: hidden;
1814
+ text-overflow: ellipsis;
1815
+ white-space: nowrap;
1816
+ color: var(--muted);
1817
+ font-weight: 400;
1818
+ }
1819
+ .subagent-bubble.folded > .subagent-bubble-header > .subagent-bubble-summary { display: block; }
1820
+ .subagent-bubble.folded > .subagent-bubble-header > .subagent-bubble-name { flex: 0 1 auto; max-width: 55%; }
1821
+ .subagent-bubble.folded > .subagent-bubble-header > .subagent-bubble-summary:empty { flex-grow: 1; }
1704
1822
  .subagent-bubble-name {
1705
1823
  font-weight: 600;
1706
1824
  color: var(--text);
@@ -1981,6 +2099,14 @@
1981
2099
  }
1982
2100
  /* Claude-only thinking control (on/off + text visibility), under the
1983
2101
  auto-compact slider. */
2102
+ /* The folder's commit attribution (attribution-control.mjs), styled like
2103
+ the thinking rows above it. */
2104
+ .ctx-attribution { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--border); }
2105
+ .ctx-attribution-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
2106
+ .ctx-attribution-label { font-size: var(--fs-meta-sm); color: var(--muted); }
2107
+ .ctx-attribution-select { font-size: var(--fs-meta-sm); max-width: 100%; }
2108
+ .ctx-attribution-note { margin-top: 6px; font-size: var(--fs-meta-sm); color: var(--muted); line-height: 1.4; overflow-wrap: anywhere; }
2109
+ .ctx-attribution-note code { font-size: inherit; }
1984
2110
  .ctx-thinking {
1985
2111
  margin-top: 14px;
1986
2112
  padding-top: 12px;
@@ -2079,6 +2205,13 @@
2079
2205
  }
2080
2206
  .plan-usage-card[data-status="unavailable"],
2081
2207
  .plan-usage-card[data-status="not-configured"] { opacity: 0.72; }
2208
+ /* A card whose provider is being read live while the kept reading shows. */
2209
+ .plan-usage-card[data-updating] .plan-usage-card-title::after {
2210
+ content: " · updating…";
2211
+ font-weight: 400;
2212
+ font-size: 0.78rem;
2213
+ color: var(--muted);
2214
+ }
2082
2215
  .plan-usage-card-head {
2083
2216
  display: flex;
2084
2217
  align-items: center;
@@ -2339,6 +2472,26 @@
2339
2472
  text-align: center;
2340
2473
  }
2341
2474
  #model-banner.visible { display: block; }
2475
+ /* The Claude usage limit (usage-limit-ui.js): a warning before the limit,
2476
+ and a turn paused at it with Resume now / Cancel. In the flow of the
2477
+ composer like #model-banner, for the same reason. */
2478
+ #usage-limit-banner {
2479
+ display: none;
2480
+ align-items: center;
2481
+ flex-wrap: wrap;
2482
+ gap: 6px 10px;
2483
+ background: var(--bg2);
2484
+ background: color-mix(in srgb, var(--warn) 14%, var(--bg2));
2485
+ border: 1px solid var(--warn);
2486
+ color: var(--warn);
2487
+ border-radius: 8px;
2488
+ padding: 6px 10px;
2489
+ margin-bottom: 10px;
2490
+ font-size: var(--fs-meta-sm);
2491
+ }
2492
+ #usage-limit-banner.visible { display: flex; }
2493
+ #usage-limit-banner .usage-limit-text { flex: 1 1 12em; min-width: 0; }
2494
+ #usage-limit-banner .relay-toast-action { flex: 0 0 auto; }
2342
2495
  /* Transient relay notices (saves, errors, action confirmations) float as a
2343
2496
  fixed toast above every overlay — the annotation editor's error paths
2344
2497
  rely on being readable over its full-screen modal. pointer-events: none
@@ -2456,6 +2609,40 @@
2456
2609
  #model-lock-note[data-provider="claude"] { color: var(--provider-claude); }
2457
2610
  #model-lock-note[data-provider="cursor"] { color: var(--provider-cursor); }
2458
2611
  #model-lock-note[data-provider="grok"] { color: var(--provider-grok); }
2612
+ #model-lock-note[data-provider="claude-cloud"] { color: var(--provider-claude-cloud); }
2613
+ /* Claude Cloud conversations (claude-cloud-conversation-ui.js): where the
2614
+ session runs and what it pushed, above the composer like the lock note.
2615
+ The items wrap instead of scrolling, so a long branch name can never push
2616
+ the composer wider than a phone. */
2617
+ #cloud-session-line {
2618
+ display: flex;
2619
+ flex-wrap: wrap;
2620
+ align-items: center;
2621
+ gap: 2px 10px;
2622
+ margin-bottom: 6px;
2623
+ min-width: 0;
2624
+ color: var(--muted);
2625
+ font-size: var(--fs-meta-sm);
2626
+ line-height: 1.4;
2627
+ }
2628
+ #cloud-session-line[hidden] { display: none; }
2629
+ .cloud-line-item {
2630
+ min-width: 0;
2631
+ max-width: 100%;
2632
+ overflow: hidden;
2633
+ text-overflow: ellipsis;
2634
+ white-space: nowrap;
2635
+ }
2636
+ a.cloud-line-item { color: var(--accent); text-decoration: none; }
2637
+ a.cloud-line-item:hover { text-decoration: underline; }
2638
+ .cloud-line-repo { color: var(--provider-claude-cloud); font-weight: 600; }
2639
+ a.cloud-line-repo { color: var(--provider-claude-cloud); }
2640
+ /* No relay modes, no effort choice and no context tier in a cloud chat. */
2641
+ body.claude-cloud-conversation #mode-select,
2642
+ body.claude-cloud-conversation #context-tier-select,
2643
+ body.claude-cloud-conversation #reasoning-effort-select {
2644
+ display: none;
2645
+ }
2459
2646
  #model-select:disabled,
2460
2647
  #reasoning-effort-select:disabled {
2461
2648
  opacity: 0.55;
@@ -2762,6 +2949,46 @@
2762
2949
  flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
2763
2950
  color: var(--muted); font-size: var(--fs-ui-chip);
2764
2951
  }
2952
+ /* "via agent · “title”": an agent on this relay started the conversation.
2953
+ A button while the conversation it runs in can be opened, a span when it
2954
+ is gone. The title is long, so in the sidebar the date keeps its share. */
2955
+ .conv-origin-marker.conv-origin-agent { max-width: 60%; }
2956
+ button.conv-origin-agent,
2957
+ button.msg-origin-badge {
2958
+ font-family: inherit; cursor: pointer; text-align: left;
2959
+ touch-action: manipulation; -webkit-tap-highlight-color: transparent;
2960
+ }
2961
+ button.conv-origin-agent {
2962
+ background: none; border: none; padding: 0; margin: 0; line-height: inherit;
2963
+ color: var(--accent);
2964
+ }
2965
+ /* A finger needs more than one line of chip text: the padding grows the
2966
+ button, the negative margin keeps the row's height. */
2967
+ button.conv-origin-marker.conv-origin-agent { padding: 6px 0; margin: -6px 0; }
2968
+ button.conv-origin-agent:hover,
2969
+ button.msg-origin-badge:hover { text-decoration: underline; }
2970
+ button.msg-origin-badge { color: inherit; }
2971
+ #chat-title-origin {
2972
+ display: block; margin-top: 2px; min-width: 0;
2973
+ font-size: var(--fs-meta-xs); line-height: 1.2; color: var(--muted);
2974
+ overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
2975
+ }
2976
+ #chat-title-origin[hidden] { display: none; }
2977
+ #chat-title-origin .conv-origin-agent {
2978
+ display: block; max-width: 100%; font-size: inherit;
2979
+ overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
2980
+ }
2981
+ #chat-title-origin button.conv-origin-agent { padding: 3px 0; }
2982
+ /* Agent sessions (Settings → Relays). The slider spans the row so a thumb
2983
+ has room to travel at phone width, with a taller touch area than the
2984
+ track itself. */
2985
+ #agent-sessions-section[hidden] { display: none; }
2986
+ #agent-sessions-max-wait-slider {
2987
+ width: min(420px, 100%); min-height: 32px; margin: 0; box-sizing: border-box;
2988
+ accent-color: var(--accent); touch-action: pan-y;
2989
+ }
2990
+ #agent-sessions-max-wait-slider:disabled { opacity: 0.5; }
2991
+ #agent-sessions-status { overflow-wrap: anywhere; }
2765
2992
  /* Transcript card: a preview published during this turn, pinned into the
2766
2993
  response bubble. Compact single row; closed previews keep the label but
2767
2994
  lose the dead link. */
@@ -2805,6 +3032,11 @@
2805
3032
  background: rgba(63, 185, 80, 0.12); color: var(--relay-tone-online);
2806
3033
  border-radius: 6px; padding: 0 6px; font-size: var(--fs-meta-sm);
2807
3034
  }
3035
+ /* The relay's note while a session's worker cannot be started
3036
+ (worker-launch-note-service.mjs): a notice of the relay's, not a reply.
3037
+ Amber while the relay keeps trying or has stopped, green once started. */
3038
+ .msg.assistant.msg-worker-launch .msg-bubble { border-left: 3px solid #d29922; }
3039
+ .msg.assistant.msg-worker-launch-started .msg-bubble { border-left-color: var(--relay-tone-online); }
2808
3040
  /* Mid-turn steering. The CLI usually FOLDS a steered message into the
2809
3041
  running turn and answers everything with one reply; the steered row then
2810
3042
  settles as a compact marker under its own message (kind='folded'). More
@@ -2866,6 +3098,7 @@
2866
3098
  body.shared-reader-mode #reasoning-effort-select,
2867
3099
  body.shared-reader-mode #send-btn,
2868
3100
  body.shared-reader-mode #model-lock-note,
3101
+ body.shared-reader-mode #cloud-session-line,
2869
3102
  body.shared-reader-mode #model-pricing-details {
2870
3103
  display: none !important;
2871
3104
  }
@@ -3008,6 +3241,17 @@
3008
3241
  .file-preview-markdown th, .file-preview-markdown td { border: 1px solid var(--border); padding: 6px 9px; }
3009
3242
  .file-preview-markdown th { background: var(--bg3); }
3010
3243
  .file-preview-markdown img { display: block; max-width: 100%; height: auto; }
3244
+ /* Without a colour of their own, links fell back to the browser's default
3245
+ blue, which cannot be read on the dark background. The accent is the
3246
+ calmer of the two blues: the bubbles' link colour is for a tinted bubble,
3247
+ and on the viewer's plain background it glares. */
3248
+ .file-preview-markdown a,
3249
+ .file-preview-markdown a:visited {
3250
+ color: var(--accent);
3251
+ text-decoration-thickness: 1.2px;
3252
+ text-underline-offset: 2px;
3253
+ }
3254
+ .file-preview-markdown a code { color: inherit; }
3011
3255
  .file-preview-markdown pre,
3012
3256
  .file-preview-code pre {
3013
3257
  background: #0b0f14;
@@ -3227,12 +3471,16 @@
3227
3471
  #new-conversation-context-select,
3228
3472
  #new-conversation-size-select,
3229
3473
  #new-conversation-cwd-select,
3230
- #new-conversation-cwd-manual {
3474
+ #new-conversation-cwd-manual,
3475
+ #new-conversation-cloud-repo,
3476
+ #new-conversation-cloud-branch {
3231
3477
  width: 100%;
3232
3478
  min-height: 42px;
3233
3479
  margin-top: 8px;
3234
3480
  }
3235
- #new-conversation-cwd-manual {
3481
+ #new-conversation-cwd-manual,
3482
+ #new-conversation-cloud-repo,
3483
+ #new-conversation-cloud-branch {
3236
3484
  box-sizing: border-box;
3237
3485
  padding: 0 10px;
3238
3486
  border-radius: 8px;
@@ -3241,6 +3489,84 @@
3241
3489
  color: var(--text);
3242
3490
  }
3243
3491
  #new-conversation-cwd-manual[hidden] { display: none; }
3492
+ #new-conversation-cloud-repo[aria-invalid="true"],
3493
+ #new-conversation-cloud-branch[aria-invalid="true"] { border-color: var(--danger); }
3494
+ /* Warning lines under Repository/Branch: what the cloud clone will not see. */
3495
+ #new-conversation-cloud-warnings {
3496
+ margin-top: 8px;
3497
+ font-size: 0.78rem;
3498
+ line-height: 1.4;
3499
+ color: var(--warn);
3500
+ overflow-wrap: anywhere;
3501
+ }
3502
+ #new-conversation-cloud-warnings:empty { display: none; }
3503
+ .new-conversation-cloud-warning::before { content: "⚠ "; }
3504
+ #new-conversation-cloud-error {
3505
+ margin-top: 8px;
3506
+ font-size: 0.78rem;
3507
+ line-height: 1.4;
3508
+ color: var(--danger);
3509
+ overflow-wrap: anywhere;
3510
+ }
3511
+ #new-conversation-cloud-error[hidden] { display: none; }
3512
+ /* Suggestions under Repository/Branch: a list in the flow of the modal
3513
+ (not a floating one: the modal scrolls on a phone and a popover would
3514
+ be clipped), at most a few rows high, scrolling inside itself. */
3515
+ .new-conversation-cloud-suggest {
3516
+ margin-top: 4px;
3517
+ max-height: min(40vh, 220px);
3518
+ overflow-y: auto;
3519
+ border: 1px solid var(--border);
3520
+ border-radius: 8px;
3521
+ background: var(--bg3);
3522
+ }
3523
+ .new-conversation-cloud-suggest[hidden] { display: none; }
3524
+ .new-conversation-cloud-suggest-item {
3525
+ display: flex;
3526
+ align-items: baseline;
3527
+ justify-content: space-between;
3528
+ gap: 8px;
3529
+ width: 100%;
3530
+ box-sizing: border-box;
3531
+ min-height: 38px;
3532
+ padding: 8px 10px;
3533
+ border: 0;
3534
+ border-bottom: 1px solid var(--border);
3535
+ background: transparent;
3536
+ color: var(--text);
3537
+ font: inherit;
3538
+ text-align: left;
3539
+ cursor: pointer;
3540
+ overflow-wrap: anywhere;
3541
+ }
3542
+ .new-conversation-cloud-suggest-item:last-child { border-bottom: 0; }
3543
+ .new-conversation-cloud-suggest-item:hover,
3544
+ .new-conversation-cloud-suggest-item[aria-selected="true"] { background: var(--bg2); }
3545
+ .new-conversation-cloud-suggest-meta {
3546
+ flex: 0 0 auto;
3547
+ font-size: 0.72rem;
3548
+ color: var(--muted);
3549
+ white-space: nowrap;
3550
+ }
3551
+ .new-conversation-cloud-refresh {
3552
+ margin-left: 6px;
3553
+ padding: 0 6px;
3554
+ min-height: 22px;
3555
+ border: 1px solid transparent;
3556
+ border-radius: 6px;
3557
+ background: transparent;
3558
+ color: var(--muted);
3559
+ font: inherit;
3560
+ cursor: pointer;
3561
+ vertical-align: middle;
3562
+ }
3563
+ .new-conversation-cloud-refresh:hover { color: var(--text); border-color: var(--border); }
3564
+ .new-conversation-cloud-refresh[aria-busy="true"] { opacity: 0.5; cursor: progress; }
3565
+ .new-conversation-cloud-suggest-note {
3566
+ padding: 8px 10px;
3567
+ font-size: 0.78rem;
3568
+ color: var(--muted);
3569
+ }
3244
3570
  /* Shared row/button recipe for the file-explorer CWD browse buttons in the
3245
3571
  New chat and Change CWD modals — one place to restyle both. */
3246
3572
  .cwd-browse-row {
@@ -4627,6 +4953,23 @@
4627
4953
  and overflow horizontally. Pin to 0 so children wrap/scroll instead. */
4628
4954
  min-width: 0;
4629
4955
  }
4956
+ /* A board inside the bubble of the reply it belongs to: set off from the
4957
+ reply's text by a rule, not by a card of its own. */
4958
+ .relay-board-inline {
4959
+ display: grid;
4960
+ gap: 10px;
4961
+ min-width: 0;
4962
+ margin-top: 12px;
4963
+ padding-top: 12px;
4964
+ border-top: 1px solid rgba(80, 227, 194, 0.35);
4965
+ }
4966
+ .relay-board-inline.relay-board-card { margin-top: 0; border-top: 0; }
4967
+ .relay-board-inline .relay-board-head { color: var(--text); font-weight: 600; font-size: var(--fs-meta-md); }
4968
+ .relay-board-outcome {
4969
+ color: var(--muted);
4970
+ font-size: var(--fs-meta-md);
4971
+ }
4972
+ .relay-board-outcome::before { content: '✓ '; color: var(--success); }
4630
4973
  .relay-board-head {
4631
4974
  display: flex;
4632
4975
  align-items: center;
@@ -4738,6 +5081,7 @@
4738
5081
  #status-btn { min-width: 72px; padding: 9px 10px; font-size: var(--fs-meta-md); }
4739
5082
  #conv-filter-row { padding: 8px 12px; }
4740
5083
  #conv-filter-clear { right: 16px; }
5084
+ #conv-archived-toggle { right: 42px; }
4741
5085
  #conv-list { padding: 0 5px 8px; }
4742
5086
  .conv-item { padding: 6px 11px; border-radius: 8px; }
4743
5087
  .conv-title {
@@ -4802,6 +5146,10 @@
4802
5146
  overflow: hidden;
4803
5147
  text-overflow: ellipsis;
4804
5148
  }
5149
+ #chat-title-origin {
5150
+ margin-top: 1px;
5151
+ font-size: clamp(0.62rem, 2vw, 0.7rem);
5152
+ }
4805
5153
  #chat-header-actions {
4806
5154
  margin-left: auto;
4807
5155
  }
@@ -4952,6 +5300,12 @@
4952
5300
  font-size: var(--fs-meta-md);
4953
5301
  }
4954
5302
  #attach-btn { order: 4; flex: 0 0 40px; }
5303
+ /* A cloud chat hides mode, context tier and effort: the model select
5304
+ takes the room they leave. */
5305
+ body.claude-cloud-conversation #model-select {
5306
+ flex: 1 1 0;
5307
+ width: auto;
5308
+ }
4955
5309
  #context-tier-select {
4956
5310
  order: 5;
4957
5311
  flex: 0 0 70px;
@@ -5269,8 +5623,10 @@
5269
5623
  <div id="conv-filter-row">
5270
5624
  <input id="conv-filter-input" type="text" placeholder="Filter conversations…" autocomplete="off" spellcheck="false" aria-label="Filter conversations by title">
5271
5625
  <button id="conv-filter-clear" type="button" title="Clear filter" aria-label="Clear filter" hidden>×</button>
5626
+ <button id="conv-archived-toggle" type="button" title="Show archived conversations" aria-label="Show archived conversations" aria-pressed="false" onclick="toggleArchivedConversations()">🗄</button>
5272
5627
  <div id="conv-filter-status" role="status" aria-live="polite"></div>
5273
5628
  </div>
5629
+ <div id="conv-archived-banner" hidden>Archived conversations <button type="button" class="conv-archived-back" onclick="toggleArchivedConversations()">Back to the list</button></div>
5274
5630
  <div id="conv-list"></div>
5275
5631
  </div>
5276
5632
  <div id="sidebar-resizer" role="separator" aria-orientation="vertical" aria-label="Resize conversations sidebar"></div>
@@ -5279,7 +5635,7 @@
5279
5635
  <div id="chat-header">
5280
5636
  <button id="sidebar-toggle" class="header-icon-btn" type="button" title="Toggle conversations sidebar" aria-label="Toggle conversations sidebar">☰</button>
5281
5637
  <div id="chat-title-wrap">
5282
- <span id="chat-title-slot"><span id="chat-title-primary"><span id="chat-title-watch-indicator" hidden>👁️ </span><span id="chat-title">Select or start a conversation</span></span><span id="chat-title-cwd" hidden></span><span id="chat-title-session-usage" hidden></span></span>
5638
+ <span id="chat-title-slot"><span id="chat-title-primary"><span id="chat-title-watch-indicator" hidden>👁️ </span><span id="chat-title">Select or start a conversation</span></span><span id="chat-title-origin" hidden></span><span id="chat-title-cwd" hidden></span><span id="chat-title-session-usage" hidden></span></span>
5283
5639
  <form id="chat-title-editor" hidden>
5284
5640
  <input id="chat-title-input" type="text" maxlength="120" autocomplete="off" spellcheck="false">
5285
5641
  <button id="chat-title-save-btn" class="chat-title-action-btn" type="submit">Save</button>
@@ -5299,11 +5655,13 @@
5299
5655
  <button id="chat-menu-usage" class="chat-actions-menu-item" type="button" role="menuitem">📊 Check Usage</button>
5300
5656
  <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>
5301
5657
  <button id="chat-menu-share-conversation" class="chat-actions-menu-item" type="button" role="menuitem">➡️ Share conversation</button>
5658
+ <button id="chat-menu-archive" class="chat-actions-menu-item" type="button" role="menuitem">🗄 Archive conversation</button>
5302
5659
  <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>
5303
5660
  <button id="chat-menu-inspect-tmux" class="chat-actions-menu-item" type="button" role="menuitem">🖥️ Inspect tmux console</button>
5304
5661
  <button id="chat-menu-select-models" class="chat-actions-menu-item" type="button" role="menuitem">🤗 Select Models</button>
5305
5662
  <button id="chat-menu-change-cwd" class="chat-actions-menu-item" type="button" role="menuitem">🗂️ Change CWD</button>
5306
5663
  <button id="chat-menu-git-changes" class="chat-actions-menu-item" type="button" role="menuitem">🌿 Git changes</button>
5664
+ <button id="chat-menu-open-cloud-session" class="chat-actions-menu-item" type="button" role="menuitem" hidden>☁️ Open on claude.ai</button>
5307
5665
  <button id="chat-menu-settings" class="chat-actions-menu-item" type="button" role="menuitem">⚙️ Settings</button>
5308
5666
  <button id="chat-menu-restart-relay" class="chat-actions-menu-item" type="button" role="menuitem">🌄 Restart web relay</button>
5309
5667
  <button id="chat-menu-suspend-host" class="chat-actions-menu-item" type="button" role="menuitem" onclick="openSuspendHostConfirmation()">💤 Suspend host</button>
@@ -5324,7 +5682,9 @@
5324
5682
  <div id="input-area">
5325
5683
  <div id="offline-banner">⚠️ CLI is offline — messages will queue until it reconnects</div>
5326
5684
  <div id="model-banner"></div>
5685
+ <div id="usage-limit-banner" role="status" aria-live="polite" hidden></div>
5327
5686
  <div id="model-lock-note" hidden></div>
5687
+ <div id="cloud-session-line" aria-label="Cloud session" hidden></div>
5328
5688
  <div id="model-metadata-blocker" aria-live="polite">
5329
5689
  <span id="model-metadata-blocker-text">Model metadata is unavailable. Refresh to choose a model and reasoning effort.</span>
5330
5690
  <button type="button" id="model-metadata-retry-btn">Refresh models</button>
@@ -5705,6 +6065,16 @@
5705
6065
  tabindex="-1"
5706
6066
  data-settings-provider-tab="claude"
5707
6067
  >Claude</button>
6068
+ <button
6069
+ id="settings-provider-tab-claude-cloud"
6070
+ class="settings-tab settings-subtab"
6071
+ type="button"
6072
+ role="tab"
6073
+ aria-selected="false"
6074
+ aria-controls="settings-provider-panel-claude-cloud"
6075
+ tabindex="-1"
6076
+ data-settings-provider-tab="claude-cloud"
6077
+ >Claude Cloud</button>
5708
6078
  <button
5709
6079
  id="settings-provider-tab-grok"
5710
6080
  class="settings-tab settings-subtab"
@@ -5893,6 +6263,13 @@
5893
6263
  placeholder="claude-sonnet-5"
5894
6264
  aria-label="Claude model ID"
5895
6265
  >
6266
+ <label for="claude-attribution-select" style="margin-top: 8px;">Commit attribution</label>
6267
+ <select id="claude-attribution-select" aria-label="Commit attribution" onchange="window.previewClaudeAttribution?.(this.value)">
6268
+ <option value="oar">OAR — Co-authored-by: Open Agent Relay (model)</option>
6269
+ <option value="vanilla">Vanilla — Claude Code's own attribution</option>
6270
+ <option value="off">Off — no attribution</option>
6271
+ </select>
6272
+ <div id="claude-attribution-example" class="settings-help"></div>
5896
6273
  <div id="claude-settings-status" class="settings-help settings-provider-status">Loading Claude settings…</div>
5897
6274
  <div style="display: flex; gap: 8px; margin-top: 8px;">
5898
6275
  <button id="claude-save-btn" type="button" class="summary-btn" onclick="saveClaudeSettings()">Save Claude settings</button>
@@ -5900,6 +6277,42 @@
5900
6277
  <div class="settings-help">Runs Claude conversations through the Claude Agent SDK using the relay host's logged-in Claude credentials (no API key stored). Disabling also rebinds conversations that have not sent a message yet.</div>
5901
6278
  </div>
5902
6279
  </div>
6280
+ <!-- Claude Cloud (claude-cloud-settings-ui.js). The login itself is managed on
6281
+ the Claude tab; this panel only says which account pays. -->
6282
+ <div
6283
+ id="settings-provider-panel-claude-cloud"
6284
+ class="settings-panel"
6285
+ role="tabpanel"
6286
+ tabindex="0"
6287
+ aria-labelledby="settings-provider-tab-claude-cloud"
6288
+ data-settings-provider-panel="claude-cloud"
6289
+ hidden
6290
+ >
6291
+ <div class="settings-row settings-row-column" style="margin-top: 12px; margin-bottom: 0;">
6292
+ <label for="claude-cloud-enabled-toggle">Claude Cloud</label>
6293
+ <div class="settings-help">Cloud chats run Claude Code in a sandbox at Anthropic, on its own clone of a GitHub repository, instead of on the relay host. They are billed to the Claude account below. The relay reads that account's login from the Claude CLI on the relay host; it does not store it or refresh it.</div>
6294
+ <div class="settings-row" style="width: 100%; margin-top: 8px; margin-bottom: 8px;">
6295
+ <label for="claude-cloud-enabled-toggle">Enable Claude Cloud for New Chat</label>
6296
+ <input id="claude-cloud-enabled-toggle" type="checkbox" onchange="toggleClaudeCloudProvider(this.checked)" disabled>
6297
+ </div>
6298
+ <div id="claude-cloud-account-row" class="settings-row" style="width: 100%; margin-bottom: 0;" hidden>
6299
+ <div id="claude-cloud-account" class="settings-help settings-provider-status" style="min-width: 0; overflow-wrap: anywhere;"></div>
6300
+ <button id="claude-cloud-login-btn" type="button" class="summary-btn" style="flex: 0 0 auto;" onclick="openClaudeCloudLoginTab()">Claude login</button>
6301
+ </div>
6302
+ <div id="claude-cloud-token" class="settings-help settings-provider-status" style="margin-top: 6px;" hidden></div>
6303
+ <label for="claude-cloud-environment-select" style="margin-top: 12px;">Cloud environment</label>
6304
+ <select id="claude-cloud-environment-select" aria-label="Cloud environment" style="max-width: 100%;" disabled></select>
6305
+ <div id="claude-cloud-environment-note" class="settings-help" hidden></div>
6306
+ <label for="claude-cloud-model-select" style="margin-top: 8px;">Default model</label>
6307
+ <select id="claude-cloud-model-select" aria-label="Default model for cloud chats" style="max-width: 100%;" disabled></select>
6308
+ <div id="claude-cloud-settings-status" class="settings-help settings-provider-status">Loading Claude Cloud settings…</div>
6309
+ <div style="display: flex; gap: 8px 12px; margin-top: 8px; flex-wrap: wrap; align-items: center;">
6310
+ <button id="claude-cloud-save-btn" type="button" class="summary-btn" onclick="saveClaudeCloudSettings()" disabled>Save Claude Cloud settings</button>
6311
+ <a id="claude-cloud-open-link" class="plan-usage-link" href="https://claude.ai/code" target="_blank" rel="noopener noreferrer" style="font-size: var(--fs-meta-sm);">Open claude.ai/code</a>
6312
+ </div>
6313
+ <div class="settings-help">A cloud chat works on what is pushed to GitHub, and its results come back as pushed branches. It has no relay modes, no reasoning effort choice and no mid-turn steering, and it takes images as its only attachments.</div>
6314
+ </div>
6315
+ </div>
5903
6316
  <div
5904
6317
  id="settings-provider-panel-grok"
5905
6318
  class="settings-panel"
@@ -6151,6 +6564,42 @@
6151
6564
  >
6152
6565
  </div>
6153
6566
  <div class="settings-help" style="margin-top: 6px;">When off, agents on paired relays can still read sessions here, but cannot send prompts, start sessions, answer questions or stop turns. The relay token stays the real boundary: anyone holding it has full access.</div>
6567
+ <!-- Agent sessions (agent-sessions-settings-ui.js). Hidden until the relay
6568
+ answers with settings; a relay without the route never shows it. -->
6569
+ <div id="agent-sessions-section" hidden>
6570
+ <div class="settings-row settings-row-column" style="margin-top: 16px; margin-bottom: 0;">
6571
+ <label>Agent sessions</label>
6572
+ </div>
6573
+ <div class="settings-row" style="margin-top: 6px; margin-bottom: 0;">
6574
+ <label for="agent-sessions-enabled-toggle" style="font-weight: normal;">Agents may start and use sessions on this relay</label>
6575
+ <input
6576
+ id="agent-sessions-enabled-toggle"
6577
+ type="checkbox"
6578
+ onchange="toggleAgentSessions(this.checked)"
6579
+ aria-label="Agents may start and use sessions on this relay"
6580
+ disabled
6581
+ >
6582
+ </div>
6583
+ <div class="settings-help" style="margin-top: 6px;">Sessions an agent starts use this relay's accounts. The first one in a conversation asks for your approval. <span id="agent-sessions-cap" hidden></span></div>
6584
+ <div class="settings-row settings-row-column" style="margin-top: 12px; margin-bottom: 0;">
6585
+ <label for="agent-sessions-max-wait-slider">Longest wait per tool call <span id="agent-sessions-max-wait-value">10 min</span></label>
6586
+ <input
6587
+ id="agent-sessions-max-wait-slider"
6588
+ type="range"
6589
+ min="120"
6590
+ max="3600"
6591
+ step="60"
6592
+ value="600"
6593
+ aria-label="Longest wait per tool call"
6594
+ aria-valuetext="10 min"
6595
+ oninput="previewAgentSessionsMaxWait(this.value)"
6596
+ onchange="saveAgentSessionsMaxWait(this.value)"
6597
+ disabled
6598
+ >
6599
+ </div>
6600
+ <div class="settings-help" style="margin-top: 6px;">How long an agent may wait for a session in one call, on this relay or a paired one. It can call again to keep waiting.</div>
6601
+ <div id="agent-sessions-status" class="settings-help settings-provider-status" style="margin-top: 6px;" role="status" aria-live="polite" hidden></div>
6602
+ </div>
6154
6603
  <div id="remote-relays-list-section" class="settings-row settings-row-column" style="margin-top: 16px; margin-bottom: 0;">
6155
6604
  <label>Remote relays</label>
6156
6605
  <div id="remote-relays-list"></div>
@@ -6325,11 +6774,25 @@
6325
6774
  </select>
6326
6775
  <div id="new-conversation-provider-help" style="margin-top:8px;font-size:0.78rem;color:var(--muted);">Copilot models use your GitHub Copilot runtime.</div>
6327
6776
  </div>
6777
+ <!-- Claude Cloud only (journal-view.js): the GitHub repository and branch
6778
+ the cloud session clones, filled from the folder picked above. -->
6779
+ <div id="new-conversation-cloud-row" hidden>
6780
+ <label for="new-conversation-cloud-repo" style="display:block;margin-top:12px;">Repository <button id="new-conversation-cloud-repo-refresh" type="button" class="new-conversation-cloud-refresh" title="Read the repository list again" aria-label="Read the repository list again" onclick="refreshNewConversationCloudRepoList()">↻</button></label>
6781
+ <input id="new-conversation-cloud-repo" type="text" role="combobox" aria-autocomplete="list" aria-expanded="false" aria-controls="new-conversation-cloud-repo-list" inputmode="url" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" placeholder="owner/repo or GitHub URL" aria-describedby="new-conversation-cloud-warnings new-conversation-cloud-error">
6782
+ <div id="new-conversation-cloud-repo-list" class="new-conversation-cloud-suggest" role="listbox" aria-label="Repositories" hidden></div>
6783
+ <label for="new-conversation-cloud-branch" style="display:block;margin-top:12px;">Branch</label>
6784
+ <input id="new-conversation-cloud-branch" type="text" role="combobox" aria-autocomplete="list" aria-expanded="false" aria-controls="new-conversation-cloud-branch-list" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" placeholder="Default branch" aria-describedby="new-conversation-cloud-warnings new-conversation-cloud-error">
6785
+ <div id="new-conversation-cloud-branch-list" class="new-conversation-cloud-suggest" role="listbox" aria-label="Branches" hidden></div>
6786
+ <div id="new-conversation-cloud-warnings" role="status" aria-live="polite"></div>
6787
+ <div id="new-conversation-cloud-error" role="alert" hidden></div>
6788
+ </div>
6328
6789
  <label for="new-conversation-model-select" style="display:block;margin-top:12px;">Model</label>
6329
6790
  <select id="new-conversation-model-select"></select>
6330
- <label for="new-conversation-reasoning-select" style="display:block;margin-top:12px;">Reasoning effort</label>
6331
- <select id="new-conversation-reasoning-select"></select>
6332
- <div id="new-conversation-reasoning-status" style="margin-top:8px;font-size:0.78rem;color:var(--muted);">Choose the effort used when this conversation starts.</div>
6791
+ <div id="new-conversation-reasoning-row">
6792
+ <label for="new-conversation-reasoning-select" style="display:block;margin-top:12px;">Reasoning effort</label>
6793
+ <select id="new-conversation-reasoning-select"></select>
6794
+ <div id="new-conversation-reasoning-status" style="margin-top:8px;font-size:0.78rem;color:var(--muted);">Choose the effort used when this conversation starts.</div>
6795
+ </div>
6333
6796
  <div id="new-conversation-context-row" style="display:none;">
6334
6797
  <label for="new-conversation-context-select" style="display:block;margin-top:12px;">Context window</label>
6335
6798
  <select id="new-conversation-context-select" disabled aria-readonly="true"></select>