Archived
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:
@@ -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,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user