pi-sdk-web 0.4.4 → 0.4.5

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/dist/server.js CHANGED
@@ -411,6 +411,11 @@ export class PiWebServer {
411
411
  case "abort":
412
412
  await this.session.abort();
413
413
  break;
414
+ case "abort_bash":
415
+ // Kill only the running bash (TUI Ctrl+C equivalent), leaving any
416
+ // agent activity untouched.
417
+ this.session.abortBash();
418
+ break;
414
419
  case "get_stats":
415
420
  this.broadcastStats();
416
421
  break;
@@ -1331,6 +1331,30 @@ class PiWebClient {
1331
1331
  if (!div) {
1332
1332
  div = this.createToolBlock('bash', { command: this.pendingBashCommand || '' }, key);
1333
1333
  div.className = 'tool-block pending';
1334
+ // Stop button in the title row (TUI Ctrl+C equivalent): abort_bash
1335
+ // kills only this running bash. Removed when the block finalizes.
1336
+ const stopBtn = document.createElement('button');
1337
+ stopBtn.className = 'bash-stop-btn';
1338
+ stopBtn.textContent = '⏹ stop';
1339
+ stopBtn.title = 'Stop this bash command (Ctrl+C in TUI)';
1340
+ stopBtn.addEventListener('click', (e) => {
1341
+ e.stopPropagation(); // don't toggle expand
1342
+ this.send({ type: 'abort_bash' });
1343
+ stopBtn.disabled = true;
1344
+ stopBtn.textContent = 'stopping...';
1345
+ });
1346
+ div.querySelector('.tool-title')?.appendChild(stopBtn);
1347
+ // The running bash block lives in the #bash-pending area (between the
1348
+ // message flow and the input box) so later messages don't push it
1349
+ // out of view - same as TUI's pendingMessagesContainer. bash_result
1350
+ // moves it into the normal message flow when done.
1351
+ const bashPending = document.getElementById('bash-pending');
1352
+ if (bashPending) {
1353
+ bashPending.appendChild(div);
1354
+ bashPending.style.display = 'block';
1355
+ } else {
1356
+ this.contentEl.appendChild(div);
1357
+ }
1334
1358
  this.bashEls.set(key, div);
1335
1359
  }
1336
1360
  // Append the delta to the full text and re-apply the preview (respects
@@ -1355,6 +1379,18 @@ class PiWebClient {
1355
1379
  if (!(div.dataset.fullOutput && div.dataset.fullOutput.length > 0)) {
1356
1380
  this.setToolOutput(div, output);
1357
1381
  }
1382
+ // Move the finished block from the bash-pending (fixed) area into the
1383
+ // normal message flow, keeping its accumulated output.
1384
+ const bashPending = document.getElementById('bash-pending');
1385
+ if (bashPending && bashPending.contains(div)) {
1386
+ this.contentEl.appendChild(div);
1387
+ if (bashPending.children.length === 0) {
1388
+ bashPending.style.display = 'none';
1389
+ }
1390
+ this.scrollToBottom();
1391
+ }
1392
+ // Bash done: the stop button is no longer relevant.
1393
+ div.querySelector('.bash-stop-btn')?.remove();
1358
1394
 
1359
1395
  const isError = result.exitCode !== undefined && result.exitCode !== 0;
1360
1396
  div.className = isError ? 'tool-block error' : 'tool-block success';
@@ -31,6 +31,7 @@
31
31
  </div>
32
32
  </div>
33
33
  <div id="pending"></div>
34
+ <div id="bash-pending" style="display:none"></div>
34
35
  <div id="widgets"></div>
35
36
  <div id="status"></div>
36
37
  <div id="footer">
@@ -544,6 +544,40 @@ body {
544
544
  font-size: 12px;
545
545
  }
546
546
 
547
+ /* Running !/!! bash output (streaming) - fixed area between messages and
548
+ input, so later messages don't push it out of view (TUI analog:
549
+ pendingMessagesContainer). Moved into the message flow on completion. */
550
+ #bash-pending {
551
+ display: none;
552
+ padding: 4px 12px;
553
+ border-top: 1px solid var(--border);
554
+ font-size: 13px;
555
+ /* ~10 lines of output visible; scrolling inside the block for more */
556
+ max-height: calc(10 * 1.5em);
557
+ overflow-y: auto;
558
+ }
559
+
560
+ .bash-stop-btn {
561
+ margin-left: 8px;
562
+ padding: 1px 8px;
563
+ font-size: 11px;
564
+ color: var(--error);
565
+ border: 1px solid var(--error);
566
+ border-radius: 4px;
567
+ background: transparent;
568
+ cursor: pointer;
569
+ vertical-align: middle;
570
+ }
571
+
572
+ .bash-stop-btn:hover {
573
+ background: color-mix(in srgb, var(--error) 15%, transparent);
574
+ }
575
+
576
+ .bash-stop-btn:disabled {
577
+ opacity: 0.6;
578
+ cursor: default;
579
+ }
580
+
547
581
  .widget-block {
548
582
  margin: 2px 0;
549
583
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-sdk-web",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "Browser Web access for Pi (AI coding agent) via the Pi SDK - standalone module, zero modification to Pi itself",
5
5
  "type": "module",
6
6
  "bin": {