@chainingintention/pi-web-cn 1.202610.3 → 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.
Files changed (202) hide show
  1. package/README.md +1 -0
  2. package/dist/cli.js +129 -122
  3. package/dist/cli.js.map +1 -1
  4. package/dist/client/assets/PiWebApp-CN3g7SqA.js +4362 -0
  5. package/dist/client/assets/external-DUGCSDhZ.js +2 -0
  6. package/dist/client/assets/index-JduZlbIF.js +2 -0
  7. package/dist/client/index.html +4 -4
  8. package/dist/client/manifest.webmanifest +2 -1
  9. package/dist/localization.js +24 -0
  10. package/dist/localization.js.map +1 -0
  11. package/dist/nativeServices/serviceDoctor.js +45 -44
  12. package/dist/nativeServices/serviceDoctor.js.map +1 -1
  13. package/dist/pi-packages/captains-log/dist/browser/index.js +46 -45
  14. package/dist/pi-packages/captains-log/dist/browser/markdown.js +2 -1
  15. package/dist/pi-packages/captains-log/dist/browser/panel.js +56 -55
  16. package/dist/pi-packages/captains-log/i18n.js +7 -0
  17. package/dist/pi-packages/relays/i18n.js +7 -0
  18. package/dist/pi-packages/relays/markdownDocument.js +2 -1
  19. package/dist/pi-packages/relays/pi-web-plugin.js +8 -6
  20. package/dist/pi-packages/relays/relaysPanelElement.js +24 -23
  21. package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +124 -124
  22. package/dist/pi-web-plugins/git/browser/git-contract.js +13 -12
  23. package/dist/pi-web-plugins/git/browser/git-panel.js +25 -24
  24. package/dist/pi-web-plugins/git/browser/i18n.js +7 -0
  25. package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +7 -3
  26. package/dist/pi-web-plugins/git/git-backend.js +10 -9
  27. package/dist/pi-web-plugins/git/i18n.js +7 -0
  28. package/dist/pi-web-plugins/git/server-plugin.js +21 -19
  29. package/dist/pi-web-plugins/info/i18n.js +7 -0
  30. package/dist/pi-web-plugins/info/infoInternals.js +57 -62
  31. package/dist/pi-web-plugins/info/pi-web-plugin.js +34 -36
  32. package/dist/pi-web-plugins/mermaid/browser/pi-web-plugin.js +3 -3
  33. package/dist/pi-web-plugins/terminal/browser/pi-web-plugin.js +55 -52
  34. package/dist/pi-web-plugins/terminal/i18n.js +7 -0
  35. package/dist/pi-web-plugins/terminal/server-plugin.js +23 -21
  36. package/dist/pi-web-plugins/terminal/terminalService.js +22 -21
  37. package/dist/pi-web-plugins/updates/i18n.js +7 -0
  38. package/dist/pi-web-plugins/updates/pi-web-plugin.js +58 -54
  39. package/dist/pi-web-plugins/updates/updatesLogic.js +21 -20
  40. package/dist/pi-web-plugins/workspace-tasks/config.js +12 -11
  41. package/dist/pi-web-plugins/workspace-tasks/i18n.js +7 -0
  42. package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +8 -6
  43. package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +20 -19
  44. package/dist/pi-web-plugins/workspace-tasks/workspaceTasksClient.js +12 -11
  45. package/dist/pi-web-plugins/zh-cn/auth.json +9 -0
  46. package/dist/pi-web-plugins/zh-cn/bundled.json +176 -0
  47. package/dist/pi-web-plugins/zh-cn/cli.json +171 -0
  48. package/dist/pi-web-plugins/zh-cn/client.json +219 -0
  49. package/dist/pi-web-plugins/zh-cn/components.json +1002 -0
  50. package/dist/pi-web-plugins/zh-cn/config-errors.json +172 -0
  51. package/dist/pi-web-plugins/zh-cn/files.json +41 -0
  52. package/dist/pi-web-plugins/zh-cn/machines.json +28 -0
  53. package/dist/pi-web-plugins/zh-cn/main.json +459 -0
  54. package/dist/pi-web-plugins/zh-cn/management-errors.json +23 -0
  55. package/dist/pi-web-plugins/zh-cn/manifest.webmanifest +25 -0
  56. package/dist/pi-web-plugins/zh-cn/metadata.json +3 -0
  57. package/dist/pi-web-plugins/zh-cn/package.json +10 -0
  58. package/dist/pi-web-plugins/zh-cn/pi-web-plugin.js +16 -0
  59. package/dist/pi-web-plugins/zh-cn/projects.json +6 -0
  60. package/dist/pi-web-plugins/zh-cn/provider-auth.json +17 -0
  61. package/dist/pi-web-plugins/zh-cn/routing.json +68 -0
  62. package/dist/pi-web-plugins/zh-cn/server-main.json +99 -0
  63. package/dist/pi-web-plugins/zh-cn/server.json +174 -0
  64. package/dist/piWebVersionReport.js +17 -16
  65. package/dist/piWebVersionReport.js.map +1 -1
  66. package/dist/plugin-api.d.ts +4 -1
  67. package/dist/pluginRecoveryCli.js +25 -24
  68. package/dist/pluginRecoveryCli.js.map +1 -1
  69. package/dist/server/app.js +43 -28
  70. package/dist/server/app.js.map +1 -1
  71. package/dist/server/audit/normalToolAuditCli.js +45 -43
  72. package/dist/server/audit/normalToolAuditCli.js.map +1 -1
  73. package/dist/server/configRoutes.js +39 -30
  74. package/dist/server/configRoutes.js.map +1 -1
  75. package/dist/server/diagnostics/nodePtyNativeModule.js +7 -6
  76. package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -1
  77. package/dist/server/diagnostics/nodePtySpawnHelper.js +21 -20
  78. package/dist/server/diagnostics/nodePtySpawnHelper.js.map +1 -1
  79. package/dist/server/knownAutoInstallPiPackages.js +2 -2
  80. package/dist/server/knownAutoInstallPiPackages.js.map +1 -1
  81. package/dist/server/knownPiPackages.js +2 -2
  82. package/dist/server/knownPiPackages.js.map +1 -1
  83. package/dist/server/machines/machineClient.js +8 -6
  84. package/dist/server/machines/machineClient.js.map +1 -1
  85. package/dist/server/machines/machinePluginProxyRoutes.js +11 -10
  86. package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
  87. package/dist/server/machines/machineProxyRoutes.js +27 -29
  88. package/dist/server/machines/machineProxyRoutes.js.map +1 -1
  89. package/dist/server/machines/machineRoutes.js +10 -12
  90. package/dist/server/machines/machineRoutes.js.map +1 -1
  91. package/dist/server/machines/machineService.js +17 -18
  92. package/dist/server/machines/machineService.js.map +1 -1
  93. package/dist/server/managementEmbed.js +26 -25
  94. package/dist/server/managementEmbed.js.map +1 -1
  95. package/dist/server/normalAuth.js +29 -26
  96. package/dist/server/normalAuth.js.map +1 -1
  97. package/dist/server/passwordVerifier.js +2 -1
  98. package/dist/server/passwordVerifier.js.map +1 -1
  99. package/dist/server/piPackageService.js +7 -5
  100. package/dist/server/piPackageService.js.map +1 -1
  101. package/dist/server/piWebPluginService.js +27 -11
  102. package/dist/server/piWebPluginService.js.map +1 -1
  103. package/dist/server/piWebStatus.js +16 -14
  104. package/dist/server/piWebStatus.js.map +1 -1
  105. package/dist/server/plugins/serverPluginRuntime.js +4 -2
  106. package/dist/server/plugins/serverPluginRuntime.js.map +1 -1
  107. package/dist/server/projects/projectService.js +4 -3
  108. package/dist/server/projects/projectService.js.map +1 -1
  109. package/dist/server/sessiond/projectMutationRoutes.js +5 -4
  110. package/dist/server/sessiond/projectMutationRoutes.js.map +1 -1
  111. package/dist/server/sessiond/sessionProxyRoutes.js +11 -8
  112. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
  113. package/dist/server/sessiond/workspaceCatalogRoutes.js +5 -3
  114. package/dist/server/sessiond/workspaceCatalogRoutes.js.map +1 -1
  115. package/dist/server/sessiond.js +8 -3
  116. package/dist/server/sessiond.js.map +1 -1
  117. package/dist/server/sessions/authRoutes.js +20 -19
  118. package/dist/server/sessions/authRoutes.js.map +1 -1
  119. package/dist/server/sessions/authService.js +13 -10
  120. package/dist/server/sessions/authService.js.map +1 -1
  121. package/dist/server/sessions/builtinCommands.js +28 -21
  122. package/dist/server/sessions/builtinCommands.js.map +1 -1
  123. package/dist/server/sessions/oauthLoginFlowService.js +17 -15
  124. package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
  125. package/dist/server/sessions/piSessionService.js +229 -208
  126. package/dist/server/sessions/piSessionService.js.map +1 -1
  127. package/dist/server/sessions/projectAuthService.js +5 -3
  128. package/dist/server/sessions/projectAuthService.js.map +1 -1
  129. package/dist/server/sessions/sessionArchiveMapping.js +8 -7
  130. package/dist/server/sessions/sessionArchiveMapping.js.map +1 -1
  131. package/dist/server/sessions/sessionCleanup.js +4 -3
  132. package/dist/server/sessions/sessionCleanup.js.map +1 -1
  133. package/dist/server/sessions/sessionCommandService.js +70 -67
  134. package/dist/server/sessions/sessionCommandService.js.map +1 -1
  135. package/dist/server/sessions/sessionNotificationStore.js +12 -11
  136. package/dist/server/sessions/sessionNotificationStore.js.map +1 -1
  137. package/dist/server/sessions/sessionRoutes.js +74 -72
  138. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  139. package/dist/server/sessions/sessionTreeProjection.js +50 -49
  140. package/dist/server/sessions/sessionTreeProjection.js.map +1 -1
  141. package/dist/server/sessions/sessionUnreadStore.js +25 -2
  142. package/dist/server/sessions/sessionUnreadStore.js.map +1 -1
  143. package/dist/server/terminals/managementCommandRunService.js +13 -12
  144. package/dist/server/terminals/managementCommandRunService.js.map +1 -1
  145. package/dist/server/workbench/accessStateStore.js +9 -7
  146. package/dist/server/workbench/accessStateStore.js.map +1 -1
  147. package/dist/server/workbench/capabilitySearch.js +3 -2
  148. package/dist/server/workbench/capabilitySearch.js.map +1 -1
  149. package/dist/server/workbench/knowledgeSearch.js +8 -7
  150. package/dist/server/workbench/knowledgeSearch.js.map +1 -1
  151. package/dist/server/workbench/mcpClient.js +6 -5
  152. package/dist/server/workbench/mcpClient.js.map +1 -1
  153. package/dist/server/workbench/skillSync.js +4 -2
  154. package/dist/server/workbench/skillSync.js.map +1 -1
  155. package/dist/server/workbench/workbenchClient.js +8 -7
  156. package/dist/server/workbench/workbenchClient.js.map +1 -1
  157. package/dist/server/workbench/workbenchTools.js +8 -6
  158. package/dist/server/workbench/workbenchTools.js.map +1 -1
  159. package/dist/server/workingDirectory.js +3 -2
  160. package/dist/server/workingDirectory.js.map +1 -1
  161. package/dist/server/workspaceExplorerRoutes.js +16 -13
  162. package/dist/server/workspaceExplorerRoutes.js.map +1 -1
  163. package/dist/server/workspaces/fileContentService.js +11 -10
  164. package/dist/server/workspaces/fileContentService.js.map +1 -1
  165. package/dist/server/workspaces/fileOperationService.js +7 -6
  166. package/dist/server/workspaces/fileOperationService.js.map +1 -1
  167. package/dist/server/workspaces/filePreviewService.js +5 -4
  168. package/dist/server/workspaces/filePreviewService.js.map +1 -1
  169. package/dist/server/workspaces/fileSuggestions.js +2 -1
  170. package/dist/server/workspaces/fileSuggestions.js.map +1 -1
  171. package/dist/server/workspaces/pathAccessPolicy.js +24 -18
  172. package/dist/server/workspaces/pathAccessPolicy.js.map +1 -1
  173. package/dist/server/workspaces/pathSafety.js +6 -5
  174. package/dist/server/workspaces/pathSafety.js.map +1 -1
  175. package/dist/server/workspaces/projectPiWebConfig.js +3 -2
  176. package/dist/server/workspaces/projectPiWebConfig.js.map +1 -1
  177. package/dist/server/workspaces/workspaceRemovalService.js +4 -3
  178. package/dist/server/workspaces/workspaceRemovalService.js.map +1 -1
  179. package/dist/server/workspaces/workspaceRouteErrors.js +4 -2
  180. package/dist/server/workspaces/workspaceRouteErrors.js.map +1 -1
  181. package/dist/server/workspaces/workspaceUserError.js +18 -0
  182. package/dist/server/workspaces/workspaceUserError.js.map +1 -0
  183. package/dist/server-plugin-api.d.ts +3 -1
  184. package/dist/server-plugin-api.js.map +1 -1
  185. package/dist/serverPluginRecovery.js +3 -2
  186. package/dist/serverPluginRecovery.js.map +1 -1
  187. package/dist/shared/apiTypes.js.map +1 -1
  188. package/dist/shared/i18n.js +41 -0
  189. package/dist/shared/i18n.js.map +1 -0
  190. package/dist/shared/piWebConfigParsing.js +52 -49
  191. package/dist/shared/piWebConfigParsing.js.map +1 -1
  192. package/dist/shared/pluginApiTypes.d.ts +7 -0
  193. package/dist/shared/requiredTerminalPlugin.js +1 -1
  194. package/dist/shared/requiredTerminalPlugin.js.map +1 -1
  195. package/dist/shared/sessionDefaults.js +7 -6
  196. package/dist/shared/sessionDefaults.js.map +1 -1
  197. package/dist/shared/thinkingLevels.js +17 -16
  198. package/dist/shared/thinkingLevels.js.map +1 -1
  199. package/docs/config.md +10 -1
  200. package/docs/plugins.md +8 -0
  201. package/package.json +1 -1
  202. package/dist/client/assets/index-CFhaGb5m.js +0 -4357
@@ -1,25 +1,26 @@
1
1
  // Generated from pi-web-plugins/updates/updatesLogic.ts. Do not edit directly.
2
+ import { t } from "./i18n.js";
2
3
  // The single command users should run when they do not want to think: if an
3
4
  // update is available, `commands.update` already chains the update and a full
4
5
  // restart; otherwise, when anything is stale, a full restart is enough.
5
6
  export function recommendedCommand(status) {
6
7
  const { commands, release, components } = status;
7
8
  if (release.updateAvailable && typeof commands.update === "string" && commands.update !== "") {
8
- return { label: "更新并重启全部服务", command: commands.update };
9
+ return { label: t("bundled.updates.update.and.restart.all.services.f469f2", "Update and restart all services"), command: commands.update };
9
10
  }
10
11
  const restartNeeded = components.web.stale || components.sessiond.stale || !components.sessiond.available;
11
12
  if (restartNeeded && typeof commands.restart === "string" && commands.restart !== "") {
12
- return { label: "重启全部服务", command: commands.restart };
13
+ return { label: t("bundled.updates.restart.all.services.f305e3", "Restart all services"), command: commands.restart };
13
14
  }
14
15
  return undefined;
15
16
  }
16
17
  export function additionalCommands(status, recommended) {
17
18
  return [
18
- ["更新", status.commands.update],
19
- ["全部重启", status.commands.restart],
20
- ["重启 Web/界面", status.commands.restartWeb],
21
- ["重启会话守护进程", status.commands.restartSessiond],
22
- ["状态", status.commands.status],
19
+ [t("bundled.updates.updates.3055a0", "Updates"), status.commands.update],
20
+ [t("bundled.updates.restart.all.9dfe69", "Restart all"), status.commands.restart],
21
+ [t("bundled.updates.restart.web.ui.9d6372", "Restart Web/UI"), status.commands.restartWeb],
22
+ [t("bundled.updates.restart.session.daemon.69f455", "Restart session daemon"), status.commands.restartSessiond],
23
+ [t("bundled.updates.status.6320b4", "Status"), status.commands.status],
23
24
  ]
24
25
  .filter((entry) => typeof entry[1] === "string" && entry[1] !== "")
25
26
  .filter(([, command]) => command !== recommended?.command)
@@ -48,7 +49,7 @@ export function shouldShowUpdatesPanel(state, hint = {}) {
48
49
  return isSelfManagedInstallation(status.components.web.installation)
49
50
  || isSelfManagedInstallation(status.components.sessiond.installation);
50
51
  }
51
- export function fallbackDockerStatus(hint, generatedAt = "联邦状态不可用") {
52
+ export function fallbackDockerStatus(hint, generatedAt = t("bundled.updates.federated.status.unavailable.ad4f0b", "Federated status unavailable")) {
52
53
  if (hint.dockerMode === undefined)
53
54
  return undefined;
54
55
  const commandPrefix = hint.dockerMode === "dev" ? "pi-web-docker --dev" : "pi-web-docker";
@@ -57,8 +58,8 @@ export function fallbackDockerStatus(hint, generatedAt = "联邦状态不可用"
57
58
  packageName: "@chainingintention/pi-web-cn",
58
59
  generatedAt,
59
60
  components: {
60
- web: { component: "web", label: "Web/界面", stale: false, available: true, installation },
61
- sessiond: { component: "sessiond", label: "会话守护进程", stale: false, available: true, installation },
61
+ web: { component: "web", label: t("bundled.updates.web.ui.86d6a2", "Web/UI"), stale: false, available: true, installation },
62
+ sessiond: { component: "sessiond", label: t("bundled.updates.session.daemon.757666", "Session daemon"), stale: false, available: true, installation },
62
63
  },
63
64
  release: { packageName: "@chainingintention/pi-web-cn", updateAvailable: false, skipped: true },
64
65
  commands: {
@@ -71,30 +72,30 @@ export function fallbackDockerStatus(hint, generatedAt = "联邦状态不可用"
71
72
  messages: [{
72
73
  id: "docker-status-compatibility",
73
74
  severity: "info",
74
- title: "Docker 更新命令可用",
75
- body: "当前更新插件由 Docker PI WEB 运行时加载,但网关尚未提供 Docker 状态详情。仍可使用下方 Docker 维护命令。",
75
+ title: t("bundled.updates.docker.update.commands.available.7ab546", "Docker update commands available"),
76
+ body: t("bundled.updates.this.plugin.was.loaded.from.a.docker.pi.web.runtime.but.the.gatew.a4f10a", "This plugin was loaded from a Docker PI WEB runtime, but the gateway has not provided Docker status details yet. The Docker maintenance commands below are still available."),
76
77
  }],
77
78
  };
78
79
  }
79
80
  export function formatVersion(version) {
80
- return version === undefined || version === "" ? "未知" : version;
81
+ return version === undefined || version === "" ? t("bundled.updates.unknown.4d8c1c", "Unknown") : version;
81
82
  }
82
83
  export function installationLabel(installation) {
83
84
  if (installation === undefined)
84
- return "安装来源未知";
85
+ return t("bundled.updates.unknown.installation.source.22c213", "Unknown installation source");
85
86
  if (installation.kind === "pi-package") {
86
87
  const scope = installation.scope === undefined ? "" : ` · ${installationScopeLabel(installation.scope)}`;
87
- const source = installation.source ?? "Pi 包";
88
+ const source = installation.source ?? t("bundled.updates.pi.package.feed18", "Pi package");
88
89
  return `${source}${scope}`;
89
90
  }
90
91
  if (installation.kind === "npm-global")
91
- return "全局 npm 包";
92
+ return t("bundled.updates.global.npm.package.5e8079", "Global npm package");
92
93
  if (installation.kind === "local")
93
- return "本地检出";
94
+ return t("bundled.updates.local.checkout.19c28f", "Local checkout");
94
95
  if (installation.kind === "docker")
95
- return installation.dockerMode === "dev" ? "Docker 开发运行时" : "Docker 运行时";
96
- return "安装来源未知";
96
+ return installation.dockerMode === "dev" ? t("bundled.updates.docker.development.runtime.9ba6d5", "Docker development runtime") : t("bundled.updates.docker.runtime.8ce6fc", "Docker runtime");
97
+ return t("bundled.updates.unknown.installation.source.22c213", "Unknown installation source");
97
98
  }
98
99
  function installationScopeLabel(scope) {
99
- return scope === "user" ? "用户范围" : "项目范围";
100
+ return scope === "user" ? t("bundled.updates.user.scope.7baed5", "User scope") : t("bundled.updates.project.scope.0d9798", "Project scope");
100
101
  }
@@ -1,4 +1,5 @@
1
1
  // Generated from pi-web-plugins/workspace-tasks/config.ts. Do not edit directly.
2
+ import { t } from "./i18n.js";
2
3
  export const TASKS_CONFIG_PATH = ".pi-web/tasks.json";
3
4
  export const TASKS_CONFIG_VERSION = 1;
4
5
  const taskIdPattern = /^[a-z][a-z0-9.-]*$/u;
@@ -8,18 +9,18 @@ export function parseTasksConfigText(text) {
8
9
  parsed = JSON.parse(text);
9
10
  }
10
11
  catch (error) {
11
- return { ok: false, error: `JSON 无效: ${error instanceof Error ? error.message : String(error)}` };
12
+ return { ok: false, error: t("bundled.workspace-tasks.invalid.json.17242b", "Invalid JSON: {value1}", { value1: error instanceof Error ? error.message : String(error) }) };
12
13
  }
13
14
  return parseTasksConfig(parsed);
14
15
  }
15
16
  export function parseTasksConfig(value) {
16
17
  if (!isRecord(value))
17
- return invalid("配置必须是对象");
18
+ return invalid(t("bundled.workspace-tasks.config.must.be.an.object.ac0503", "Config must be an object"));
18
19
  if (value["version"] !== TASKS_CONFIG_VERSION)
19
- return invalid("配置 version 必须是 1");
20
+ return invalid(t("bundled.workspace-tasks.config.version.must.be.1.ca03d7", "Config version must be 1"));
20
21
  const tasks = value["tasks"];
21
22
  if (!Array.isArray(tasks))
22
- return invalid("配置 tasks 必须是数组");
23
+ return invalid(t("bundled.workspace-tasks.config.tasks.must.be.an.array.5c6ec9", "Config tasks must be an array"));
23
24
  const ids = new Set();
24
25
  const parsedTasks = [];
25
26
  for (const [index, task] of tasks.entries()) {
@@ -27,21 +28,21 @@ export function parseTasksConfig(value) {
27
28
  if (!parsedTask.ok)
28
29
  return parsedTask;
29
30
  if (ids.has(parsedTask.task.id))
30
- return invalid(`任务 id 重复: ${parsedTask.task.id}`);
31
+ return invalid(t("bundled.workspace-tasks.duplicate.task.id.bd4749", "Duplicate task id: {value1}", { value1: parsedTask.task.id }));
31
32
  ids.add(parsedTask.task.id);
32
33
  parsedTasks.push(parsedTask.task);
33
34
  }
34
35
  return { ok: true, config: { version: TASKS_CONFIG_VERSION, tasks: parsedTasks } };
35
36
  }
36
37
  function parseTask(value, index) {
37
- const label = `任务 ${String(index + 1)}`;
38
+ const label = t("bundled.workspace-tasks.task.17bccc", "Task {value1}", { value1: String(index + 1) });
38
39
  if (!isRecord(value))
39
- return invalid(`${label} 必须是对象`);
40
+ return invalid(t("bundled.workspace-tasks.must.be.an.object.f7baec", "{value1} must be an object", { value1: label }));
40
41
  const id = requireNonEmptyString(value, "id", label);
41
42
  if (!id.ok)
42
43
  return id;
43
44
  if (!taskIdPattern.test(id.value))
44
- return invalid(`${label} id 必须匹配 ${taskIdPattern.source}`);
45
+ return invalid(t("bundled.workspace-tasks.id.must.match.8c38f3", "{value1} id must match {value2}", { value1: label, value2: taskIdPattern.source }));
45
46
  const title = requireNonEmptyString(value, "title", label);
46
47
  if (!title.ok)
47
48
  return title;
@@ -56,7 +57,7 @@ function parseTask(value, index) {
56
57
  return group;
57
58
  const confirm = value["confirm"];
58
59
  if (confirm !== undefined && typeof confirm !== "boolean")
59
- return invalid(`${label} confirm 必须是布尔值`);
60
+ return invalid(t("bundled.workspace-tasks.confirm.must.be.a.boolean.f785a1", "{value1} confirm must be a boolean", { value1: label }));
60
61
  return {
61
62
  ok: true,
62
63
  task: {
@@ -72,7 +73,7 @@ function parseTask(value, index) {
72
73
  function requireNonEmptyString(record, key, label) {
73
74
  const value = record[key];
74
75
  if (typeof value !== "string" || value.trim() === "")
75
- return invalid(`${label} ${key} 必须是非空字符串`);
76
+ return invalid(t("bundled.workspace-tasks.must.be.a.non.empty.string.838d0a", "{value1} {value2} must be a non-empty string", { value1: label, value2: key }));
76
77
  return { ok: true, value };
77
78
  }
78
79
  function optionalNonEmptyString(record, key, label) {
@@ -80,7 +81,7 @@ function optionalNonEmptyString(record, key, label) {
80
81
  if (value === undefined)
81
82
  return { ok: true, value: undefined };
82
83
  if (typeof value !== "string" || value.trim() === "")
83
- return invalid(`${label} ${key} 提供时必须是非空字符串`);
84
+ return invalid(t("bundled.workspace-tasks.must.be.a.non.empty.string.when.provided.a6f9ee", "{value1} {value2} must be a non-empty string when provided", { value1: label, value2: key }));
84
85
  return { ok: true, value };
85
86
  }
86
87
  function invalid(error) {
@@ -0,0 +1,7 @@
1
+ // Generated from pi-web-plugins/workspace-tasks/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,19 +1,21 @@
1
1
  // Generated from pi-web-plugins/workspace-tasks/pi-web-plugin.ts. Do not edit directly.
2
+ import { t, setTranslator } from "./i18n.js";
2
3
  import { TASKS_CONFIG_PATH } from "./config.js";
3
4
  import { defineTasksPanelElement, tasksPanelBadge } from "./tasksPanelElement.js";
4
5
  const plugin = {
5
6
  apiVersion: 4,
6
- name: "工作区任务",
7
- activate: ({ runtimePluginId, html, svg }) => {
7
+ name: t("bundled.workspace-tasks.workspace.tasks.b4ef49", "Workspace tasks"),
8
+ activate: ({ runtimePluginId, html, svg, translate }) => {
9
+ setTranslator(translate);
8
10
  defineTasksPanelElement();
9
11
  return {
10
12
  contributions: {
11
13
  actions: [
12
14
  {
13
15
  id: "workspace.open-tasks",
14
- title: "打开工作区任务",
15
- description: `打开工作区任务标签页。在 ${TASKS_CONFIG_PATH} 中配置任务。`,
16
- group: "工作区",
16
+ title: t("bundled.workspace-tasks.open.workspace.tasks.6243e7", "Open workspace tasks"),
17
+ description: t("bundled.workspace-tasks.open.the.workspace.tasks.tab.configure.tasks.in.d72915", "Open the workspace tasks tab. Configure tasks in {value1}.", { value1: TASKS_CONFIG_PATH }),
18
+ group: t("bundled.workspace-tasks.workspace.379798", "Workspace"),
17
19
  enabled: (context) => context.state.selectedWorkspace !== undefined,
18
20
  run: (context) => {
19
21
  if (context.state.selectedWorkspace === undefined)
@@ -25,7 +27,7 @@ const plugin = {
25
27
  workspacePanels: [
26
28
  {
27
29
  id: "workspace.tasks",
28
- title: "任务",
30
+ title: t("bundled.workspace-tasks.tasks.525304", "Tasks"),
29
31
  icon: svg `
30
32
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
31
33
  <path d="M9 6h11"></path>
@@ -1,4 +1,5 @@
1
1
  // Generated from pi-web-plugins/workspace-tasks/tasksPanelElement.ts. Do not edit directly.
2
+ import { t } from "./i18n.js";
2
3
  import { TASKS_CONFIG_PATH } from "./config.js";
3
4
  import { runWorkspaceTaskInTerminal } from "./taskRunner.js";
4
5
  import { loadWorkspaceTasksConfig, tasksConfigRefreshHint, tasksConfigUnavailableMessage } from "./workspaceTasksClient.js";
@@ -47,17 +48,17 @@ class PiWebTasksPanel extends HTMLElement {
47
48
  render() {
48
49
  const context = this.contextValue;
49
50
  if (context === undefined) {
50
- this.root.innerHTML = `${taskStyles()}<section class="empty">请选择一个工作区。</section>`;
51
+ this.root.innerHTML = `${taskStyles()}<section class="empty">${escapeHtml(t("bundled.workspace-tasks.select.a.workspace.95796d", "Select a workspace."))}</section>`;
51
52
  return;
52
53
  }
53
54
  const state = getOrLoadWorkspaceConfig(context);
54
55
  this.root.innerHTML = `
55
56
  ${taskStyles()}
56
57
  <section class="toolbar">
57
- <strong>工作区任务</strong>
58
+ <strong>${escapeHtml(t("bundled.workspace-tasks.workspace.tasks.b4ef49", "Workspace tasks"))}</strong>
58
59
  <span class="toolbar-tasks">
59
- <button class="secondary" data-refresh-config ${state.kind === "loading" ? "disabled" : ""}>刷新</button>
60
- <button class="secondary" data-open-terminal>打开终端</button>
60
+ <button class="secondary" data-refresh-config ${state.kind === "loading" ? "disabled" : ""}>${escapeHtml(t("bundled.workspace-tasks.refresh.aee887", "Refresh"))}</button>
61
+ <button class="secondary" data-open-terminal>${escapeHtml(t("bundled.workspace-tasks.open.terminal.b89a0e", "Open terminal"))}</button>
61
62
  </span>
62
63
  </section>
63
64
  ${this.renderStatus()}
@@ -82,7 +83,7 @@ class PiWebTasksPanel extends HTMLElement {
82
83
  return Promise.resolve();
83
84
  const task = taskFromConfigState(getCachedWorkspaceConfig(context), taskId);
84
85
  if (task === undefined) {
85
- this.status = { kind: "error", message: "该任务已不可用。请点击刷新后重试。" };
86
+ this.status = { kind: "error", message: t("bundled.workspace-tasks.this.task.is.no.longer.available.click.refresh.and.try.again.158c41", "This task is no longer available. Click Refresh and try again.") };
86
87
  this.render();
87
88
  return Promise.resolve();
88
89
  }
@@ -93,15 +94,15 @@ class PiWebTasksPanel extends HTMLElement {
93
94
  }
94
95
  renderConfigState(state) {
95
96
  if (state.kind === "loading")
96
- return `<p class="muted">正在加载 ${escapeHtml(TASKS_CONFIG_PATH)}…</p>`;
97
+ return `<p class="muted">${escapeHtml(t("bundled.workspace-tasks.loading.9f624f", "Loading {value1}...", { value1: TASKS_CONFIG_PATH }))}</p>`;
97
98
  if (state.kind === "missing")
98
99
  return renderMissingState(state);
99
100
  if (state.kind === "unavailable")
100
101
  return renderUnavailableState(state);
101
102
  if (state.config.tasks.length === 0)
102
- return `<p class="muted">${escapeHtml(state.path)} 中没有定义任务。请在文件中添加任务,然后点击刷新。</p>`;
103
+ return `<p class="muted">${escapeHtml(t("bundled.workspace-tasks.no.tasks.defined.in.add.tasks.to.the.file.then.click.refresh.3af272", "No tasks defined in {value1}. Add tasks to the file, then click Refresh.", { value1: state.path }))}</p>`;
103
104
  return `
104
- <p class="muted">任务会在专用工作区终端中运行,并切换到该终端。编辑 ${escapeHtml(state.path)} 后点击刷新重新加载。</p>
105
+ <p class="muted">${escapeHtml(t("bundled.workspace-tasks.tasks.run.in.a.dedicated.workspace.terminal.and.switch.to.it.edit.3188f4", "Tasks run in a dedicated workspace terminal and switch to it. Edit {value1}, then click Refresh to reload.", { value1: state.path }))}</p>
105
106
  ${renderTaskGroups(state.config.tasks, this.runningTaskId)}
106
107
  `;
107
108
  }
@@ -112,30 +113,30 @@ class PiWebTasksPanel extends HTMLElement {
112
113
  return `<div class="status panel-status ${escapeAttr(this.status.kind)}">${escapeHtml(this.status.message)}${detail}</div>`;
113
114
  }
114
115
  async refreshConfig(context) {
115
- this.status = { kind: "info", message: `正在刷新 ${TASKS_CONFIG_PATH}…` };
116
+ this.status = { kind: "info", message: t("bundled.workspace-tasks.refreshing.b85709", "Refreshing {value1}...", { value1: TASKS_CONFIG_PATH }) };
116
117
  configCache.set(cacheKeyForContext(context), { kind: "loading" });
117
118
  this.render();
118
119
  const state = await refreshWorkspaceConfig(context);
119
120
  if (!this.isCurrentContext(context))
120
121
  return;
121
122
  this.status = state.kind === "loaded"
122
- ? { kind: "success", message: `已加载 ${String(state.config.tasks.length)} 个任务。` }
123
+ ? { kind: "success", message: t("bundled.workspace-tasks.loaded.tasks.cc36a1", "Loaded {value1} tasks.", { value1: String(state.config.tasks.length) }) }
123
124
  : undefined;
124
125
  this.render();
125
126
  }
126
127
  async dispatchTask(context, task) {
127
128
  if (this.runningTaskId !== undefined) {
128
- this.status = { kind: "info", message: "已有其他任务正在启动。请等待其分发完成后重试。" };
129
+ this.status = { kind: "info", message: t("bundled.workspace-tasks.another.task.is.starting.wait.for.dispatch.to.finish.and.try.agai.e4971f", "Another task is starting. Wait for dispatch to finish and try again.") };
129
130
  this.render();
130
131
  return;
131
132
  }
132
- if (task.confirm && !window.confirm(`运行 ${task.title}?\n\n${task.command}`)) {
133
- this.status = { kind: "info", message: `已取消 ${task.title}。` };
133
+ if (task.confirm && !window.confirm(t("bundled.workspace-tasks.run.e5ba41", "Run {value1}?\n\n{value2}", { value1: task.title, value2: task.command }))) {
134
+ this.status = { kind: "info", message: t("bundled.workspace-tasks.cancelled.1a65c2", "Cancelled {value1}.", { value1: task.title }) };
134
135
  this.render();
135
136
  return;
136
137
  }
137
138
  this.runningTaskId = task.id;
138
- this.status = { kind: "info", message: `正在启动 ${task.title}…` };
139
+ this.status = { kind: "info", message: t("bundled.workspace-tasks.starting.80ae5c", "Starting {value1}...", { value1: task.title }) };
139
140
  this.render();
140
141
  try {
141
142
  const handle = await runWorkspaceTaskInTerminal(context.terminal, task);
@@ -143,7 +144,7 @@ class PiWebTasksPanel extends HTMLElement {
143
144
  return;
144
145
  this.status = {
145
146
  kind: "success",
146
- message: `已启动终端命令“${handle.run.title}”。`,
147
+ message: t("bundled.workspace-tasks.started.terminal.command.318e6c", "Started terminal command \"{value1}\".", { value1: handle.run.title }),
147
148
  detail: task.command,
148
149
  };
149
150
  this.runningTaskId = undefined;
@@ -160,7 +161,7 @@ class PiWebTasksPanel extends HTMLElement {
160
161
  openWorkspaceTerminal(terminalId) {
161
162
  const context = this.contextValue;
162
163
  if (context === undefined) {
163
- this.status = { kind: "error", message: "打开终端前请先选择工作区。" };
164
+ this.status = { kind: "error", message: t("bundled.workspace-tasks.select.a.workspace.before.opening.a.terminal.1f87b4", "Select a workspace before opening a terminal.") };
164
165
  this.render();
165
166
  return;
166
167
  }
@@ -186,8 +187,8 @@ async function refreshWorkspaceConfig(context) {
186
187
  const key = cacheKeyForContext(context);
187
188
  const state = await loadWorkspaceTasksConfig(context.files).catch((error) => ({
188
189
  kind: "unavailable",
189
- message: tasksConfigUnavailableMessage,
190
- hint: tasksConfigRefreshHint,
190
+ message: tasksConfigUnavailableMessage(),
191
+ hint: tasksConfigRefreshHint(),
191
192
  detail: error instanceof Error ? error.message : String(error),
192
193
  }));
193
194
  configCache.set(key, state);
@@ -236,7 +237,7 @@ function renderTask(task, runningTaskId) {
236
237
  ${description}
237
238
  <code>${escapeHtml(task.command)}</code>
238
239
  </div>
239
- <button data-task-id="${escapeAttr(task.id)}" ${disabled ? "disabled" : ""}>${running ? "正在分发…" : "运行"}</button>
240
+ <button data-task-id="${escapeAttr(task.id)}" ${disabled ? "disabled" : ""}>${escapeHtml(running ? t("bundled.workspace-tasks.dispatching.f0ad17", "Dispatching...") : t("bundled.workspace-tasks.run.75b269", "Run"))}</button>
240
241
  </article>
241
242
  `;
242
243
  }
@@ -1,9 +1,10 @@
1
1
  // Generated from pi-web-plugins/workspace-tasks/workspaceTasksClient.ts. Do not edit directly.
2
+ import { t } from "./i18n.js";
2
3
  import { TASKS_CONFIG_PATH, parseTasksConfigText } from "./config.js";
3
- export const tasksConfigMissingMessage = "这里还没有配置工作区任务。";
4
- export const tasksConfigMissingHint = `${TASKS_CONFIG_PATH} 是可选文件。如果需要自定义任务,请在当前工作区创建它。`;
5
- export const tasksConfigUnavailableMessage = "无法加载工作区任务。";
6
- export const tasksConfigRefreshHint = `修复 ${TASKS_CONFIG_PATH} 后点击刷新。`;
4
+ export const tasksConfigMissingMessage = () => t("bundled.workspace-tasks.no.workspace.tasks.configured.here.bb6994", "No workspace tasks configured here.");
5
+ export const tasksConfigMissingHint = () => t("bundled.workspace-tasks.is.optional.create.it.in.this.workspace.for.custom.tasks.306cdb", "{value1} is optional. Create it in this workspace for custom tasks.", { value1: TASKS_CONFIG_PATH });
6
+ export const tasksConfigUnavailableMessage = () => t("bundled.workspace-tasks.could.not.load.workspace.tasks.977b0c", "Could not load workspace tasks.");
7
+ export const tasksConfigRefreshHint = () => t("bundled.workspace-tasks.fix.then.click.refresh.04d032", "Fix {value1}, then click Refresh.", { value1: TASKS_CONFIG_PATH });
7
8
  const missingWorkspaceFileError = "Path does not exist";
8
9
  export async function loadWorkspaceTasksConfig(files) {
9
10
  let file;
@@ -18,12 +19,12 @@ export async function loadWorkspaceTasksConfig(files) {
18
19
  catch (error) {
19
20
  if (errorMessage(error) === missingWorkspaceFileError)
20
21
  return missing();
21
- return unavailable(`无法读取 ${TASKS_CONFIG_PATH}: ${formatUnknownError(error)}`);
22
+ return unavailable(t("bundled.workspace-tasks.unable.to.read.3b416a", "Unable to read {value1}: {value2}", { value1: TASKS_CONFIG_PATH, value2: formatUnknownError(error) }));
22
23
  }
23
24
  if (file.binary)
24
- return unavailable(`${TASKS_CONFIG_PATH} 必须是文本文件`);
25
+ return unavailable(t("bundled.workspace-tasks.must.be.a.text.file.3648c8", "{value1} must be a text file", { value1: TASKS_CONFIG_PATH }));
25
26
  if (file.truncated)
26
- return unavailable(`${TASKS_CONFIG_PATH} 过大,内容已被截断`);
27
+ return unavailable(t("bundled.workspace-tasks.is.too.large.and.was.truncated.ce18be", "{value1} is too large and was truncated", { value1: TASKS_CONFIG_PATH }));
27
28
  const result = parseTasksConfigText(file.content);
28
29
  if (!result.ok)
29
30
  return unavailable(result.error);
@@ -32,15 +33,15 @@ export async function loadWorkspaceTasksConfig(files) {
32
33
  function missing() {
33
34
  return {
34
35
  kind: "missing",
35
- message: tasksConfigMissingMessage,
36
- hint: tasksConfigMissingHint,
36
+ message: tasksConfigMissingMessage(),
37
+ hint: tasksConfigMissingHint(),
37
38
  };
38
39
  }
39
40
  function unavailable(detail) {
40
41
  return {
41
42
  kind: "unavailable",
42
- message: tasksConfigUnavailableMessage,
43
- hint: tasksConfigRefreshHint,
43
+ message: tasksConfigUnavailableMessage(),
44
+ hint: tasksConfigRefreshHint(),
44
45
  detail,
45
46
  };
46
47
  }
@@ -0,0 +1,9 @@
1
+ {
2
+ "auth.alreadyConfigured": "普通模式密码已配置",
3
+ "auth.invalidPassword": "普通模式密码无效",
4
+ "auth.loginRequired": "需要登录普通模式",
5
+ "auth.setupRequired": "需要设置普通模式密码",
6
+ "auth.rateLimited": "普通模式登录失败次数过多",
7
+ "auth.passwordRequired": "{field}必须是非空字符串",
8
+ "auth.bodyObject": "请求正文必须是对象"
9
+ }
@@ -0,0 +1,176 @@
1
+ {
2
+ "bundled.info.component.details": "{component}:{details}",
3
+ "bundled.info.list.separator": "、",
4
+ "bundled.relays.document.files": "中继包通常包含 {files}。",
5
+ "bundled.relays.empty.location": "中继包存放在 {path},此工作区目前还没有中继包。",
6
+ "bundled.workspace-tasks.no.workspace.tasks.configured.here.bb6994": "这里还没有配置工作区任务。",
7
+ "bundled.workspace-tasks.is.optional.create.it.in.this.workspace.for.custom.tasks.306cdb": "{value1} 是可选文件。如果需要自定义任务,请在当前工作区创建它。",
8
+ "bundled.workspace-tasks.could.not.load.workspace.tasks.977b0c": "无法加载工作区任务。",
9
+ "bundled.workspace-tasks.fix.then.click.refresh.04d032": "修复 {value1} 后点击刷新。",
10
+ "bundled.workspace-tasks.unable.to.read.3b416a": "无法读取 {value1}: {value2}",
11
+ "bundled.workspace-tasks.must.be.a.text.file.3648c8": "{value1} 必须是文本文件",
12
+ "bundled.workspace-tasks.is.too.large.and.was.truncated.ce18be": "{value1} 过大,内容已被截断",
13
+ "bundled.workspace-tasks.this.task.is.no.longer.available.click.refresh.and.try.again.158c41": "该任务已不可用。请点击刷新后重试。",
14
+ "bundled.workspace-tasks.refreshing.b85709": "正在刷新 {value1}…",
15
+ "bundled.workspace-tasks.loaded.tasks.cc36a1": "已加载 {value1} 个任务。",
16
+ "bundled.workspace-tasks.another.task.is.starting.wait.for.dispatch.to.finish.and.try.agai.e4971f": "已有其他任务正在启动。请等待其分发完成后重试。",
17
+ "bundled.workspace-tasks.run.e5ba41": "运行 {value1}?\n\n{value2}",
18
+ "bundled.workspace-tasks.cancelled.1a65c2": "已取消 {value1}。",
19
+ "bundled.workspace-tasks.starting.80ae5c": "正在启动 {value1}…",
20
+ "bundled.workspace-tasks.started.terminal.command.318e6c": "已启动终端命令“{value1}”。",
21
+ "bundled.workspace-tasks.select.a.workspace.before.opening.a.terminal.1f87b4": "打开终端前请先选择工作区。",
22
+ "bundled.workspace-tasks.dispatching.f0ad17": "正在分发…",
23
+ "bundled.workspace-tasks.run.75b269": "运行",
24
+ "bundled.workspace-tasks.select.a.workspace.95796d": "请选择一个工作区。",
25
+ "bundled.workspace-tasks.workspace.tasks.b4ef49": "工作区任务",
26
+ "bundled.workspace-tasks.refresh.aee887": "刷新",
27
+ "bundled.workspace-tasks.open.terminal.b89a0e": "打开终端",
28
+ "bundled.workspace-tasks.loading.9f624f": "正在加载 {value1}…",
29
+ "bundled.workspace-tasks.no.tasks.defined.in.add.tasks.to.the.file.then.click.refresh.3af272": "{value1} 中没有定义任务。请在文件中添加任务,然后点击刷新。",
30
+ "bundled.workspace-tasks.tasks.run.in.a.dedicated.workspace.terminal.and.switch.to.it.edit.3188f4": "任务会在专用工作区终端中运行,并切换到该终端。编辑 {value1} 后点击刷新重新加载。",
31
+ "bundled.workspace-tasks.invalid.json.17242b": "JSON 无效: {value1}",
32
+ "bundled.workspace-tasks.config.must.be.an.object.ac0503": "配置必须是对象",
33
+ "bundled.workspace-tasks.config.version.must.be.1.ca03d7": "配置 version 必须是 1",
34
+ "bundled.workspace-tasks.config.tasks.must.be.an.array.5c6ec9": "配置 tasks 必须是数组",
35
+ "bundled.workspace-tasks.duplicate.task.id.bd4749": "任务 id 重复: {value1}",
36
+ "bundled.workspace-tasks.task.17bccc": "任务 {value1}",
37
+ "bundled.workspace-tasks.must.be.an.object.f7baec": "{value1} 必须是对象",
38
+ "bundled.workspace-tasks.id.must.match.8c38f3": "{value1} id 必须匹配 {value2}",
39
+ "bundled.workspace-tasks.confirm.must.be.a.boolean.f785a1": "{value1} confirm 必须是布尔值",
40
+ "bundled.workspace-tasks.must.be.a.non.empty.string.838d0a": "{value1} {value2} 必须是非空字符串",
41
+ "bundled.workspace-tasks.must.be.a.non.empty.string.when.provided.a6f9ee": "{value1} {value2} 提供时必须是非空字符串",
42
+ "bundled.workspace-tasks.open.workspace.tasks.6243e7": "打开工作区任务",
43
+ "bundled.workspace-tasks.open.the.workspace.tasks.tab.configure.tasks.in.d72915": "打开工作区任务标签页。在 {value1} 中配置任务。",
44
+ "bundled.workspace-tasks.workspace.379798": "工作区",
45
+ "bundled.workspace-tasks.tasks.525304": "任务",
46
+ "bundled.updates.update.and.restart.all.services.f469f2": "更新并重启全部服务",
47
+ "bundled.updates.restart.all.services.f305e3": "重启全部服务",
48
+ "bundled.updates.updates.3055a0": "更新",
49
+ "bundled.updates.restart.all.9dfe69": "全部重启",
50
+ "bundled.updates.restart.web.ui.9d6372": "重启 Web/界面",
51
+ "bundled.updates.restart.session.daemon.69f455": "重启会话守护进程",
52
+ "bundled.updates.status.6320b4": "状态",
53
+ "bundled.updates.federated.status.unavailable.ad4f0b": "联邦状态不可用",
54
+ "bundled.updates.web.ui.86d6a2": "Web/界面",
55
+ "bundled.updates.session.daemon.757666": "会话守护进程",
56
+ "bundled.updates.docker.update.commands.available.7ab546": "Docker 更新命令可用",
57
+ "bundled.updates.this.plugin.was.loaded.from.a.docker.pi.web.runtime.but.the.gatew.a4f10a": "当前更新插件由 Docker PI WEB 运行时加载,但网关尚未提供 Docker 状态详情。仍可使用下方 Docker 维护命令。",
58
+ "bundled.updates.unknown.4d8c1c": "未知",
59
+ "bundled.updates.unknown.installation.source.22c213": "安装来源未知",
60
+ "bundled.updates.pi.package.feed18": "Pi 包",
61
+ "bundled.updates.global.npm.package.5e8079": "全局 npm 包",
62
+ "bundled.updates.local.checkout.19c28f": "本地检出",
63
+ "bundled.updates.docker.development.runtime.9ba6d5": "Docker 开发运行时",
64
+ "bundled.updates.docker.runtime.8ce6fc": "Docker 运行时",
65
+ "bundled.updates.user.scope.7baed5": "用户范围",
66
+ "bundled.updates.project.scope.0d9798": "项目范围",
67
+ "bundled.updates.copied.8f6f8d": "已复制",
68
+ "bundled.updates.copy.failed.753d8b": "复制失败",
69
+ "bundled.updates.unavailable.460b35": "不可用",
70
+ "bundled.updates.restart.needed.1ffd00": "需要重启",
71
+ "bundled.updates.current.837bc9": "当前版本",
72
+ "bundled.updates.warning.a8b7a4": "警告",
73
+ "bundled.updates.error.0bc1fb": "错误",
74
+ "bundled.updates.check.for.pi.web.updates.2062d8": "检查 PI WEB 更新",
75
+ "bundled.updates.check.the.selected.machine.now.ignoring.cached.release.informatio.e12ea5": "忽略缓存的发布信息,立即检查所选机器",
76
+ "bundled.updates.checking.for.updates.requires.a.newer.pi.web.gateway.0a72c8": "检查更新需要较新版本的 PI WEB 网关",
77
+ "bundled.updates.running.installed.00b7cd": "运行中 {value1} · 已安装 {value2}",
78
+ "bundled.updates.copy.63d90d": "复制",
79
+ "bundled.updates.run.75b269": "运行",
80
+ "bundled.updates.recommended.1452de": "推荐",
81
+ "bundled.updates.run.this.command.to.bring.the.current.installation.up.to.date.no..99197c": "运行这一条命令即可将当前安装更新到最新状态。不需要其他操作。",
82
+ "bundled.updates.suggested.commands.d22916": "建议命令",
83
+ "bundled.updates.use.only.for.finer.control.such.as.restarting.a.single.service.f2c8d9": "仅在需要更细粒度控制时使用,例如只重启某个服务。",
84
+ "bundled.updates.checking.pi.web.update.status.24e243": "正在检查 PI WEB 更新状态…",
85
+ "bundled.updates.no.pi.web.update.or.restart.messages.a2f50d": "没有 PI WEB 更新或重启消息。",
86
+ "bundled.updates.installed.services.ef70c6": "已安装服务",
87
+ "bundled.updates.generated.at.0be2a0": "生成时间 {value1}",
88
+ "bundled.updates.latest.npm.version.e34c2f": "最新 npm 版本 {value1}",
89
+ "bundled.updates.remote.version.check.skipped.66de71": "远程版本检查已跳过。",
90
+ "bundled.updates.remote.version.check.failed.4e0f4a": "远程版本检查失败:{value1}",
91
+ "bundled.info.current.837bc9": "当前版本",
92
+ "bundled.info.restart.needed.1ffd00": "需要重启",
93
+ "bundled.info.unavailable.460b35": "不可用",
94
+ "bundled.info.web.ui.86d6a2": "Web/界面",
95
+ "bundled.info.session.daemon.757666": "会话守护进程",
96
+ "bundled.info.unknown.4d8c1c": "未知",
97
+ "bundled.info.unknown.installation.b61c94": "安装方式未知",
98
+ "bundled.info.pi.package.feed18": "Pi 包",
99
+ "bundled.info.global.npm.package.5e8079": "全局 npm 包",
100
+ "bundled.info.local.checkout.19c28f": "本地检出",
101
+ "bundled.info.docker.development.runtime.9ba6d5": "Docker 开发运行时",
102
+ "bundled.info.docker.runtime.8ce6fc": "Docker 运行时",
103
+ "bundled.info.user.scope.7baed5": "用户范围",
104
+ "bundled.info.project.scope.0d9798": "项目范围",
105
+ "bundled.info.local.machine.ae3fff": "本地机器",
106
+ "bundled.info.remote.machine.674281": "远程机器",
107
+ "bundled.info.update.available.5f3ed8": "有可用更新",
108
+ "bundled.info.update.available.6dee04": "有可用更新:{value1}",
109
+ "bundled.info.update.check.failed.b2e600": "更新检查失败:{value1}",
110
+ "bundled.info.update.check.skipped.966bfb": "已跳过更新检查",
111
+ "bundled.info.up.to.date.bc3104": "已是最新版本",
112
+ "bundled.info.runtime.09b6b8": "运行版本 {value1}",
113
+ "bundled.info.installed.a6f713": "安装版本 {value1}",
114
+ "bundled.info.error.66432a": "错误:{value1}",
115
+ "bundled.info.branch.198c3e": "分支 {value1}",
116
+ "bundled.info.git.worktree.c0db6b": "Git 工作树",
117
+ "bundled.info.git.repository.6a0dac": "Git 仓库",
118
+ "bundled.info.non.git.directory.0936b0": "非 Git 仓库",
119
+ "bundled.info.main.workspace.2ac45d": "主工作区",
120
+ "bundled.info.pi.web.diagnostics.1e6afe": "PI WEB 诊断信息",
121
+ "bundled.info.status.unavailable.e0e66a": "状态:不可用",
122
+ "bundled.info.package.6efebc": "包:{value1}",
123
+ "bundled.info.checked.at.1ecc98": "(检查于 {value1})",
124
+ "bundled.info.release.386d3e": "发布状态:{value1}{value2}",
125
+ "bundled.info.status.generated.ff5eec": "状态生成时间:{value1}",
126
+ "bundled.info.machine.58d58d": "机器:{value1}({value2})",
127
+ "bundled.info.workspace.not.selected.a88368": "工作区:未选择",
128
+ "bundled.info.workspace.fd59a8": "工作区:{value1} - {value2}({value3})",
129
+ "bundled.info.pi.web.status.is.unavailable.it.will.refresh.automatically.381f51": "PI WEB 状态暂不可用,后台会自动刷新。",
130
+ "bundled.info.version.5f76b2": "版本",
131
+ "bundled.info.installed.5e7cb6": "已安装 {value1}",
132
+ "bundled.info.package.26b9c4": "包",
133
+ "bundled.info.installation.9c320c": "安装方式",
134
+ "bundled.info.release.5100f0": "发布状态",
135
+ "bundled.info.checked.at.cc4691": "检查于 {value1}",
136
+ "bundled.info.status.messages.open.updates.for.details.6ca1fc": "{value1} 条状态消息,请打开“更新”标签页查看详情。",
137
+ "bundled.info.status.generated.at.92be3c": "状态生成于 {value1}",
138
+ "bundled.info.services.ec309a": "服务",
139
+ "bundled.info.machine.ece969": "机器",
140
+ "bundled.info.name.d44e9b": "名称",
141
+ "bundled.info.type.ba4001": "类型",
142
+ "bundled.info.workspace.379798": "工作区",
143
+ "bundled.info.path.77e1ea": "路径",
144
+ "bundled.info.info.e70286": "信息",
145
+ "bundled.relays.table.22d9e7": "表格",
146
+ "bundled.info.info.plugin.b6e61e": "信息插件",
147
+ "bundled.info.copy.pi.web.diagnostics.250f13": "复制 PI WEB 诊断信息",
148
+ "bundled.info.copy.this.machine.s.version.installation.and.status.details.for.a.c01908": "复制此机器的版本、安装和状态详情,以便粘贴到错误报告中",
149
+ "bundled.info.folder.7c7802": "文件夹",
150
+ "bundled.relays.relays.715ce8": "中继",
151
+ "bundled.relays.open.workspace.relays.ead958": "打开工作区中继",
152
+ "bundled.relays.open.the.workspace.relays.tab.relays.are.stored.in.3d8901": "打开工作区的中继标签页。中继存放在 {value1}。",
153
+ "bundled.relays.workspace.379798": "工作区",
154
+ "bundled.relays.could.not.scan.workspace.relays.d8b2bc": "无法扫描工作区中继。",
155
+ "bundled.relays.could.not.list.documents.for.this.relay.cad056": "无法列出此中继的文档。",
156
+ "bundled.relays.could.not.read.this.document.7cd2d0": "无法读取此文档。",
157
+ "bundled.relays.select.a.workspace.234859": "请选择工作区。",
158
+ "bundled.relays.scanning.d7c334": "正在扫描 {value1}…",
159
+ "bundled.relays.loading.relay.documents.94db7f": "正在加载中继文档…",
160
+ "bundled.relays.this.relay.no.longer.exists.f8d39d": "此中继已不存在。",
161
+ "bundled.relays.click.refresh.to.rescan.7a2ef0": "点击“刷新”重新扫描 {value1}。",
162
+ "bundled.relays.this.relay.has.no.documents.yet.d5948c": "此中继还没有文档。",
163
+ "bundled.relays.select.a.document.1c46a5": "请选择文档。",
164
+ "bundled.relays.loading.9f624f": "正在加载 {value1}…",
165
+ "bundled.relays.this.document.no.longer.exists.6d4a00": "此文档已不存在。",
166
+ "bundled.relays.click.refresh.to.rescan.relays.2fe15f": "点击“刷新”重新扫描中继。",
167
+ "bundled.relays.binary.file.f080cb": "二进制文件:{value1}",
168
+ "bundled.relays.binary.documents.cannot.be.previewed.as.text.535534": "二进制文档无法提供文本预览。",
169
+ "bundled.relays.this.document.is.truncated.only.the.beginning.is.shown.bf465f": "此文档已截断,仅显示开头内容。",
170
+ "bundled.relays.no.relays.in.this.workspace.6ba356": "此工作区中没有中继。",
171
+ "bundled.relays.relay.documents.91711b": "中继文档",
172
+ "bundled.relays.refresh.aee887": "刷新",
173
+ "bundled.relays.partial": "部分嵌套内容未列出:此中继目录树超过了面板的深度或数量限制。",
174
+ "builtin.argument.name": "<会话名称>",
175
+ "builtin.argument.compact": "[说明]"
176
+ }