python-codex 0.2.5__py3-none-any.whl → 0.2.7__py3-none-any.whl

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.
@@ -8,22 +8,33 @@
8
8
  <style>
9
9
  :root {
10
10
  color-scheme: light;
11
- --bg: #f2f6f3;
12
- --panel: #ffffff;
13
- --ink: #1e2529;
14
- --muted: #5f6f75;
15
- --line: #d2ddd5;
16
- --accent: #0f8f55;
11
+ --bg: #eef3f6;
12
+ --panel: #f8fbfd;
13
+ --panel-deep: #f2f6f8;
14
+ --panel-raised: #ffffff;
15
+ --panel-hover: #e8f1f5;
16
+ --board-chrome: #ffffff;
17
+ --ink: #172630;
18
+ --muted: #60727d;
19
+ --line: #cbd8df;
20
+ --line-strong: #aebfc9;
21
+ --accent: #087f9a;
17
22
  --accent-ink: #ffffff;
18
- --warn-soft: #fff5cf;
19
- --info: #1f6fa4;
20
- --info-soft: #edf8ff;
21
- --danger: #b23a3a;
22
- --danger-soft: #fff1ef;
23
- --violet: #6b4fb0;
24
- --violet-soft: #f5f0ff;
25
- --code: #f3f7f8;
26
- --entry-shadow: 0 1px 2px rgba(25, 35, 31, 0.04);
23
+ --accent-soft: #e6f6f8;
24
+ --warn: #b77908;
25
+ --warn-ink: #62480c;
26
+ --warn-soft: #fff7df;
27
+ --info: #2868b2;
28
+ --info-soft: #edf5ff;
29
+ --success: #247a52;
30
+ --success-line: #8bc9a8;
31
+ --success-soft: #edf9f2;
32
+ --danger: #b33d50;
33
+ --danger-soft: #fff0f2;
34
+ --violet: #6850a4;
35
+ --violet-soft: #f4f0ff;
36
+ --code: #f1f5f7;
37
+ --entry-shadow: 0 1px 2px rgba(27, 57, 72, 0.06);
27
38
  --space-1: 2px;
28
39
  --space-2: 4px;
29
40
  --space-3: 6px;
@@ -52,14 +63,14 @@
52
63
  min-width: 0;
53
64
  }
54
65
  .workspace.collapsed .splitter::after {
55
- background: #4f6f60;
66
+ background: var(--accent);
56
67
  }
57
68
  .board-pane {
58
69
  min-width: 0;
59
70
  height: 100dvh;
60
71
  display: grid;
61
72
  grid-template-rows: auto minmax(0, 1fr);
62
- background: #fff;
73
+ background: var(--board-chrome);
63
74
  }
64
75
  .boardbar {
65
76
  min-width: 0;
@@ -101,10 +112,10 @@
101
112
  text-decoration: none;
102
113
  }
103
114
  .workspace-back:hover {
104
- background: #eef7f1;
115
+ background: var(--accent-soft);
105
116
  }
106
117
  .workspace-back:focus {
107
- outline: 2px solid #9bb7a6;
118
+ outline: 2px solid var(--accent);
108
119
  outline-offset: 1px;
109
120
  }
110
121
  .workspace-back::before {
@@ -120,16 +131,16 @@
120
131
  min-width: 0;
121
132
  width: 100%;
122
133
  height: 100%;
123
- background: #fff;
134
+ background: var(--board-chrome);
124
135
  }
125
136
  .splitter {
126
137
  position: relative;
127
138
  width: 8px;
128
139
  height: 100dvh;
129
140
  border: 0;
130
- border-left: 1px solid #c1cec6;
131
- border-right: 1px solid #c1cec6;
132
- background: #dfe8e2;
141
+ border-left: 1px solid var(--line);
142
+ border-right: 1px solid var(--line);
143
+ background: var(--panel-hover);
133
144
  cursor: col-resize;
134
145
  padding: 0;
135
146
  touch-action: none;
@@ -142,17 +153,17 @@
142
153
  width: 3px;
143
154
  height: 42px;
144
155
  border-radius: 999px;
145
- background: #7d9588;
156
+ background: var(--muted);
146
157
  transform: translate(-50%, -50%);
147
158
  }
148
159
  .splitter:hover,
149
160
  .workspace.resizing .splitter {
150
- background: #d3dfd7;
151
- border-color: #aebeb4;
161
+ background: #dce9ee;
162
+ border-color: var(--line-strong);
152
163
  }
153
164
  .splitter:hover::after,
154
165
  .workspace.resizing .splitter::after {
155
- background: #527465;
166
+ background: var(--accent);
156
167
  }
157
168
  .workspace.resizing,
158
169
  .workspace.resizing * {
@@ -190,8 +201,8 @@
190
201
  width: var(--context-meter-size);
191
202
  height: var(--context-meter-size);
192
203
  border-radius: 999px;
193
- background: conic-gradient(#4ca56f 0 var(--context-remaining), #cfd8d2 0 100%);
194
- color: #335243;
204
+ background: conic-gradient(var(--accent) 0 var(--context-remaining), var(--line-strong) 0 100%);
205
+ color: var(--muted);
195
206
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
196
207
  font-size: 9px;
197
208
  line-height: 1;
@@ -205,7 +216,7 @@
205
216
  position: absolute;
206
217
  inset: 4px;
207
218
  border-radius: 999px;
208
- background: #fff;
219
+ background: var(--panel);
209
220
  }
210
221
  .context-meter-value {
211
222
  position: relative;
@@ -227,9 +238,9 @@
227
238
  min-width: 88px;
228
239
  max-width: 180px;
229
240
  height: 31px;
230
- border: 1px solid #d5ddd7;
241
+ border: 1px solid var(--line);
231
242
  border-radius: var(--radius-sm);
232
- background: #f6f8f7;
243
+ background: var(--panel-raised);
233
244
  color: var(--ink);
234
245
  padding: 0 var(--space-3) 0 var(--space-4);
235
246
  font: inherit;
@@ -238,12 +249,12 @@
238
249
  }
239
250
  .tab:focus-within,
240
251
  .tab-new:focus {
241
- outline: 2px solid #9bb7a6;
252
+ outline: 2px solid var(--accent);
242
253
  outline-offset: 1px;
243
254
  }
244
255
  .tab.active {
245
- border-color: #afd6bd;
246
- background: #eef7f1;
256
+ border-color: var(--accent);
257
+ background: var(--accent-soft);
247
258
  box-shadow: inset 0 -2px 0 var(--accent);
248
259
  }
249
260
  .tab-status {
@@ -281,7 +292,7 @@
281
292
  height: 31px;
282
293
  border: 1px solid var(--line);
283
294
  border-radius: var(--radius-md);
284
- background: #eef7f1;
295
+ background: var(--panel-raised);
285
296
  color: var(--muted);
286
297
  padding: 0;
287
298
  line-height: 1;
@@ -293,7 +304,9 @@
293
304
  height: 18px;
294
305
  border: 0;
295
306
  background: transparent;
296
- opacity: 0.42;
307
+ opacity: 0;
308
+ visibility: hidden;
309
+ pointer-events: none;
297
310
  font-size: 17px;
298
311
  font-weight: 500;
299
312
  line-height: 18px;
@@ -303,19 +316,19 @@
303
316
  font-weight: 400;
304
317
  line-height: 31px;
305
318
  }
306
- .tab:hover .tab-close,
307
- .tab:focus-within .tab-close,
308
319
  .tab.active .tab-close {
309
320
  opacity: 0.85;
321
+ visibility: visible;
322
+ pointer-events: auto;
310
323
  }
311
- .tab-close:disabled {
324
+ .tab.active .tab-close:disabled {
312
325
  opacity: 0.22;
313
326
  cursor: default;
314
327
  }
315
328
  .tab-close:hover,
316
329
  .tab-new:hover {
317
330
  color: var(--ink);
318
- background: #ffffff;
331
+ background: var(--panel-hover);
319
332
  }
320
333
  .log {
321
334
  min-height: 0;
@@ -325,45 +338,45 @@
325
338
  display: flex;
326
339
  flex-direction: column;
327
340
  gap: var(--space-4);
328
- background: #fbfcfa;
341
+ background: var(--bg);
329
342
  }
330
343
  .entry {
331
344
  min-width: 0;
332
345
  border: 1px solid var(--line);
333
346
  border-radius: var(--radius-sm);
334
347
  padding: var(--space-4) var(--space-5);
335
- background: #fff;
348
+ background: var(--panel-raised);
336
349
  box-shadow: var(--entry-shadow);
337
350
  }
338
351
  .entry.user {
339
- border-color: #edd17a;
352
+ border-color: var(--warn);
340
353
  background: var(--warn-soft);
341
- color: #5a4714;
354
+ color: var(--warn-ink);
342
355
  }
343
356
  .entry.response,
344
357
  .entry.assistant {
345
- border-color: #d0ddd5;
346
- background: #ffffff;
358
+ border-color: var(--line);
359
+ background: var(--panel-raised);
347
360
  }
348
361
  .entry.thinking {
349
- border-color: #b9dcc5;
350
- background: #f0fbf3;
351
- color: #256b43;
362
+ border-color: var(--success-line);
363
+ background: var(--success-soft);
364
+ color: var(--success);
352
365
  animation: thinking-breathe 4.8s ease-in-out infinite;
353
366
  }
354
367
  .entry.control {
355
- border-color: #b9d8ea;
368
+ border-color: #b7d3ee;
356
369
  background: var(--info-soft);
357
370
  color: var(--info);
358
371
  }
359
372
  .entry.tool {
360
- border-color: #d7c8f0;
373
+ border-color: #d8cdf1;
361
374
  background: var(--violet-soft);
362
375
  color: var(--violet);
363
376
  font-size: 12px;
364
377
  }
365
378
  .entry.error {
366
- border-color: #efb4ad;
379
+ border-color: #efb8c1;
367
380
  background: var(--danger-soft);
368
381
  color: var(--danger);
369
382
  }
@@ -422,11 +435,11 @@
422
435
  vertical-align: top;
423
436
  }
424
437
  .markdown th {
425
- background: #eef7f1;
438
+ background: var(--accent-soft);
426
439
  font-weight: 650;
427
440
  }
428
441
  .markdown a {
429
- color: #176fa8;
442
+ color: var(--info);
430
443
  text-decoration: none;
431
444
  }
432
445
  .markdown a:hover {
@@ -436,6 +449,17 @@
436
449
  margin: 0 0 var(--space-4);
437
450
  overflow-x: auto;
438
451
  overflow-y: hidden;
452
+ overflow-wrap: normal;
453
+ word-break: normal;
454
+ }
455
+ .markdown .katex {
456
+ overflow-wrap: normal;
457
+ word-break: normal;
458
+ }
459
+ .markdown .katex .text {
460
+ white-space: normal;
461
+ overflow-wrap: normal;
462
+ word-break: normal;
439
463
  }
440
464
  .markdown .katex-display:last-child {
441
465
  margin-bottom: 0;
@@ -447,7 +471,7 @@
447
471
  display: grid;
448
472
  gap: var(--space-3);
449
473
  align-content: end;
450
- background: #fff;
474
+ background: var(--panel);
451
475
  }
452
476
  textarea {
453
477
  min-width: 0;
@@ -457,15 +481,15 @@
457
481
  border: 1px solid var(--line);
458
482
  border-radius: var(--radius-sm);
459
483
  padding: var(--space-4) var(--space-5);
460
- background: #ffffff;
484
+ background: var(--panel-deep);
461
485
  color: var(--ink);
462
486
  font: inherit;
463
487
  line-height: 1.4;
464
488
  overflow-y: auto;
465
489
  }
466
490
  textarea:focus {
467
- border-color: #65b782;
468
- box-shadow: 0 0 0 3px rgba(15, 143, 85, 0.13);
491
+ border-color: var(--accent);
492
+ box-shadow: 0 0 0 3px rgba(8, 127, 154, 0.18);
469
493
  outline: 0;
470
494
  }
471
495
  .actions {
@@ -501,8 +525,8 @@
501
525
  text-overflow: ellipsis;
502
526
  padding: var(--space-1) var(--space-4) var(--space-1) 18px;
503
527
  border-radius: 999px;
504
- background: rgba(240, 250, 244, 0.96);
505
- border: 1px solid rgba(172, 216, 188, 0.9);
528
+ background: rgba(230, 246, 248, 0.96);
529
+ border: 1px solid rgba(8, 127, 154, 0.35);
506
530
  font: inherit;
507
531
  font-size: 12px;
508
532
  cursor: pointer;
@@ -514,8 +538,8 @@
514
538
  display: none;
515
539
  }
516
540
  .spinner:focus-visible {
517
- border-color: #65b782;
518
- box-shadow: 0 0 0 3px rgba(15, 143, 85, 0.13);
541
+ border-color: var(--accent);
542
+ box-shadow: 0 0 0 3px rgba(8, 127, 154, 0.18);
519
543
  outline: 0;
520
544
  }
521
545
  .spinner-wrap:has(.spinner:not(:empty)) {
@@ -534,12 +558,12 @@
534
558
  animation: spinner-pulse 1.2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
535
559
  }
536
560
  .spinner.notify-enabled {
537
- color: #0b6b43;
538
- background: #e6f4eb;
539
- border-color: #4ca56f;
561
+ color: var(--success);
562
+ background: var(--success-soft);
563
+ border-color: var(--success-line);
540
564
  box-shadow:
541
- inset 0 1px 2px rgba(9, 93, 55, 0.16),
542
- inset 0 0 0 1px rgba(15, 143, 85, 0.1);
565
+ inset 0 1px 2px rgba(27, 57, 72, 0.08),
566
+ inset 0 0 0 1px rgba(36, 122, 82, 0.1);
543
567
  }
544
568
  .toast {
545
569
  position: absolute;
@@ -548,11 +572,11 @@
548
572
  z-index: 5;
549
573
  width: max-content;
550
574
  max-width: min(320px, calc(100vw - var(--space-6) * 2));
551
- border: 1px solid #bfd6c8;
575
+ border: 1px solid var(--line-strong);
552
576
  border-radius: var(--radius-sm);
553
- background: #f6fbf8;
577
+ background: var(--panel-raised);
554
578
  color: var(--ink);
555
- box-shadow: 0 8px 20px rgba(25, 35, 31, 0.12);
579
+ box-shadow: 0 8px 20px rgba(27, 57, 72, 0.14);
556
580
  padding: var(--space-4) var(--space-6);
557
581
  font-size: 12px;
558
582
  opacity: 0;
@@ -577,14 +601,14 @@
577
601
  }
578
602
  @keyframes thinking-breathe {
579
603
  0%, 100% {
580
- border-color: #b9dcc5;
604
+ border-color: var(--success-line);
581
605
  box-shadow: var(--entry-shadow);
582
606
  }
583
607
  50% {
584
- border-color: #72d494;
608
+ border-color: var(--success);
585
609
  box-shadow:
586
- 0 0 0 2px rgba(22, 168, 90, 0.16),
587
- 0 2px 7px rgba(25, 35, 31, 0.08);
610
+ 0 0 0 2px rgba(36, 122, 82, 0.14),
611
+ 0 2px 7px rgba(27, 57, 72, 0.08);
588
612
  }
589
613
  }
590
614
  @media (prefers-reduced-motion: reduce) {
@@ -683,12 +707,14 @@
683
707
  const markdownRenderer = window.markdownit
684
708
  ? window.markdownit({html: false, linkify: true, breaks: false})
685
709
  : null;
686
- const mathDelimiterPlaceholders = [
687
- ["\\[", "\uE000"],
688
- ["\\]", "\uE001"],
689
- ["\\(", "\uE002"],
690
- ["\\)", "\uE003"],
710
+ const mathDelimiters = [
711
+ {left: "$$", right: "$$", display: true},
712
+ {left: "\\[", right: "\\]", display: true},
713
+ {left: "\\(", right: "\\)", display: false},
714
+ {left: "$", right: "$", display: false},
691
715
  ];
716
+ const mathTokenPrefix = "\uE000math";
717
+ const mathTokenSuffix = "\uE001";
692
718
 
693
719
  function relativeUrl(path) {
694
720
  return new URL(path, window.location.href).toString();
@@ -725,41 +751,211 @@
725
751
  root.textContent = source || "";
726
752
  return;
727
753
  }
728
- let markdownSource = String(source || "");
729
- mathDelimiterPlaceholders.forEach(([delimiter, placeholder]) => {
730
- markdownSource = markdownSource.split(delimiter).join(placeholder);
731
- });
732
- const dirtyHtml = markdownRenderer.render(markdownSource);
754
+ const protectedMath = protectMath(String(source || ""));
755
+ const dirtyHtml = markdownRenderer.render(protectedMath.source);
733
756
  root.innerHTML = window.DOMPurify.sanitize(dirtyHtml, {
734
757
  USE_PROFILES: {html: true},
735
758
  ADD_ATTR: ["target", "rel"],
736
759
  });
760
+ renderProtectedMath(root, protectedMath.expressions);
761
+ root.querySelectorAll("a").forEach((anchor) => {
762
+ anchor.target = "_blank";
763
+ anchor.rel = "noopener noreferrer";
764
+ });
765
+ }
766
+
767
+ function isEscapedAt(source, index) {
768
+ let slashCount = 0;
769
+ for (let cursor = index - 1; cursor >= 0 && source[cursor] === "\\"; cursor -= 1) {
770
+ slashCount += 1;
771
+ }
772
+ return slashCount % 2 === 1;
773
+ }
774
+
775
+ function countBackticks(source, index) {
776
+ let count = 0;
777
+ while (source[index + count] === "`") {
778
+ count += 1;
779
+ }
780
+ return count;
781
+ }
782
+
783
+ function findMathEnd(source, start, delimiter) {
784
+ let searchFrom = start + delimiter.left.length;
785
+ while (searchFrom < source.length) {
786
+ const end = source.indexOf(delimiter.right, searchFrom);
787
+ if (end < 0) {
788
+ return -1;
789
+ }
790
+ if (!isEscapedAt(source, end)) {
791
+ if (
792
+ delimiter.left === "$" &&
793
+ (source[end - 1] === "$" || source[end + 1] === "$")
794
+ ) {
795
+ searchFrom = end + delimiter.right.length;
796
+ continue;
797
+ }
798
+ return end;
799
+ }
800
+ searchFrom = end + delimiter.right.length;
801
+ }
802
+ return -1;
803
+ }
804
+
805
+ function protectMath(source) {
806
+ const expressions = [];
807
+ let protectedSource = "";
808
+ let index = 0;
809
+ while (index < source.length) {
810
+ if (source[index] === "`") {
811
+ const tickCount = countBackticks(source, index);
812
+ const fence = "`".repeat(tickCount);
813
+ const close = source.indexOf(fence, index + tickCount);
814
+ if (close >= 0) {
815
+ const end = close + tickCount;
816
+ protectedSource += source.slice(index, end);
817
+ index = end;
818
+ continue;
819
+ }
820
+ }
821
+
822
+ let matched = null;
823
+ if (!isEscapedAt(source, index)) {
824
+ for (const delimiter of mathDelimiters) {
825
+ if (
826
+ source.indexOf(delimiter.left, index) !== index ||
827
+ (delimiter.left === "$" && source[index + 1] === "$")
828
+ ) {
829
+ continue;
830
+ }
831
+ const end = findMathEnd(source, index, delimiter);
832
+ if (end > index + delimiter.left.length) {
833
+ matched = {
834
+ delimiter: delimiter,
835
+ start: index,
836
+ end: end,
837
+ };
838
+ break;
839
+ }
840
+ }
841
+ }
842
+
843
+ if (matched) {
844
+ const expressionIndex = expressions.length;
845
+ expressions.push({
846
+ body: source.slice(
847
+ matched.start + matched.delimiter.left.length,
848
+ matched.end,
849
+ ),
850
+ delimiter: matched.delimiter,
851
+ });
852
+ protectedSource += mathTokenPrefix + expressionIndex + mathTokenSuffix;
853
+ index = matched.end + matched.delimiter.right.length;
854
+ continue;
855
+ }
856
+
857
+ protectedSource += source[index];
858
+ index += 1;
859
+ }
860
+ return {
861
+ source: protectedSource,
862
+ expressions: expressions,
863
+ };
864
+ }
865
+
866
+ function renderProtectedMath(root, expressions) {
867
+ if (!expressions.length) {
868
+ return;
869
+ }
870
+ const expressionByToken = new Map();
871
+ expressions.forEach((expression, index) => {
872
+ expressionByToken.set(
873
+ mathTokenPrefix + index + mathTokenSuffix,
874
+ expression,
875
+ );
876
+ });
737
877
  const textWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
878
+ const textNodes = [];
738
879
  let textNode = textWalker.nextNode();
739
880
  while (textNode) {
881
+ textNodes.push(textNode);
882
+ textNode = textWalker.nextNode();
883
+ }
884
+ for (const textNode of textNodes) {
740
885
  let value = textNode.nodeValue || "";
741
- mathDelimiterPlaceholders.forEach(([delimiter, placeholder]) => {
742
- value = value.split(placeholder).join(delimiter);
886
+ let cursor = 0;
887
+ let tokenIndex = value.indexOf(mathTokenPrefix, cursor);
888
+ if (tokenIndex < 0) {
889
+ continue;
890
+ }
891
+ const fragment = document.createDocumentFragment();
892
+ while (tokenIndex >= 0) {
893
+ const tokenEnd = value.indexOf(mathTokenSuffix, tokenIndex);
894
+ if (tokenEnd < 0) {
895
+ break;
896
+ }
897
+ const token = value.slice(tokenIndex, tokenEnd + mathTokenSuffix.length);
898
+ const expression = expressionByToken.get(token);
899
+ if (!expression) {
900
+ break;
901
+ }
902
+ if (tokenIndex > cursor) {
903
+ fragment.appendChild(
904
+ document.createTextNode(value.slice(cursor, tokenIndex)),
905
+ );
906
+ }
907
+ const mathNode = document.createElement("span");
908
+ const sourceText =
909
+ expression.delimiter.left +
910
+ expression.body +
911
+ expression.delimiter.right;
912
+ if (window.renderMathInElement) {
913
+ mathNode.textContent = sourceText;
914
+ window.renderMathInElement(mathNode, {
915
+ delimiters: [
916
+ {
917
+ left: expression.delimiter.left,
918
+ right: expression.delimiter.right,
919
+ display: expression.delimiter.display,
920
+ },
921
+ ],
922
+ throwOnError: false,
923
+ trust: false,
924
+ });
925
+ } else {
926
+ mathNode.textContent = expression.body;
927
+ }
928
+ fragment.appendChild(mathNode);
929
+ cursor = tokenEnd + mathTokenSuffix.length;
930
+ tokenIndex = value.indexOf(mathTokenPrefix, cursor);
931
+ }
932
+ if (cursor > 0) {
933
+ if (cursor < value.length) {
934
+ fragment.appendChild(document.createTextNode(value.slice(cursor)));
935
+ }
936
+ if (textNode.parentNode) {
937
+ textNode.parentNode.replaceChild(fragment, textNode);
938
+ }
939
+ }
940
+ }
941
+ restoreUnrenderedMathTokens(root, expressionByToken);
942
+ }
943
+
944
+ function restoreUnrenderedMathTokens(root, expressionByToken) {
945
+ const textWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
946
+ let textNode = textWalker.nextNode();
947
+ while (textNode) {
948
+ let value = textNode.nodeValue || "";
949
+ expressionByToken.forEach((expression, token) => {
950
+ const sourceText =
951
+ expression.delimiter.left +
952
+ expression.body +
953
+ expression.delimiter.right;
954
+ value = value.split(token).join(sourceText);
743
955
  });
744
956
  textNode.nodeValue = value;
745
957
  textNode = textWalker.nextNode();
746
958
  }
747
- if (window.renderMathInElement) {
748
- window.renderMathInElement(root, {
749
- delimiters: [
750
- {left: "$$", right: "$$", display: true},
751
- {left: "\\[", right: "\\]", display: true},
752
- {left: "\\(", right: "\\)", display: false},
753
- {left: "$", right: "$", display: false},
754
- ],
755
- throwOnError: false,
756
- trust: false,
757
- });
758
- }
759
- root.querySelectorAll("a").forEach((anchor) => {
760
- anchor.target = "_blank";
761
- anchor.rel = "noopener noreferrer";
762
- });
763
959
  }
764
960
 
765
961
  function loadChatWidth() {
@@ -1263,6 +1459,7 @@
1263
1459
  if (!sessionId || sessionId === activeSessionId) return;
1264
1460
  saveActiveSessionUiState();
1265
1461
  activeSessionId = sessionId;
1462
+ renderTabs();
1266
1463
  const state = stateForSession(sessionId);
1267
1464
  state.lastRenderedSignature = "";
1268
1465
  lastRenderedSignature = "";