@chainingintention/pi-web-cn 1.202610.2 → 1.202610.4
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/README.md +1 -0
- package/dist/cli.js +129 -122
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/PiWebApp-CN3g7SqA.js +4362 -0
- package/dist/client/assets/external-DUGCSDhZ.js +2 -0
- package/dist/client/assets/index-JduZlbIF.js +2 -0
- package/dist/client/index.html +4 -4
- package/dist/client/manifest.webmanifest +2 -1
- package/dist/localization.js +24 -0
- package/dist/localization.js.map +1 -0
- package/dist/nativeServices/serviceDoctor.js +45 -44
- package/dist/nativeServices/serviceDoctor.js.map +1 -1
- package/dist/pi-packages/captains-log/dist/browser/index.js +46 -45
- package/dist/pi-packages/captains-log/dist/browser/markdown.js +2 -1
- package/dist/pi-packages/captains-log/dist/browser/panel.js +56 -55
- package/dist/pi-packages/captains-log/i18n.js +7 -0
- package/dist/pi-packages/relays/i18n.js +7 -0
- package/dist/pi-packages/relays/markdownDocument.js +2 -1
- package/dist/pi-packages/relays/pi-web-plugin.js +8 -6
- package/dist/pi-packages/relays/relaysPanelElement.js +24 -23
- package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +124 -124
- package/dist/pi-web-plugins/git/browser/git-contract.js +13 -12
- package/dist/pi-web-plugins/git/browser/git-panel.js +25 -24
- package/dist/pi-web-plugins/git/browser/i18n.js +7 -0
- package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +7 -3
- package/dist/pi-web-plugins/git/git-backend.js +10 -9
- package/dist/pi-web-plugins/git/i18n.js +7 -0
- package/dist/pi-web-plugins/git/server-plugin.js +21 -19
- package/dist/pi-web-plugins/info/i18n.js +7 -0
- package/dist/pi-web-plugins/info/infoInternals.js +57 -62
- package/dist/pi-web-plugins/info/pi-web-plugin.js +34 -36
- package/dist/pi-web-plugins/mermaid/browser/pi-web-plugin.js +3 -3
- package/dist/pi-web-plugins/terminal/browser/pi-web-plugin.js +55 -52
- package/dist/pi-web-plugins/terminal/i18n.js +7 -0
- package/dist/pi-web-plugins/terminal/server-plugin.js +23 -21
- package/dist/pi-web-plugins/terminal/terminalService.js +22 -21
- package/dist/pi-web-plugins/updates/i18n.js +7 -0
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +58 -54
- package/dist/pi-web-plugins/updates/updatesLogic.js +21 -20
- package/dist/pi-web-plugins/workspace-tasks/config.js +12 -11
- package/dist/pi-web-plugins/workspace-tasks/i18n.js +7 -0
- package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +8 -6
- package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +20 -19
- package/dist/pi-web-plugins/workspace-tasks/workspaceTasksClient.js +12 -11
- package/dist/pi-web-plugins/zh-cn/auth.json +9 -0
- package/dist/pi-web-plugins/zh-cn/bundled.json +176 -0
- package/dist/pi-web-plugins/zh-cn/cli.json +171 -0
- package/dist/pi-web-plugins/zh-cn/client.json +219 -0
- package/dist/pi-web-plugins/zh-cn/components.json +1002 -0
- package/dist/pi-web-plugins/zh-cn/config-errors.json +172 -0
- package/dist/pi-web-plugins/zh-cn/files.json +41 -0
- package/dist/pi-web-plugins/zh-cn/machines.json +28 -0
- package/dist/pi-web-plugins/zh-cn/main.json +459 -0
- package/dist/pi-web-plugins/zh-cn/management-errors.json +23 -0
- package/dist/pi-web-plugins/zh-cn/manifest.webmanifest +25 -0
- package/dist/pi-web-plugins/zh-cn/metadata.json +3 -0
- package/dist/pi-web-plugins/zh-cn/package.json +10 -0
- package/dist/pi-web-plugins/zh-cn/pi-web-plugin.js +16 -0
- package/dist/pi-web-plugins/zh-cn/projects.json +6 -0
- package/dist/pi-web-plugins/zh-cn/provider-auth.json +17 -0
- package/dist/pi-web-plugins/zh-cn/routing.json +68 -0
- package/dist/pi-web-plugins/zh-cn/server-main.json +99 -0
- package/dist/pi-web-plugins/zh-cn/server.json +174 -0
- package/dist/piWebVersionReport.js +17 -16
- package/dist/piWebVersionReport.js.map +1 -1
- package/dist/plugin-api.d.ts +4 -1
- package/dist/pluginRecoveryCli.js +25 -24
- package/dist/pluginRecoveryCli.js.map +1 -1
- package/dist/server/app.js +43 -28
- package/dist/server/app.js.map +1 -1
- package/dist/server/audit/normalToolAuditCli.js +45 -43
- package/dist/server/audit/normalToolAuditCli.js.map +1 -1
- package/dist/server/configRoutes.js +39 -30
- package/dist/server/configRoutes.js.map +1 -1
- package/dist/server/diagnostics/nodePtyNativeModule.js +7 -6
- package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -1
- package/dist/server/diagnostics/nodePtySpawnHelper.js +21 -20
- package/dist/server/diagnostics/nodePtySpawnHelper.js.map +1 -1
- package/dist/server/knownAutoInstallPiPackages.js +2 -2
- package/dist/server/knownAutoInstallPiPackages.js.map +1 -1
- package/dist/server/knownPiPackages.js +2 -2
- package/dist/server/knownPiPackages.js.map +1 -1
- package/dist/server/machines/machineClient.js +8 -6
- package/dist/server/machines/machineClient.js.map +1 -1
- package/dist/server/machines/machinePluginProxyRoutes.js +11 -10
- package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineProxyRoutes.js +27 -29
- package/dist/server/machines/machineProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineRoutes.js +10 -12
- package/dist/server/machines/machineRoutes.js.map +1 -1
- package/dist/server/machines/machineService.js +17 -18
- package/dist/server/machines/machineService.js.map +1 -1
- package/dist/server/managementEmbed.js +26 -25
- package/dist/server/managementEmbed.js.map +1 -1
- package/dist/server/normalAuth.js +29 -26
- package/dist/server/normalAuth.js.map +1 -1
- package/dist/server/passwordVerifier.js +2 -1
- package/dist/server/passwordVerifier.js.map +1 -1
- package/dist/server/piPackageService.js +7 -5
- package/dist/server/piPackageService.js.map +1 -1
- package/dist/server/piWebPluginService.js +27 -11
- package/dist/server/piWebPluginService.js.map +1 -1
- package/dist/server/piWebStatus.js +16 -14
- package/dist/server/piWebStatus.js.map +1 -1
- package/dist/server/plugins/serverPluginRuntime.js +4 -2
- package/dist/server/plugins/serverPluginRuntime.js.map +1 -1
- package/dist/server/projects/projectService.js +4 -3
- package/dist/server/projects/projectService.js.map +1 -1
- package/dist/server/sessiond/projectMutationRoutes.js +5 -4
- package/dist/server/sessiond/projectMutationRoutes.js.map +1 -1
- package/dist/server/sessiond/sessionProxyRoutes.js +11 -8
- package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
- package/dist/server/sessiond/workspaceCatalogRoutes.js +5 -3
- package/dist/server/sessiond/workspaceCatalogRoutes.js.map +1 -1
- package/dist/server/sessiond.js +8 -3
- package/dist/server/sessiond.js.map +1 -1
- package/dist/server/sessions/authRoutes.js +20 -19
- package/dist/server/sessions/authRoutes.js.map +1 -1
- package/dist/server/sessions/authService.js +13 -10
- package/dist/server/sessions/authService.js.map +1 -1
- package/dist/server/sessions/builtinCommands.js +28 -21
- package/dist/server/sessions/builtinCommands.js.map +1 -1
- package/dist/server/sessions/oauthLoginFlowService.js +17 -15
- package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
- package/dist/server/sessions/piSessionService.js +229 -208
- package/dist/server/sessions/piSessionService.js.map +1 -1
- package/dist/server/sessions/projectAuthService.js +5 -3
- package/dist/server/sessions/projectAuthService.js.map +1 -1
- package/dist/server/sessions/sessionArchiveMapping.js +8 -7
- package/dist/server/sessions/sessionArchiveMapping.js.map +1 -1
- package/dist/server/sessions/sessionCleanup.js +4 -3
- package/dist/server/sessions/sessionCleanup.js.map +1 -1
- package/dist/server/sessions/sessionCommandService.js +70 -67
- package/dist/server/sessions/sessionCommandService.js.map +1 -1
- package/dist/server/sessions/sessionNotificationStore.js +12 -11
- package/dist/server/sessions/sessionNotificationStore.js.map +1 -1
- package/dist/server/sessions/sessionRoutes.js +74 -72
- package/dist/server/sessions/sessionRoutes.js.map +1 -1
- package/dist/server/sessions/sessionTreeProjection.js +50 -49
- package/dist/server/sessions/sessionTreeProjection.js.map +1 -1
- package/dist/server/sessions/sessionUnreadStore.js +25 -2
- package/dist/server/sessions/sessionUnreadStore.js.map +1 -1
- package/dist/server/terminals/managementCommandRunService.js +13 -12
- package/dist/server/terminals/managementCommandRunService.js.map +1 -1
- package/dist/server/workbench/accessStateStore.js +9 -7
- package/dist/server/workbench/accessStateStore.js.map +1 -1
- package/dist/server/workbench/capabilitySearch.js +3 -2
- package/dist/server/workbench/capabilitySearch.js.map +1 -1
- package/dist/server/workbench/knowledgeSearch.js +8 -7
- package/dist/server/workbench/knowledgeSearch.js.map +1 -1
- package/dist/server/workbench/mcpClient.js +6 -5
- package/dist/server/workbench/mcpClient.js.map +1 -1
- package/dist/server/workbench/skillSync.js +4 -2
- package/dist/server/workbench/skillSync.js.map +1 -1
- package/dist/server/workbench/workbenchClient.js +8 -7
- package/dist/server/workbench/workbenchClient.js.map +1 -1
- package/dist/server/workbench/workbenchTools.js +8 -6
- package/dist/server/workbench/workbenchTools.js.map +1 -1
- package/dist/server/workingDirectory.js +3 -2
- package/dist/server/workingDirectory.js.map +1 -1
- package/dist/server/workspaceExplorerRoutes.js +16 -13
- package/dist/server/workspaceExplorerRoutes.js.map +1 -1
- package/dist/server/workspaces/fileContentService.js +11 -10
- package/dist/server/workspaces/fileContentService.js.map +1 -1
- package/dist/server/workspaces/fileOperationService.js +7 -6
- package/dist/server/workspaces/fileOperationService.js.map +1 -1
- package/dist/server/workspaces/filePreviewService.js +5 -4
- package/dist/server/workspaces/filePreviewService.js.map +1 -1
- package/dist/server/workspaces/fileSuggestions.js +2 -1
- package/dist/server/workspaces/fileSuggestions.js.map +1 -1
- package/dist/server/workspaces/pathAccessPolicy.js +24 -18
- package/dist/server/workspaces/pathAccessPolicy.js.map +1 -1
- package/dist/server/workspaces/pathSafety.js +6 -5
- package/dist/server/workspaces/pathSafety.js.map +1 -1
- package/dist/server/workspaces/projectPiWebConfig.js +3 -2
- package/dist/server/workspaces/projectPiWebConfig.js.map +1 -1
- package/dist/server/workspaces/workspaceRemovalService.js +4 -3
- package/dist/server/workspaces/workspaceRemovalService.js.map +1 -1
- package/dist/server/workspaces/workspaceRouteErrors.js +4 -2
- package/dist/server/workspaces/workspaceRouteErrors.js.map +1 -1
- package/dist/server/workspaces/workspaceUserError.js +18 -0
- package/dist/server/workspaces/workspaceUserError.js.map +1 -0
- package/dist/server-plugin-api.d.ts +3 -1
- package/dist/server-plugin-api.js.map +1 -1
- package/dist/serverPluginRecovery.js +3 -2
- package/dist/serverPluginRecovery.js.map +1 -1
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/i18n.js +41 -0
- package/dist/shared/i18n.js.map +1 -0
- package/dist/shared/piWebConfigParsing.js +52 -49
- package/dist/shared/piWebConfigParsing.js.map +1 -1
- package/dist/shared/pluginApiTypes.d.ts +7 -0
- package/dist/shared/requiredTerminalPlugin.js +1 -1
- package/dist/shared/requiredTerminalPlugin.js.map +1 -1
- package/dist/shared/sessionDefaults.js +7 -6
- package/dist/shared/sessionDefaults.js.map +1 -1
- package/dist/shared/thinkingLevels.js +17 -16
- package/dist/shared/thinkingLevels.js.map +1 -1
- package/docs/config.md +10 -1
- package/docs/plugins.md +8 -0
- package/package.json +1 -1
- package/dist/client/assets/index-CFhaGb5m.js +0 -4357
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Generated from pi-web-plugins/terminal/server/i18n.ts. Do not edit directly.
|
|
2
|
+
let translate;
|
|
3
|
+
export function setTranslator(value) {
|
|
4
|
+
translate = value;
|
|
5
|
+
}
|
|
6
|
+
export const t = (key, fallback, params) => translate?.(key, fallback, params)
|
|
7
|
+
?? fallback.replace(/\{([A-Za-z0-9_]+)\}/g, (match, name) => String(params?.[name] ?? match));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Generated from pi-web-plugins/terminal/server/server-plugin.ts. Do not edit directly.
|
|
2
|
+
import { t, setTranslator } from "./i18n.js";
|
|
2
3
|
import { TerminalService, } from "./terminalService.js";
|
|
3
4
|
const TERMINAL_CHANNEL_OUTPUT_FRAME_TARGET_BYTES = 60 * 1024;
|
|
4
5
|
export const TERMINAL_SERVICE_CAPABILITY = Object.freeze({
|
|
@@ -9,19 +10,20 @@ export const TERMINAL_SERVICE_CAPABILITY = Object.freeze({
|
|
|
9
10
|
});
|
|
10
11
|
const plugin = {
|
|
11
12
|
apiVersion: 3,
|
|
12
|
-
name: "
|
|
13
|
+
name: t("client.panels.terminal.e2a76e", "Terminal"),
|
|
13
14
|
activate(context) {
|
|
14
15
|
return activateTerminalPlugin(context);
|
|
15
16
|
},
|
|
16
17
|
};
|
|
17
18
|
export default plugin;
|
|
18
19
|
export function activateTerminalPlugin(context) {
|
|
20
|
+
setTranslator(context.translate);
|
|
19
21
|
if (context.pluginId !== "pi-web.terminal") {
|
|
20
|
-
throw new Error(
|
|
22
|
+
throw new Error(t("ui.main.4b7ba025964e", "The terminal server entry must activate as pi-web.terminal, received {arg0}", { arg0: context.pluginId }));
|
|
21
23
|
}
|
|
22
24
|
const notices = context.notices;
|
|
23
25
|
if (notices?.version !== 1) {
|
|
24
|
-
throw new Error("
|
|
26
|
+
throw new Error(t("ui.main.1bf6de0c1567", "Terminal server entry requires server notice reporter version 1"));
|
|
25
27
|
}
|
|
26
28
|
const service = new TerminalService((input) => { notices.record(input); });
|
|
27
29
|
const requiredTerminalService = Object.freeze({
|
|
@@ -38,7 +40,7 @@ export function activateTerminalPlugin(context) {
|
|
|
38
40
|
peer: createTerminalPeer(service, context),
|
|
39
41
|
provides: Object.freeze([serviceProvision]),
|
|
40
42
|
health: () => stopped
|
|
41
|
-
? Object.freeze({ status: "unhealthy", message: "
|
|
43
|
+
? Object.freeze({ status: "unhealthy", message: t("ui.main.ee0fa7cb477f", "Terminal service is stopped") })
|
|
42
44
|
: Object.freeze({ status: "healthy" }),
|
|
43
45
|
dispose: () => {
|
|
44
46
|
if (stopped)
|
|
@@ -50,7 +52,7 @@ export function activateTerminalPlugin(context) {
|
|
|
50
52
|
}
|
|
51
53
|
function snapshotTerminalServiceCapability(value) {
|
|
52
54
|
if (!isRequiredTerminalServiceContribution(value)) {
|
|
53
|
-
throw new Error("
|
|
55
|
+
throw new Error(t("ui.main.11f40a27d612", "Terminal service capability must expose closeForCwd, runCommand, and bindActivitySink"));
|
|
54
56
|
}
|
|
55
57
|
return Object.freeze({
|
|
56
58
|
closeForCwd: (cwd) => { value.closeForCwd(cwd); },
|
|
@@ -107,12 +109,12 @@ function terminalRequest(service, context) {
|
|
|
107
109
|
case "terminal.cancel-run":
|
|
108
110
|
return commandRunJson(service.cancelCommandRunForScope(scope, requireIdInput(context.input, context.operation, "runId")));
|
|
109
111
|
default:
|
|
110
|
-
throw new Error(
|
|
112
|
+
throw new Error(t("ui.main.1ba4d446a5f7", "Unsupported terminal operation: {arg0}", { arg0: context.operation }));
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
115
|
function openTerminalChannel(service, context, activationContext) {
|
|
114
116
|
if (context.operation !== "terminal.attach") {
|
|
115
|
-
throw new Error(
|
|
117
|
+
throw new Error(t("ui.main.745a3a62852f", "Unsupported terminal channel operation: {arg0}", { arg0: context.operation }));
|
|
116
118
|
}
|
|
117
119
|
throwIfAborted(context.signal);
|
|
118
120
|
const scope = terminalScope(context);
|
|
@@ -134,7 +136,7 @@ function openTerminalChannel(service, context, activationContext) {
|
|
|
134
136
|
if (opening)
|
|
135
137
|
throw error;
|
|
136
138
|
detach();
|
|
137
|
-
activationContext?.logger.error("
|
|
139
|
+
activationContext?.logger.error("Terminal channel output failed", {
|
|
138
140
|
terminalId,
|
|
139
141
|
message: boundedErrorMessage(error),
|
|
140
142
|
});
|
|
@@ -178,7 +180,7 @@ function openTerminalChannel(service, context, activationContext) {
|
|
|
178
180
|
service.resize(scope, terminalId, parsed.cols, parsed.rows);
|
|
179
181
|
return;
|
|
180
182
|
}
|
|
181
|
-
throw new Error(
|
|
183
|
+
throw new Error(t("ui.main.8de3f24e9b34", "Unsupported terminal channel message: {arg0}", { arg0: type }));
|
|
182
184
|
},
|
|
183
185
|
close() {
|
|
184
186
|
cleanup();
|
|
@@ -187,7 +189,7 @@ function openTerminalChannel(service, context, activationContext) {
|
|
|
187
189
|
}
|
|
188
190
|
function terminalScope(context) {
|
|
189
191
|
if (context.workspace.projectId !== context.project.id) {
|
|
190
|
-
throw new Error("
|
|
192
|
+
throw new Error(t("ui.main.0e2bca4bb08e", "Terminal workspace project scope does not match the host project"));
|
|
191
193
|
}
|
|
192
194
|
return Object.freeze({
|
|
193
195
|
projectId: context.project.id,
|
|
@@ -261,9 +263,9 @@ function requireTerminalSize(input, label) {
|
|
|
261
263
|
const cols = input["cols"];
|
|
262
264
|
const rows = input["rows"];
|
|
263
265
|
if (typeof cols !== "number" || !Number.isFinite(cols) || cols <= 0)
|
|
264
|
-
throw new Error(
|
|
266
|
+
throw new Error(t("ui.main.4fe2e9e99007", "{arg0} cols must be positive", { arg0: label }));
|
|
265
267
|
if (typeof rows !== "number" || !Number.isFinite(rows) || rows <= 0)
|
|
266
|
-
throw new Error(
|
|
268
|
+
throw new Error(t("ui.main.8c77f7625da9", "{arg0} rows must be positive", { arg0: label }));
|
|
267
269
|
return { cols: Math.floor(cols), rows: Math.floor(rows) };
|
|
268
270
|
}
|
|
269
271
|
function requireIdInput(input, operation, key) {
|
|
@@ -271,7 +273,7 @@ function requireIdInput(input, operation, key) {
|
|
|
271
273
|
}
|
|
272
274
|
function requireObject(value, label) {
|
|
273
275
|
if (!isJsonObject(value))
|
|
274
|
-
throw new Error(
|
|
276
|
+
throw new Error(t("ui.main.d808dc8965e3", "{arg0} input must be an object", { arg0: label }));
|
|
275
277
|
return value;
|
|
276
278
|
}
|
|
277
279
|
function isJsonObject(value) {
|
|
@@ -282,19 +284,19 @@ function requireObjectOrEmpty(value, label) {
|
|
|
282
284
|
}
|
|
283
285
|
function requireNullishInput(value, label) {
|
|
284
286
|
if (value !== null && (typeof value !== "object" || Array.isArray(value) || Object.keys(value).length > 0)) {
|
|
285
|
-
throw new Error(
|
|
287
|
+
throw new Error(t("ui.main.5c96c91dedb1", "{arg0} input must be null or an empty object", { arg0: label }));
|
|
286
288
|
}
|
|
287
289
|
}
|
|
288
290
|
function requireString(record, key, label) {
|
|
289
291
|
const value = record[key];
|
|
290
292
|
if (typeof value !== "string" || value.trim() === "")
|
|
291
|
-
throw new Error(
|
|
293
|
+
throw new Error(t("bundled.workspace-tasks.must.be.a.non.empty.string.838d0a", "{value1} {value2} must be a non-empty string", { value1: label, value2: key }));
|
|
292
294
|
return value;
|
|
293
295
|
}
|
|
294
296
|
function requireTerminalInputData(record) {
|
|
295
297
|
const value = record["data"];
|
|
296
298
|
if (typeof value !== "string" || value === "")
|
|
297
|
-
throw new Error("terminal.attach input frame data
|
|
299
|
+
throw new Error(t("ui.main.5bac4f59d1de", "terminal.attach input frame data must be a non-empty string"));
|
|
298
300
|
return value;
|
|
299
301
|
}
|
|
300
302
|
function optionalString(record, key, label) {
|
|
@@ -302,20 +304,20 @@ function optionalString(record, key, label) {
|
|
|
302
304
|
if (value === undefined)
|
|
303
305
|
return undefined;
|
|
304
306
|
if (typeof value !== "string")
|
|
305
|
-
throw new Error(
|
|
307
|
+
throw new Error(t("ui.main.90ec567aed4b", "{arg0} {arg1} must be a string", { arg0: label, arg1: key }));
|
|
306
308
|
return value;
|
|
307
309
|
}
|
|
308
310
|
function stringRecord(value, label) {
|
|
309
311
|
const record = requireObject(value, label);
|
|
310
312
|
return Object.fromEntries(Object.entries(record).map(([key, child]) => {
|
|
311
313
|
if (typeof child !== "string")
|
|
312
|
-
throw new Error(
|
|
314
|
+
throw new Error(t("ui.main.90ec567aed4b", "{arg0} {arg1} must be a string", { arg0: label, arg1: key }));
|
|
313
315
|
return [key, child];
|
|
314
316
|
}));
|
|
315
317
|
}
|
|
316
318
|
function requireArray(value, label) {
|
|
317
319
|
if (!isJsonArray(value))
|
|
318
|
-
throw new Error(
|
|
320
|
+
throw new Error(t("ui.main.05dcf0046d6e", "{arg0} must be an array", { arg0: label }));
|
|
319
321
|
return value;
|
|
320
322
|
}
|
|
321
323
|
function isJsonArray(value) {
|
|
@@ -324,7 +326,7 @@ function isJsonArray(value) {
|
|
|
324
326
|
function parseCommandRunStatus(value) {
|
|
325
327
|
if (value === "queued" || value === "running" || value === "succeeded" || value === "failed")
|
|
326
328
|
return value;
|
|
327
|
-
throw new Error(
|
|
329
|
+
throw new Error(t("ui.main.b302a96237f7", "Invalid terminal command run status: {arg0}", { arg0: JSON.stringify(value) }));
|
|
328
330
|
}
|
|
329
331
|
export function terminalOutputFrames(value, replay) {
|
|
330
332
|
const emptyFrame = terminalOutputFrame("", replay, false);
|
|
@@ -357,7 +359,7 @@ function throwIfAborted(signal) {
|
|
|
357
359
|
if (!signal.aborted)
|
|
358
360
|
return;
|
|
359
361
|
const reason = signal.reason;
|
|
360
|
-
throw reason instanceof Error ? reason : new Error("
|
|
362
|
+
throw reason instanceof Error ? reason : new Error(t("ui.main.398328b7ef67", "Terminal operation was cancelled"), { cause: reason });
|
|
361
363
|
}
|
|
362
364
|
function boundedErrorMessage(error) {
|
|
363
365
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Generated from pi-web-plugins/terminal/server/terminalService.ts. Do not edit directly.
|
|
2
|
+
import { t } from "./i18n.js";
|
|
2
3
|
import { randomUUID } from "node:crypto";
|
|
3
4
|
import { EventEmitter } from "node:events";
|
|
4
5
|
import { existsSync } from "node:fs";
|
|
@@ -17,7 +18,7 @@ export class TerminalService {
|
|
|
17
18
|
}
|
|
18
19
|
bindActivitySink(sink) {
|
|
19
20
|
if (this.activitySink !== undefined)
|
|
20
|
-
throw new Error("
|
|
21
|
+
throw new Error(t("ui.main.5d3c64acebaa", "Terminal activity sink is already bound"));
|
|
21
22
|
this.activitySink = sink;
|
|
22
23
|
}
|
|
23
24
|
list(scope) {
|
|
@@ -28,7 +29,7 @@ export class TerminalService {
|
|
|
28
29
|
}
|
|
29
30
|
closeForCwd(cwd) {
|
|
30
31
|
if (cwd === "")
|
|
31
|
-
throw new Error("cwd
|
|
32
|
+
throw new Error(t("ui.main.3554e67956ef", "cwd is required"));
|
|
32
33
|
for (const terminal of [...this.terminals.values()].filter((candidate) => candidate.cwd === cwd)) {
|
|
33
34
|
this.closeRecord(terminal);
|
|
34
35
|
}
|
|
@@ -47,7 +48,7 @@ export class TerminalService {
|
|
|
47
48
|
const metadata = parseMetadata(options.metadata);
|
|
48
49
|
const failureNotice = parseFailureNotice(options.failureNotice);
|
|
49
50
|
if (failureNotice !== undefined && this.recordNotice === undefined) {
|
|
50
|
-
throw new Error("
|
|
51
|
+
throw new Error(t("ui.main.e4f11dab9de6", "Terminal command failure notices are unavailable"));
|
|
51
52
|
}
|
|
52
53
|
const queued = {
|
|
53
54
|
id: commandRunId,
|
|
@@ -110,7 +111,7 @@ export class TerminalService {
|
|
|
110
111
|
cancelCommandRunForScope(scope, runId) {
|
|
111
112
|
const run = this.getCommandRunForScope(scope, runId);
|
|
112
113
|
if (run === undefined)
|
|
113
|
-
throw new Error("
|
|
114
|
+
throw new Error(t("ui.main.3bea6b3edcd2", "Terminal command run not found in this workspace"));
|
|
114
115
|
return this.cancelCommandRunRecord(this.requireCommandRun(runId));
|
|
115
116
|
}
|
|
116
117
|
get(scope, id) {
|
|
@@ -157,7 +158,7 @@ export class TerminalService {
|
|
|
157
158
|
delete record.exitCode;
|
|
158
159
|
delete record.commandRunId;
|
|
159
160
|
record.exited = false;
|
|
160
|
-
const marker = "\r\n[
|
|
161
|
+
const marker = t("ui.main.7e39d66ff416", "\r\n[continued in interactive shell]\r\n");
|
|
161
162
|
record.buffer = trimReplayBuffer(record.buffer + marker);
|
|
162
163
|
record.events.emit("output", marker);
|
|
163
164
|
const shell = interactiveShell();
|
|
@@ -185,7 +186,7 @@ export class TerminalService {
|
|
|
185
186
|
if (terminal === undefined)
|
|
186
187
|
return;
|
|
187
188
|
if (!matchesScope(terminal, scope))
|
|
188
|
-
throw new Error("
|
|
189
|
+
throw new Error(t("ui.main.002ca07f2de5", "Terminal not found in this workspace"));
|
|
189
190
|
this.closeRecord(terminal);
|
|
190
191
|
}
|
|
191
192
|
dispose() {
|
|
@@ -269,14 +270,14 @@ export class TerminalService {
|
|
|
269
270
|
validateScope(scope);
|
|
270
271
|
const terminal = this.terminals.get(id);
|
|
271
272
|
if (terminal === undefined || !matchesScope(terminal, scope)) {
|
|
272
|
-
throw new Error("
|
|
273
|
+
throw new Error(t("ui.main.002ca07f2de5", "Terminal not found in this workspace"));
|
|
273
274
|
}
|
|
274
275
|
return terminal;
|
|
275
276
|
}
|
|
276
277
|
requireCommandRun(runId) {
|
|
277
278
|
const run = this.commandRuns.get(runId);
|
|
278
279
|
if (run === undefined)
|
|
279
|
-
throw new Error("
|
|
280
|
+
throw new Error(t("ui.shared.ca71fd855ae2", "Terminal command run not found"));
|
|
280
281
|
return run;
|
|
281
282
|
}
|
|
282
283
|
cancelCommandRunRecord(run) {
|
|
@@ -284,7 +285,7 @@ export class TerminalService {
|
|
|
284
285
|
return copyCommandRun(run);
|
|
285
286
|
const terminal = this.terminals.get(run.terminalId);
|
|
286
287
|
if (terminal === undefined)
|
|
287
|
-
throw new Error("
|
|
288
|
+
throw new Error(t("ui.main.970ebf253e68", "Terminal not found"));
|
|
288
289
|
if (!terminal.exited && terminal.cancellationRequested !== true) {
|
|
289
290
|
terminal.cancellationRequested = true;
|
|
290
291
|
try {
|
|
@@ -308,7 +309,7 @@ export class TerminalService {
|
|
|
308
309
|
}
|
|
309
310
|
requireAvailable() {
|
|
310
311
|
if (this.disposed)
|
|
311
|
-
throw new Error("
|
|
312
|
+
throw new Error(t("ui.main.ee0fa7cb477f", "Terminal service is stopped"));
|
|
312
313
|
}
|
|
313
314
|
}
|
|
314
315
|
function toInfo(record) {
|
|
@@ -364,11 +365,11 @@ function shellQuote(value) {
|
|
|
364
365
|
}
|
|
365
366
|
function validateScope(scope) {
|
|
366
367
|
if (scope.projectId.trim() === "")
|
|
367
|
-
throw new Error("projectId
|
|
368
|
+
throw new Error(t("ui.main.c785a1f6204e", "projectId is required"));
|
|
368
369
|
if (scope.workspaceId.trim() === "")
|
|
369
|
-
throw new Error("workspaceId
|
|
370
|
+
throw new Error(t("ui.main.9850b858e3ba", "workspaceId is required"));
|
|
370
371
|
if (scope.cwd.trim() === "")
|
|
371
|
-
throw new Error("cwd
|
|
372
|
+
throw new Error(t("ui.main.3554e67956ef", "cwd is required"));
|
|
372
373
|
}
|
|
373
374
|
function matchesScope(record, scope) {
|
|
374
375
|
return record.projectId === scope.projectId
|
|
@@ -378,23 +379,23 @@ function matchesScope(record, scope) {
|
|
|
378
379
|
function validateCommandRunOptions(options) {
|
|
379
380
|
validateScope(options);
|
|
380
381
|
if (options.origin.trim() === "")
|
|
381
|
-
throw new Error("origin
|
|
382
|
+
throw new Error(t("ui.main.0b08e0eda1a4", "origin is required"));
|
|
382
383
|
if (options.title.trim() === "")
|
|
383
|
-
throw new Error("title
|
|
384
|
+
throw new Error(t("ui.main.394f110fbd2e", "title is required"));
|
|
384
385
|
if (options.command.trim() === "")
|
|
385
|
-
throw new Error("command
|
|
386
|
+
throw new Error(t("ui.main.f3029405fa76", "command is required"));
|
|
386
387
|
parseMetadata(options.metadata);
|
|
387
388
|
}
|
|
388
389
|
function parseMetadata(value) {
|
|
389
390
|
if (value === undefined || value === null)
|
|
390
391
|
return {};
|
|
391
392
|
if (!isRecord(value))
|
|
392
|
-
throw new Error("metadata
|
|
393
|
+
throw new Error(t("ui.main.8aaf09278346", "metadata must be an object"));
|
|
393
394
|
return Object.fromEntries(Object.entries(value).map(([key, metadataValue]) => {
|
|
394
395
|
if (key.trim() === "")
|
|
395
|
-
throw new Error("metadata
|
|
396
|
+
throw new Error(t("ui.main.32968c7e6565", "metadata keys must not be empty"));
|
|
396
397
|
if (typeof metadataValue !== "string")
|
|
397
|
-
throw new Error("metadata
|
|
398
|
+
throw new Error(t("ui.main.ca6186d140b2", "metadata values must be strings"));
|
|
398
399
|
return [key, metadataValue];
|
|
399
400
|
}));
|
|
400
401
|
}
|
|
@@ -402,10 +403,10 @@ function parseFailureNotice(value) {
|
|
|
402
403
|
if (value === undefined)
|
|
403
404
|
return undefined;
|
|
404
405
|
if (typeof value.message !== "string" || value.message.trim() === "") {
|
|
405
|
-
throw new Error("failureNotice message
|
|
406
|
+
throw new Error(t("ui.main.b63294884798", "failureNotice message must be a non-empty string"));
|
|
406
407
|
}
|
|
407
408
|
if (!isRecord(value.context) || !Object.values(value.context).every((item) => typeof item === "string")) {
|
|
408
|
-
throw new Error("failureNotice context
|
|
409
|
+
throw new Error(t("ui.main.a38dcafc6669", "failureNotice context must contain only strings"));
|
|
409
410
|
}
|
|
410
411
|
return Object.freeze({ message: value.message, context: Object.freeze({ ...value.context }) });
|
|
411
412
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Generated from pi-web-plugins/updates/i18n.ts. Do not edit directly.
|
|
2
|
+
let translate;
|
|
3
|
+
export function setTranslator(value) {
|
|
4
|
+
translate = value;
|
|
5
|
+
}
|
|
6
|
+
export const t = (key, fallback, params) => translate?.(key, fallback, params)
|
|
7
|
+
?? fallback.replace(/\{([A-Za-z0-9_]+)\}/g, (match, name) => String(params?.[name] ?? match));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Generated from pi-web-plugins/updates/pi-web-plugin.ts. Do not edit directly.
|
|
2
|
+
import { t, setTranslator } from "./i18n.js";
|
|
2
3
|
import { additionalCommands, fallbackDockerStatus, formatVersion, installationLabel, messageCount, recommendedCommand, shouldShowUpdatesPanel, statusFor } from "./updatesLogic.js";
|
|
3
4
|
function runCommandInTerminal(terminal, label, command) {
|
|
4
5
|
void terminal.runCommand({
|
|
@@ -7,7 +8,7 @@ function runCommandInTerminal(terminal, label, command) {
|
|
|
7
8
|
open: true,
|
|
8
9
|
metadata: { "pi.plugin": "updates" },
|
|
9
10
|
}).catch((error) => {
|
|
10
|
-
console.error(
|
|
11
|
+
console.error(t("ui.main.3b3df75b9391", "Updates plugin failed to run \"{arg0}\"", { arg0: label }), error);
|
|
11
12
|
});
|
|
12
13
|
}
|
|
13
14
|
async function copyCommandToClipboard(command, target) {
|
|
@@ -16,7 +17,7 @@ async function copyCommandToClipboard(command, target) {
|
|
|
16
17
|
if (button === undefined)
|
|
17
18
|
return;
|
|
18
19
|
const original = button.textContent;
|
|
19
|
-
button.textContent = copied ? "
|
|
20
|
+
button.textContent = copied ? t("ui.toolExecutionView.copied", "Copied") : t("bundled.updates.copy.failed.753d8b", "Copy failed");
|
|
20
21
|
window.setTimeout(() => {
|
|
21
22
|
button.textContent = original;
|
|
22
23
|
}, 1200);
|
|
@@ -68,17 +69,17 @@ function copyWithSelectionFallback(text) {
|
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
71
|
function renderComponent(html, component) {
|
|
71
|
-
const label = component.component === "sessiond" ? "
|
|
72
|
+
const label = component.component === "sessiond" ? t("bundled.updates.session.daemon.757666", "Session daemon") : t("bundled.updates.web.ui.86d6a2", "Web/UI");
|
|
72
73
|
const status = !component.available
|
|
73
|
-
? "
|
|
74
|
+
? t("bundled.info.unavailable.460b35", "Unavailable")
|
|
74
75
|
: component.stale
|
|
75
|
-
? "
|
|
76
|
-
: "
|
|
76
|
+
? t("bundled.info.restart.needed.1ffd00", "Restart needed")
|
|
77
|
+
: t("bundled.info.current.837bc9", "Current");
|
|
77
78
|
return html `
|
|
78
79
|
<div class="updates-version-row">
|
|
79
80
|
<strong>${label}</strong>
|
|
80
81
|
<span>${status}</span>
|
|
81
|
-
<small
|
|
82
|
+
<small>${t("ui.toolExecutionView.running", "Running")} ${formatVersion(component.runtimeVersion)}${t("ui.main.b2a2f69aef6f", " · installed ")}${formatVersion(component.installedVersion)}</small>
|
|
82
83
|
<small>${installationLabel(component.installation)}${component.installation?.path === undefined ? "" : ` · ${component.installation.path}`}</small>
|
|
83
84
|
</div>
|
|
84
85
|
`;
|
|
@@ -86,8 +87,8 @@ function renderComponent(html, component) {
|
|
|
86
87
|
function renderCommandActions(html, terminal, label, command) {
|
|
87
88
|
return html `
|
|
88
89
|
<span class="updates-command-actions">
|
|
89
|
-
<button @click=${(event) => { void copyCommandToClipboard(command, event?.currentTarget); }}
|
|
90
|
-
${terminal === undefined ? null : html `<button class="primary" @click=${() => { runCommandInTerminal(terminal, label, command); }}
|
|
90
|
+
<button @click=${(event) => { void copyCommandToClipboard(command, event?.currentTarget); }}>${t("bundled.updates.copy.63d90d", "Copy")}</button>
|
|
91
|
+
${terminal === undefined ? null : html `<button class="primary" @click=${() => { runCommandInTerminal(terminal, label, command); }}>${t("bundled.workspace-tasks.run.75b269", "Run")}</button>`}
|
|
91
92
|
</span>
|
|
92
93
|
`;
|
|
93
94
|
}
|
|
@@ -119,13 +120,13 @@ function renderNotice(html, message) {
|
|
|
119
120
|
`;
|
|
120
121
|
}
|
|
121
122
|
function renderNotices(html, messages) {
|
|
122
|
-
return html `<section>${messages.length === 0 ? html `<p class="muted"
|
|
123
|
+
return html `<section>${messages.length === 0 ? html `<p class="muted">${t("bundled.updates.no.pi.web.update.or.restart.messages.a2f50d", "No PI WEB update or restart messages.")}</p>` : messages.map((message) => renderNotice(html, message))}</section>`;
|
|
123
124
|
}
|
|
124
125
|
function renderRecommended(html, terminal, recommended, messages) {
|
|
125
126
|
return html `
|
|
126
127
|
<section class="updates-recommended">
|
|
127
|
-
<strong
|
|
128
|
-
${messages.length === 0 ? html `<p class="muted"
|
|
128
|
+
<strong>${t("bundled.updates.recommended.1452de", "Recommended")}</strong>
|
|
129
|
+
${messages.length === 0 ? html `<p class="muted">${t("bundled.updates.run.this.command.to.bring.the.current.installation.up.to.date.no..99197c", "Run this command to bring the current installation up to date. No other steps are required.")}</p>` : messages.map((message) => renderNotice(html, message))}
|
|
129
130
|
${renderCommand(html, terminal, recommended.label, recommended.command)}
|
|
130
131
|
</section>
|
|
131
132
|
`;
|
|
@@ -135,8 +136,8 @@ function renderAdditionalCommands(html, terminal, additional, hasRecommended) {
|
|
|
135
136
|
return undefined;
|
|
136
137
|
return html `
|
|
137
138
|
<section>
|
|
138
|
-
<strong>${hasRecommended ? "
|
|
139
|
-
${hasRecommended ? html `<p class="muted"
|
|
139
|
+
<strong>${hasRecommended ? t("ui.main.7ccbaa176fa0", "Additional commands (optional)") : t("bundled.updates.suggested.commands.d22916", "Suggested commands")}</strong>
|
|
140
|
+
${hasRecommended ? html `<p class="muted">${t("bundled.updates.use.only.for.finer.control.such.as.restarting.a.single.service.f2c8d9", "Use only for finer control, such as restarting a single service.")}</p>` : null}
|
|
140
141
|
${additional.map((entry) => renderCommand(html, terminal, entry.label, entry.command))}
|
|
141
142
|
</section>
|
|
142
143
|
`;
|
|
@@ -145,8 +146,8 @@ function renderUpdatesPanel(html, terminal, state) {
|
|
|
145
146
|
const status = statusFor(state) ?? fallbackDockerStatus(runtimeHint);
|
|
146
147
|
if (status === undefined) {
|
|
147
148
|
return html `
|
|
148
|
-
<section class="toolbar"><strong
|
|
149
|
-
<section class="viewer"><p class="muted"
|
|
149
|
+
<section class="toolbar"><strong>${t("bundled.updates.updates.3055a0", "Updates")}</strong></section>
|
|
150
|
+
<section class="viewer"><p class="muted">${t("bundled.updates.checking.pi.web.update.status.24e243", "Checking PI WEB update status...")}</p></section>
|
|
150
151
|
`;
|
|
151
152
|
}
|
|
152
153
|
const messages = status.messages;
|
|
@@ -176,12 +177,12 @@ function renderUpdatesPanel(html, terminal, state) {
|
|
|
176
177
|
.updates-command > span { grid-column: 1 / -1; }
|
|
177
178
|
}
|
|
178
179
|
</style>
|
|
179
|
-
<section class="toolbar"><strong
|
|
180
|
+
<section class="toolbar"><strong>${t("bundled.updates.updates.3055a0", "Updates")}</strong>${messages.length > 0 ? html `<span class="stale">${String(messages.length)}</span>` : null}</section>
|
|
180
181
|
<section class="viewer updates-status">
|
|
181
182
|
${recommended === undefined ? renderNotices(html, messages) : renderRecommended(html, terminal, recommended, messages)}
|
|
182
183
|
|
|
183
184
|
<section>
|
|
184
|
-
<strong
|
|
185
|
+
<strong>${t("bundled.updates.installed.services.ef70c6", "Installed services")}</strong>
|
|
185
186
|
${renderComponent(html, status.components.web)}
|
|
186
187
|
${renderComponent(html, status.components.sessiond)}
|
|
187
188
|
</section>
|
|
@@ -189,43 +190,45 @@ function renderUpdatesPanel(html, terminal, state) {
|
|
|
189
190
|
${renderAdditionalCommands(html, terminal, additional, recommended !== undefined)}
|
|
190
191
|
|
|
191
192
|
<section class="updates-meta">
|
|
192
|
-
<span
|
|
193
|
-
${status.release.latestVersion === undefined ? null : html `<span
|
|
194
|
-
${status.release.checkedAt === undefined || status.release.skipped === true ? null : html `<span
|
|
195
|
-
${status.release.skipped === true ? html `<span
|
|
196
|
-
${status.release.error === undefined ? null : html `<span
|
|
193
|
+
<span>${t("ui.main.2213d2e64aff", "Generated")} ${status.generatedAt}</span>
|
|
194
|
+
${status.release.latestVersion === undefined ? null : html `<span>${t("ui.main.f7047c4cb0e0", "Latest npm release")} ${status.release.latestVersion}</span>`}
|
|
195
|
+
${status.release.checkedAt === undefined || status.release.skipped === true ? null : html `<span>${t("ui.main.58006f4511ed", "Release checked")} ${status.release.checkedAt}</span>`}
|
|
196
|
+
${status.release.skipped === true ? html `<span>${t("bundled.updates.remote.version.check.skipped.66de71", "Remote version check skipped.")}</span>` : null}
|
|
197
|
+
${status.release.error === undefined ? null : html `<span>${t("ui.main.30c7a262a7d1", "Remote version check failed:")}${status.release.error}</span>`}
|
|
197
198
|
</section>
|
|
198
199
|
</section>
|
|
199
200
|
`;
|
|
200
201
|
}
|
|
201
202
|
function severityLabel(severity) {
|
|
202
203
|
if (severity === "warning")
|
|
203
|
-
return "
|
|
204
|
+
return t("client.sessionNotifications.warning.a8b7a4", "Warning");
|
|
204
205
|
if (severity === "error")
|
|
205
|
-
return "
|
|
206
|
+
return t("client.sessionNotifications.error.0bc1fb", "Error");
|
|
206
207
|
return severity;
|
|
207
208
|
}
|
|
208
209
|
const plugin = {
|
|
209
210
|
apiVersion: 4,
|
|
210
|
-
name: "
|
|
211
|
-
activate: ({ html, svg }) =>
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
211
|
+
name: t("bundled.updates.updates.3055a0", "Updates"),
|
|
212
|
+
activate: ({ html, svg, translate }) => {
|
|
213
|
+
setTranslator(translate);
|
|
214
|
+
return ({
|
|
215
|
+
contributions: {
|
|
216
|
+
actions: [
|
|
217
|
+
{
|
|
218
|
+
id: "check",
|
|
219
|
+
title: t("bundled.updates.check.for.pi.web.updates.2062d8", "Check for PI WEB updates"),
|
|
220
|
+
description: t("bundled.updates.check.the.selected.machine.now.ignoring.cached.release.informatio.e12ea5", "Check the selected machine now, ignoring cached release information"),
|
|
221
|
+
group: t("bundled.updates.updates.3055a0", "Updates"),
|
|
222
|
+
enabled: (context) => context.checkForPiWebUpdates !== undefined,
|
|
223
|
+
disabledReason: () => t("bundled.updates.checking.for.updates.requires.a.newer.pi.web.gateway.0a72c8", "Checking for updates requires a newer PI WEB gateway"),
|
|
224
|
+
run: (context) => context.checkForPiWebUpdates?.(),
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
workspacePanels: [
|
|
228
|
+
{
|
|
229
|
+
id: "workspace.updates",
|
|
230
|
+
title: t("bundled.updates.updates.3055a0", "Updates"),
|
|
231
|
+
icon: svg `
|
|
229
232
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
230
233
|
<path d="M20 6v5h-5"></path>
|
|
231
234
|
<path d="M4 18v-5h5"></path>
|
|
@@ -233,16 +236,17 @@ const plugin = {
|
|
|
233
236
|
<path d="M5.6 15A7 7 0 0 0 17.9 17.3L20 15.2"></path>
|
|
234
237
|
</svg>
|
|
235
238
|
`,
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
239
|
+
order: 100,
|
|
240
|
+
visible: (context) => shouldShowUpdatesPanel(context.state, runtimeHint),
|
|
241
|
+
badge: (context) => {
|
|
242
|
+
const count = messageCount(context.state);
|
|
243
|
+
return count > 0 ? count : undefined;
|
|
244
|
+
},
|
|
245
|
+
render: (context) => renderUpdatesPanel(html, context.terminal, context.state),
|
|
241
246
|
},
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}),
|
|
247
|
+
],
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
},
|
|
247
251
|
};
|
|
248
252
|
export default plugin;
|