@hyperdreamer/pi-webui 1.6.1
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/LICENSE +23 -0
- package/README.md +148 -0
- package/dist/cli.js +975 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/apple-touch-icon.png +0 -0
- package/dist/client/assets/CodeViewer-aB4ZVzEu.js +4 -0
- package/dist/client/assets/UnifiedDiffViewer-f8X7aTkU.js +39 -0
- package/dist/client/assets/index-Cffeusjy.js +6022 -0
- package/dist/client/assets/vendor-editor-core-vUi74DnD.js +12 -0
- package/dist/client/assets/vendor-editor-languages-DoaXUodB.js +46 -0
- package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +1 -0
- package/dist/client/assets/vendor-terminal-BrP-ENHg.css +1 -0
- package/dist/client/assets/vendor-terminal-D8k4UKM2.js +35 -0
- package/dist/client/favicon.svg +8 -0
- package/dist/client/index.html +65 -0
- package/dist/client/manifest.webmanifest +24 -0
- package/dist/client/pwa-icon-192.png +0 -0
- package/dist/client/pwa-icon-512.png +0 -0
- package/dist/config.js +417 -0
- package/dist/config.js.map +1 -0
- package/dist/docker/piWebUiDockerCommandPlan.js +211 -0
- package/dist/docker/piWebUiDockerCommandPlan.js.map +1 -0
- package/dist/nativeServices/serviceDoctor.js +480 -0
- package/dist/nativeServices/serviceDoctor.js.map +1 -0
- package/dist/nativeServices/serviceInstall.js +35 -0
- package/dist/nativeServices/serviceInstall.js.map +1 -0
- package/dist/nativeServices/servicePlan.js +358 -0
- package/dist/nativeServices/servicePlan.js.map +1 -0
- package/dist/nativeServices/serviceProbe.js +447 -0
- package/dist/nativeServices/serviceProbe.js.map +1 -0
- package/dist/nativeServices/serviceRendering.js +122 -0
- package/dist/nativeServices/serviceRendering.js.map +1 -0
- package/dist/pi-webui-plugins/info/package.json +9 -0
- package/dist/pi-webui-plugins/info/pi-webui-plugin.js +51 -0
- package/dist/pi-webui-plugins/updates/package.json +9 -0
- package/dist/pi-webui-plugins/updates/pi-webui-plugin.js +185 -0
- package/dist/pi-webui-plugins/updates/updatesLogic.js +97 -0
- package/dist/pi-webui-plugins/workspace-tasks/config.js +91 -0
- package/dist/pi-webui-plugins/workspace-tasks/package.json +9 -0
- package/dist/pi-webui-plugins/workspace-tasks/pi-webui-plugin.js +48 -0
- package/dist/pi-webui-plugins/workspace-tasks/taskRunner.js +12 -0
- package/dist/pi-webui-plugins/workspace-tasks/tasksPanelElement.js +288 -0
- package/dist/pi-webui-plugins/workspace-tasks/workspaceTasksClient.js +47 -0
- package/dist/piWebUiVersionReport.js +225 -0
- package/dist/piWebUiVersionReport.js.map +1 -0
- package/dist/plugin-api/unstable.d.ts +22 -0
- package/dist/plugin-api.d.ts +199 -0
- package/dist/server/activeAgentProfileProvider.js +25 -0
- package/dist/server/activeAgentProfileProvider.js.map +1 -0
- package/dist/server/activity/workspaceActivityRoutes.js +4 -0
- package/dist/server/activity/workspaceActivityRoutes.js.map +1 -0
- package/dist/server/activity/workspaceActivityService.js +98 -0
- package/dist/server/activity/workspaceActivityService.js.map +1 -0
- package/dist/server/app.js +211 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/browserMessageProjection.js +56 -0
- package/dist/server/browserMessageProjection.js.map +1 -0
- package/dist/server/configRoutes.js +309 -0
- package/dist/server/configRoutes.js.map +1 -0
- package/dist/server/diagnostics/nodePtyNativeModule.js +36 -0
- package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -0
- package/dist/server/diagnostics/nodePtySpawnHelper.js +135 -0
- package/dist/server/diagnostics/nodePtySpawnHelper.js.map +1 -0
- package/dist/server/git/gitEnv.js +15 -0
- package/dist/server/git/gitEnv.js.map +1 -0
- package/dist/server/git/gitService.js +123 -0
- package/dist/server/git/gitService.js.map +1 -0
- package/dist/server/gitRoutes.js +23 -0
- package/dist/server/gitRoutes.js.map +1 -0
- package/dist/server/index.js +7 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/machines/machineClient.js +172 -0
- package/dist/server/machines/machineClient.js.map +1 -0
- package/dist/server/machines/machinePluginProxyRoutes.js +190 -0
- package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -0
- package/dist/server/machines/machineProxyRoutes.js +172 -0
- package/dist/server/machines/machineProxyRoutes.js.map +1 -0
- package/dist/server/machines/machineRoutes.js +56 -0
- package/dist/server/machines/machineRoutes.js.map +1 -0
- package/dist/server/machines/machineService.js +238 -0
- package/dist/server/machines/machineService.js.map +1 -0
- package/dist/server/machines/machineStore.js +128 -0
- package/dist/server/machines/machineStore.js.map +1 -0
- package/dist/server/models/modelsConfigRoutes.js +40 -0
- package/dist/server/models/modelsConfigRoutes.js.map +1 -0
- package/dist/server/models/modelsConfigService.js +339 -0
- package/dist/server/models/modelsConfigService.js.map +1 -0
- package/dist/server/piPackagePluginsConfigRoutes.js +86 -0
- package/dist/server/piPackagePluginsConfigRoutes.js.map +1 -0
- package/dist/server/piPackagePluginsConfigService.js +311 -0
- package/dist/server/piPackagePluginsConfigService.js.map +1 -0
- package/dist/server/piPackageRoutes.js +91 -0
- package/dist/server/piPackageRoutes.js.map +1 -0
- package/dist/server/piPackageService.js +101 -0
- package/dist/server/piPackageService.js.map +1 -0
- package/dist/server/piWebUiPluginService.js +326 -0
- package/dist/server/piWebUiPluginService.js.map +1 -0
- package/dist/server/piWebUiReleaseLookupCache.js +37 -0
- package/dist/server/piWebUiReleaseLookupCache.js.map +1 -0
- package/dist/server/piWebUiStatus.js +622 -0
- package/dist/server/piWebUiStatus.js.map +1 -0
- package/dist/server/piWebUiStatusCache.js +45 -0
- package/dist/server/piWebUiStatusCache.js.map +1 -0
- package/dist/server/projects/directorySuggestions.js +37 -0
- package/dist/server/projects/directorySuggestions.js.map +1 -0
- package/dist/server/projects/projectService.js +31 -0
- package/dist/server/projects/projectService.js.map +1 -0
- package/dist/server/realtime/sessionEventHub.js +70 -0
- package/dist/server/realtime/sessionEventHub.js.map +1 -0
- package/dist/server/sessiond/sessionDaemonStartup.js +49 -0
- package/dist/server/sessiond/sessionDaemonStartup.js.map +1 -0
- package/dist/server/sessiond/sessionProxyRoutes.js +87 -0
- package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -0
- package/dist/server/sessiond/skillsGithubToken.js +7 -0
- package/dist/server/sessiond/skillsGithubToken.js.map +1 -0
- package/dist/server/sessiond.js +152 -0
- package/dist/server/sessiond.js.map +1 -0
- package/dist/server/sessions/attachmentService.js +119 -0
- package/dist/server/sessions/attachmentService.js.map +1 -0
- package/dist/server/sessions/authProviderOptions.js +50 -0
- package/dist/server/sessions/authProviderOptions.js.map +1 -0
- package/dist/server/sessions/authRoutes.js +69 -0
- package/dist/server/sessions/authRoutes.js.map +1 -0
- package/dist/server/sessions/authService.js +134 -0
- package/dist/server/sessions/authService.js.map +1 -0
- package/dist/server/sessions/builtinCommands.js +27 -0
- package/dist/server/sessions/builtinCommands.js.map +1 -0
- package/dist/server/sessions/editPreview.js +196 -0
- package/dist/server/sessions/editPreview.js.map +1 -0
- package/dist/server/sessions/messagePaging.js +43 -0
- package/dist/server/sessions/messagePaging.js.map +1 -0
- package/dist/server/sessions/oauthLoginFlowService.js +349 -0
- package/dist/server/sessions/oauthLoginFlowService.js.map +1 -0
- package/dist/server/sessions/piSessionManagerGateway.js +115 -0
- package/dist/server/sessions/piSessionManagerGateway.js.map +1 -0
- package/dist/server/sessions/piSessionService.js +3230 -0
- package/dist/server/sessions/piSessionService.js.map +1 -0
- package/dist/server/sessions/plainTextTheme.js +112 -0
- package/dist/server/sessions/plainTextTheme.js.map +1 -0
- package/dist/server/sessions/sessionArchiveMigration.js +590 -0
- package/dist/server/sessions/sessionArchiveMigration.js.map +1 -0
- package/dist/server/sessions/sessionArchiveStore.js +262 -0
- package/dist/server/sessions/sessionArchiveStore.js.map +1 -0
- package/dist/server/sessions/sessionArchiveTree.js +35 -0
- package/dist/server/sessions/sessionArchiveTree.js.map +1 -0
- package/dist/server/sessions/sessionCleanup.js +157 -0
- package/dist/server/sessions/sessionCleanup.js.map +1 -0
- package/dist/server/sessions/sessionCommandService.js +313 -0
- package/dist/server/sessions/sessionCommandService.js.map +1 -0
- package/dist/server/sessions/sessionDefaultsRoutes.js +65 -0
- package/dist/server/sessions/sessionDefaultsRoutes.js.map +1 -0
- package/dist/server/sessions/sessionDefaultsService.js +90 -0
- package/dist/server/sessions/sessionDefaultsService.js.map +1 -0
- package/dist/server/sessions/sessionHistoryExport.js +115 -0
- package/dist/server/sessions/sessionHistoryExport.js.map +1 -0
- package/dist/server/sessions/sessionMetadataStore.js +102 -0
- package/dist/server/sessions/sessionMetadataStore.js.map +1 -0
- package/dist/server/sessions/sessionNameGenerator.js +90 -0
- package/dist/server/sessions/sessionNameGenerator.js.map +1 -0
- package/dist/server/sessions/sessionNotificationStore.js +484 -0
- package/dist/server/sessions/sessionNotificationStore.js.map +1 -0
- package/dist/server/sessions/sessionRoutes.js +590 -0
- package/dist/server/sessions/sessionRoutes.js.map +1 -0
- package/dist/server/sessions/sessionRuntimeStore.js +2 -0
- package/dist/server/sessions/sessionRuntimeStore.js.map +1 -0
- package/dist/server/sessions/sessionService.js +2 -0
- package/dist/server/sessions/sessionService.js.map +1 -0
- package/dist/server/sessions/sessionTreeProjection.js +250 -0
- package/dist/server/sessions/sessionTreeProjection.js.map +1 -0
- package/dist/server/sessions/sessionUnreadStore.js +520 -0
- package/dist/server/sessions/sessionUnreadStore.js.map +1 -0
- package/dist/server/sessions/spawnSessionTool.js +41 -0
- package/dist/server/sessions/spawnSessionTool.js.map +1 -0
- package/dist/server/sessions/spawnSubsessionTool.js +214 -0
- package/dist/server/sessions/spawnSubsessionTool.js.map +1 -0
- package/dist/server/sessions/spawnTargetResolver.js +36 -0
- package/dist/server/sessions/spawnTargetResolver.js.map +1 -0
- package/dist/server/sessions/subsessionTranscript.js +235 -0
- package/dist/server/sessions/subsessionTranscript.js.map +1 -0
- package/dist/server/skills/runNpx.js +30 -0
- package/dist/server/skills/runNpx.js.map +1 -0
- package/dist/server/skills/skillLock.js +115 -0
- package/dist/server/skills/skillLock.js.map +1 -0
- package/dist/server/skills/skillUpdates.js +194 -0
- package/dist/server/skills/skillUpdates.js.map +1 -0
- package/dist/server/skills/skillsConfigRoutes.js +64 -0
- package/dist/server/skills/skillsConfigRoutes.js.map +1 -0
- package/dist/server/skills/skillsConfigService.js +391 -0
- package/dist/server/skills/skillsConfigService.js.map +1 -0
- package/dist/server/storage/projectStore.js +88 -0
- package/dist/server/storage/projectStore.js.map +1 -0
- package/dist/server/systemInfoRoutes.js +265 -0
- package/dist/server/systemInfoRoutes.js.map +1 -0
- package/dist/server/terminalProxyRoutes.js +140 -0
- package/dist/server/terminalProxyRoutes.js.map +1 -0
- package/dist/server/terminals/terminalRoutes.js +155 -0
- package/dist/server/terminals/terminalRoutes.js.map +1 -0
- package/dist/server/terminals/terminalService.js +305 -0
- package/dist/server/terminals/terminalService.js.map +1 -0
- package/dist/server/terminals/terminalSize.js +17 -0
- package/dist/server/terminals/terminalSize.js.map +1 -0
- package/dist/server/types.js +2 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server/webSocketBridge.js +32 -0
- package/dist/server/webSocketBridge.js.map +1 -0
- package/dist/server/workingDirectory.js +44 -0
- package/dist/server/workingDirectory.js.map +1 -0
- package/dist/server/workspaceExplorerRoutes.js +109 -0
- package/dist/server/workspaceExplorerRoutes.js.map +1 -0
- package/dist/server/workspaces/effectivePathAccess.js +27 -0
- package/dist/server/workspaces/effectivePathAccess.js.map +1 -0
- package/dist/server/workspaces/fileContentService.js +181 -0
- package/dist/server/workspaces/fileContentService.js.map +1 -0
- package/dist/server/workspaces/fileSuggestions.js +520 -0
- package/dist/server/workspaces/fileSuggestions.js.map +1 -0
- package/dist/server/workspaces/fileTreeService.js +35 -0
- package/dist/server/workspaces/fileTreeService.js.map +1 -0
- package/dist/server/workspaces/gitWorktreeDiscovery.js +34 -0
- package/dist/server/workspaces/gitWorktreeDiscovery.js.map +1 -0
- package/dist/server/workspaces/imagePreviewService.js +40 -0
- package/dist/server/workspaces/imagePreviewService.js.map +1 -0
- package/dist/server/workspaces/pathAccessPolicy.js +90 -0
- package/dist/server/workspaces/pathAccessPolicy.js.map +1 -0
- package/dist/server/workspaces/pathSafety.js +45 -0
- package/dist/server/workspaces/pathSafety.js.map +1 -0
- package/dist/server/workspaces/projectPiWebUiConfig.js +61 -0
- package/dist/server/workspaces/projectPiWebUiConfig.js.map +1 -0
- package/dist/server/workspaces/workspaceContext.js +8 -0
- package/dist/server/workspaces/workspaceContext.js.map +1 -0
- package/dist/server/workspaces/workspaceDeletionRoutes.js +113 -0
- package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -0
- package/dist/server/workspaces/workspaceService.js +39 -0
- package/dist/server/workspaces/workspaceService.js.map +1 -0
- package/dist/sessiond/activeAgentProfile.js +31 -0
- package/dist/sessiond/activeAgentProfile.js.map +1 -0
- package/dist/sessiond/config.js +9 -0
- package/dist/sessiond/config.js.map +1 -0
- package/dist/sessiond/sessionDaemonClient.js +103 -0
- package/dist/sessiond/sessionDaemonClient.js.map +1 -0
- package/dist/shared/activeAgentProfile.js +76 -0
- package/dist/shared/activeAgentProfile.js.map +1 -0
- package/dist/shared/activity.js +11 -0
- package/dist/shared/activity.js.map +1 -0
- package/dist/shared/apiTypes.d.ts +1212 -0
- package/dist/shared/apiTypes.js +25 -0
- package/dist/shared/apiTypes.js.map +1 -0
- package/dist/shared/capabilities.js +69 -0
- package/dist/shared/capabilities.js.map +1 -0
- package/dist/shared/federatedRoutes.js +109 -0
- package/dist/shared/federatedRoutes.js.map +1 -0
- package/dist/shared/machinePluginIds.js +41 -0
- package/dist/shared/machinePluginIds.js.map +1 -0
- package/dist/shared/piWebUiStatusParsing.js +108 -0
- package/dist/shared/piWebUiStatusParsing.js.map +1 -0
- package/dist/shared/pluginIds.js +5 -0
- package/dist/shared/pluginIds.js.map +1 -0
- package/dist/shared/promptAttachments.js +92 -0
- package/dist/shared/promptAttachments.js.map +1 -0
- package/dist/shared/thinkingLevels.d.ts +27 -0
- package/dist/shared/thinkingLevels.js +31 -0
- package/dist/shared/thinkingLevels.js.map +1 -0
- package/dist/shared/workspaceDeletion.js +12 -0
- package/dist/shared/workspaceDeletion.js.map +1 -0
- package/dist/shared/workspaceFiles.js +3 -0
- package/dist/shared/workspaceFiles.js.map +1 -0
- package/docs/assets/favicon.svg +8 -0
- package/docs/assets/pi-webui-banner.png +0 -0
- package/docs/assets/pi-webui-desktop.png +0 -0
- package/docs/assets/pi-webui-mobile.png +0 -0
- package/docs/assets/pi-webui-tablet.png +0 -0
- package/docs/config.md +265 -0
- package/docs/plugins.md +988 -0
- package/extensions/pi-webui.ts +133 -0
- package/package.json +143 -0
- package/plugin-api/unstable.d.ts +1 -0
- package/plugin-api.d.ts +1 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Generated from pi-webui-plugins/info/pi-webui-plugin.ts. Do not edit directly.
|
|
2
|
+
const plugin = {
|
|
3
|
+
apiVersion: 1,
|
|
4
|
+
name: "Info Plugin",
|
|
5
|
+
activate: ({ html, svg }) => ({
|
|
6
|
+
contributions: {
|
|
7
|
+
actions: [
|
|
8
|
+
{
|
|
9
|
+
id: "workspace.show-path",
|
|
10
|
+
title: "Show Current Workspace Path",
|
|
11
|
+
group: "Info",
|
|
12
|
+
enabled: (context) => context.state.selectedWorkspace !== undefined,
|
|
13
|
+
run: (context) => {
|
|
14
|
+
const path = context.state.selectedWorkspace?.path ?? "No workspace selected";
|
|
15
|
+
window.alert(path);
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
workspaceLabels: [
|
|
20
|
+
{
|
|
21
|
+
id: "workspace.kind-label",
|
|
22
|
+
order: 100,
|
|
23
|
+
items: (context) => [{ type: "text", text: context.workspace.isGitRepo ? "git" : "folder", title: context.workspace.path }],
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
workspacePanels: [
|
|
27
|
+
{
|
|
28
|
+
id: "workspace.info",
|
|
29
|
+
title: "Info",
|
|
30
|
+
icon: svg `
|
|
31
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
32
|
+
<circle cx="12" cy="12" r="9"></circle>
|
|
33
|
+
<path d="M12 11v5"></path>
|
|
34
|
+
<path d="M12 8h.01"></path>
|
|
35
|
+
</svg>
|
|
36
|
+
`,
|
|
37
|
+
order: 1000,
|
|
38
|
+
render: (context) => html `
|
|
39
|
+
<section class="toolbar"><strong>Info</strong></section>
|
|
40
|
+
<section class="viewer">
|
|
41
|
+
<p><strong>Workspace</strong></p>
|
|
42
|
+
<p class="muted">${context.workspace.label}</p>
|
|
43
|
+
<p class="muted">${context.workspace.path}</p>
|
|
44
|
+
</section>
|
|
45
|
+
`,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
}),
|
|
50
|
+
};
|
|
51
|
+
export default plugin;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// Generated from pi-webui-plugins/updates/pi-webui-plugin.ts. Do not edit directly.
|
|
2
|
+
import { additionalCommands, fallbackDockerStatus, formatVersion, installationLabel, messageCount, recommendedCommand, shouldShowUpdatesPanel, statusFor } from "./updatesLogic.js";
|
|
3
|
+
function runCommandInTerminal(terminal, label, command) {
|
|
4
|
+
void terminal.runCommand({
|
|
5
|
+
title: label,
|
|
6
|
+
command,
|
|
7
|
+
open: true,
|
|
8
|
+
metadata: { "pi.plugin": "updates" },
|
|
9
|
+
}).catch((error) => {
|
|
10
|
+
console.error(`Updates plugin failed to run "${label}"`, error);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function renderComponent(html, component) {
|
|
14
|
+
const status = !component.available
|
|
15
|
+
? "unavailable"
|
|
16
|
+
: component.stale
|
|
17
|
+
? "restart needed"
|
|
18
|
+
: "current";
|
|
19
|
+
return html `
|
|
20
|
+
<div class="updates-version-row">
|
|
21
|
+
<strong>${component.label}</strong>
|
|
22
|
+
<span>${status}</span>
|
|
23
|
+
<small>running ${formatVersion(component.runtimeVersion)} · installed ${formatVersion(component.installedVersion)}</small>
|
|
24
|
+
<small>${installationLabel(component.installation)}${component.installation?.path === undefined ? "" : ` · ${component.installation.path}`}</small>
|
|
25
|
+
</div>
|
|
26
|
+
`;
|
|
27
|
+
}
|
|
28
|
+
function renderCommandActions(html, terminal, label, command) {
|
|
29
|
+
return html `
|
|
30
|
+
<span class="updates-command-actions">
|
|
31
|
+
<button @click=${() => { void navigator.clipboard.writeText(command); }}>Copy</button>
|
|
32
|
+
${terminal === undefined ? null : html `<button class="primary" @click=${() => { runCommandInTerminal(terminal, label, command); }}>Run</button>`}
|
|
33
|
+
</span>
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
function renderCommand(html, terminal, label, command) {
|
|
37
|
+
return html `
|
|
38
|
+
<div class="updates-command">
|
|
39
|
+
<span>${label}</span>
|
|
40
|
+
<code>${command}</code>
|
|
41
|
+
${renderCommandActions(html, terminal, label, command)}
|
|
42
|
+
</div>
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
function updatesRuntimeHintFromModuleUrl(moduleUrl) {
|
|
46
|
+
try {
|
|
47
|
+
const dockerMode = new URL(moduleUrl).searchParams.get("piWebUiDockerMode");
|
|
48
|
+
return dockerMode === "runtime" || dockerMode === "dev" ? { dockerMode } : {};
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const runtimeHint = updatesRuntimeHintFromModuleUrl(import.meta.url);
|
|
55
|
+
function renderCommands(html, terminal, status) {
|
|
56
|
+
const recommended = recommendedCommand(status);
|
|
57
|
+
const additional = additionalCommands(status, recommended);
|
|
58
|
+
if (recommended === undefined && additional.length === 0)
|
|
59
|
+
return undefined;
|
|
60
|
+
return html `
|
|
61
|
+
${recommended === undefined ? null : html `
|
|
62
|
+
<section class="updates-recommended">
|
|
63
|
+
<strong>Recommended</strong>
|
|
64
|
+
<p class="muted">Run this one command to bring this installation fully up to date. Nothing else is required.</p>
|
|
65
|
+
${renderCommand(html, terminal, recommended.label, recommended.command)}
|
|
66
|
+
</section>
|
|
67
|
+
`}
|
|
68
|
+
${additional.length === 0 ? null : html `
|
|
69
|
+
<section>
|
|
70
|
+
<strong>${recommended === undefined ? "Suggested commands" : "Additional commands (optional)"}</strong>
|
|
71
|
+
${recommended === undefined ? null : html `<p class="muted">Only needed for finer control, such as restarting a single service.</p>`}
|
|
72
|
+
${additional.map((entry) => renderCommand(html, terminal, entry.label, entry.command))}
|
|
73
|
+
</section>
|
|
74
|
+
`}
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
function renderUpdatesPanel(html, terminal, state) {
|
|
78
|
+
const status = statusFor(state) ?? fallbackDockerStatus(runtimeHint);
|
|
79
|
+
if (status === undefined) {
|
|
80
|
+
return html `
|
|
81
|
+
<section class="toolbar"><strong>Updates</strong></section>
|
|
82
|
+
<section class="viewer"><p class="muted">Checking PI WEBUI update status…</p></section>
|
|
83
|
+
`;
|
|
84
|
+
}
|
|
85
|
+
const messages = status.messages;
|
|
86
|
+
return html `
|
|
87
|
+
<style>
|
|
88
|
+
.viewer.updates-status { flex: 1 1 auto; min-height: 0; box-sizing: border-box; display: flex; flex-direction: column; gap: 14px; padding: 12px; overflow-y: auto; overflow-x: hidden; }
|
|
89
|
+
.viewer.updates-status section { flex: 0 0 auto; min-width: 0; display: grid; gap: 8px; }
|
|
90
|
+
.updates-message { display: grid; gap: 5px; border: 1px solid var(--pi-border); border-radius: 8px; padding: 10px; background: var(--pi-surface); }
|
|
91
|
+
.updates-message.warning { border-color: var(--pi-warning-border); background: var(--pi-warning-surface); }
|
|
92
|
+
.updates-message.error { border-color: var(--pi-danger); }
|
|
93
|
+
.updates-message-title { display: flex; gap: 8px; align-items: baseline; }
|
|
94
|
+
.updates-message-title span { color: var(--pi-muted); font-size: 12px; text-transform: uppercase; }
|
|
95
|
+
.updates-version-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px 10px; border-bottom: 1px solid var(--pi-border-muted); padding: 6px 0; }
|
|
96
|
+
.updates-version-row small { grid-column: 1 / -1; color: var(--pi-muted); }
|
|
97
|
+
.updates-command { min-width: 0; display: grid; grid-template-columns: minmax(90px, auto) minmax(0, 1fr) auto; gap: 8px; align-items: center; }
|
|
98
|
+
.updates-command code { overflow: auto; border: 1px solid var(--pi-border-muted); border-radius: 6px; background: var(--pi-bg); padding: 5px 7px; white-space: nowrap; }
|
|
99
|
+
.updates-command-inline { grid-template-columns: minmax(0, 1fr) auto; }
|
|
100
|
+
.updates-command-actions { display: inline-flex; gap: 6px; }
|
|
101
|
+
.updates-command-actions button.primary { border-color: var(--pi-accent-border); color: var(--pi-text-bright); }
|
|
102
|
+
.updates-recommended { border: 1px solid var(--pi-accent-border); border-radius: 8px; padding: 10px; background: var(--pi-surface); }
|
|
103
|
+
.updates-recommended > strong { color: var(--pi-text-bright); }
|
|
104
|
+
.updates-meta { display: grid; gap: 2px; color: var(--pi-muted); font-size: 12px; }
|
|
105
|
+
@media (max-width: 520px) {
|
|
106
|
+
.updates-command { grid-template-columns: minmax(0, 1fr) auto; }
|
|
107
|
+
.updates-command > span { grid-column: 1 / -1; }
|
|
108
|
+
}
|
|
109
|
+
</style>
|
|
110
|
+
<section class="toolbar"><strong>Updates</strong>${messages.length > 0 ? html `<span class="stale">${String(messages.length)}</span>` : null}</section>
|
|
111
|
+
<section class="viewer updates-status">
|
|
112
|
+
<section>
|
|
113
|
+
${messages.length === 0 ? html `<p class="muted">No PI WEBUI update or restart messages.</p>` : messages.map((message) => html `
|
|
114
|
+
<article class=${`updates-message ${message.severity}`}>
|
|
115
|
+
<div class="updates-message-title"><strong>${message.title}</strong><span>${message.severity}</span></div>
|
|
116
|
+
<p>${message.body}</p>
|
|
117
|
+
${message.command === undefined ? null : html `
|
|
118
|
+
<div class="updates-command updates-command-inline">
|
|
119
|
+
<code>${message.command}</code>
|
|
120
|
+
${renderCommandActions(html, terminal, message.title, message.command)}
|
|
121
|
+
</div>
|
|
122
|
+
`}
|
|
123
|
+
</article>
|
|
124
|
+
`)}
|
|
125
|
+
</section>
|
|
126
|
+
|
|
127
|
+
<section>
|
|
128
|
+
<strong>Installed services</strong>
|
|
129
|
+
${renderComponent(html, status.components.web)}
|
|
130
|
+
${renderComponent(html, status.components.sessiond)}
|
|
131
|
+
</section>
|
|
132
|
+
|
|
133
|
+
${renderCommands(html, terminal, status)}
|
|
134
|
+
|
|
135
|
+
<section class="updates-meta">
|
|
136
|
+
<span>Generated ${status.generatedAt}</span>
|
|
137
|
+
${status.release.latestVersion === undefined ? null : html `<span>Latest npm release ${status.release.latestVersion}</span>`}
|
|
138
|
+
${status.release.checkedAt === undefined || status.release.skipped === true ? null : html `<span>Release checked ${status.release.checkedAt}</span>`}
|
|
139
|
+
${status.release.skipped === true ? html `<span>Remote version check skipped.</span>` : null}
|
|
140
|
+
${status.release.error === undefined ? null : html `<span>Remote version check failed: ${status.release.error}</span>`}
|
|
141
|
+
</section>
|
|
142
|
+
</section>
|
|
143
|
+
`;
|
|
144
|
+
}
|
|
145
|
+
const plugin = {
|
|
146
|
+
apiVersion: 1,
|
|
147
|
+
name: "Updates",
|
|
148
|
+
activate: ({ html, svg }) => ({
|
|
149
|
+
contributions: {
|
|
150
|
+
actions: [
|
|
151
|
+
{
|
|
152
|
+
id: "check",
|
|
153
|
+
title: "Check for PI WEBUI Updates",
|
|
154
|
+
description: "Bypass cached release data and check the selected machine now",
|
|
155
|
+
group: "Updates",
|
|
156
|
+
enabled: (context) => context.checkForPiWebUiUpdates !== undefined,
|
|
157
|
+
disabledReason: () => "Update checks require a newer PI WEBUI gateway",
|
|
158
|
+
run: (context) => context.checkForPiWebUiUpdates?.(),
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
workspacePanels: [
|
|
162
|
+
{
|
|
163
|
+
id: "workspace.updates",
|
|
164
|
+
title: "Updates",
|
|
165
|
+
icon: svg `
|
|
166
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
167
|
+
<path d="M20 6v5h-5"></path>
|
|
168
|
+
<path d="M4 18v-5h5"></path>
|
|
169
|
+
<path d="M18.4 9A7 7 0 0 0 6.1 6.7L4 8.8"></path>
|
|
170
|
+
<path d="M5.6 15A7 7 0 0 0 17.9 17.3L20 15.2"></path>
|
|
171
|
+
</svg>
|
|
172
|
+
`,
|
|
173
|
+
order: 100,
|
|
174
|
+
visible: (context) => shouldShowUpdatesPanel(context.state, runtimeHint),
|
|
175
|
+
badge: (context) => {
|
|
176
|
+
const count = messageCount(context.state);
|
|
177
|
+
return count > 0 ? count : undefined;
|
|
178
|
+
},
|
|
179
|
+
render: (context) => renderUpdatesPanel(html, context.terminal, context.state),
|
|
180
|
+
},
|
|
181
|
+
],
|
|
182
|
+
},
|
|
183
|
+
}),
|
|
184
|
+
};
|
|
185
|
+
export default plugin;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Generated from pi-webui-plugins/updates/updatesLogic.ts. Do not edit directly.
|
|
2
|
+
// The single command users should run when they do not want to think: if an
|
|
3
|
+
// update is available, `commands.update` already chains the update and a full
|
|
4
|
+
// restart; otherwise, when anything is stale, a full restart is enough.
|
|
5
|
+
export function recommendedCommand(status) {
|
|
6
|
+
const { commands, release, components } = status;
|
|
7
|
+
if (release.updateAvailable && typeof commands.update === "string" && commands.update !== "") {
|
|
8
|
+
return { label: "Update & restart everything", command: commands.update };
|
|
9
|
+
}
|
|
10
|
+
const restartNeeded = components.web.stale || components.sessiond.stale || !components.sessiond.available;
|
|
11
|
+
if (restartNeeded && typeof commands.restart === "string" && commands.restart !== "") {
|
|
12
|
+
return { label: "Restart everything", command: commands.restart };
|
|
13
|
+
}
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
export function additionalCommands(status, recommended) {
|
|
17
|
+
return [
|
|
18
|
+
["Update", status.commands.update],
|
|
19
|
+
["Restart all", status.commands.restart],
|
|
20
|
+
["Restart Web/UI", status.commands.restartWeb],
|
|
21
|
+
["Restart session daemon", status.commands.restartSessiond],
|
|
22
|
+
["Status", status.commands.status],
|
|
23
|
+
]
|
|
24
|
+
.filter((entry) => typeof entry[1] === "string" && entry[1] !== "")
|
|
25
|
+
.filter(([, command]) => command !== recommended?.command)
|
|
26
|
+
.map(([label, command]) => ({ label, command }));
|
|
27
|
+
}
|
|
28
|
+
export function messagesFor(state) {
|
|
29
|
+
return state?.piWebUiStatus?.messages ?? [];
|
|
30
|
+
}
|
|
31
|
+
export function statusFor(state) {
|
|
32
|
+
return state?.piWebUiStatus;
|
|
33
|
+
}
|
|
34
|
+
export function messageCount(state) {
|
|
35
|
+
return messagesFor(state).length;
|
|
36
|
+
}
|
|
37
|
+
export function isSelfManagedInstallation(installation) {
|
|
38
|
+
return installation === undefined || installation.kind === "local" || installation.kind === "docker" || installation.kind === "unknown";
|
|
39
|
+
}
|
|
40
|
+
export function shouldShowUpdatesPanel(state, hint = {}) {
|
|
41
|
+
const status = statusFor(state);
|
|
42
|
+
if (hint.dockerMode !== undefined)
|
|
43
|
+
return true;
|
|
44
|
+
if (messageCount(state) > 0)
|
|
45
|
+
return true;
|
|
46
|
+
if (status === undefined)
|
|
47
|
+
return false;
|
|
48
|
+
return isSelfManagedInstallation(status.components.web.installation)
|
|
49
|
+
|| isSelfManagedInstallation(status.components.sessiond.installation);
|
|
50
|
+
}
|
|
51
|
+
export function fallbackDockerStatus(hint, generatedAt = "federated status unavailable") {
|
|
52
|
+
if (hint.dockerMode === undefined)
|
|
53
|
+
return undefined;
|
|
54
|
+
const commandPrefix = hint.dockerMode === "dev" ? "pi-webui-docker --dev" : "pi-webui-docker";
|
|
55
|
+
const installation = { kind: "docker", dockerMode: hint.dockerMode };
|
|
56
|
+
return {
|
|
57
|
+
packageName: "@hyperdreamer/pi-webui",
|
|
58
|
+
generatedAt,
|
|
59
|
+
components: {
|
|
60
|
+
web: { component: "web", label: "Web/UI", stale: false, available: true, installation },
|
|
61
|
+
sessiond: { component: "sessiond", label: "Session daemon", stale: false, available: true, installation },
|
|
62
|
+
},
|
|
63
|
+
release: { packageName: "@hyperdreamer/pi-webui", updateAvailable: false, skipped: true },
|
|
64
|
+
commands: {
|
|
65
|
+
update: `${commandPrefix} update`,
|
|
66
|
+
restart: `${commandPrefix} restart`,
|
|
67
|
+
restartWeb: `${commandPrefix} restart-web`,
|
|
68
|
+
restartSessiond: `${commandPrefix} restart-sessiond`,
|
|
69
|
+
status: `${commandPrefix} status`,
|
|
70
|
+
},
|
|
71
|
+
messages: [{
|
|
72
|
+
id: "docker-status-compatibility",
|
|
73
|
+
severity: "info",
|
|
74
|
+
title: "Docker update commands available",
|
|
75
|
+
body: "This Updates plugin was loaded from a Docker PI WEBUI runtime, but the gateway has not provided Docker-aware status details yet. The Docker maintenance commands below are still available.",
|
|
76
|
+
}],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export function formatVersion(version) {
|
|
80
|
+
return version === undefined || version === "" ? "unknown" : version;
|
|
81
|
+
}
|
|
82
|
+
export function installationLabel(installation) {
|
|
83
|
+
if (installation === undefined)
|
|
84
|
+
return "installation unknown";
|
|
85
|
+
if (installation.kind === "pi-package") {
|
|
86
|
+
const scope = installation.scope === undefined ? "" : ` · ${installation.scope}`;
|
|
87
|
+
const source = installation.source ?? "Pi package";
|
|
88
|
+
return `${source}${scope}`;
|
|
89
|
+
}
|
|
90
|
+
if (installation.kind === "npm-global")
|
|
91
|
+
return "global npm package";
|
|
92
|
+
if (installation.kind === "local")
|
|
93
|
+
return "local checkout";
|
|
94
|
+
if (installation.kind === "docker")
|
|
95
|
+
return installation.dockerMode === "dev" ? "Docker development runtime" : "Docker runtime";
|
|
96
|
+
return "installation unknown";
|
|
97
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Generated from pi-webui-plugins/workspace-tasks/config.ts. Do not edit directly.
|
|
2
|
+
export const TASKS_CONFIG_PATH = ".pi-webui/tasks.json";
|
|
3
|
+
export const TASKS_CONFIG_VERSION = 1;
|
|
4
|
+
const taskIdPattern = /^[a-z][a-z0-9.-]*$/u;
|
|
5
|
+
export function parseTasksConfigText(text) {
|
|
6
|
+
let parsed;
|
|
7
|
+
try {
|
|
8
|
+
parsed = JSON.parse(text);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
return { ok: false, error: `Invalid JSON: ${error instanceof Error ? error.message : String(error)}` };
|
|
12
|
+
}
|
|
13
|
+
return parseTasksConfig(parsed);
|
|
14
|
+
}
|
|
15
|
+
export function parseTasksConfig(value) {
|
|
16
|
+
if (!isRecord(value))
|
|
17
|
+
return invalid("Config must be an object");
|
|
18
|
+
if (value["version"] !== TASKS_CONFIG_VERSION)
|
|
19
|
+
return invalid("Config version must be 1");
|
|
20
|
+
const tasks = value["tasks"];
|
|
21
|
+
if (!Array.isArray(tasks))
|
|
22
|
+
return invalid("Config tasks must be an array");
|
|
23
|
+
const ids = new Set();
|
|
24
|
+
const parsedTasks = [];
|
|
25
|
+
for (const [index, task] of tasks.entries()) {
|
|
26
|
+
const parsedTask = parseTask(task, index);
|
|
27
|
+
if (!parsedTask.ok)
|
|
28
|
+
return parsedTask;
|
|
29
|
+
if (ids.has(parsedTask.task.id))
|
|
30
|
+
return invalid(`Duplicate task id: ${parsedTask.task.id}`);
|
|
31
|
+
ids.add(parsedTask.task.id);
|
|
32
|
+
parsedTasks.push(parsedTask.task);
|
|
33
|
+
}
|
|
34
|
+
return { ok: true, config: { version: TASKS_CONFIG_VERSION, tasks: parsedTasks } };
|
|
35
|
+
}
|
|
36
|
+
function parseTask(value, index) {
|
|
37
|
+
const label = `Task ${String(index + 1)}`;
|
|
38
|
+
if (!isRecord(value))
|
|
39
|
+
return invalid(`${label} must be an object`);
|
|
40
|
+
const id = requireNonEmptyString(value, "id", label);
|
|
41
|
+
if (!id.ok)
|
|
42
|
+
return id;
|
|
43
|
+
if (!taskIdPattern.test(id.value))
|
|
44
|
+
return invalid(`${label} id must match ${taskIdPattern.source}`);
|
|
45
|
+
const title = requireNonEmptyString(value, "title", label);
|
|
46
|
+
if (!title.ok)
|
|
47
|
+
return title;
|
|
48
|
+
const command = requireNonEmptyString(value, "command", label);
|
|
49
|
+
if (!command.ok)
|
|
50
|
+
return command;
|
|
51
|
+
const description = optionalNonEmptyString(value, "description", label);
|
|
52
|
+
if (!description.ok)
|
|
53
|
+
return description;
|
|
54
|
+
const group = optionalNonEmptyString(value, "group", label);
|
|
55
|
+
if (!group.ok)
|
|
56
|
+
return group;
|
|
57
|
+
const confirm = value["confirm"];
|
|
58
|
+
if (confirm !== undefined && typeof confirm !== "boolean")
|
|
59
|
+
return invalid(`${label} confirm must be a boolean`);
|
|
60
|
+
return {
|
|
61
|
+
ok: true,
|
|
62
|
+
task: {
|
|
63
|
+
id: id.value,
|
|
64
|
+
title: title.value,
|
|
65
|
+
command: command.value,
|
|
66
|
+
...(description.value === undefined ? {} : { description: description.value }),
|
|
67
|
+
...(group.value === undefined ? {} : { group: group.value }),
|
|
68
|
+
confirm: confirm ?? false,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function requireNonEmptyString(record, key, label) {
|
|
73
|
+
const value = record[key];
|
|
74
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
75
|
+
return invalid(`${label} ${key} must be a non-empty string`);
|
|
76
|
+
return { ok: true, value };
|
|
77
|
+
}
|
|
78
|
+
function optionalNonEmptyString(record, key, label) {
|
|
79
|
+
const value = record[key];
|
|
80
|
+
if (value === undefined)
|
|
81
|
+
return { ok: true, value: undefined };
|
|
82
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
83
|
+
return invalid(`${label} ${key} must be a non-empty string when provided`);
|
|
84
|
+
return { ok: true, value };
|
|
85
|
+
}
|
|
86
|
+
function invalid(error) {
|
|
87
|
+
return { ok: false, error };
|
|
88
|
+
}
|
|
89
|
+
function isRecord(value) {
|
|
90
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
91
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Generated from pi-webui-plugins/workspace-tasks/pi-webui-plugin.ts. Do not edit directly.
|
|
2
|
+
import { TASKS_CONFIG_PATH } from "./config.js";
|
|
3
|
+
import { defineTasksPanelElement, tasksPanelBadge } from "./tasksPanelElement.js";
|
|
4
|
+
const plugin = {
|
|
5
|
+
apiVersion: 1,
|
|
6
|
+
name: "Workspace Tasks",
|
|
7
|
+
activate: ({ pluginId, html, svg }) => {
|
|
8
|
+
defineTasksPanelElement();
|
|
9
|
+
return {
|
|
10
|
+
contributions: {
|
|
11
|
+
actions: [
|
|
12
|
+
{
|
|
13
|
+
id: "workspace.open-tasks",
|
|
14
|
+
title: "Open Workspace Tasks",
|
|
15
|
+
description: `Open the workspace Tasks tab. Configure tasks in ${TASKS_CONFIG_PATH}.`,
|
|
16
|
+
group: "Workspace",
|
|
17
|
+
enabled: (context) => context.state.selectedWorkspace !== undefined,
|
|
18
|
+
run: (context) => {
|
|
19
|
+
if (context.state.selectedWorkspace === undefined)
|
|
20
|
+
return;
|
|
21
|
+
context.selectWorkspaceTool(`${pluginId}:workspace.tasks`);
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
workspacePanels: [
|
|
26
|
+
{
|
|
27
|
+
id: "workspace.tasks",
|
|
28
|
+
title: "Tasks",
|
|
29
|
+
icon: svg `
|
|
30
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
31
|
+
<path d="M9 6h11"></path>
|
|
32
|
+
<path d="M9 12h11"></path>
|
|
33
|
+
<path d="M9 18h11"></path>
|
|
34
|
+
<path d="m4 6 .8 .8L6.5 5"></path>
|
|
35
|
+
<path d="m4 12 .8 .8 1.7-1.8"></path>
|
|
36
|
+
<path d="m4 18 .8 .8 1.7-1.8"></path>
|
|
37
|
+
</svg>
|
|
38
|
+
`,
|
|
39
|
+
order: 40,
|
|
40
|
+
badge: (context) => tasksPanelBadge(context),
|
|
41
|
+
render: (context) => html `<pi-webui-workspace-tasks-panel .context=${context}></pi-webui-workspace-tasks-panel>`,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
export default plugin;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Generated from pi-webui-plugins/workspace-tasks/taskRunner.ts. Do not edit directly.
|
|
2
|
+
export function runWorkspaceTaskInTerminal(terminal, task) {
|
|
3
|
+
return terminal.runCommand({
|
|
4
|
+
title: task.title,
|
|
5
|
+
command: task.command,
|
|
6
|
+
open: true,
|
|
7
|
+
metadata: {
|
|
8
|
+
"pi.plugin": "workspace-tasks",
|
|
9
|
+
"task.id": task.id,
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
}
|