@firstpick/pi-package-webui 0.1.0 → 0.1.1

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.
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Pi Web UI">
2
+ <rect width="64" height="64" rx="14" fill="#11111b"/>
3
+ <rect x="5" y="5" width="54" height="54" rx="12" fill="#1e1e2e" stroke="#89b4fa" stroke-width="3"/>
4
+ <path d="M17 20h31" fill="none" stroke="#f5c2e7" stroke-width="8" stroke-linecap="round"/>
5
+ <path d="M24 21v27" fill="none" stroke="#94e2d5" stroke-width="8" stroke-linecap="round"/>
6
+ <path d="M43 21v27" fill="none" stroke="#94e2d5" stroke-width="8" stroke-linecap="round"/>
7
+ <path d="M17 48h10" fill="none" stroke="#cba6f7" stroke-width="6" stroke-linecap="round" opacity="0.95"/>
8
+ </svg>
package/public/index.html CHANGED
@@ -4,6 +4,7 @@
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>Pi Web UI</title>
7
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
8
  <link rel="stylesheet" href="/styles.css" />
8
9
  </head>
9
10
  <body>
@@ -16,6 +17,10 @@
16
17
 
17
18
  <main class="layout">
18
19
  <section class="chat-panel">
20
+ <header class="terminal-tabs-shell">
21
+ <div id="tabBar" class="terminal-tabs" role="tablist" aria-label="Pi terminal tabs"></div>
22
+ <button id="newTabButton" class="terminal-new-tab-button" type="button" title="Start a separate isolated Pi terminal">+ Tab</button>
23
+ </header>
19
24
  <div id="widgetArea" class="widget-area"></div>
20
25
  <div id="chat" class="chat" aria-live="polite"></div>
21
26
  <div id="statusBar" class="statusbar" aria-live="polite"></div>
@@ -95,6 +100,11 @@
95
100
  </select>
96
101
  <button id="setThinkingButton" type="button">Set thinking</button>
97
102
  </div>
103
+ <div class="control-field network-control-field">
104
+ <label>Network</label>
105
+ <div id="networkStatus" class="network-status closed">Local only</div>
106
+ <button id="openNetworkButton" type="button">Open to network</button>
107
+ </div>
98
108
  <button id="abortButton" type="button" class="danger">Abort</button>
99
109
  </div>
100
110
  <h2>Session</h2>
@@ -118,6 +128,24 @@
118
128
  </form>
119
129
  </dialog>
120
130
 
131
+ <dialog id="pathPickerDialog" class="extension-dialog path-picker-dialog">
132
+ <form method="dialog">
133
+ <h2 id="pathPickerTitle">Choose working directory</h2>
134
+ <div class="path-picker-current-row">
135
+ <p id="pathPickerCurrent" class="path-picker-current"></p>
136
+ <button id="pathPickerAddFastPickButton" type="button" class="path-picker-add-fast-pick">Add fast pick</button>
137
+ </div>
138
+ <div id="pathPickerFastPicks" class="path-picker-fast-picks" aria-label="Fast picks"></div>
139
+ <div id="pathPickerRoots" class="path-picker-roots"></div>
140
+ <div id="pathPickerList" class="path-picker-list" role="listbox" aria-label="Directories"></div>
141
+ <p id="pathPickerError" class="path-picker-error" hidden></p>
142
+ <menu>
143
+ <button id="pathPickerCancelButton" type="button">Cancel</button>
144
+ <button id="pathPickerChooseButton" type="button" class="primary">Use this directory</button>
145
+ </menu>
146
+ </form>
147
+ </dialog>
148
+
121
149
  <script type="module" src="/app.js"></script>
122
150
  </body>
123
151
  </html>
package/public/styles.css CHANGED
@@ -287,6 +287,9 @@ body.side-panel-collapsed .side-panel {
287
287
  body.side-panel-collapsed .side-panel-expand-button {
288
288
  display: grid;
289
289
  }
290
+ body.side-panel-collapsed .terminal-tabs-shell {
291
+ padding-right: 4.35rem;
292
+ }
290
293
  .side-panel-button-icon {
291
294
  position: relative;
292
295
  z-index: 1;
@@ -456,10 +459,161 @@ body.side-panel-collapsed .side-panel-expand-button {
456
459
  width: 100%;
457
460
  min-width: 0;
458
461
  }
462
+ .network-status {
463
+ min-width: 0;
464
+ padding: 0.58rem 0.68rem;
465
+ overflow: hidden;
466
+ color: rgba(205, 214, 244, 0.88);
467
+ text-overflow: ellipsis;
468
+ white-space: nowrap;
469
+ border: 1px solid rgba(180, 190, 254, 0.16);
470
+ border-radius: 0.72rem;
471
+ background: rgba(17, 17, 27, 0.62);
472
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
473
+ font-size: 0.78rem;
474
+ font-weight: 800;
475
+ }
476
+ .network-status.open {
477
+ color: var(--ctp-yellow);
478
+ border-color: rgba(249, 226, 175, 0.34);
479
+ box-shadow: 0 0 0.9rem rgba(249, 226, 175, 0.10);
480
+ }
481
+ .network-status.opening {
482
+ color: var(--ctp-teal);
483
+ border-color: rgba(148, 226, 213, 0.34);
484
+ }
485
+ .network-status.closed {
486
+ color: rgba(186, 194, 222, 0.72);
487
+ }
488
+ #openNetworkButton {
489
+ color: var(--ctp-yellow);
490
+ border-color: rgba(249, 226, 175, 0.32);
491
+ }
492
+ #openNetworkButton:not(:disabled):hover {
493
+ color: #11111b;
494
+ border-color: transparent;
495
+ background: linear-gradient(120deg, var(--ctp-yellow), var(--ctp-peach), var(--ctp-red));
496
+ }
459
497
  .side-panel-controls .danger {
460
498
  margin-top: 0.15rem;
461
499
  }
462
500
 
501
+ .terminal-tabs-shell {
502
+ flex: 0 0 auto;
503
+ display: flex;
504
+ align-items: center;
505
+ gap: 0.55rem;
506
+ min-width: 0;
507
+ padding: 0.62rem 0.78rem;
508
+ border-bottom: 1px solid rgba(180, 190, 254, 0.16);
509
+ background:
510
+ linear-gradient(90deg, rgba(17, 17, 27, 0.96), rgba(30, 30, 46, 0.82), rgba(24, 24, 37, 0.92)),
511
+ radial-gradient(circle at 0% 0%, rgba(245, 194, 231, 0.12), transparent 18rem);
512
+ box-shadow: inset 0 -1px 0 rgba(255,255,255,0.035), 0 0.45rem 1rem rgba(17, 17, 27, 0.20);
513
+ }
514
+ .terminal-tabs {
515
+ display: flex;
516
+ align-items: center;
517
+ gap: 0.45rem;
518
+ min-width: 0;
519
+ flex: 1 1 auto;
520
+ overflow-x: auto;
521
+ scrollbar-width: thin;
522
+ }
523
+ .terminal-tab {
524
+ display: inline-flex;
525
+ align-items: stretch;
526
+ min-width: 9rem;
527
+ max-width: 16rem;
528
+ border: 1px solid rgba(180, 190, 254, 0.16);
529
+ border-radius: 0.82rem;
530
+ overflow: hidden;
531
+ background: rgba(17, 17, 27, 0.54);
532
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.035);
533
+ }
534
+ .terminal-tab.active {
535
+ border-color: rgba(148, 226, 213, 0.54);
536
+ background:
537
+ linear-gradient(120deg, rgba(148, 226, 213, 0.17), rgba(203, 166, 247, 0.12)),
538
+ rgba(17, 17, 27, 0.60);
539
+ box-shadow: 0 0 1rem rgba(148, 226, 213, 0.18), inset 0 1px 0 rgba(255,255,255,0.05);
540
+ }
541
+ .terminal-tab.stopped {
542
+ opacity: 0.72;
543
+ border-color: rgba(243, 139, 168, 0.28);
544
+ }
545
+ .terminal-tab-button,
546
+ .terminal-tab-close,
547
+ .terminal-new-tab-button {
548
+ min-height: 2.35rem;
549
+ border: 0;
550
+ border-radius: 0;
551
+ background: transparent;
552
+ box-shadow: none;
553
+ }
554
+ .terminal-tab-button {
555
+ display: grid;
556
+ grid-template-columns: minmax(0, 1fr);
557
+ gap: 0.1rem;
558
+ min-width: 0;
559
+ flex: 1 1 auto;
560
+ padding: 0.38rem 0.66rem;
561
+ text-align: left;
562
+ }
563
+ .terminal-tab-button:hover,
564
+ .terminal-tab-close:hover,
565
+ .terminal-new-tab-button:hover {
566
+ transform: none;
567
+ }
568
+ .terminal-tab-title,
569
+ .terminal-tab-meta {
570
+ min-width: 0;
571
+ overflow: hidden;
572
+ text-overflow: ellipsis;
573
+ white-space: nowrap;
574
+ }
575
+ .terminal-tab-title {
576
+ color: var(--ctp-text);
577
+ font-size: 0.84rem;
578
+ font-weight: 900;
579
+ letter-spacing: 0.03em;
580
+ }
581
+ .terminal-tab-meta {
582
+ color: rgba(186, 194, 222, 0.62);
583
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
584
+ font-size: 0.68rem;
585
+ }
586
+ .terminal-tab.active .terminal-tab-title {
587
+ color: var(--ctp-teal);
588
+ text-shadow: 0 0 0.8rem var(--glow-teal);
589
+ }
590
+ .terminal-tab-close {
591
+ flex: 0 0 2.1rem;
592
+ color: rgba(186, 194, 222, 0.72);
593
+ border-left: 1px solid rgba(180, 190, 254, 0.10);
594
+ font-size: 1.2rem;
595
+ line-height: 1;
596
+ }
597
+ .terminal-tab-close:hover {
598
+ color: #11111b;
599
+ background: linear-gradient(120deg, var(--ctp-red), var(--ctp-peach));
600
+ }
601
+ .terminal-new-tab-button {
602
+ flex: 0 0 auto;
603
+ padding: 0.45rem 0.72rem;
604
+ color: var(--ctp-pink);
605
+ border: 1px solid rgba(245, 194, 231, 0.30);
606
+ border-radius: 0.78rem;
607
+ background:
608
+ linear-gradient(120deg, rgba(245, 194, 231, 0.12), rgba(137, 180, 250, 0.08)),
609
+ rgba(17, 17, 27, 0.58);
610
+ }
611
+ .terminal-new-tab-button:hover {
612
+ color: #11111b;
613
+ border-color: transparent;
614
+ background: linear-gradient(120deg, var(--ctp-pink), var(--ctp-mauve), var(--ctp-blue));
615
+ }
616
+
463
617
  .widget-area {
464
618
  flex: 0 0 auto;
465
619
  border-bottom: 1px solid rgba(180, 190, 254, 0.16);
@@ -568,6 +722,25 @@ body.side-panel-collapsed .side-panel-expand-button {
568
722
  padding: 0.28rem 0.52rem;
569
723
  border-radius: 0.7rem;
570
724
  }
725
+ button.footer-meta {
726
+ appearance: none;
727
+ color: inherit;
728
+ font: inherit;
729
+ text-align: left;
730
+ cursor: pointer;
731
+ }
732
+ .footer-meta-action {
733
+ transition: border-color 140ms ease, box-shadow 140ms ease, transform 140ms ease;
734
+ }
735
+ .footer-meta-action:hover,
736
+ .footer-meta-action:focus-visible {
737
+ border-color: rgba(166, 227, 161, 0.46);
738
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.055), 0 0 1rem rgba(166, 227, 161, 0.16);
739
+ outline: none;
740
+ }
741
+ .footer-workspace.footer-meta-action .footer-meta-value {
742
+ color: var(--ctp-green);
743
+ }
571
744
  .footer-model .footer-meta-value {
572
745
  color: var(--ctp-teal);
573
746
  text-shadow: 0 0 0.6rem rgba(148, 226, 213, 0.22);
@@ -1092,6 +1265,145 @@ summary { cursor: pointer; color: var(--warning); }
1092
1265
  .dialog-input { width: 100%; padding: 0.7rem; }
1093
1266
  .dialog-editor { width: 100%; min-height: 12rem; padding: 0.7rem; }
1094
1267
 
1268
+ .path-picker-dialog {
1269
+ width: min(48rem, calc(100vw - 2rem));
1270
+ }
1271
+ .path-picker-current-row {
1272
+ display: grid;
1273
+ grid-template-columns: minmax(0, 1fr) auto;
1274
+ gap: 0.55rem;
1275
+ align-items: stretch;
1276
+ }
1277
+ .path-picker-current {
1278
+ min-width: 0;
1279
+ margin: 0;
1280
+ padding: 0.72rem 0.82rem;
1281
+ overflow-wrap: anywhere;
1282
+ border: 1px solid rgba(166, 227, 161, 0.24);
1283
+ border-radius: 0.82rem;
1284
+ background: rgba(17, 17, 27, 0.64);
1285
+ color: var(--ctp-green);
1286
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
1287
+ font-weight: 850;
1288
+ }
1289
+ .path-picker-add-fast-pick {
1290
+ align-self: stretch;
1291
+ padding: 0.52rem 0.72rem;
1292
+ color: var(--ctp-yellow);
1293
+ border-color: rgba(249, 226, 175, 0.32);
1294
+ }
1295
+ .path-picker-add-fast-pick:disabled {
1296
+ cursor: default;
1297
+ opacity: 0.62;
1298
+ }
1299
+ .path-picker-fast-picks {
1300
+ display: grid;
1301
+ grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
1302
+ gap: 0.42rem;
1303
+ margin: 0.72rem 0 0;
1304
+ padding: 0.5rem;
1305
+ border: 1px solid rgba(249, 226, 175, 0.14);
1306
+ border-radius: 0.82rem;
1307
+ background: rgba(17, 17, 27, 0.34);
1308
+ }
1309
+ .path-picker-fast-pick {
1310
+ display: grid;
1311
+ grid-template-columns: minmax(0, 1fr) 1.45rem;
1312
+ overflow: hidden;
1313
+ min-width: 0;
1314
+ width: 100%;
1315
+ border: 1px solid rgba(249, 226, 175, 0.22);
1316
+ border-radius: 0.72rem;
1317
+ background: rgba(49, 50, 68, 0.36);
1318
+ }
1319
+ .path-picker-fast-pick-button,
1320
+ .path-picker-fast-pick-remove {
1321
+ min-height: 2rem;
1322
+ border: 0;
1323
+ border-radius: 0;
1324
+ background: transparent;
1325
+ box-shadow: none;
1326
+ }
1327
+ .path-picker-fast-pick-button {
1328
+ min-width: 0;
1329
+ padding: 0.42rem 0.58rem;
1330
+ overflow: hidden;
1331
+ color: var(--ctp-yellow);
1332
+ text-align: left;
1333
+ text-overflow: ellipsis;
1334
+ white-space: nowrap;
1335
+ }
1336
+ .path-picker-fast-pick-remove {
1337
+ min-width: 1.45rem;
1338
+ width: 1.45rem;
1339
+ padding: 0;
1340
+ color: rgba(186, 194, 222, 0.72);
1341
+ border-left: 1px solid rgba(249, 226, 175, 0.14);
1342
+ font-size: 0.78rem;
1343
+ }
1344
+ .path-picker-fast-pick-button:hover,
1345
+ .path-picker-fast-pick-button:focus-visible {
1346
+ color: #11111b;
1347
+ background: linear-gradient(120deg, var(--ctp-yellow), var(--ctp-peach));
1348
+ }
1349
+ .path-picker-fast-pick-remove:hover,
1350
+ .path-picker-fast-pick-remove:focus-visible {
1351
+ color: #11111b;
1352
+ background: linear-gradient(120deg, var(--ctp-red), var(--ctp-peach));
1353
+ }
1354
+ .path-picker-fast-picks-empty {
1355
+ grid-column: 1 / -1;
1356
+ padding: 0.15rem 0.25rem;
1357
+ }
1358
+ .path-picker-roots {
1359
+ display: flex;
1360
+ flex-wrap: wrap;
1361
+ gap: 0.45rem;
1362
+ margin: 0.72rem 0;
1363
+ }
1364
+ .path-picker-root-button {
1365
+ padding: 0.42rem 0.66rem;
1366
+ color: var(--ctp-teal);
1367
+ border-color: rgba(148, 226, 213, 0.30);
1368
+ }
1369
+ .path-picker-list {
1370
+ display: grid;
1371
+ gap: 0.4rem;
1372
+ max-height: min(24rem, 46vh);
1373
+ overflow: auto;
1374
+ padding: 0.4rem;
1375
+ border: 1px solid rgba(180, 190, 254, 0.16);
1376
+ border-radius: 0.82rem;
1377
+ background: rgba(17, 17, 27, 0.48);
1378
+ }
1379
+ .path-picker-directory {
1380
+ justify-content: flex-start;
1381
+ width: 100%;
1382
+ padding: 0.58rem 0.72rem;
1383
+ color: rgba(205, 214, 244, 0.94);
1384
+ text-align: left;
1385
+ border-color: rgba(180, 190, 254, 0.14);
1386
+ background: rgba(49, 50, 68, 0.36);
1387
+ }
1388
+ .path-picker-directory:hover,
1389
+ .path-picker-directory:focus-visible,
1390
+ .path-picker-root-button:hover,
1391
+ .path-picker-root-button:focus-visible {
1392
+ color: #11111b;
1393
+ border-color: transparent;
1394
+ background: linear-gradient(120deg, var(--ctp-green), var(--ctp-teal), var(--ctp-blue));
1395
+ }
1396
+ .path-picker-directory.hidden-directory {
1397
+ color: rgba(186, 194, 222, 0.68);
1398
+ }
1399
+ .path-picker-empty,
1400
+ .path-picker-error {
1401
+ padding: 0.62rem 0.72rem;
1402
+ }
1403
+ .path-picker-error {
1404
+ color: var(--danger);
1405
+ }
1406
+
1095
1407
  ::-webkit-scrollbar { width: 0.75rem; height: 0.75rem; }
1096
1408
  ::-webkit-scrollbar-track { background: rgba(17, 17, 27, 0.55); }
1097
1409
  ::-webkit-scrollbar-thumb {
@@ -1114,6 +1426,11 @@ summary { cursor: pointer; color: var(--warning); }
1114
1426
 
1115
1427
  @media (max-width: 720px) {
1116
1428
  .layout { padding: 0.65rem; }
1429
+ .terminal-tabs-shell { align-items: stretch; flex-direction: column; }
1430
+ body.side-panel-collapsed .terminal-tabs-shell { padding-right: 4.2rem; }
1431
+ .terminal-new-tab-button { width: 100%; }
1432
+ .path-picker-current-row { grid-template-columns: 1fr; }
1433
+ .path-picker-add-fast-pick { width: 100%; }
1117
1434
  .statusbar { padding: 0.68rem; }
1118
1435
  .footer-line-main,
1119
1436
  .footer-line-meta { grid-template-columns: 1fr; }