@firstpick/pi-package-webui 0.4.2 → 0.4.4

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/public/index.html CHANGED
@@ -12,7 +12,7 @@
12
12
  <link rel="manifest" href="/manifest.webmanifest" />
13
13
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
14
14
  <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
15
- <link rel="stylesheet" href="/styles.css?v=50" />
15
+ <link rel="stylesheet" href="/styles.css?v=54" />
16
16
  </head>
17
17
  <body>
18
18
  <button id="sidePanelExpandButton" class="side-panel-expand-button" type="button" aria-controls="sidePanel" aria-expanded="false" aria-label="Expand side panel" title="Expand side panel">
@@ -210,7 +210,7 @@
210
210
  aria-haspopup="menu"
211
211
  aria-expanded="false"
212
212
  aria-controls="optionsMenu"
213
- data-tooltip="Options: command palette, resume, reload, name, clone, settings, export, fork, or tree."
213
+ data-tooltip="Options: command palette, resume, reload, remote, name, clone, settings, export, fork, or tree."
214
214
  ><svg class="composer-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M4 7h16M4 12h16M4 17h16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="8" cy="7" r="1.6" fill="currentColor"/><circle cx="16" cy="12" r="1.6" fill="currentColor"/><circle cx="11" cy="17" r="1.6" fill="currentColor"/></svg></button>
215
215
  <div id="optionsMenu" class="composer-publish-menu-panel composer-options-menu-panel" role="menu" aria-label="Common Pi options">
216
216
  <button id="optionsCommandPaletteButton" class="composer-publish-menu-item composer-options-menu-item" type="button" role="menuitem">
@@ -237,6 +237,9 @@
237
237
  <button id="optionsNameButton" class="composer-publish-menu-item composer-options-menu-item" type="button" role="menuitem" data-command="/name">
238
238
  <span>Name Session</span>
239
239
  </button>
240
+ <button id="optionsRemoteButton" class="composer-publish-menu-item composer-options-menu-item" type="button" role="menuitem" data-command="/remote" hidden>
241
+ <span>Open Remote</span>
242
+ </button>
240
243
  <button id="optionsReloadButton" class="composer-publish-menu-item composer-options-menu-item" type="button" role="menuitem" data-command="/reload">
241
244
  <span>Reload Pi</span>
242
245
  </button>
@@ -285,7 +288,16 @@
285
288
  aria-label="Follow-up: type your message first, then tap this button to send it as a follow-up."
286
289
  data-tooltip="Follow-up usage:&#10;1. Type your message in the textarea.&#10;2. Tap Follow-up to send it as a follow-up.&#10;Use for extra context or the next request."
287
290
  >Follow-up</button>
288
- <button id="abortButton" class="composer-abort-button danger" type="button" title="Abort the active Pi run (Esc or hold)" aria-label="Abort the active Pi run (Esc or hold)" hidden disabled>Abort</button>
291
+ <button id="abortButton" class="composer-abort-button danger" type="button" title="Hold Esc or the Abort button for 3 seconds to abort the active Pi run" aria-label="Hold Esc or the Abort button for 3 seconds to abort the active Pi run" hidden disabled>Abort</button>
292
+ <button
293
+ id="btwButton"
294
+ class="composer-icon-button composer-btw-button"
295
+ type="button"
296
+ title="Ask as a /btw side question"
297
+ aria-label="Ask the current composer text as a /btw side question"
298
+ data-tooltip="/btw side question:&#10;Type a question, then tap /btw to ask without adding it to the main conversation."
299
+ hidden
300
+ ><svg class="composer-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M5.5 6.5h10.75a2.25 2.25 0 0 1 2.25 2.25v4.5a2.25 2.25 0 0 1-2.25 2.25h-4.4L8 18.25V15.5H5.5a2.25 2.25 0 0 1-2.25-2.25v-4.5A2.25 2.25 0 0 1 5.5 6.5Z" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"/><path d="m15.75 5.25 1.1-2.1 1.1 2.1 2.3 1.1-2.3 1.1-1.1 2.1-1.1-2.1-2.3-1.1 2.3-1.1Z" fill="currentColor"/><path d="M7.25 10.25h5.8M7.25 12.75h4.1" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/></svg></button>
289
301
  <button id="sendButton" type="submit" class="primary" title="Send prompt">Send</button>
290
302
  </div>
291
303
  </form>
@@ -599,7 +611,10 @@
599
611
  <span class="command-palette-kicker">Quick launcher</span>
600
612
  <h2>Command palette</h2>
601
613
  </div>
602
- <span class="command-palette-shortcut">Ctrl/Cmd+K</span>
614
+ <div class="command-palette-header-actions">
615
+ <span class="command-palette-shortcut">Ctrl/Cmd+K</span>
616
+ <button id="commandPaletteCloseButton" class="command-palette-close-button" type="button" aria-label="Close command palette" title="Close command palette">Close</button>
617
+ </div>
603
618
  </div>
604
619
  <input id="commandPaletteInput" class="dialog-input command-palette-input" type="search" autocomplete="off" spellcheck="false" placeholder="Search commands, tabs, models, sessions…" aria-label="Search command palette" />
605
620
  <div id="commandPaletteList" class="command-palette-list" role="listbox" aria-label="Command palette results"></div>
@@ -697,6 +712,6 @@
697
712
  </form>
698
713
  </dialog>
699
714
 
700
- <script type="module" src="/app.js?v=50"></script>
715
+ <script type="module" src="/app.js?v=52"></script>
701
716
  </body>
702
717
  </html>
package/public/styles.css CHANGED
@@ -1701,6 +1701,7 @@ body.side-panel-collapsed .terminal-tabs-shell {
1701
1701
  }
1702
1702
  .widget-area:has(.release-npm-live-widget .release-npm-output-details[open]),
1703
1703
  .widget-area:has(.release-aur-live-widget .release-npm-output-details[open]),
1704
+ .widget-area:has(.workflow-live-widget .release-npm-output-details[open]),
1704
1705
  .widget-area:has(.app-runner-live-widget .release-npm-output-details[open]) {
1705
1706
  flex: 0 0 min(44rem, 68dvh);
1706
1707
  min-height: 0;
@@ -2745,6 +2746,120 @@ button.git-workflow-step:hover:not(:disabled) {
2745
2746
  linear-gradient(145deg, rgba(var(--ctp-crust-rgb), 0.98), rgba(var(--ctp-mantle-rgb), 0.92));
2746
2747
  }
2747
2748
  .app-runner-widget .release-npm-kicker { color: var(--ctp-green); }
2749
+ .workflow-widget {
2750
+ border-color: rgba(137, 180, 250, 0.62);
2751
+ border-left-color: rgba(137, 180, 250, 0.88);
2752
+ background:
2753
+ radial-gradient(circle at 4% 0%, rgba(137, 180, 250, 0.20), transparent 16rem),
2754
+ radial-gradient(circle at 96% 12%, rgba(203, 166, 247, 0.14), transparent 18rem),
2755
+ linear-gradient(145deg, rgba(var(--ctp-crust-rgb), 0.98), rgba(var(--ctp-mantle-rgb), 0.92));
2756
+ }
2757
+ .workflow-widget .release-npm-kicker { color: var(--ctp-blue); }
2758
+ .workflow-widget .release-npm-pill.workflow-status.completed { color: var(--ctp-green); }
2759
+ .workflow-widget .release-npm-pill.workflow-status.failed { color: var(--ctp-red); }
2760
+ .workflow-widget .release-npm-pill.workflow-status.cancelled { color: var(--ctp-yellow); }
2761
+ .workflow-widget .release-npm-pill.workflow-status.running,
2762
+ .workflow-widget .release-npm-pill.workflow-status.queued { color: var(--ctp-blue); }
2763
+ .workflow-widget .release-npm-pill.workflow-truncated { color: var(--ctp-peach); }
2764
+ .btw-widget {
2765
+ border-color: rgba(148, 226, 213, 0.62);
2766
+ border-left-color: rgba(148, 226, 213, 0.88);
2767
+ background:
2768
+ radial-gradient(circle at 4% 0%, rgba(148, 226, 213, 0.20), transparent 16rem),
2769
+ radial-gradient(circle at 96% 12%, rgba(137, 180, 250, 0.14), transparent 18rem),
2770
+ linear-gradient(145deg, rgba(var(--ctp-crust-rgb), 0.98), rgba(var(--ctp-mantle-rgb), 0.92));
2771
+ }
2772
+ .btw-widget .release-npm-kicker { color: var(--ctp-teal); }
2773
+ .btw-widget-question {
2774
+ display: grid;
2775
+ gap: 0.28rem;
2776
+ min-width: 0;
2777
+ padding: 0.56rem 0.64rem;
2778
+ border: 1px solid rgba(148, 226, 213, 0.20);
2779
+ border-radius: 0.68rem;
2780
+ background: rgba(var(--ctp-crust-rgb), 0.54);
2781
+ }
2782
+ .btw-widget-question-label {
2783
+ color: var(--ctp-teal);
2784
+ font-size: 0.66rem;
2785
+ font-weight: 950;
2786
+ letter-spacing: 0.12em;
2787
+ text-transform: uppercase;
2788
+ }
2789
+ .btw-widget-question-text {
2790
+ min-width: 0;
2791
+ color: rgba(var(--ctp-text-rgb), 0.94);
2792
+ line-height: 1.4;
2793
+ overflow-wrap: anywhere;
2794
+ }
2795
+ .btw-widget .release-npm-line {
2796
+ width: auto;
2797
+ white-space: pre-wrap;
2798
+ overflow-wrap: anywhere;
2799
+ }
2800
+ .btw-widget-composer {
2801
+ display: grid;
2802
+ grid-template-columns: minmax(0, 1fr) auto;
2803
+ gap: 0.5rem;
2804
+ align-items: stretch;
2805
+ min-width: 0;
2806
+ }
2807
+ .btw-widget-input {
2808
+ min-height: 2.5rem;
2809
+ max-height: min(16dvh, 7rem);
2810
+ padding: 0.64rem 0.72rem;
2811
+ resize: vertical;
2812
+ border: 1px solid rgba(148, 226, 213, 0.28);
2813
+ border-radius: 0.72rem;
2814
+ color: rgba(var(--ctp-text-rgb), 0.96);
2815
+ background: rgba(var(--ctp-crust-rgb), 0.72);
2816
+ box-shadow: inset 0 1px 0 rgba(var(--ctp-text-rgb), 0.04);
2817
+ font: inherit;
2818
+ line-height: 1.35;
2819
+ }
2820
+ .btw-widget-input:focus {
2821
+ outline: 2px solid rgba(148, 226, 213, 0.62);
2822
+ outline-offset: 0.12rem;
2823
+ border-color: rgba(148, 226, 213, 0.54);
2824
+ }
2825
+ .btw-widget-send {
2826
+ min-width: 5.8rem;
2827
+ color: var(--ctp-teal);
2828
+ border-color: rgba(148, 226, 213, 0.34);
2829
+ }
2830
+ .btw-widget-send:not(:disabled):hover,
2831
+ .btw-widget-send:not(:disabled):focus-visible {
2832
+ color: #11111b;
2833
+ border-color: transparent;
2834
+ background: linear-gradient(120deg, var(--ctp-teal), var(--ctp-blue));
2835
+ }
2836
+ .btw-transfer-action {
2837
+ display: inline-flex;
2838
+ align-items: center;
2839
+ gap: 0.38rem;
2840
+ color: var(--ctp-teal);
2841
+ border-color: rgba(148, 226, 213, 0.34);
2842
+ }
2843
+ .btw-transfer-action:not(:disabled):hover,
2844
+ .btw-transfer-action:not(:disabled):focus-visible {
2845
+ color: #11111b;
2846
+ border-color: transparent;
2847
+ background: linear-gradient(120deg, var(--ctp-teal), var(--ctp-blue));
2848
+ }
2849
+ .btw-transfer-icon {
2850
+ display: block;
2851
+ width: 1.05rem;
2852
+ height: 1.05rem;
2853
+ flex: 0 0 auto;
2854
+ }
2855
+ .btw-widget .release-npm-pill.btw-status.ready { color: var(--ctp-teal); }
2856
+ .btw-widget .release-npm-pill.btw-status.done { color: var(--ctp-green); }
2857
+ .btw-widget .release-npm-pill.btw-status.error { color: var(--ctp-red); }
2858
+ .btw-widget .release-npm-pill.btw-status.aborted { color: var(--ctp-yellow); }
2859
+ .btw-live-widget .release-npm-output-details[open] .release-npm-terminal {
2860
+ height: clamp(9rem, 28dvh, 22rem);
2861
+ min-height: 0;
2862
+ }
2748
2863
  .app-runner-status.done { color: var(--ctp-green); }
2749
2864
  .app-runner-status.failed,
2750
2865
  .app-runner-status.error { color: var(--ctp-red); }
@@ -2951,6 +3066,7 @@ button.git-workflow-step:hover:not(:disabled) {
2951
3066
  }
2952
3067
  .release-npm-live-widget .release-npm-output-details[open] .release-npm-terminal,
2953
3068
  .release-aur-live-widget .release-npm-output-details[open] .release-npm-terminal,
3069
+ .workflow-live-widget .release-npm-output-details[open] .release-npm-terminal,
2954
3070
  .app-runner-live-widget .release-npm-output-details[open] .release-npm-terminal {
2955
3071
  height: clamp(15rem, 42dvh, 31rem);
2956
3072
  min-height: 0;
@@ -4223,13 +4339,32 @@ button.composer-skill-tag:focus-visible {
4223
4339
  }
4224
4340
  .composer-actions-button { display: none; }
4225
4341
  .composer-actions-panel { display: contents; }
4342
+ .composer-btw-button {
4343
+ color: var(--ctp-teal);
4344
+ border-color: rgba(148, 226, 213, 0.34);
4345
+ background:
4346
+ linear-gradient(120deg, rgba(148, 226, 213, 0.14), rgba(137, 180, 250, 0.10)),
4347
+ linear-gradient(180deg, rgba(var(--ctp-surface-rgb), 0.82), rgba(var(--ctp-crust-rgb), 0.86));
4348
+ }
4349
+ .composer-btw-button .composer-icon {
4350
+ width: 1.34rem;
4351
+ height: 1.34rem;
4352
+ }
4353
+ .composer-btw-button:not(:disabled):hover,
4354
+ .composer-btw-button:not(:disabled):focus-visible {
4355
+ color: #11111b;
4356
+ border-color: transparent;
4357
+ background: linear-gradient(120deg, var(--ctp-teal), var(--ctp-blue));
4358
+ }
4226
4359
  .composer-abort-button,
4227
4360
  .composer-row button.primary {
4228
4361
  min-width: 5.8rem;
4229
4362
  }
4230
4363
  .composer-abort-button {
4364
+ min-width: 8.2rem;
4231
4365
  position: relative;
4232
4366
  overflow: hidden;
4367
+ white-space: nowrap;
4233
4368
  box-shadow: 0 0 1rem rgba(243, 139, 168, 0.30), inset 0 1px 0 rgba(255,255,255,0.05);
4234
4369
  }
4235
4370
  .composer-abort-button.long-pressing {
@@ -4244,7 +4379,7 @@ button.composer-skill-tag:focus-visible {
4244
4379
  background: linear-gradient(90deg, rgba(255,255,255,0.28), rgba(255,255,255,0.08));
4245
4380
  transform: scaleX(0);
4246
4381
  transform-origin: left center;
4247
- animation: abort-long-press-fill 700ms linear forwards;
4382
+ animation: abort-long-press-fill var(--abort-long-press-duration, 3000ms) linear forwards;
4248
4383
  }
4249
4384
  @keyframes abort-long-press-fill {
4250
4385
  to { transform: scaleX(1); }
@@ -4432,6 +4567,9 @@ button.composer-skill-tag:focus-visible {
4432
4567
  max-height: min(60vh, 24rem);
4433
4568
  padding-bottom: 0.38rem;
4434
4569
  overflow: auto;
4570
+ overflow-y: auto;
4571
+ overscroll-behavior: contain;
4572
+ -webkit-overflow-scrolling: touch;
4435
4573
  scrollbar-width: thin;
4436
4574
  }
4437
4575
  .composer-publish-menu:hover .composer-publish-menu-panel,
@@ -6264,7 +6402,10 @@ button.composer-skill-tag:focus-visible {
6264
6402
  body.side-panel-collapsed .terminal-tabs-shell { padding-right: calc(44px + 0.8rem); }
6265
6403
  .terminal-tabs-toggle-button {
6266
6404
  display: block;
6267
- width: min(14rem, calc(100vw - 8.8rem));
6405
+ flex: 1 1 auto;
6406
+ width: auto;
6407
+ min-width: 0;
6408
+ max-width: min(14rem, calc(100vw - 11.4rem));
6268
6409
  min-height: 28px;
6269
6410
  padding: 0.16rem 0.58rem;
6270
6411
  overflow: hidden;
@@ -6301,6 +6442,7 @@ button.composer-skill-tag:focus-visible {
6301
6442
  line-height: 1.1;
6302
6443
  }
6303
6444
  .terminal-tabs {
6445
+ position: absolute;
6304
6446
  left: 0.55rem;
6305
6447
  right: 0.55rem;
6306
6448
  top: calc(100% + 0.35rem);
@@ -6310,6 +6452,8 @@ button.composer-skill-tag:focus-visible {
6310
6452
  gap: 0.34rem;
6311
6453
  max-height: min(42dvh, 20rem);
6312
6454
  overflow: auto;
6455
+ overscroll-behavior: contain;
6456
+ -webkit-overflow-scrolling: touch;
6313
6457
  padding: 0.55rem;
6314
6458
  border: 1px solid rgba(148, 226, 213, 0.26);
6315
6459
  border-radius: 0.95rem;
@@ -6423,6 +6567,8 @@ button.composer-skill-tag:focus-visible {
6423
6567
  }
6424
6568
  .release-npm-meta,
6425
6569
  .release-npm-actions { justify-content: flex-start; }
6570
+ .btw-widget-composer { grid-template-columns: minmax(0, 1fr); }
6571
+ .btw-widget-send { width: 100%; }
6426
6572
  .release-npm-stream-header {
6427
6573
  padding: 0.3rem 0.42rem;
6428
6574
  font-size: 0.66rem;
@@ -6486,19 +6632,34 @@ button.composer-skill-tag:focus-visible {
6486
6632
  }
6487
6633
  .sticky-user-prompt-button {
6488
6634
  grid-template-columns: minmax(0, 1fr) auto;
6489
- margin: 0 0 0.5rem;
6490
- padding: 0.48rem 0.58rem;
6491
- gap: 0.48rem;
6635
+ min-height: 36px;
6636
+ margin: 0 0 0.32rem;
6637
+ padding: 0.32rem 0.46rem;
6638
+ gap: 0.32rem;
6639
+ border-radius: 0.72rem;
6492
6640
  }
6493
6641
  .sticky-user-prompt-label { display: none; }
6494
- .sticky-user-prompt-text { font-size: 0.78rem; }
6642
+ .sticky-user-prompt-text {
6643
+ font-size: 0.72rem;
6644
+ line-height: 1.2;
6645
+ }
6646
+ .sticky-user-prompt-meta {
6647
+ font-size: 0.64rem;
6648
+ line-height: 1.1;
6649
+ }
6495
6650
  .sticky-user-follow-up-prompt {
6496
6651
  grid-template-columns: minmax(0, 1fr);
6497
- gap: 0.2rem;
6498
- padding-top: 0.38rem;
6652
+ gap: 0.14rem;
6653
+ padding-top: 0.22rem;
6654
+ }
6655
+ .sticky-user-follow-up-label {
6656
+ font-size: 0.56rem;
6657
+ line-height: 1.1;
6658
+ }
6659
+ .sticky-user-follow-up-text {
6660
+ font-size: 0.66rem;
6661
+ line-height: 1.15;
6499
6662
  }
6500
- .sticky-user-follow-up-label { font-size: 0.62rem; }
6501
- .sticky-user-follow-up-text { font-size: 0.74rem; }
6502
6663
  .jump-to-latest-button {
6503
6664
  min-height: 44px;
6504
6665
  margin: 0.35rem auto;
@@ -6548,9 +6709,10 @@ button.composer-skill-tag:focus-visible {
6548
6709
  .statusbar {
6549
6710
  max-height: none;
6550
6711
  overflow: visible;
6551
- padding: 0.42rem 0.55rem;
6552
- font-size: 0.68rem;
6712
+ padding: 0.28rem 0.42rem;
6713
+ font-size: 0.64rem;
6553
6714
  }
6715
+ .context-meter-bar { display: none !important; }
6554
6716
  body.footer-details-expanded .statusbar {
6555
6717
  max-height: min(42dvh, 20rem);
6556
6718
  overflow: auto;
@@ -6578,7 +6740,7 @@ button.composer-skill-tag:focus-visible {
6578
6740
  position: fixed;
6579
6741
  left: max(0.55rem, env(safe-area-inset-left));
6580
6742
  right: max(0.55rem, env(safe-area-inset-right));
6581
- bottom: var(--footer-model-picker-bottom, calc(8.5rem + env(safe-area-inset-bottom)));
6743
+ bottom: var(--footer-model-picker-bottom, calc(7.2rem + env(safe-area-inset-bottom)));
6582
6744
  width: auto;
6583
6745
  max-height: min(52dvh, 24rem);
6584
6746
  z-index: 60;
@@ -6586,15 +6748,15 @@ button.composer-skill-tag:focus-visible {
6586
6748
  .footer-line-main {
6587
6749
  display: none;
6588
6750
  grid-template-columns: repeat(2, minmax(0, 1fr));
6589
- gap: 0.35rem;
6590
- margin-bottom: 0.35rem;
6751
+ gap: 0.26rem;
6752
+ margin-bottom: 0.26rem;
6591
6753
  }
6592
6754
  body.footer-details-expanded .footer-line-main { display: grid; }
6593
6755
  body.footer-details-expanded .footer-line-main .footer-metric { display: inline-grid; }
6594
6756
  .footer-line-meta {
6595
6757
  display: grid;
6596
6758
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr) auto;
6597
- gap: 0.35rem;
6759
+ gap: 0.26rem;
6598
6760
  align-items: stretch;
6599
6761
  }
6600
6762
  .footer-line-meta .footer-meta { display: none; }
@@ -6616,38 +6778,51 @@ button.composer-skill-tag:focus-visible {
6616
6778
  width: 100%;
6617
6779
  min-width: 0;
6618
6780
  }
6619
- .footer-metric { padding: 0.35rem 0.45rem; }
6781
+ .footer-metric,
6782
+ .footer-meta {
6783
+ min-height: 0;
6784
+ padding: 0.24rem 0.38rem;
6785
+ }
6620
6786
  .footer-details-toggle {
6621
6787
  display: block;
6622
- min-height: 44px;
6623
- padding: 0.35rem 0.62rem;
6788
+ min-height: 36px;
6789
+ padding: 0.24rem 0.5rem;
6624
6790
  color: var(--ctp-yellow);
6625
6791
  border-color: rgba(249, 226, 175, 0.34);
6626
- font-size: 0.72rem;
6792
+ font-size: 0.68rem;
6627
6793
  font-weight: 900;
6794
+ line-height: 1.1;
6628
6795
  }
6629
6796
  .composer {
6630
6797
  position: sticky;
6631
6798
  bottom: 0;
6632
6799
  z-index: 50;
6633
- padding: 0.55rem 0.55rem calc(0.55rem + env(safe-area-inset-bottom));
6800
+ padding: 0.38rem 0.42rem calc(0.38rem + env(safe-area-inset-bottom));
6634
6801
  background: linear-gradient(180deg, rgba(var(--ctp-crust-rgb), 0.92), rgba(var(--ctp-crust-rgb), 0.98));
6635
6802
  box-shadow: 0 -0.85rem 1.8rem rgba(var(--ctp-crust-rgb), 0.56), inset 0 1px 0 rgba(255,255,255,0.04);
6636
6803
  }
6804
+ .composer-input-row { gap: 0.36rem; }
6805
+ .composer-attach-button {
6806
+ width: 2.55rem;
6807
+ min-width: 2.55rem;
6808
+ min-height: 38px;
6809
+ padding: 0.44rem;
6810
+ border-radius: 0.72rem;
6811
+ }
6637
6812
  #promptInput {
6638
- min-height: calc(1.45em + 1.5rem);
6639
- max-height: min(28dvh, 12rem);
6640
- padding: 0.75rem;
6813
+ min-height: calc(1.35em + 1.05rem);
6814
+ max-height: min(24dvh, 10rem);
6815
+ padding: 0.52rem 0.62rem;
6641
6816
  resize: none;
6642
- font-size: 1rem;
6643
- line-height: 1.45;
6817
+ font-size: 0.95rem;
6818
+ line-height: 1.35;
6644
6819
  }
6645
6820
  .composer-row {
6646
6821
  display: grid;
6647
6822
  grid-template-columns: repeat(6, minmax(0, 1fr));
6648
- gap: 0.42rem;
6823
+ gap: 0.3rem;
6649
6824
  align-items: stretch;
6650
- margin-top: 0.55rem;
6825
+ margin-top: 0.38rem;
6651
6826
  }
6652
6827
  .composer-actions-button {
6653
6828
  display: block;
@@ -6669,15 +6844,15 @@ button.composer-skill-tag:focus-visible {
6669
6844
  scroll-padding-bottom: calc(7.5rem + var(--keyboard-inset-bottom, 0px));
6670
6845
  }
6671
6846
  body.mobile-keyboard-open .composer {
6672
- padding: 0.42rem 0.5rem calc(0.42rem + env(safe-area-inset-bottom));
6847
+ padding: 0.32rem 0.4rem calc(0.32rem + env(safe-area-inset-bottom));
6673
6848
  }
6674
6849
  body.mobile-keyboard-open #promptInput {
6675
- min-height: calc(1.45em + 1.5rem);
6676
- max-height: min(24dvh, 9rem);
6850
+ min-height: calc(1.35em + 1.05rem);
6851
+ max-height: min(22dvh, 8rem);
6677
6852
  }
6678
6853
  body.mobile-keyboard-open .composer-row {
6679
6854
  grid-template-columns: 1fr;
6680
- margin-top: 0.35rem;
6855
+ margin-top: 0.28rem;
6681
6856
  }
6682
6857
  body.mobile-keyboard-open .composer-actions-button,
6683
6858
  body.mobile-keyboard-open .composer-actions-panel {
@@ -6686,7 +6861,7 @@ button.composer-skill-tag:focus-visible {
6686
6861
  body.mobile-keyboard-open .composer-row button.primary,
6687
6862
  body.mobile-keyboard-open .composer-abort-button:not([hidden]) {
6688
6863
  grid-column: 1 / -1;
6689
- min-height: 44px;
6864
+ min-height: 40px;
6690
6865
  }
6691
6866
  .composer-actions-panel {
6692
6867
  position: absolute;
@@ -6720,17 +6895,18 @@ button.composer-skill-tag:focus-visible {
6720
6895
  .spacer { display: none; }
6721
6896
  .composer-row button {
6722
6897
  width: 100%;
6723
- min-height: 44px;
6898
+ min-height: 40px;
6724
6899
  margin-right: 0;
6725
- padding: 0.48rem 0.5rem;
6726
- font-size: 0.82rem;
6900
+ padding: 0.34rem 0.44rem;
6901
+ font-size: 0.78rem;
6727
6902
  }
6728
6903
  .composer-row button.primary {
6729
6904
  grid-column: 1 / -1;
6730
- min-height: 48px;
6731
- font-size: 0.92rem;
6905
+ min-height: 40px;
6906
+ font-size: 0.86rem;
6732
6907
  }
6733
- body:not(.pi-run-active):not(.mobile-keyboard-open) .composer-row button.primary { grid-column: span 4; }
6908
+ body:not(.pi-run-active):not(.mobile-keyboard-open) .composer-row button.primary { grid-column: span 2; }
6909
+ body:not(.pi-run-active):not(.mobile-keyboard-open) .composer-btw-button[hidden] + button.primary { grid-column: span 4; }
6734
6910
  body.pi-run-active:not(.mobile-keyboard-open) .composer-abort-button:not([hidden]) {
6735
6911
  order: 1;
6736
6912
  grid-column: span 2;
@@ -6738,12 +6914,21 @@ button.composer-skill-tag:focus-visible {
6738
6914
  body.pi-run-active:not(.mobile-keyboard-open) .composer-row > #steerButton { order: 2; }
6739
6915
  body.pi-run-active:not(.mobile-keyboard-open) .composer-row > #followUpButton { order: 3; }
6740
6916
  body.pi-run-active:not(.mobile-keyboard-open) .composer-actions-button { order: 4; }
6917
+ body.pi-run-active:not(.mobile-keyboard-open) .composer-btw-button:not([hidden]) {
6918
+ order: 5;
6919
+ grid-column: span 2;
6920
+ }
6741
6921
  body.pi-run-active:not(.mobile-keyboard-open) .composer-row button.primary {
6922
+ order: 6;
6923
+ grid-column: span 2;
6924
+ }
6925
+ body.pi-run-active:not(.mobile-keyboard-open) .composer-btw-button[hidden] + button.primary {
6742
6926
  order: 5;
6743
6927
  grid-column: span 4;
6744
6928
  }
6745
6929
  .composer-row > #followUpButton,
6746
6930
  .composer-row > #steerButton,
6931
+ .composer-row > #btwButton,
6747
6932
  .composer-actions-button { grid-column: span 2; }
6748
6933
  .composer-actions-panel > #followUpButton,
6749
6934
  .composer-actions-panel > #steerButton,
@@ -6783,18 +6968,17 @@ button.composer-skill-tag:focus-visible {
6783
6968
  width: 100%;
6784
6969
  min-width: 0;
6785
6970
  max-width: 100%;
6786
- max-height: min(34dvh, 18rem);
6971
+ max-height: min(var(--mobile-dropdown-max-height, 34dvh), calc(var(--visual-viewport-height, 100dvh) - 2rem));
6787
6972
  margin: 0;
6788
6973
  padding-bottom: 0;
6789
6974
  overflow: auto;
6975
+ overflow-y: auto;
6976
+ overscroll-behavior: contain;
6977
+ -webkit-overflow-scrolling: touch;
6790
6978
  }
6791
- .composer-actions-panel > .composer-options-menu .composer-publish-menu-panel {
6792
- inset-inline: auto 0;
6793
- max-height: min(calc(var(--visual-viewport-height, 100dvh) - 2rem), 44rem);
6794
- }
6979
+ .composer-actions-panel > .composer-options-menu .composer-publish-menu-panel,
6795
6980
  .composer-actions-panel > .composer-app-runner-menu .composer-publish-menu-panel {
6796
6981
  inset-inline: auto 0;
6797
- max-height: min(calc(var(--visual-viewport-height, 100dvh) - 2rem), 44rem);
6798
6982
  }
6799
6983
  .composer-actions-panel > .composer-publish-menu .composer-publish-menu-item {
6800
6984
  width: 100%;
@@ -7329,6 +7513,39 @@ button.composer-skill-tag:focus-visible {
7329
7513
  .command-palette-header > div {
7330
7514
  min-width: 0;
7331
7515
  }
7516
+ .command-palette-header-actions {
7517
+ display: inline-flex;
7518
+ flex: 0 0 auto;
7519
+ align-items: center;
7520
+ justify-content: flex-end;
7521
+ gap: 0.5rem;
7522
+ min-width: 0;
7523
+ }
7524
+ .command-palette-close-button {
7525
+ display: inline-flex;
7526
+ align-items: center;
7527
+ justify-content: center;
7528
+ min-width: 44px;
7529
+ min-height: 44px;
7530
+ padding: 0.42rem 0.74rem;
7531
+ border: 1px solid rgba(180, 190, 254, 0.22);
7532
+ border-radius: 999px;
7533
+ color: rgba(var(--ctp-subtext-rgb), 0.88);
7534
+ font-weight: 850;
7535
+ background:
7536
+ linear-gradient(180deg, rgba(var(--ctp-surface-rgb), 0.42), rgba(var(--ctp-crust-rgb), 0.58)),
7537
+ rgba(var(--ctp-crust-rgb), 0.58);
7538
+ box-shadow: 0 0 0 1px rgba(203, 166, 247, 0.04), 0 0.45rem 1rem rgba(var(--ctp-crust-rgb), 0.18);
7539
+ }
7540
+ .command-palette-close-button:hover,
7541
+ .command-palette-close-button:focus-visible {
7542
+ color: var(--ctp-text);
7543
+ border-color: rgba(148, 226, 213, 0.58);
7544
+ background:
7545
+ linear-gradient(120deg, rgba(148, 226, 213, 0.16), rgba(137, 180, 250, 0.12)),
7546
+ rgba(var(--ctp-surface-rgb), 0.62);
7547
+ box-shadow: 0 0 0 1px rgba(148, 226, 213, 0.16), 0 0 1rem rgba(148, 226, 213, 0.14);
7548
+ }
7332
7549
  .command-palette-shortcut {
7333
7550
  flex: 0 0 auto;
7334
7551
  max-width: 9rem;
@@ -7481,24 +7698,73 @@ button.composer-skill-tag:focus-visible {
7481
7698
  .context-meter-actions button { flex: 1 1 auto; }
7482
7699
  }
7483
7700
  @media (max-width: 720px) {
7484
- .terminal-command-palette-button { display: none; }
7701
+ .terminal-command-palette-button,
7702
+ .terminal-dashboard-button {
7703
+ display: inline-grid;
7704
+ width: 32px;
7705
+ min-width: 32px;
7706
+ min-height: 28px;
7707
+ border-radius: 0.58rem;
7708
+ }
7709
+ .terminal-command-palette-button .command-palette-launcher-icon,
7710
+ .terminal-dashboard-button .workspace-overview-icon {
7711
+ width: 1rem;
7712
+ height: 1rem;
7713
+ }
7485
7714
  .workspace-dashboard { padding: 0.62rem 0.7rem; }
7486
7715
  .workspace-dashboard-metrics { grid-template-columns: 1fr; }
7487
7716
  .command-palette-dialog {
7488
- inset: calc(0.5rem + env(safe-area-inset-top)) 0 auto 0;
7489
- width: min(100vw - 1rem, 42rem);
7490
- max-height: calc(var(--visual-viewport-height, 100dvh) - 1rem - env(safe-area-inset-top));
7717
+ inset: calc(0.38rem + env(safe-area-inset-top)) 0 auto 0;
7718
+ width: min(100vw - 0.5rem, 42rem);
7719
+ max-height: calc(var(--visual-viewport-height, 100dvh) - 0.76rem - env(safe-area-inset-top));
7491
7720
  margin-inline: auto;
7492
- border-radius: 1rem;
7721
+ border-radius: 0.9rem;
7722
+ }
7723
+ .command-palette-header {
7724
+ gap: 0.52rem;
7725
+ padding: 0.62rem 0.58rem 0.42rem;
7726
+ }
7727
+ .command-palette-header h2 { font-size: 0.92rem; }
7728
+ .command-palette-header-actions { gap: 0.38rem; }
7729
+ .command-palette-kicker,
7730
+ .command-palette-shortcut { font-size: 0.58rem; }
7731
+ .command-palette-shortcut {
7732
+ max-width: 5.8rem;
7733
+ padding: 0.12rem 0.38rem;
7734
+ }
7735
+ .command-palette-close-button {
7736
+ min-width: 54px;
7737
+ min-height: 44px;
7738
+ padding: 0.42rem 0.58rem;
7739
+ font-size: 0.72rem;
7493
7740
  }
7494
- .command-palette-header { padding: 0.85rem 0.85rem 0.62rem; }
7495
7741
  .command-palette-input {
7496
- width: calc(100% - 1.7rem);
7497
- margin-inline: 0.85rem;
7742
+ width: calc(100% - 1.16rem);
7743
+ min-height: 38px;
7744
+ margin: 0 0.58rem 0.46rem;
7745
+ padding: 0.62rem 0.68rem;
7746
+ font-size: 0.92rem;
7498
7747
  }
7499
- .command-palette-list { padding-inline: 0.85rem; }
7500
- .command-palette-item { grid-template-columns: 1fr; }
7501
- .command-palette-item-kind { grid-row: auto; }
7748
+ .command-palette-list {
7749
+ gap: 0.3rem;
7750
+ padding: 0 0.46rem 0.52rem;
7751
+ scrollbar-gutter: auto;
7752
+ }
7753
+ .command-palette-item {
7754
+ grid-template-columns: minmax(3.4rem, 0.26fr) minmax(0, 1fr);
7755
+ gap: 0.04rem 0.46rem;
7756
+ min-height: 2.72rem;
7757
+ padding: 0.42rem 0.5rem;
7758
+ border-radius: 0.68rem;
7759
+ line-height: 1.18;
7760
+ }
7761
+ .command-palette-item-kind {
7762
+ grid-row: 1 / span 2;
7763
+ font-size: 0.56rem;
7764
+ letter-spacing: 0.055em;
7765
+ }
7766
+ .command-palette-item-label { font-size: 0.82rem; }
7767
+ .command-palette-item-description { font-size: 0.6rem; }
7502
7768
  .message-edit-retry-button {
7503
7769
  top: 0.38rem;
7504
7770
  right: 2.8rem;
@@ -38,6 +38,7 @@ async function request(host, pathname, { method = "GET", body, timeoutMs = 5_000
38
38
  }
39
39
 
40
40
  const cwd = await mkdtemp(path.join(tmpdir(), "pi-webui-http-harness-"));
41
+ const settingsFile = path.join(cwd, "webui-settings.json");
41
42
  await chmod(fakePi, 0o755);
42
43
 
43
44
  const child = spawn(process.execPath, [serverScript, "--cwd", cwd, "--host", "0.0.0.0", "--port", String(port), "--pi", fakePi], {
@@ -48,6 +49,7 @@ const child = spawn(process.execPath, [serverScript, "--cwd", cwd, "--host", "0.
48
49
  GIT_AUTHOR_EMAIL: "pi-webui-test@example.invalid",
49
50
  GIT_COMMITTER_NAME: "Pi WebUI Test",
50
51
  GIT_COMMITTER_EMAIL: "pi-webui-test@example.invalid",
52
+ PI_WEBUI_SETTINGS_FILE: settingsFile,
51
53
  },
52
54
  });
53
55
  let serverOutput = "";