pi-better-background-tasks 0.6.2 → 0.6.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-better-background-tasks",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Pi extension for durable background shell tasks, watchers, logs, and status inspection.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -66,6 +66,8 @@ export type BackgroundWorkProvider = {
66
66
  detail(id: string, now: number, options?: { logTailLines?: number }): BackgroundWorkDetail | null;
67
67
  armCloseLabel(row: BackgroundWorkRow): string;
68
68
  close(id: string): BackgroundWorkCloseOutcome;
69
+ /** Return true when this detail handled the key. The navigator refreshes the sheet. */
70
+ handleDetailInput?(id: string, data: string): boolean;
69
71
  onVisibleChanged?(notify: () => void): () => void;
70
72
  };
71
73
 
@@ -559,7 +561,7 @@ function rowSummary(row: InternalRow): string {
559
561
  const parts: string[] = [];
560
562
  if (row.statusTone !== "running" && row.kind !== "main agent") parts.push(singleLine(row.status));
561
563
  if (row.model) parts.push(row.effort ? `${singleLine(row.model)} ${singleLine(row.effort)}` : singleLine(row.model));
562
- if (row.tool) parts.push(`tool ${singleLine(row.tool)}`);
564
+ if (row.tool) parts.push(singleLine(row.tool));
563
565
  if (row.tokens) parts.push(singleLine(row.tokens));
564
566
  else if (row.primary) parts.push(singleLine(row.primary));
565
567
  if (parts.length) return parts.join(" · ");
@@ -703,12 +705,7 @@ function handleMainListInput(data: string, deps: HostDeps): boolean {
703
705
  return true;
704
706
  }
705
707
  if (deps.matchKey(data, "enter")) {
706
- const selected = selectedMainListRow();
707
- if (selected?.parentRow) {
708
- unfocusMainList();
709
- dismissOverlay();
710
- }
711
- else openNavigator();
708
+ openNavigator();
712
709
  return true;
713
710
  }
714
711
  if (data === "x" || data === "X" || deps.matchKey(data, "x") || deps.matchKey(data, "X")) {
@@ -851,7 +848,8 @@ function createOverlayComponent(
851
848
  let logTailRows: number = DEFAULT_LOG_TAIL_ROWS;
852
849
  const expandedSections = new Set<string>();
853
850
  let detailId: string = initialDetailId;
854
- let detail: BackgroundWorkDetail | null = detailFor(detailId, Date.now(), { logTailLines: logTailRows }) ?? null;
851
+ const initialRow = initialRows.find((row) => row.navigatorId === detailId);
852
+ let detail: BackgroundWorkDetail | null = detailFor(detailId, Date.now(), { logTailLines: logTailRows }) ?? (initialRow ? fallbackDetail(initialRow) : null);
855
853
  applyDefaultExpandedSections(detail, expandedSections);
856
854
  {
857
855
  const idx = overlayState.rows.findIndex((row) => row.navigatorId === detailId);
@@ -891,8 +889,7 @@ function createOverlayComponent(
891
889
  }
892
890
 
893
891
  function activateSelectedRow(): void {
894
- if (selectedRow()?.parentRow) close();
895
- else openDetail();
892
+ openDetail();
896
893
  }
897
894
 
898
895
  function clearCloseArm(): void {
@@ -922,10 +919,6 @@ function createOverlayComponent(
922
919
  function openDetail(): void {
923
920
  const row = selectedRow();
924
921
  if (!row) return;
925
- if (row.parentRow) {
926
- close();
927
- return;
928
- }
929
922
  clearCloseArm();
930
923
  detailId = row.navigatorId;
931
924
  expandedSections.clear();
@@ -1073,6 +1066,15 @@ function createOverlayComponent(
1073
1066
  requestRender();
1074
1067
  }
1075
1068
  }
1069
+ else if (data === "m" || data === "M" || data === "\x13" || deps.matchKey(data, "ctrl+s")) {
1070
+ const row = selectedRow();
1071
+ const provider = row ? state().providers.get(row.providerId) : undefined;
1072
+ const key = data === "m" || data === "M" ? "m" : "ctrl+s";
1073
+ if (!row || !provider?.handleDetailInput?.(row.id, key)) return;
1074
+ detail = detailFor(detailId, Date.now(), { logTailLines: logTailRows }) ?? detail;
1075
+ refreshMainListWidget();
1076
+ requestRender();
1077
+ }
1076
1078
  else if (data === "l" || data === "L") {
1077
1079
  logTailRows = cycleLogTailRows(logTailRows);
1078
1080
  if (detailId) detail = detailFor(detailId, Date.now(), { logTailLines: logTailRows }) ?? detail;
@@ -1091,8 +1093,7 @@ function createOverlayComponent(
1091
1093
  if (idx < 0) return;
1092
1094
  overlayState.selected = idx;
1093
1095
  state().mainListSelectedId = navigatorId;
1094
- if (overlayState.rows[idx]!.parentRow) close();
1095
- else openDetail();
1096
+ openDetail();
1096
1097
  },
1097
1098
  /** Close the overlay (done), e.g. when the navigator is disposed. */
1098
1099
  dismiss() { close(); },
@@ -1150,7 +1151,11 @@ function buildTranscriptDetailLines(
1150
1151
  ...detail.metadata.map((item) => ` ${item.label.padEnd(8, " ").slice(0, 8)} ${item.value}`),
1151
1152
  ];
1152
1153
  const transcriptHeader = ["", dim(section(`transcript · latest ${tailRows} rows`, width), fg)];
1153
- if (detail.transcriptDiagnostic) transcriptHeader.push(` ${dim(detail.transcriptDiagnostic, fg)}`);
1154
+ if (detail.transcriptDiagnostic) {
1155
+ for (const diagnosticRow of detail.transcriptDiagnostic.split(/\r\n|\r|\n/)) {
1156
+ transcriptHeader.push(` ${dim(diagnosticRow, fg)}`);
1157
+ }
1158
+ }
1154
1159
  // Metadata always renders; the transcript tail takes only the rows left over (the tail size is a cap, not a guarantee).
1155
1160
  lines.push(...optionalMetadata);
1156
1161
  if (options.maxRows !== undefined) {