@pi-unipi/info-screen 0.1.7 → 0.1.8

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/core-groups.ts CHANGED
@@ -322,8 +322,10 @@ export function setPiApi(api: any): void {
322
322
  * Add a module to the announced list.
323
323
  */
324
324
  export function trackModule(name: string, version: string): void {
325
+
325
326
  if (!announcedModules.find((m) => m.name === name)) {
326
327
  announcedModules.push({ name, version });
328
+
327
329
  }
328
330
  }
329
331
 
@@ -331,6 +333,7 @@ export function trackModule(name: string, version: string): void {
331
333
  * Get list of announced modules.
332
334
  */
333
335
  export function getAnnouncedModules(): Array<{ name: string; version: string }> {
336
+
334
337
  return [...announcedModules];
335
338
  }
336
339
 
@@ -375,16 +378,32 @@ export function registerCoreGroups(): void {
375
378
  const homeDir = process.env.HOME || process.env.USERPROFILE || homedir();
376
379
  const shortCwd = cwd.startsWith(homeDir) ? `~${cwd.slice(homeDir.length)}` : cwd;
377
380
 
378
- const modules = getAnnouncedModules();
379
- const moduleNames = modules.map((m) => m.name.replace(/^@[^/]+\//, ""));
381
+ // Get modules from announced events AND registered groups
382
+ const announced = getAnnouncedModules();
383
+ const registeredGroups = infoRegistry.getAllGroups();
384
+
385
+ // Combine: announced modules + groups that aren't from announced modules
386
+ const moduleNames = new Set<string>();
387
+ for (const m of announced) {
388
+ moduleNames.add(m.name.replace(/^@[^/]+\//, ""));
389
+ }
390
+ // Add non-core groups as modules (they come from extensions)
391
+ const coreGroupIds = new Set(["overview", "usage", "tools", "extensions", "skills"]);
392
+ for (const g of registeredGroups) {
393
+ if (!coreGroupIds.has(g.id)) {
394
+ moduleNames.add(g.id);
395
+ }
396
+ }
397
+
380
398
  const totalLoadTime = getTotalLoadTime();
399
+ const moduleList = Array.from(moduleNames);
381
400
 
382
401
  return {
383
402
  version: { value: getPiVersion(), detail: "pi" },
384
403
  cwd: { value: shortCwd },
385
404
  modules: {
386
- value: String(modules.length),
387
- detail: moduleNames.slice(0, 4).join(", ") + (moduleNames.length > 4 ? ` +${moduleNames.length - 4} more` : ""),
405
+ value: String(moduleList.length),
406
+ detail: moduleList.slice(0, 4).join(", ") + (moduleList.length > 4 ? ` +${moduleList.length - 4} more` : ""),
388
407
  },
389
408
  uptime: { value: formatUptime(process.uptime()) },
390
409
  loadTime: { value: `${totalLoadTime}ms` },
package/index.ts CHANGED
@@ -64,6 +64,9 @@ export default function (pi: ExtensionAPI) {
64
64
  trackModule(event.name, event.version || "unknown");
65
65
  recordLoadTime(event.name, "module", event.loadTimeMs);
66
66
 
67
+ // Invalidate overview cache so next render shows updated modules
68
+ infoRegistry.invalidateCache("overview");
69
+
67
70
  // Track tools from this module
68
71
  if (event.tools && Array.isArray(event.tools)) {
69
72
  for (const tool of event.tools) {
@@ -96,11 +99,11 @@ export default function (pi: ExtensionAPI) {
96
99
  });
97
100
 
98
101
  // Session lifecycle
99
- pi.on("session_start", async (_event, ctx) => {
102
+ pi.on("session_start", async (event, ctx) => {
100
103
  const settings = getInfoSettings();
101
104
 
102
- // Show dashboard on boot if enabled
103
- if (settings.showOnBoot) {
105
+ // Show dashboard only on initial startup, not on /new
106
+ if (settings.showOnBoot && event.reason === "startup") {
104
107
  // Wait for other modules to announce
105
108
  await waitForModules();
106
109
 
@@ -109,6 +112,7 @@ export default function (pi: ExtensionAPI) {
109
112
  (tui, _theme, _keybindings, done) => {
110
113
  const overlay = new InfoOverlay();
111
114
  overlay.onClose = () => done(undefined);
115
+ overlay.requestRender = () => tui.requestRender();
112
116
  // Return three-method object as per pi-tui docs
113
117
  return {
114
118
  render: (w: number) => overlay.render(w),
@@ -151,6 +155,7 @@ export default function (pi: ExtensionAPI) {
151
155
  (tui, _theme, _keybindings, done) => {
152
156
  const overlay = new InfoOverlay();
153
157
  overlay.onClose = () => done(undefined);
158
+ overlay.requestRender = () => tui.requestRender();
154
159
  return {
155
160
  render: (w: number) => overlay.render(w),
156
161
  invalidate: () => overlay.invalidate(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/info-screen",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Dashboard and module registry for Unipi — configurable info overlay with tabbed groups",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -54,6 +54,7 @@ export class InfoOverlay implements Component {
54
54
  onClose?: () => void;
55
55
 
56
56
  constructor() {
57
+ // Start loading data immediately
57
58
  this.loadData();
58
59
  }
59
60
 
@@ -69,6 +70,8 @@ export class InfoOverlay implements Component {
69
70
  */
70
71
  private async loadData(): Promise<void> {
71
72
  this.loading = true;
73
+ // Wait a bit for modules to announce before fetching groups
74
+ await new Promise(r => setTimeout(r, 500));
72
75
  // Always re-fetch ALL groups to catch late registrations
73
76
  this.groups = infoRegistry.getAllGroups();
74
77
 
@@ -145,6 +148,7 @@ export class InfoOverlay implements Component {
145
148
  * Render the component.
146
149
  */
147
150
  render(width: number): string[] {
151
+ // While loading, show loading state
148
152
  if (this.loading) {
149
153
  return this.renderLoading(width);
150
154
  }
@@ -198,6 +202,11 @@ export class InfoOverlay implements Component {
198
202
  }
199
203
  }
200
204
 
205
+ /**
206
+ * Callback set by wrapper to trigger re-render.
207
+ */
208
+ requestRender?: () => void;
209
+
201
210
  /**
202
211
  * Refresh data for all groups (non-blocking).
203
212
  */
@@ -207,7 +216,14 @@ export class InfoOverlay implements Component {
207
216
  infoRegistry.invalidateCache(group.id);
208
217
  // Fetch fresh data (non-blocking)
209
218
  infoRegistry.getGroupData(group.id).then(data => {
219
+ const old = this.groupData.get(group.id);
220
+ const oldStr = JSON.stringify(old);
221
+ const newStr = JSON.stringify(data);
210
222
  this.groupData.set(group.id, data);
223
+ // Trigger re-render if data changed
224
+ if (oldStr !== newStr && this.requestRender) {
225
+ this.requestRender();
226
+ }
211
227
  }).catch(() => {
212
228
  // Ignore errors
213
229
  });