pi-bar 0.3.4 → 0.3.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/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  ◈ claude-opus-4.7 ❯ ✦ think:med ❯ ◷ 2.6% / 1.0M ❯ ✧ plan:active
10
10
  ```
11
11
 
12
- ![pi-bar screenshot, three rows showing green, yellow, and red context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.4/assets/screenshot.png)
12
+ ![pi-bar screenshot, three rows showing green, yellow, and red context usage](https://cdn.jsdelivr.net/npm/pi-bar@0.3.5/assets/screenshot.png)
13
13
 
14
14
  ## Why use it?
15
15
 
@@ -56,7 +56,7 @@ Use `/bar` inside pi to open an interactive status-visibility picker.
56
56
 
57
57
  Toggle each status key between `shown` and `hidden`. The `New statuses` row controls whether status keys discovered later are shown or hidden by default.
58
58
 
59
- Status filter choices persist in the current session. Advanced command forms like `/bar status hide <key>` still work for scripting.
59
+ Status filter choices persist globally across pi sessions. Set `PI_BAR_CONFIG=/path/to/config.json` before launching pi to override the default config path (`~/.pi/agent/pi-bar.json`). Advanced command forms like `/bar status hide <key>` still work for scripting.
60
60
 
61
61
  ### Change context thresholds
62
62
 
@@ -16,6 +16,9 @@
16
16
  * PI_BAR_ICONS=unicode|plain|emoji|nerdfont
17
17
  */
18
18
 
19
+ import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
20
+ import { homedir } from "node:os";
21
+ import { dirname, join } from "node:path";
19
22
  import {
20
23
  getSettingsListTheme,
21
24
  type ExtensionAPI,
@@ -38,6 +41,8 @@ type SerializedStatusFilter =
38
41
  | { mode: "only"; shown: string[] };
39
42
 
40
43
  const STATUS_FILTER_ENTRY_TYPE = "pi-bar-status-filter";
44
+ const CONFIG_PATH =
45
+ process.env.PI_BAR_CONFIG ?? join(homedir(), ".pi", "agent", "pi-bar.json");
41
46
 
42
47
  const DEFAULT_SEGMENTS: SegmentName[] = [
43
48
  "model",
@@ -250,6 +255,29 @@ function describeStatusFilter(filter: StatusFilter): string {
250
255
  return hidden.length > 0 ? `showing all except: ${hidden.join(", ")}` : "showing all";
251
256
  }
252
257
 
258
+ function readGlobalStatusFilter(): StatusFilter | null {
259
+ try {
260
+ const data = JSON.parse(readFileSync(CONFIG_PATH, "utf8")) as {
261
+ statusFilter?: unknown;
262
+ };
263
+ return parseSerializedStatusFilter(data.statusFilter ?? data);
264
+ } catch {
265
+ return null;
266
+ }
267
+ }
268
+
269
+ function writeGlobalStatusFilter(filter: StatusFilter): void {
270
+ const data = JSON.stringify(
271
+ { statusFilter: serializeStatusFilter(filter) },
272
+ null,
273
+ 2,
274
+ );
275
+ mkdirSync(dirname(CONFIG_PATH), { recursive: true });
276
+ const tmpPath = `${CONFIG_PATH}.${process.pid}.tmp`;
277
+ writeFileSync(tmpPath, `${data}\n`, "utf8");
278
+ renameSync(tmpPath, CONFIG_PATH);
279
+ }
280
+
253
281
  function getKnownStatusKeys(filter: StatusFilter, seenStatusKeys: Set<string>): string[] {
254
282
  const keys = new Set(seenStatusKeys);
255
283
  if (filter.mode === "only") {
@@ -266,16 +294,18 @@ export default function (pi: ExtensionAPI) {
266
294
  const seenStatusKeys = new Set<string>();
267
295
  const refresh = () => requestRender?.();
268
296
  const restoreStatusFilter = (ctx: ExtensionContext) => {
269
- let restoredFilter: StatusFilter | null = null;
270
- for (const entry of ctx.sessionManager.getBranch()) {
271
- if (entry.type === "custom" && entry.customType === STATUS_FILTER_ENTRY_TYPE) {
272
- restoredFilter = parseSerializedStatusFilter(entry.data);
297
+ let restoredFilter = readGlobalStatusFilter();
298
+ if (!restoredFilter) {
299
+ for (const entry of ctx.sessionManager.getBranch()) {
300
+ if (entry.type === "custom" && entry.customType === STATUS_FILTER_ENTRY_TYPE) {
301
+ restoredFilter = parseSerializedStatusFilter(entry.data);
302
+ }
273
303
  }
274
304
  }
275
305
  statusFilter = restoredFilter ?? { mode: "all", hidden: new Set() };
276
306
  };
277
307
  const persistStatusFilter = () => {
278
- pi.appendEntry(STATUS_FILTER_ENTRY_TYPE, serializeStatusFilter(statusFilter));
308
+ writeGlobalStatusFilter(statusFilter);
279
309
  refresh();
280
310
  };
281
311
  const openStatusConfigurator = async (ctx: ExtensionContext) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-bar",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "Never accidentally run Opus on a typo. Pi footer/statusline showing active model, thinking level, context usage, and extension statuses.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -46,6 +46,6 @@
46
46
  "extensions": [
47
47
  "./extensions/status-footer.ts"
48
48
  ],
49
- "image": "https://cdn.jsdelivr.net/npm/pi-bar@0.3.4/assets/screenshot.png"
49
+ "image": "https://cdn.jsdelivr.net/npm/pi-bar@0.3.5/assets/screenshot.png"
50
50
  }
51
51
  }