pi-bar 0.3.33 → 0.3.35

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/README.md CHANGED
@@ -6,12 +6,12 @@
6
6
  **Never accidentally run Opus on a typo again.** pi-bar keeps your model, thinking level, context pressure, a live progress update, and any extension statuses visible in pi's footer.
7
7
 
8
8
  ```text
9
- claude-opus-4.7 ❯ think:med ❯ 2.6% / 1.0M ❯ Reviewing package structure ❯ plan:active
9
+ claude-opus-4.7 ❯ think:med ❯ 2.6% / 1.0M ❯ Reviewing package structure ❯ plan:active │ queue:2
10
10
  ```
11
11
 
12
- ![pi-bar with low context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.33/assets/screenshot-green.png)
13
- ![pi-bar with medium context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.33/assets/screenshot-yellow.png)
14
- ![pi-bar with high context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.33/assets/screenshot-red.png)
12
+ ![pi-bar with low context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.35/assets/screenshot-green.png)
13
+ ![pi-bar with medium context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.35/assets/screenshot-yellow.png)
14
+ ![pi-bar with high context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.35/assets/screenshot-red.png)
15
15
 
16
16
  ## Why use it?
17
17
 
@@ -37,13 +37,13 @@ If pi is already running after install, reload resources:
37
37
 
38
38
  ## Customization
39
39
 
40
- pi-bar works out of the box. Run `/bar` inside pi to choose which footer segments are shown:
40
+ pi-bar works out of the box. Run `/bar` inside pi to choose which footer segments and extension statuses are shown:
41
41
 
42
42
  ```text
43
43
  /bar
44
44
  ```
45
45
 
46
- Toggle `Model`, `Thinking level`, `Context usage`, `Progress update`, and `Extension statuses` between `shown` and `hidden`. You can also use commands:
46
+ Toggle `Model`, `Thinking level`, `Context usage`, `Progress update`, and `Extension statuses` between `shown` and `hidden`. If other extensions have published status badges, `/bar` also shows fine-grained `Status: <key>` rows plus a `New extension statuses` default. You can also use commands:
47
47
 
48
48
  ```text
49
49
  /bar segments list
@@ -75,7 +75,7 @@ Or in pi settings: `bar.progressModel`. Otherwise pi-bar picks a fast model you
75
75
 
76
76
  ### Configure extension statuses
77
77
 
78
- Other pi extensions can publish small status badges. Pi-bar collects them into the `extensions` segment. Run `/bar status` inside pi to pick which ones to show:
78
+ Other pi extensions can publish small status badges. Pi-bar collects them into the `extensions` segment and separates each badge with `│`. Run `/bar` or `/bar status` inside pi to pick which ones to show:
79
79
 
80
80
  ```text
81
81
  /bar status
@@ -132,6 +132,7 @@ const DEFAULT_WARNING_THRESHOLD = 70;
132
132
  const DEFAULT_ERROR_THRESHOLD = 90;
133
133
 
134
134
  const SEGMENT_SEPARATOR = "❯";
135
+ const EXTENSION_STATUS_SEPARATOR = "│";
135
136
 
136
137
  function formatTokens(n: number): string {
137
138
  if (n >= 1_000_000) {
@@ -1533,7 +1534,9 @@ function formatExtensionStatuses(
1533
1534
  })
1534
1535
  .map(([key, text]) => `${key}:${text}`);
1535
1536
 
1536
- return parts.length > 0 ? parts.join(" ") : null;
1537
+ return parts.length > 0
1538
+ ? parts.join(` ${EXTENSION_STATUS_SEPARATOR} `)
1539
+ : null;
1537
1540
  }
1538
1541
 
1539
1542
  function serializeStatusFilter(filter: StatusFilter): SerializedStatusFilter {
@@ -1679,33 +1682,83 @@ export default function (pi: ExtensionAPI) {
1679
1682
  };
1680
1683
  const openSegmentConfigurator = async (ctx: ExtensionContext) => {
1681
1684
  await ctx.ui.custom((tui, theme, _kb, done) => {
1685
+ const knownStatusKeys = getKnownStatusKeys(statusFilter, seenStatusKeys);
1682
1686
  const segmentVisibility = new Map(
1683
1687
  ALL_SEGMENTS.map(
1684
1688
  (segment): [SegmentName, boolean] => [segment, visibleSegments.includes(segment)],
1685
1689
  ),
1686
1690
  );
1687
- const persistFromVisibility = () => {
1691
+ let futureShown = statusFilter.mode === "all";
1692
+ const statusVisibility = new Map(
1693
+ knownStatusKeys.map((key): [string, boolean] => [
1694
+ key,
1695
+ shouldShowStatus(key, statusFilter),
1696
+ ]),
1697
+ );
1698
+ const persistSegmentsFromVisibility = () => {
1688
1699
  setVisibleSegments(
1689
1700
  ALL_SEGMENTS.filter((segment) => segmentVisibility.get(segment)),
1690
1701
  ctx,
1691
1702
  );
1692
1703
  };
1704
+ const persistStatusesFromVisibility = () => {
1705
+ if (futureShown) {
1706
+ statusFilter = {
1707
+ mode: "all",
1708
+ hidden: new Set(
1709
+ knownStatusKeys.filter((key) => !statusVisibility.get(key)),
1710
+ ),
1711
+ };
1712
+ } else {
1713
+ statusFilter = {
1714
+ mode: "only",
1715
+ shown: new Set(
1716
+ knownStatusKeys.filter((key) => statusVisibility.get(key)),
1717
+ ),
1718
+ };
1719
+ }
1720
+ persistStatusFilter();
1721
+ };
1693
1722
 
1694
- const items: SettingItem[] = ALL_SEGMENTS.map((segment): SettingItem => ({
1695
- id: segment,
1723
+ const segmentItems: SettingItem[] = ALL_SEGMENTS.map((segment): SettingItem => ({
1724
+ id: `segment:${segment}`,
1696
1725
  label: SEGMENT_LABELS[segment],
1697
1726
  description: "Footer segment visibility",
1698
1727
  currentValue: segmentVisibility.get(segment) ? "shown" : "hidden",
1699
1728
  values: ["shown", "hidden"],
1700
1729
  }));
1730
+ const statusItems: SettingItem[] = knownStatusKeys.length > 0
1731
+ ? [
1732
+ {
1733
+ id: "status:__future",
1734
+ label: "New extension statuses",
1735
+ description: "Default visibility for status keys discovered later",
1736
+ currentValue: futureShown ? "shown" : "hidden",
1737
+ values: ["shown", "hidden"],
1738
+ },
1739
+ ...knownStatusKeys.map((key): SettingItem => ({
1740
+ id: `status:${key}`,
1741
+ label: `Status: ${key}`,
1742
+ description: "Extension status visibility",
1743
+ currentValue: statusVisibility.get(key) ? "shown" : "hidden",
1744
+ values: ["shown", "hidden"],
1745
+ })),
1746
+ ]
1747
+ : [];
1748
+ const items: SettingItem[] = [...segmentItems, ...statusItems];
1701
1749
 
1702
1750
  const container = new Container();
1703
1751
  container.addChild(
1704
1752
  new (class {
1705
1753
  render(_width: number) {
1706
1754
  return [
1707
- theme.fg("accent", theme.bold("pi-bar footer visibility")),
1708
- theme.fg("dim", "Enter/Space toggles · Esc closes"),
1755
+ theme.fg("accent", theme.bold("pi-bar visibility")),
1756
+ theme.fg(
1757
+ "dim",
1758
+ knownStatusKeys.length > 0
1759
+ ? "Footer segments + extension statuses · Enter/Space toggles · Esc closes"
1760
+ : "Footer segments · no extension statuses seen yet · Esc closes",
1761
+ ),
1709
1762
  "",
1710
1763
  ];
1711
1764
  }
@@ -1715,12 +1768,26 @@ export default function (pi: ExtensionAPI) {
1715
1768
 
1716
1769
  const settingsList = new SettingsList(
1717
1770
  items,
1718
- Math.min(items.length + 2, 15),
1771
+ Math.min(items.length + 2, 18),
1719
1772
  getSettingsListTheme(),
1720
1773
  (id, newValue) => {
1721
- if (isSegmentName(id)) {
1722
- segmentVisibility.set(id, newValue === "shown");
1723
- persistFromVisibility();
1774
+ if (id.startsWith("segment:")) {
1775
+ const segment = id.slice("segment:".length);
1776
+ if (!isSegmentName(segment)) return;
1777
+ segmentVisibility.set(segment, newValue === "shown");
1778
+ persistSegmentsFromVisibility();
1779
+ return;
1780
+ }
1781
+
1782
+ if (id === "status:__future") {
1783
+ futureShown = newValue === "shown";
1784
+ persistStatusesFromVisibility();
1785
+ return;
1786
+ }
1787
+
1788
+ if (id.startsWith("status:")) {
1789
+ statusVisibility.set(id.slice("status:".length), newValue === "shown");
1790
+ persistStatusesFromVisibility();
1724
1791
  }
1725
1792
  },
1726
1793
  () => done(undefined),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-bar",
3
- "version": "0.3.33",
3
+ "version": "0.3.35",
4
4
  "description": "Pi footer/statusline showing active model, thinking level, context pressure, live progress updates, and extension statuses.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -51,6 +51,6 @@
51
51
  "extensions": [
52
52
  "./extensions/status-footer.ts"
53
53
  ],
54
- "image": "https://cdn.jsdelivr.net/npm/pi-bar@0.3.33/assets/screenshot-yellow.png"
54
+ "image": "https://cdn.jsdelivr.net/npm/pi-bar@0.3.35/assets/screenshot-yellow.png"
55
55
  }
56
56
  }