@pi-unipi/info-screen 0.1.6 → 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 +23 -4
- package/index.ts +9 -4
- package/package.json +1 -1
- package/tui/info-overlay.ts +16 -0
- package/types.ts +1 -1
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
|
-
|
|
379
|
-
const
|
|
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(
|
|
387
|
-
detail:
|
|
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
|
@@ -31,7 +31,7 @@ const moduleReadyPromise = new Promise<void>((resolve) => {
|
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
/** Timeout for waiting for modules */
|
|
34
|
-
const MODULE_WAIT_TIMEOUT_MS =
|
|
34
|
+
const MODULE_WAIT_TIMEOUT_MS = 8000;
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* Wait for modules to announce, then return.
|
|
@@ -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 (
|
|
102
|
+
pi.on("session_start", async (event, ctx) => {
|
|
100
103
|
const settings = getInfoSettings();
|
|
101
104
|
|
|
102
|
-
// Show dashboard on
|
|
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
package/tui/info-overlay.ts
CHANGED
|
@@ -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
|
});
|