@danypops/pi-packed 0.12.0 → 0.13.0

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.
@@ -12,13 +12,18 @@
12
12
  * only the footer moves as content height changes. Enter opens a second,
13
13
  * smaller overlay action menu on top of it. U's batch update stays on
14
14
  * this same package list -- progress renders inline next to the row
15
- * currently being updated, not as a separate screen. All data flows
16
- * through the packed CLI (thin seam).
15
+ * currently being updated, not as a separate screen. Rows render through
16
+ * Malevich's Table (real column-aligned Package/Version/status cells,
17
+ * per-row selection styling baked into each cell since Table's own
18
+ * cellStyle is column-wide, not row-wide) inside this panel's own
19
+ * scroll-window slice -- Table deliberately owns no pagination of its
20
+ * own, so the visible-window-around-selectedIndex math stays here. All
21
+ * data flows through the packed CLI (thin seam).
17
22
  */
18
23
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
19
24
  import { DynamicBorder, rawKeyHint } from "@earendil-works/pi-coding-agent";
20
- import { Container, Input, Spacer, truncateToWidth } from "@earendil-works/pi-tui";
21
- import { Envelope, Menu, ProgressBar, type MenuItem } from "malevich-tui-components";
25
+ import { Container, Input, Spacer, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
26
+ import { Envelope, Menu, ProgressBar, Table, type MenuItem, type TableColumn, type TextMeasure } from "malevich-tui-components";
22
27
  import { filterRows, mergeRows, nextMode, visibleRows } from "./model.js";
23
28
  import type { Row, ViewMode } from "./model.js";
24
29
  import type { Natives, PackageResources } from "./packed.js";
@@ -409,6 +414,19 @@ function renderPanel(ctx: ExtensionCommandContext, natives: Natives, initialRows
409
414
  },
410
415
  };
411
416
 
417
+ // pi-tui's own visibleWidth/truncateToWidth are ANSI-aware (they strip
418
+ // escape codes for measurement, matching the pair Malevich's TextMeasure
419
+ // port expects) -- rows below bake selection/status styling directly
420
+ // into each cell's text since Table's own cellStyle is column-wide, not
421
+ // per-row.
422
+ const measure: TextMeasure = { visibleWidth, truncateToWidth };
423
+ const columns: TableColumn[] = [
424
+ { header: "Package", key: "name" },
425
+ { header: "Version", key: "version" },
426
+ { header: "", key: "status" },
427
+ ];
428
+ const table = new Table({ columns, rows: [], measure, headerStyle: (s) => theme.fg("muted", s) });
429
+
412
430
  const list = {
413
431
  invalidate() {},
414
432
  render(width: number): string[] {
@@ -419,20 +437,25 @@ function renderPanel(ctx: ExtensionCommandContext, natives: Natives, initialRows
419
437
  lines.push(theme.fg("muted", " No packages"));
420
438
  return lines;
421
439
  }
440
+ // No scrolling of its own (Malevich's Table is deliberately
441
+ // unopinionated about pagination) -- the visible window around
442
+ // selectedIndex stays this panel's own job, same as before.
422
443
  const start = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisible / 2), filtered.length - maxVisible));
423
444
  const end = Math.min(start + maxVisible, filtered.length);
424
- for (let i = start; i < end; i++) {
425
- const row = filtered[i]!;
426
- const selected = i === selectedIndex;
427
- const cursor = selected ? theme.fg("accent", "❯") : " ";
428
- const name = selected ? theme.bold(row.name) : row.name;
429
- const ver = theme.fg("dim", `@${row.version}`);
430
- const isUpdating = updatingRowName === row.name;
431
- const upd = isUpdating
432
- ? theme.fg("accent", ` ${updatingBar.format(10)} updating…`)
433
- : row.hasUpdate ? theme.fg("warning", ` ↑${row.latest}`) : "";
434
- lines.push(truncateToWidth(`${cursor} ${name}${ver}${upd}`, width, ""));
435
- }
445
+ table.setRows(
446
+ filtered.slice(start, end).map((row, offset) => {
447
+ const i = start + offset;
448
+ const selected = i === selectedIndex;
449
+ const cursor = selected ? theme.fg("accent", "❯ ") : " ";
450
+ const name = selected ? theme.bold(row.name) : row.name;
451
+ const isUpdating = updatingRowName === row.name;
452
+ const status = isUpdating
453
+ ? theme.fg("accent", `${updatingBar.format(10)} updating…`)
454
+ : row.hasUpdate ? theme.fg("warning", `↑${row.latest}`) : "";
455
+ return { name: `${cursor}${name}`, version: theme.fg("dim", row.version), status };
456
+ }),
457
+ );
458
+ lines.push(...table.render(width));
436
459
  const hasScroll = start > 0 || end < filtered.length;
437
460
  lines.push(theme.fg("dim", ` ${hasScroll ? `${selectedIndex + 1}/${filtered.length} ` : ""}${mode}`));
438
461
  return lines;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danypops/pi-packed",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Pi package tools, commands, profiles, and TUI for the Packed daemon",
5
5
  "type": "module",
6
6
  "keywords": ["pi-package"],