feat(plugins): turn Info panel into a PI WEB status view

Rework the bundled Info plugin from a demo into an always-available
status view: running and installed versions, installation details,
release state, and per-service health rendered from host-provided
state, plus machine and workspace details. Replace the window.alert
demo action with a Copy PI WEB Diagnostics action that copies a
plain-text summary for bug reports.

Add state.selectedMachine to the stable plugin runtime state so
actions and other runtime callbacks can read the selected machine's
identity, and split the plugin into a copy-paste-friendly skeleton
(pi-web-plugin.ts) and replaceable internals (infoInternals.ts).
This commit is contained in:
Federico Jaramillo Martinez
2026-07-27 18:03:25 +02:00
parent 0a35748478
commit 8517800a24
9 changed files with 496 additions and 25 deletions
+71
View File
@@ -0,0 +1,71 @@
import { html, svg } from "lit";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { PluginRuntimeContext } from "@jmfederico/pi-web/plugin-api";
import plugin from "./pi-web-plugin.js";
describe("Info plugin copy-diagnostics action", () => {
afterEach(() => {
vi.unstubAllGlobals();
});
it("copies a diagnostics summary to the clipboard", async () => {
const writeText = vi.fn((text: string) => { void text; return Promise.resolve(); });
vi.stubGlobal("navigator", { clipboard: { writeText } });
const action = findCopyDiagnosticsAction();
const context = runtimeContext({
state: {
selectedMachine: { id: "local", name: "devbox", kind: "local" },
selectedWorkspace: {
id: "ws-1",
projectId: "proj-1",
path: "/srv/dev/pi-web",
label: "pi-web",
branch: "main",
isMain: true,
isGitRepo: true,
isGitWorktree: false,
},
},
});
await action.run(context);
expect(writeText).toHaveBeenCalledOnce();
const summary = writeText.mock.calls[0]?.[0];
expect(summary).toContain("PI WEB diagnostics");
expect(summary).toContain("Status: unavailable");
expect(summary).toContain("Machine: devbox (local machine)");
expect(summary).toContain("Workspace: pi-web — /srv/dev/pi-web (branch main, git repo, main workspace)");
});
});
function findCopyDiagnosticsAction() {
const action = plugin.activate({ apiVersion: 1, pluginId: "info", html, svg }).contributions.actions?.find((candidate) => candidate.id === "copy-diagnostics");
if (action === undefined) throw new Error("Expected copy-diagnostics action");
return action;
}
function runtimeContext(patch: Partial<PluginRuntimeContext> = {}): PluginRuntimeContext {
const noop = () => undefined;
return {
state: {},
prompt: { insertText: noop, getText: () => "", getSelection: () => null },
openActionPalette: noop,
focusPrompt: noop,
addProject: noop,
configureAuth: noop,
logoutAuth: noop,
openThemePicker: noop,
selectMainView: noop,
selectWorkspaceTool: noop,
openTerminal: noop,
refreshFiles: noop,
refreshGit: noop,
refreshAppData: noop,
reloadPage: noop,
startSession: noop,
archiveSession: noop,
stopActiveWork: noop,
...patch,
};
}