@pi-unipi/btw 2.6.1 → 2.6.2

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.
Files changed (2) hide show
  1. package/extensions/btw.ts +18 -45
  2. package/package.json +7 -3
package/extensions/btw.ts CHANGED
@@ -606,9 +606,8 @@ function applyAssistantMessageToTranscript(
606
606
  message: AssistantMessage,
607
607
  streaming: boolean,
608
608
  ): void {
609
- const assistantMessage = message;
610
- const thinking = extractThinking(assistantMessage);
611
- const answer = extractMessageText(assistantMessage);
609
+ const thinking = extractThinking(message);
610
+ const answer = extractMessageText(message);
612
611
 
613
612
  if (thinking) {
614
613
  upsertTranscriptTextEntry(state, turnId, "thinking", thinking, streaming);
@@ -972,11 +971,6 @@ function getOverlayTitle(mode: BtwThreadMode): string {
972
971
 
973
972
  class BtwOverlayComponent extends Container implements Focusable {
974
973
  private readonly input: Input;
975
- private readonly transcript: Container;
976
- private readonly statusText: Text;
977
- private readonly modeText: Text;
978
- private readonly summaryText: Text;
979
- private readonly hintsText: Text;
980
974
  private readonly readTranscriptEntries: () => BtwTranscript;
981
975
  private readonly getStatus: () => string | null;
982
976
  private readonly getMode: () => BtwThreadMode;
@@ -1025,11 +1019,6 @@ class BtwOverlayComponent extends Container implements Focusable {
1025
1019
  this.onDismissCallback = onDismiss;
1026
1020
  this.onUnfocusCallback = onUnfocus;
1027
1021
 
1028
- this.modeText = new Text("", 1, 0);
1029
- this.summaryText = new Text("", 1, 0);
1030
- this.transcript = new Container();
1031
- this.statusText = new Text("", 1, 0);
1032
-
1033
1022
  this.input = new Input();
1034
1023
  this.input.onSubmit = (value) => {
1035
1024
  this.followTranscript = true;
@@ -1039,8 +1028,6 @@ class BtwOverlayComponent extends Container implements Focusable {
1039
1028
  this.onDismissCallback();
1040
1029
  };
1041
1030
 
1042
- this.hintsText = new Text("", 1, 0);
1043
-
1044
1031
  const originalHandleInput = this.input.handleInput.bind(this.input);
1045
1032
  this.input.handleInput = (data: string) => {
1046
1033
  if (keybindings.matches(data, "tui.select.cancel")) {
@@ -1092,14 +1079,14 @@ class BtwOverlayComponent extends Container implements Focusable {
1092
1079
  return;
1093
1080
  }
1094
1081
 
1095
- if (matchesKey(data, Key.pageUp)) {
1082
+ if (matchesKey(data, Key.pageUp) || matchesKey(data, Key.ctrl("pageUp")) || matchesKey(data, Key.alt("pageUp"))) {
1096
1083
  this.followTranscript = false;
1097
1084
  this.transcriptScrollOffset = Math.max(0, this.transcriptScrollOffset - Math.max(1, this.transcriptViewportHeight - 1));
1098
1085
  this.tui.requestRender();
1099
1086
  return;
1100
1087
  }
1101
1088
 
1102
- if (matchesKey(data, Key.pageDown)) {
1089
+ if (matchesKey(data, Key.pageDown) || matchesKey(data, Key.ctrl("pageDown")) || matchesKey(data, Key.alt("pageDown"))) {
1103
1090
  this.transcriptScrollOffset += Math.max(1, this.transcriptViewportHeight - 1);
1104
1091
  this.tui.requestRender();
1105
1092
  return;
@@ -1182,30 +1169,18 @@ class BtwOverlayComponent extends Container implements Focusable {
1182
1169
  return this.input.getValue();
1183
1170
  }
1184
1171
 
1185
- getTranscriptEntries(): BtwTranscript {
1186
- return this.readTranscriptEntries().map((entry) => ({ ...entry }));
1187
- }
1188
-
1189
1172
  refresh(): void {
1190
1173
  this.modeTextValue = `${getOverlayTitle(this.getMode())} · hidden thread preserved`;
1191
- this.modeText.setText(this.modeTextValue);
1192
1174
  const entries = this.readTranscriptEntries();
1193
1175
  const exchanges = getCompletedExchangeCount(entries);
1194
1176
  const active = hasStreamingTranscriptEntry(entries) ? " · streaming" : " · idle";
1195
1177
  this.summaryTextValue = `${exchanges} exchange${exchanges === 1 ? "" : "s"}${active}`;
1196
- this.summaryText.setText(this.summaryTextValue);
1197
1178
 
1198
1179
  this.transcriptLines = buildOverlayTranscript(entries, this.theme);
1199
- this.transcript.clear();
1200
- for (const line of this.transcriptLines) {
1201
- this.transcript.addChild(new Text(line, 1, 0));
1202
- }
1203
1180
 
1204
1181
  const status = this.getStatus() ?? "Ready. Enter submits; Escape dismisses without clearing.";
1205
1182
  this.statusTextValue = status;
1206
- this.statusText.setText(this.statusTextValue);
1207
- this.hintsTextValue = "Enter submit · Alt+/ toggle focus · Escape dismiss · PgUp/PgDn scroll";
1208
- this.hintsText.setText(this.hintsTextValue);
1183
+ this.hintsTextValue = "Enter submit · Alt+/ toggle focus · Escape dismiss · PgUp/Ctrl+PgUp scroll up · PgDn/Ctrl+PgDn scroll down";
1209
1184
  this.tui.requestRender();
1210
1185
  }
1211
1186
  }
@@ -1498,7 +1473,7 @@ export default function (pi: ExtensionAPI) {
1498
1473
  });
1499
1474
  }
1500
1475
 
1501
- async function dispatchBtwCommand(name: string, args: string, ctx: ExtensionCommandContext): Promise<boolean> {
1476
+ async function dispatchBtwCommand(name: string, args: string, ctx: ExtensionCommandContext): Promise<void> {
1502
1477
  const trimmedArgs = args.trim();
1503
1478
 
1504
1479
  if (name === "btw") {
@@ -1506,7 +1481,7 @@ export default function (pi: ExtensionAPI) {
1506
1481
  if (!question) {
1507
1482
  await ensureBtwSession(ctx, pendingMode);
1508
1483
  await ensureOverlay(ctx);
1509
- return true;
1484
+ return;
1510
1485
  }
1511
1486
 
1512
1487
  if (pendingMode !== "contextual") {
@@ -1514,7 +1489,7 @@ export default function (pi: ExtensionAPI) {
1514
1489
  }
1515
1490
 
1516
1491
  await runBtw(ctx, question, save, "contextual");
1517
- return true;
1492
+ return;
1518
1493
  }
1519
1494
 
1520
1495
  if (name === "btw:tangent") {
@@ -1526,11 +1501,11 @@ export default function (pi: ExtensionAPI) {
1526
1501
  if (!question) {
1527
1502
  await ensureBtwSession(ctx, "tangent");
1528
1503
  await ensureOverlay(ctx);
1529
- return true;
1504
+ return;
1530
1505
  }
1531
1506
 
1532
1507
  await runBtw(ctx, question, save, "tangent");
1533
- return true;
1508
+ return;
1534
1509
  }
1535
1510
 
1536
1511
  if (name === "btw:new") {
@@ -1544,20 +1519,20 @@ export default function (pi: ExtensionAPI) {
1544
1519
  await ensureOverlay(ctx);
1545
1520
  notify(ctx, "Started a fresh BTW thread.", "info");
1546
1521
  }
1547
- return true;
1522
+ return;
1548
1523
  }
1549
1524
 
1550
1525
  if (name === "btw:clear") {
1551
1526
  await resetThread(ctx);
1552
1527
  dismissOverlay();
1553
1528
  notify(ctx, "Cleared BTW thread.", "info");
1554
- return true;
1529
+ return;
1555
1530
  }
1556
1531
 
1557
1532
  if (name === "btw:inject") {
1558
1533
  if (pendingThread.length === 0) {
1559
1534
  notify(ctx, "No BTW thread to inject.", "warning");
1560
- return true;
1535
+ return;
1561
1536
  }
1562
1537
 
1563
1538
  setOverlayStatus("⏳ injecting into the main session...", ctx);
@@ -1579,13 +1554,13 @@ export default function (pi: ExtensionAPI) {
1579
1554
  setOverlayStatus("Inject failed. Thread preserved for retry or summarize.", ctx);
1580
1555
  notify(ctx, error instanceof Error ? error.message : String(error), "error");
1581
1556
  }
1582
- return true;
1557
+ return;
1583
1558
  }
1584
1559
 
1585
1560
  if (name === "btw:summarize") {
1586
1561
  if (pendingThread.length === 0) {
1587
1562
  notify(ctx, "No BTW thread to summarize.", "warning");
1588
- return true;
1563
+ return;
1589
1564
  }
1590
1565
 
1591
1566
  setOverlayStatus("⏳ summarizing...", ctx);
@@ -1608,10 +1583,8 @@ export default function (pi: ExtensionAPI) {
1608
1583
  setOverlayStatus("Summarize failed. Thread preserved for retry or injection.", ctx);
1609
1584
  notify(ctx, error instanceof Error ? error.message : String(error), "error");
1610
1585
  }
1611
- return true;
1586
+ return;
1612
1587
  }
1613
-
1614
- return false;
1615
1588
  }
1616
1589
 
1617
1590
  function parseOverlayBtwCommand(value: string): { name: string; args: string } | null {
@@ -1817,7 +1790,7 @@ export default function (pi: ExtensionAPI) {
1817
1790
 
1818
1791
  async function getBtwHandoffThread(
1819
1792
  ctx: ExtensionCommandContext,
1820
- ): Promise<{ sessionRuntime: BtwSessionRuntime | null; thread: BtwHandoffExchange[] }> {
1793
+ ): Promise<{ thread: BtwHandoffExchange[] }> {
1821
1794
  const sessionRuntime = activeBtwSession ?? (await ensureBtwSession(ctx, pendingMode));
1822
1795
  const thread = sessionRuntime ? extractBtwHandoffThread(sessionRuntime) : [];
1823
1796
  const resolvedThread = thread.length > 0 ? thread : getPendingThreadForHandoff();
@@ -1826,7 +1799,7 @@ export default function (pi: ExtensionAPI) {
1826
1799
  throw new Error("No BTW thread available for handoff.");
1827
1800
  }
1828
1801
 
1829
- return { sessionRuntime, thread: resolvedThread };
1802
+ return { thread: resolvedThread };
1830
1803
  }
1831
1804
 
1832
1805
  async function summarizeThread(ctx: ExtensionCommandContext, thread: BtwHandoffExchange[]): Promise<string> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/btw",
3
- "version": "2.6.1",
3
+ "version": "2.6.2",
4
4
  "description": "A pi extension for parallel side conversations with /unipi:btw — part of the Unipi suite",
5
5
  "type": "module",
6
6
  "main": "extensions/btw.ts",
@@ -40,8 +40,12 @@
40
40
  "@pi-unipi/core": "2.6.1"
41
41
  },
42
42
  "pi": {
43
- "extensions": [],
44
- "skills": [],
43
+ "extensions": [
44
+ "./extensions/btw.ts"
45
+ ],
46
+ "skills": [
47
+ "./skills"
48
+ ],
45
49
  "prompts": [],
46
50
  "themes": []
47
51
  }