pi-sdk-web 0.4.3 → 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 +5 -0
- package/dist/static/app.js +36 -0
- package/dist/static/index.html +1 -0
- package/dist/static/style.css +34 -0
- package/dist/ui-context.js +24 -0
- package/package.json +1 -1
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;
|
package/dist/static/app.js
CHANGED
|
@@ -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';
|
package/dist/static/index.html
CHANGED
package/dist/static/style.css
CHANGED
|
@@ -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/dist/ui-context.js
CHANGED
|
@@ -68,6 +68,30 @@ export class WebUIContext {
|
|
|
68
68
|
statusMap = new Map();
|
|
69
69
|
constructor(sink) {
|
|
70
70
|
this.sink = sink;
|
|
71
|
+
// Pi's ExtensionRunner wraps the ui context with `{...ui}` (a shallow
|
|
72
|
+
// spread) when building the extension ctx - class prototype members
|
|
73
|
+
// (methods AND the theme getter) would be LOST by that spread (only own
|
|
74
|
+
// enumerable properties survive). Copy prototype methods onto the
|
|
75
|
+
// instance as own bound properties, and expose theme as an own
|
|
76
|
+
// property, so extensions see the same shape as TUI's object-literal
|
|
77
|
+
// UIContext (all methods + theme as own props).
|
|
78
|
+
const proto = Object.getPrototypeOf(this);
|
|
79
|
+
for (const name of Object.getOwnPropertyNames(proto)) {
|
|
80
|
+
if (name === "constructor")
|
|
81
|
+
continue;
|
|
82
|
+
const desc = Object.getOwnPropertyDescriptor(proto, name);
|
|
83
|
+
if (desc && typeof desc.value === "function") {
|
|
84
|
+
this[name] = desc.value.bind(this);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Theme: the prototype getter is not picked up by `{...}` and the own
|
|
88
|
+
// property cannot shadow a getter-only prototype via assignment. Define
|
|
89
|
+
// an own enumerable getter returning webTheme (fresh after setWebTheme).
|
|
90
|
+
Object.defineProperty(this, "theme", {
|
|
91
|
+
configurable: true,
|
|
92
|
+
enumerable: true,
|
|
93
|
+
get: () => this.webTheme,
|
|
94
|
+
});
|
|
71
95
|
}
|
|
72
96
|
/** Current extension status snapshot (key -> text) for new connections. */
|
|
73
97
|
getStatusSnapshot() {
|