@chainingintention/pi-web-cn 2.0.0 → 2.202610.0

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 (584) hide show
  1. package/README.md +61 -106
  2. package/dist/.plugins-ready +1 -0
  3. package/dist/cli.js +331 -174
  4. package/dist/cli.js.map +1 -1
  5. package/dist/client/apple-touch-icon-dev.png +0 -0
  6. package/dist/client/assets/PiWebApp-BXSziMEg.js +4921 -0
  7. package/dist/client/assets/classic-CyM97Akm.css +54 -0
  8. package/dist/client/assets/external-B9K8duyP.js +2 -0
  9. package/dist/client/assets/graphite-DquaqFXU.css +54 -0
  10. package/dist/client/assets/index-cdtUOfOW.js +2 -0
  11. package/dist/client/assets/paper-CB1oLuRr.css +54 -0
  12. package/dist/client/assets/pi-web-dark-D_KtbM95.css +54 -0
  13. package/dist/client/assets/pi-web-light-DSNLMIBI.css +54 -0
  14. package/dist/client/assets/vendor-editor-core-BfnHL1Dg.js +10 -0
  15. package/dist/client/assets/vendor-editor-languages-bNquDJP0.js +28 -0
  16. package/dist/client/favicon-dev.svg +8 -0
  17. package/dist/client/index.html +7 -51
  18. package/dist/client/manifest.webmanifest +2 -1
  19. package/dist/client/pwa-icon-dev-192.png +0 -0
  20. package/dist/client/pwa-icon-dev-512.png +0 -0
  21. package/dist/config.js +55 -8
  22. package/dist/config.js.map +1 -1
  23. package/dist/docker/piWebDockerCommandPlan.js +13 -4
  24. package/dist/docker/piWebDockerCommandPlan.js.map +1 -1
  25. package/dist/environment.js +4 -0
  26. package/dist/environment.js.map +1 -0
  27. package/dist/localization.js +24 -0
  28. package/dist/localization.js.map +1 -0
  29. package/dist/nativeServices/installedServiceDefinitions.js +617 -0
  30. package/dist/nativeServices/installedServiceDefinitions.js.map +1 -0
  31. package/dist/nativeServices/serviceAction.js +78 -20
  32. package/dist/nativeServices/serviceAction.js.map +1 -1
  33. package/dist/nativeServices/serviceDoctor.js +418 -114
  34. package/dist/nativeServices/serviceDoctor.js.map +1 -1
  35. package/dist/nativeServices/servicePlan.js +2 -2
  36. package/dist/nativeServices/servicePlan.js.map +1 -1
  37. package/dist/pi-packages/captains-log/README.md +11 -0
  38. package/dist/pi-packages/captains-log/dist/browser/channelProtocol.js +29 -0
  39. package/dist/pi-packages/captains-log/dist/browser/index.js +143 -0
  40. package/dist/pi-packages/captains-log/dist/browser/markdown.js +68 -0
  41. package/dist/pi-packages/captains-log/dist/browser/panel.js +148 -0
  42. package/dist/pi-packages/captains-log/dist/browser/protocol.js +26 -0
  43. package/dist/pi-packages/captains-log/dist/companion.js +126 -0
  44. package/dist/pi-packages/captains-log/dist/roundtrip.js +62 -0
  45. package/dist/pi-packages/captains-log/dist/server.js +210 -0
  46. package/dist/pi-packages/captains-log/dist/store.js +75 -0
  47. package/dist/pi-packages/captains-log/docs/usage.md +29 -0
  48. package/dist/pi-packages/captains-log/i18n.js +7 -0
  49. package/dist/pi-packages/captains-log/package.json +35 -0
  50. package/dist/pi-packages/captains-log/tsconfig.json +21 -0
  51. package/dist/pi-packages/captains-log/vite.config.mjs +28 -0
  52. package/dist/pi-packages/relays/extensions/index.js +61 -0
  53. package/dist/pi-packages/relays/i18n.js +7 -0
  54. package/dist/{pi-web-plugins → pi-packages}/relays/markdownDocument.js +3 -2
  55. package/dist/pi-packages/relays/package.json +20 -0
  56. package/dist/pi-packages/relays/pi-web-plugin.js +96 -0
  57. package/dist/pi-packages/relays/prompts/relay-worktree.md +18 -0
  58. package/dist/pi-packages/relays/prompts/relay.md +18 -0
  59. package/dist/{pi-web-plugins → pi-packages}/relays/relayDiscovery.js +2 -2
  60. package/dist/pi-packages/relays/relayDispatch.js +67 -0
  61. package/dist/pi-packages/relays/relayIdentity.js +37 -0
  62. package/dist/{pi-web-plugins → pi-packages}/relays/relaysPanelElement.js +98 -59
  63. package/dist/pi-packages/relays/skills/relay/SKILL.md +50 -0
  64. package/dist/pi-packages/relays/skills/relay-runner/SKILL.md +74 -0
  65. package/dist/pi-packages/workflows/browser/pi-web-plugin.js +42 -0
  66. package/dist/pi-packages/workflows/browser/worktreeDialog.js +170 -0
  67. package/dist/pi-packages/workflows/package.json +23 -0
  68. package/dist/pi-packages/workflows/prompts/worktree.md +21 -0
  69. package/dist/pi-packages/workflows/server-plugin.js +586 -0
  70. package/dist/pi-packages/workflows/vite.config.mjs +17 -0
  71. package/dist/pi-web-plugins/code-highlight/browser/pi-web-plugin.js +22 -0
  72. package/dist/pi-web-plugins/code-highlight/package.json +13 -0
  73. package/dist/pi-web-plugins/files/browser/assets/files-icon-DZObYhxb.svg +3 -0
  74. package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +466 -0
  75. package/dist/pi-web-plugins/files/package.json +15 -0
  76. package/dist/pi-web-plugins/git/browser/git-contract.js +22 -11
  77. package/dist/pi-web-plugins/git/browser/git-panel.js +228 -100
  78. package/dist/pi-web-plugins/git/browser/i18n.js +7 -0
  79. package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +28 -4
  80. package/dist/pi-web-plugins/git/git-backend.js +61 -21
  81. package/dist/pi-web-plugins/git/gitStatusCache.js +48 -0
  82. package/dist/pi-web-plugins/git/i18n.js +7 -0
  83. package/dist/pi-web-plugins/git/package.json +1 -0
  84. package/dist/pi-web-plugins/git/server-plugin.js +45 -24
  85. package/dist/pi-web-plugins/git/workspace-discovery-notify.cjs +14 -0
  86. package/dist/pi-web-plugins/git/workspaceDiscoveryHooks.js +186 -0
  87. package/dist/pi-web-plugins/info/i18n.js +7 -0
  88. package/dist/pi-web-plugins/info/infoInternals.js +76 -65
  89. package/dist/pi-web-plugins/info/package.json +1 -1
  90. package/dist/pi-web-plugins/info/pi-web-plugin.js +40 -42
  91. package/dist/pi-web-plugins/mermaid/browser/mermaid-engine.js +4255 -0
  92. package/dist/pi-web-plugins/mermaid/browser/pi-web-plugin.js +11 -0
  93. package/dist/pi-web-plugins/mermaid/package.json +13 -0
  94. package/dist/pi-web-plugins/terminal/browser/pi-web-plugin.js +219 -0
  95. package/dist/pi-web-plugins/terminal/i18n.js +7 -0
  96. package/dist/pi-web-plugins/terminal/package.json +16 -0
  97. package/dist/pi-web-plugins/terminal/server-plugin.js +367 -0
  98. package/dist/pi-web-plugins/terminal/terminalService.js +436 -0
  99. package/dist/pi-web-plugins/updates/i18n.js +7 -0
  100. package/dist/pi-web-plugins/updates/package.json +1 -1
  101. package/dist/pi-web-plugins/updates/pi-web-plugin.js +143 -140
  102. package/dist/pi-web-plugins/updates/updatesLogic.js +24 -24
  103. package/dist/pi-web-plugins/workspace-tasks/config.js +12 -11
  104. package/dist/pi-web-plugins/workspace-tasks/i18n.js +7 -0
  105. package/dist/pi-web-plugins/workspace-tasks/package.json +1 -1
  106. package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +31 -9
  107. package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +54 -36
  108. package/dist/pi-web-plugins/workspace-tasks/workspaceTasksClient.js +12 -11
  109. package/dist/pi-web-plugins/zh-cn/auth.json +9 -0
  110. package/dist/pi-web-plugins/zh-cn/bundled.json +219 -0
  111. package/dist/pi-web-plugins/zh-cn/cli.json +230 -0
  112. package/dist/pi-web-plugins/zh-cn/client.json +225 -0
  113. package/dist/pi-web-plugins/zh-cn/components.json +1252 -0
  114. package/dist/pi-web-plugins/zh-cn/config-errors.json +188 -0
  115. package/dist/pi-web-plugins/zh-cn/files.json +50 -0
  116. package/dist/pi-web-plugins/zh-cn/machines.json +28 -0
  117. package/dist/pi-web-plugins/zh-cn/main.json +459 -0
  118. package/dist/pi-web-plugins/zh-cn/management-errors.json +23 -0
  119. package/dist/pi-web-plugins/zh-cn/manifest.webmanifest +25 -0
  120. package/dist/pi-web-plugins/zh-cn/metadata.json +3 -0
  121. package/dist/pi-web-plugins/zh-cn/package.json +10 -0
  122. package/dist/pi-web-plugins/zh-cn/pi-web-plugin.js +16 -0
  123. package/dist/pi-web-plugins/zh-cn/projects.json +6 -0
  124. package/dist/pi-web-plugins/zh-cn/provider-auth.json +18 -0
  125. package/dist/pi-web-plugins/zh-cn/routing.json +68 -0
  126. package/dist/pi-web-plugins/zh-cn/server-main.json +99 -0
  127. package/dist/pi-web-plugins/zh-cn/server.json +256 -0
  128. package/dist/piAi.js +4 -0
  129. package/dist/piAi.js.map +1 -0
  130. package/dist/piRuntime.js +150 -0
  131. package/dist/piRuntime.js.map +1 -0
  132. package/dist/piSdk.js +5 -0
  133. package/dist/piSdk.js.map +1 -0
  134. package/dist/piWebUpdate.js +508 -0
  135. package/dist/piWebUpdate.js.map +1 -0
  136. package/dist/piWebVersionReport.js +109 -41
  137. package/dist/piWebVersionReport.js.map +1 -1
  138. package/dist/plugin-api.d.ts +609 -29
  139. package/dist/plugin-api.js +1 -0
  140. package/dist/pluginRecoveryCli.js +27 -25
  141. package/dist/pluginRecoveryCli.js.map +1 -1
  142. package/dist/server/activity/workspaceActivityService.js +13 -6
  143. package/dist/server/activity/workspaceActivityService.js.map +1 -1
  144. package/dist/server/app.js +155 -77
  145. package/dist/server/app.js.map +1 -1
  146. package/dist/server/audit/managementAuditStore.js +6 -1
  147. package/dist/server/audit/managementAuditStore.js.map +1 -1
  148. package/dist/server/audit/normalToolAuditCli.js +45 -43
  149. package/dist/server/audit/normalToolAuditCli.js.map +1 -1
  150. package/dist/server/browserMessageProjection.js +39 -22
  151. package/dist/server/browserMessageProjection.js.map +1 -1
  152. package/dist/server/configRoutes.js +54 -33
  153. package/dist/server/configRoutes.js.map +1 -1
  154. package/dist/server/deploymentIdentity.js +67 -0
  155. package/dist/server/deploymentIdentity.js.map +1 -0
  156. package/dist/server/deploymentIdentityRoutes.js +22 -0
  157. package/dist/server/deploymentIdentityRoutes.js.map +1 -0
  158. package/dist/server/diagnostics/nodePtyNativeModule.js +7 -6
  159. package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -1
  160. package/dist/server/diagnostics/nodePtySpawnHelper.js +21 -20
  161. package/dist/server/diagnostics/nodePtySpawnHelper.js.map +1 -1
  162. package/dist/server/index.js +10 -1
  163. package/dist/server/index.js.map +1 -1
  164. package/dist/server/knownAutoInstallPiPackages.js +36 -0
  165. package/dist/server/knownAutoInstallPiPackages.js.map +1 -0
  166. package/dist/server/knownPiPackages.js +12 -0
  167. package/dist/server/knownPiPackages.js.map +1 -0
  168. package/dist/server/machines/machineClient.js +23 -19
  169. package/dist/server/machines/machineClient.js.map +1 -1
  170. package/dist/server/machines/machinePluginProxyRoutes.js +131 -31
  171. package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
  172. package/dist/server/machines/machineProxyRoutes.js +138 -47
  173. package/dist/server/machines/machineProxyRoutes.js.map +1 -1
  174. package/dist/server/machines/machineRoutes.js +18 -13
  175. package/dist/server/machines/machineRoutes.js.map +1 -1
  176. package/dist/server/machines/machineService.js +40 -18
  177. package/dist/server/machines/machineService.js.map +1 -1
  178. package/dist/server/managementEmbed.js +149 -30
  179. package/dist/server/managementEmbed.js.map +1 -1
  180. package/dist/server/managementPrivileges.js +21 -0
  181. package/dist/server/managementPrivileges.js.map +1 -0
  182. package/dist/server/managementTerminalProxyRoutes.js +124 -0
  183. package/dist/server/managementTerminalProxyRoutes.js.map +1 -0
  184. package/dist/server/navigationPreferenceRoutes.js +59 -0
  185. package/dist/server/navigationPreferenceRoutes.js.map +1 -0
  186. package/dist/server/normalAuth.js +77 -53
  187. package/dist/server/normalAuth.js.map +1 -1
  188. package/dist/server/notices/serverNoticeRoutes.js +43 -0
  189. package/dist/server/notices/serverNoticeRoutes.js.map +1 -0
  190. package/dist/server/notices/serverNoticeService.js +26 -0
  191. package/dist/server/notices/serverNoticeService.js.map +1 -0
  192. package/dist/server/notices/serverNoticeStore.js +122 -0
  193. package/dist/server/notices/serverNoticeStore.js.map +1 -0
  194. package/dist/server/passwordVerifier.js +91 -0
  195. package/dist/server/passwordVerifier.js.map +1 -0
  196. package/dist/server/piPackageIdentity.js +25 -0
  197. package/dist/server/piPackageIdentity.js.map +1 -0
  198. package/dist/server/piPackageService.js +72 -9
  199. package/dist/server/piPackageService.js.map +1 -1
  200. package/dist/server/piWebPluginCatalog.js +212 -35
  201. package/dist/server/piWebPluginCatalog.js.map +1 -1
  202. package/dist/server/piWebPluginLifecycle.js +29 -3
  203. package/dist/server/piWebPluginLifecycle.js.map +1 -1
  204. package/dist/server/piWebPluginService.js +199 -292
  205. package/dist/server/piWebPluginService.js.map +1 -1
  206. package/dist/server/piWebStatus.js +57 -100
  207. package/dist/server/piWebStatus.js.map +1 -1
  208. package/dist/server/pluginCallbackDrain.js +35 -0
  209. package/dist/server/pluginCallbackDrain.js.map +1 -0
  210. package/dist/server/plugins/pluginBackendChannelProxyAdmission.js +84 -0
  211. package/dist/server/plugins/pluginBackendChannelProxyAdmission.js.map +1 -0
  212. package/dist/server/plugins/pluginBackendChannelProxyCoordinator.js +234 -0
  213. package/dist/server/plugins/pluginBackendChannelProxyCoordinator.js.map +1 -0
  214. package/dist/server/plugins/pluginBackendChannelProxyRoutes.js +61 -0
  215. package/dist/server/plugins/pluginBackendChannelProxyRoutes.js.map +1 -0
  216. package/dist/server/plugins/pluginBackendProxyRoutes.js +47 -57
  217. package/dist/server/plugins/pluginBackendProxyRoutes.js.map +1 -1
  218. package/dist/server/plugins/pluginBackendRegistry.js +804 -0
  219. package/dist/server/plugins/pluginBackendRegistry.js.map +1 -0
  220. package/dist/server/plugins/projectPluginSettings.js +95 -0
  221. package/dist/server/plugins/projectPluginSettings.js.map +1 -0
  222. package/dist/server/plugins/serverPluginCatalogCapability.js +106 -0
  223. package/dist/server/plugins/serverPluginCatalogCapability.js.map +1 -0
  224. package/dist/server/plugins/serverPluginPiSessionEventsCapability.js +34 -0
  225. package/dist/server/plugins/serverPluginPiSessionEventsCapability.js.map +1 -0
  226. package/dist/server/plugins/serverPluginPiSessionsCapability.js +185 -0
  227. package/dist/server/plugins/serverPluginPiSessionsCapability.js.map +1 -0
  228. package/dist/server/plugins/serverPluginRuntime.js +1088 -108
  229. package/dist/server/plugins/serverPluginRuntime.js.map +1 -1
  230. package/dist/server/plugins/serverPluginWorkspacesCapability.js +114 -0
  231. package/dist/server/plugins/serverPluginWorkspacesCapability.js.map +1 -0
  232. package/dist/server/projectTrustRoutes.js +86 -0
  233. package/dist/server/projectTrustRoutes.js.map +1 -0
  234. package/dist/server/projects/projectLifecycleService.js +94 -0
  235. package/dist/server/projects/projectLifecycleService.js.map +1 -0
  236. package/dist/server/projects/projectService.js +7 -4
  237. package/dist/server/projects/projectService.js.map +1 -1
  238. package/dist/server/realtime/sessionEventHub.js +58 -39
  239. package/dist/server/realtime/sessionEventHub.js.map +1 -1
  240. package/dist/server/realtime/sessionEventScope.js +4 -0
  241. package/dist/server/realtime/sessionEventScope.js.map +1 -1
  242. package/dist/server/requestCancellation.js +15 -1
  243. package/dist/server/requestCancellation.js.map +1 -1
  244. package/dist/server/sessiond/agentHttpDispatcher.js +108 -0
  245. package/dist/server/sessiond/agentHttpDispatcher.js.map +1 -0
  246. package/dist/server/sessiond/autoInstallPiPackages.js +63 -0
  247. package/dist/server/sessiond/autoInstallPiPackages.js.map +1 -0
  248. package/dist/server/sessiond/pluginBackendChannelRoutes.js +410 -0
  249. package/dist/server/sessiond/pluginBackendChannelRoutes.js.map +1 -0
  250. package/dist/server/sessiond/pluginBackendRoutes.js +64 -47
  251. package/dist/server/sessiond/pluginBackendRoutes.js.map +1 -1
  252. package/dist/server/sessiond/pluginCatalogRoutes.js +41 -0
  253. package/dist/server/sessiond/pluginCatalogRoutes.js.map +1 -0
  254. package/dist/server/sessiond/projectMutationRoutes.js +39 -0
  255. package/dist/server/sessiond/projectMutationRoutes.js.map +1 -0
  256. package/dist/server/sessiond/sessionDaemonShutdown.js +36 -0
  257. package/dist/server/sessiond/sessionDaemonShutdown.js.map +1 -0
  258. package/dist/server/sessiond/sessionDaemonStartup.js +30 -4
  259. package/dist/server/sessiond/sessionDaemonStartup.js.map +1 -1
  260. package/dist/server/sessiond/sessionProxyRoutes.js +263 -91
  261. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
  262. package/dist/server/sessiond/sessionServiceDependencies.js +5 -0
  263. package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -1
  264. package/dist/server/sessiond/sessiondStateOwnership.js +174 -39
  265. package/dist/server/sessiond/sessiondStateOwnership.js.map +1 -1
  266. package/dist/server/sessiond/workspaceCatalogRoutes.js +11 -5
  267. package/dist/server/sessiond/workspaceCatalogRoutes.js.map +1 -1
  268. package/dist/server/sessiond/workspaceNotificationRoutes.js +55 -0
  269. package/dist/server/sessiond/workspaceNotificationRoutes.js.map +1 -0
  270. package/dist/server/sessiond/workspaceRemovalRoutes.js +1 -1
  271. package/dist/server/sessiond/workspaceRemovalRoutes.js.map +1 -1
  272. package/dist/server/sessiond.js +313 -69
  273. package/dist/server/sessiond.js.map +1 -1
  274. package/dist/server/sessions/askUserDomain.js +232 -0
  275. package/dist/server/sessions/askUserDomain.js.map +1 -0
  276. package/dist/server/sessions/askUserTool.js +18 -21
  277. package/dist/server/sessions/askUserTool.js.map +1 -1
  278. package/dist/server/sessions/attachmentService.js +2 -6
  279. package/dist/server/sessions/attachmentService.js.map +1 -1
  280. package/dist/server/sessions/authRoutes.js +32 -19
  281. package/dist/server/sessions/authRoutes.js.map +1 -1
  282. package/dist/server/sessions/authService.js +31 -11
  283. package/dist/server/sessions/authService.js.map +1 -1
  284. package/dist/server/sessions/builtinCommands.js +28 -21
  285. package/dist/server/sessions/builtinCommands.js.map +1 -1
  286. package/dist/server/sessions/builtinExtensionFactories.js +36 -0
  287. package/dist/server/sessions/builtinExtensionFactories.js.map +1 -0
  288. package/dist/server/sessions/clientSessionPreview.js +14 -0
  289. package/dist/server/sessions/clientSessionPreview.js.map +1 -0
  290. package/dist/server/sessions/companionBackend.js +286 -0
  291. package/dist/server/sessions/companionBackend.js.map +1 -0
  292. package/dist/server/sessions/dockerEnvironmentFacts.js +98 -10
  293. package/dist/server/sessions/dockerEnvironmentFacts.js.map +1 -1
  294. package/dist/server/sessions/extensionSessionDispatch.js +76 -0
  295. package/dist/server/sessions/extensionSessionDispatch.js.map +1 -0
  296. package/dist/server/sessions/globalProviderPolicy.js +88 -19
  297. package/dist/server/sessions/globalProviderPolicy.js.map +1 -1
  298. package/dist/server/sessions/managementAgentTools.js +116 -6
  299. package/dist/server/sessions/managementAgentTools.js.map +1 -1
  300. package/dist/server/sessions/managementPermissionSystem.js +36 -14
  301. package/dist/server/sessions/managementPermissionSystem.js.map +1 -1
  302. package/dist/server/sessions/managementSandbox.js +7 -18
  303. package/dist/server/sessions/managementSandbox.js.map +1 -1
  304. package/dist/server/sessions/mcpAuthFlowService.js +289 -0
  305. package/dist/server/sessions/mcpAuthFlowService.js.map +1 -0
  306. package/dist/server/sessions/mcpAuthRoutes.js +104 -0
  307. package/dist/server/sessions/mcpAuthRoutes.js.map +1 -0
  308. package/dist/server/sessions/mcpOAuthCredentialAdapter.js +92 -0
  309. package/dist/server/sessions/mcpOAuthCredentialAdapter.js.map +1 -0
  310. package/dist/server/sessions/messageHistoryTarget.js +79 -0
  311. package/dist/server/sessions/messageHistoryTarget.js.map +1 -0
  312. package/dist/server/sessions/messagePaging.js +2 -2
  313. package/dist/server/sessions/messagePaging.js.map +1 -1
  314. package/dist/server/sessions/modelCatalogRefresher.js +4 -3
  315. package/dist/server/sessions/modelCatalogRefresher.js.map +1 -1
  316. package/dist/server/sessions/oauthLoginFlowService.js +19 -20
  317. package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
  318. package/dist/server/sessions/piSessionEventConnections.js +68 -0
  319. package/dist/server/sessions/piSessionEventConnections.js.map +1 -0
  320. package/dist/server/sessions/piSessionManagerGateway.js +206 -27
  321. package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
  322. package/dist/server/sessions/piSessionService.js +2508 -991
  323. package/dist/server/sessions/piSessionService.js.map +1 -1
  324. package/dist/server/sessions/plainTextTheme.js +1 -1
  325. package/dist/server/sessions/plainTextTheme.js.map +1 -1
  326. package/dist/server/sessions/projectAuthService.js +35 -6
  327. package/dist/server/sessions/projectAuthService.js.map +1 -1
  328. package/dist/server/sessions/projectSettingsScope.js +88 -33
  329. package/dist/server/sessions/projectSettingsScope.js.map +1 -1
  330. package/dist/server/sessions/projectTrust.js +119 -0
  331. package/dist/server/sessions/projectTrust.js.map +1 -0
  332. package/dist/server/sessions/queuedMessageMutation.js +170 -0
  333. package/dist/server/sessions/queuedMessageMutation.js.map +1 -0
  334. package/dist/server/sessions/relaySkill.js +169 -0
  335. package/dist/server/sessions/relaySkill.js.map +1 -0
  336. package/dist/server/sessions/sessionActivityMarker.js +105 -0
  337. package/dist/server/sessions/sessionActivityMarker.js.map +1 -0
  338. package/dist/server/sessions/sessionArchiveMapping.js +16 -15
  339. package/dist/server/sessions/sessionArchiveMapping.js.map +1 -1
  340. package/dist/server/sessions/sessionArchiveStore.js +5 -1
  341. package/dist/server/sessions/sessionArchiveStore.js.map +1 -1
  342. package/dist/server/sessions/sessionArchiveTree.js +2 -2
  343. package/dist/server/sessions/sessionArchiveTree.js.map +1 -1
  344. package/dist/server/sessions/sessionCleanup.js +4 -3
  345. package/dist/server/sessions/sessionCleanup.js.map +1 -1
  346. package/dist/server/sessions/sessionCommandService.js +79 -87
  347. package/dist/server/sessions/sessionCommandService.js.map +1 -1
  348. package/dist/server/sessions/sessionEnvironmentFacts.js +5 -4
  349. package/dist/server/sessions/sessionEnvironmentFacts.js.map +1 -1
  350. package/dist/server/sessions/sessionFileHeader.js +41 -0
  351. package/dist/server/sessions/sessionFileHeader.js.map +1 -1
  352. package/dist/server/sessions/sessionImageDimensions.js +31 -0
  353. package/dist/server/sessions/sessionImageDimensions.js.map +1 -0
  354. package/dist/server/sessions/sessionMediaIndex.js +191 -0
  355. package/dist/server/sessions/sessionMediaIndex.js.map +1 -0
  356. package/dist/server/sessions/sessionMetadata.js +51 -0
  357. package/dist/server/sessions/sessionMetadata.js.map +1 -0
  358. package/dist/server/sessions/sessionModelScope.js +160 -0
  359. package/dist/server/sessions/sessionModelScope.js.map +1 -0
  360. package/dist/server/sessions/sessionNameGenerator.js +16 -35
  361. package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
  362. package/dist/server/sessions/sessionNotificationStore.js +14 -11
  363. package/dist/server/sessions/sessionNotificationStore.js.map +1 -1
  364. package/dist/server/sessions/sessionReadAccess.js +41 -0
  365. package/dist/server/sessions/sessionReadAccess.js.map +1 -0
  366. package/dist/server/sessions/sessionRoutes.js +221 -78
  367. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  368. package/dist/server/sessions/sessionSummaryScanner.js +62 -5
  369. package/dist/server/sessions/sessionSummaryScanner.js.map +1 -1
  370. package/dist/server/sessions/sessionTreeProjection.js +50 -49
  371. package/dist/server/sessions/sessionTreeProjection.js.map +1 -1
  372. package/dist/server/sessions/sessionUiEvents.js +22 -10
  373. package/dist/server/sessions/sessionUiEvents.js.map +1 -1
  374. package/dist/server/sessions/sessionUnreadStore.js +53 -3
  375. package/dist/server/sessions/sessionUnreadStore.js.map +1 -1
  376. package/dist/server/sessions/spawnSessionTool.js +14 -6
  377. package/dist/server/sessions/spawnSessionTool.js.map +1 -1
  378. package/dist/server/sessions/spawnSubsessionTool.js +40 -24
  379. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
  380. package/dist/server/sessions/spawnTargetResolver.js +1 -1
  381. package/dist/server/sessions/subsessionCompletionDelivery.js +15 -0
  382. package/dist/server/sessions/subsessionCompletionDelivery.js.map +1 -0
  383. package/dist/server/sessions/subsessionCompletionInbox.js +134 -0
  384. package/dist/server/sessions/subsessionCompletionInbox.js.map +1 -0
  385. package/dist/server/sessions/subsessionProvenance.js +27 -0
  386. package/dist/server/sessions/subsessionProvenance.js.map +1 -0
  387. package/dist/server/sessions/transcriptBranchCache.js +81 -0
  388. package/dist/server/sessions/transcriptBranchCache.js.map +1 -0
  389. package/dist/server/sessions/transcriptMarkdown.js +48 -0
  390. package/dist/server/sessions/transcriptMarkdown.js.map +1 -0
  391. package/dist/server/sessions/transcriptMessages.js +57 -0
  392. package/dist/server/sessions/transcriptMessages.js.map +1 -0
  393. package/dist/server/startupLogger.js +13 -0
  394. package/dist/server/startupLogger.js.map +1 -0
  395. package/dist/server/startupUrls.js +27 -0
  396. package/dist/server/startupUrls.js.map +1 -0
  397. package/dist/server/status/machineStatusService.js +15 -7
  398. package/dist/server/status/machineStatusService.js.map +1 -1
  399. package/dist/server/storage/navigationPreferenceStore.js +138 -0
  400. package/dist/server/storage/navigationPreferenceStore.js.map +1 -0
  401. package/dist/server/storage/piPackageDismissalStore.js +78 -0
  402. package/dist/server/storage/piPackageDismissalStore.js.map +1 -0
  403. package/dist/server/terminals/{terminalService.js → managementCommandRunService.js} +98 -102
  404. package/dist/server/terminals/managementCommandRunService.js.map +1 -0
  405. package/dist/server/terminals/managementTerminalRoutes.js +91 -0
  406. package/dist/server/terminals/managementTerminalRoutes.js.map +1 -0
  407. package/dist/server/terminals/requiredTerminalService.js +103 -0
  408. package/dist/server/terminals/requiredTerminalService.js.map +1 -0
  409. package/dist/server/webSocketBridge.js +348 -0
  410. package/dist/server/webSocketBridge.js.map +1 -1
  411. package/dist/server/workbench/accessStateStore.js +33 -5
  412. package/dist/server/workbench/accessStateStore.js.map +1 -1
  413. package/dist/server/workbench/capabilitySearch.js +3 -2
  414. package/dist/server/workbench/capabilitySearch.js.map +1 -1
  415. package/dist/server/workbench/gatewayIntegration.js +40 -13
  416. package/dist/server/workbench/gatewayIntegration.js.map +1 -1
  417. package/dist/server/workbench/knowledgeSearch.js +100 -0
  418. package/dist/server/workbench/knowledgeSearch.js.map +1 -0
  419. package/dist/server/workbench/mcpClient.js +41 -8
  420. package/dist/server/workbench/mcpClient.js.map +1 -1
  421. package/dist/server/workbench/skillSync.js +11 -3
  422. package/dist/server/workbench/skillSync.js.map +1 -1
  423. package/dist/server/workbench/workbenchClient.js +130 -7
  424. package/dist/server/workbench/workbenchClient.js.map +1 -1
  425. package/dist/server/workbench/workbenchTools.js +196 -14
  426. package/dist/server/workbench/workbenchTools.js.map +1 -1
  427. package/dist/server/workingDirectory.js +3 -2
  428. package/dist/server/workingDirectory.js.map +1 -1
  429. package/dist/server/workspaceExplorerRoutes.js +53 -21
  430. package/dist/server/workspaceExplorerRoutes.js.map +1 -1
  431. package/dist/server/workspaces/fileContentService.js +31 -16
  432. package/dist/server/workspaces/fileContentService.js.map +1 -1
  433. package/dist/server/workspaces/fileOperationService.js +11 -9
  434. package/dist/server/workspaces/fileOperationService.js.map +1 -1
  435. package/dist/server/workspaces/filePreviewService.js +10 -6
  436. package/dist/server/workspaces/filePreviewService.js.map +1 -1
  437. package/dist/server/workspaces/fileSuggestions.js +77 -10
  438. package/dist/server/workspaces/fileSuggestions.js.map +1 -1
  439. package/dist/server/workspaces/fileTreeService.js +103 -15
  440. package/dist/server/workspaces/fileTreeService.js.map +1 -1
  441. package/dist/server/workspaces/normalProjectCwdResolver.js +35 -0
  442. package/dist/server/workspaces/normalProjectCwdResolver.js.map +1 -0
  443. package/dist/server/workspaces/pathAccessPolicy.js +24 -18
  444. package/dist/server/workspaces/pathAccessPolicy.js.map +1 -1
  445. package/dist/server/workspaces/pathSafety.js +6 -5
  446. package/dist/server/workspaces/pathSafety.js.map +1 -1
  447. package/dist/server/workspaces/projectPiWebConfig.js +95 -8
  448. package/dist/server/workspaces/projectPiWebConfig.js.map +1 -1
  449. package/dist/server/workspaces/projectWorkspaceCwds.js +0 -5
  450. package/dist/server/workspaces/projectWorkspaceCwds.js.map +1 -1
  451. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js +37 -22
  452. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js.map +1 -1
  453. package/dist/server/workspaces/workspaceCatalog.js +6 -4
  454. package/dist/server/workspaces/workspaceCatalog.js.map +1 -1
  455. package/dist/server/workspaces/workspaceChangeNotifier.js +12 -0
  456. package/dist/server/workspaces/workspaceChangeNotifier.js.map +1 -0
  457. package/dist/server/workspaces/workspaceDeletionRoutes.js +9 -70
  458. package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -1
  459. package/dist/server/workspaces/workspaceNotificationCommand.js +64 -0
  460. package/dist/server/workspaces/workspaceNotificationCommand.js.map +1 -0
  461. package/dist/server/workspaces/workspaceProviderRegistry.js +128 -24
  462. package/dist/server/workspaces/workspaceProviderRegistry.js.map +1 -1
  463. package/dist/server/workspaces/workspaceRemovalService.js +41 -7
  464. package/dist/server/workspaces/workspaceRemovalService.js.map +1 -1
  465. package/dist/server/workspaces/workspaceRouteContext.js +1 -1
  466. package/dist/server/workspaces/workspaceRouteContext.js.map +1 -1
  467. package/dist/server/workspaces/workspaceRouteErrors.js +4 -2
  468. package/dist/server/workspaces/workspaceRouteErrors.js.map +1 -1
  469. package/dist/server/workspaces/workspaceUserError.js +18 -0
  470. package/dist/server/workspaces/workspaceUserError.js.map +1 -0
  471. package/dist/server-plugin-api.d.ts +349 -49
  472. package/dist/server-plugin-api.js +344 -2
  473. package/dist/server-plugin-api.js.map +1 -1
  474. package/dist/serverPluginRecovery.js +6 -1
  475. package/dist/serverPluginRecovery.js.map +1 -1
  476. package/dist/sessiond/activeAgentProfile.js +27 -2
  477. package/dist/sessiond/activeAgentProfile.js.map +1 -1
  478. package/dist/sessiond/config.js +4 -3
  479. package/dist/sessiond/config.js.map +1 -1
  480. package/dist/sessiond/sessionDaemonClient.js +75 -19
  481. package/dist/sessiond/sessionDaemonClient.js.map +1 -1
  482. package/dist/sessiond/sessionDaemonErrors.js +49 -0
  483. package/dist/sessiond/sessionDaemonErrors.js.map +1 -0
  484. package/dist/shared/activeAgentProfile.js +2 -34
  485. package/dist/shared/activeAgentProfile.js.map +1 -1
  486. package/dist/shared/activity.js +0 -3
  487. package/dist/shared/activity.js.map +1 -1
  488. package/dist/shared/apiTypes.js +10 -3
  489. package/dist/shared/apiTypes.js.map +1 -1
  490. package/dist/shared/capabilities.js +8 -0
  491. package/dist/shared/capabilities.js.map +1 -1
  492. package/dist/shared/federatedRoutes.js +77 -11
  493. package/dist/shared/federatedRoutes.js.map +1 -1
  494. package/dist/shared/i18n.js +41 -0
  495. package/dist/shared/i18n.js.map +1 -0
  496. package/dist/shared/machinePluginIds.js +30 -7
  497. package/dist/shared/machinePluginIds.js.map +1 -1
  498. package/dist/shared/machineStatus.js +46 -3
  499. package/dist/shared/machineStatus.js.map +1 -1
  500. package/dist/shared/navigationPreferences.js +6 -0
  501. package/dist/shared/navigationPreferences.js.map +1 -0
  502. package/dist/shared/piWebConfigParsing.js +118 -49
  503. package/dist/shared/piWebConfigParsing.js.map +1 -1
  504. package/dist/shared/piWebStatusParsing.js +33 -0
  505. package/dist/shared/piWebStatusParsing.js.map +1 -1
  506. package/dist/shared/pluginApiTypes.d.ts +87 -8
  507. package/dist/shared/pluginApiTypes.js +2 -0
  508. package/dist/shared/pluginApiTypes.js.map +1 -0
  509. package/dist/shared/pluginBackendProtocol.js +218 -2
  510. package/dist/shared/pluginBackendProtocol.js.map +1 -1
  511. package/dist/shared/pluginCatalogTypes.d.ts +49 -0
  512. package/dist/shared/pluginCatalogTypes.js +156 -0
  513. package/dist/shared/pluginCatalogTypes.js.map +1 -0
  514. package/dist/shared/pluginIds.js +10 -1
  515. package/dist/shared/pluginIds.js.map +1 -1
  516. package/dist/shared/requiredTerminalPlugin.js +6 -0
  517. package/dist/shared/requiredTerminalPlugin.js.map +1 -0
  518. package/dist/shared/serverNoticeContract.js +88 -0
  519. package/dist/shared/serverNoticeContract.js.map +1 -0
  520. package/dist/shared/sessionDefaults.js +42 -0
  521. package/dist/shared/sessionDefaults.js.map +1 -0
  522. package/dist/shared/sessionMedia.js +12 -0
  523. package/dist/shared/sessionMedia.js.map +1 -0
  524. package/dist/shared/streamingBehavior.js +8 -0
  525. package/dist/shared/streamingBehavior.js.map +1 -0
  526. package/dist/shared/themePreference.js +24 -0
  527. package/dist/shared/themePreference.js.map +1 -0
  528. package/dist/shared/thinkingLevels.js +17 -16
  529. package/dist/shared/thinkingLevels.js.map +1 -1
  530. package/dist/shared/workspaceFiles.js.map +1 -1
  531. package/dist/workspaceNotificationCli.js +95 -0
  532. package/dist/workspaceNotificationCli.js.map +1 -0
  533. package/docs/README.md +31 -0
  534. package/docs/config.md +344 -277
  535. package/docs/plugins.md +204 -930
  536. package/examples/session-bridge-plugin/README.md +20 -0
  537. package/examples/session-bridge-plugin/docs/usage.md +54 -0
  538. package/examples/session-bridge-plugin/package.json +26 -0
  539. package/examples/session-bridge-plugin/src/browser/index.ts +87 -0
  540. package/examples/session-bridge-plugin/src/browser/protocol.ts +24 -0
  541. package/examples/session-bridge-plugin/src/companion.ts +65 -0
  542. package/examples/session-bridge-plugin/src/reviewRun.ts +39 -0
  543. package/examples/session-bridge-plugin/src/server.ts +85 -0
  544. package/examples/session-bridge-plugin/src/store.ts +80 -0
  545. package/examples/session-bridge-plugin/tsconfig.json +21 -0
  546. package/examples/workspace-provider-plugin/README.md +39 -0
  547. package/examples/workspace-provider-plugin/package.json +25 -0
  548. package/examples/workspace-provider-plugin/src/browser/index.ts +69 -0
  549. package/examples/workspace-provider-plugin/src/server.ts +68 -0
  550. package/examples/workspace-provider-plugin/tsconfig.json +21 -0
  551. package/extensions/pi-web.ts +3 -1
  552. package/package.json +59 -36
  553. package/skills/README.md +28 -2
  554. package/skills/relay/SKILL.md +24 -89
  555. package/skills/relay-runner/SKILL.md +74 -0
  556. package/dist/client/assets/CodeViewer-DCl56K0Z.js +0 -4
  557. package/dist/client/assets/TerminalPanel-DCvoEjUF.js +0 -187
  558. package/dist/client/assets/index-CMvms5cF.js +0 -4325
  559. package/dist/client/assets/vendor-editor-core-vUi74DnD.js +0 -12
  560. package/dist/client/assets/vendor-editor-languages-DoaXUodB.js +0 -46
  561. package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +0 -1
  562. package/dist/client/assets/vendor-terminal-BrP-ENHg.css +0 -1
  563. package/dist/client/assets/vendor-terminal-D8k4UKM2.js +0 -35
  564. package/dist/pi-web-plugins/relays/package.json +0 -9
  565. package/dist/pi-web-plugins/relays/pi-web-plugin.js +0 -44
  566. package/dist/server/git/gitService.js +0 -290
  567. package/dist/server/git/gitService.js.map +0 -1
  568. package/dist/server/gitRoutes.js +0 -23
  569. package/dist/server/gitRoutes.js.map +0 -1
  570. package/dist/server/sessions/pendingAskStore.js +0 -278
  571. package/dist/server/sessions/pendingAskStore.js.map +0 -1
  572. package/dist/server/terminalProxyRoutes.js +0 -178
  573. package/dist/server/terminalProxyRoutes.js.map +0 -1
  574. package/dist/server/terminals/terminalRoutes.js +0 -164
  575. package/dist/server/terminals/terminalRoutes.js.map +0 -1
  576. package/dist/server/terminals/terminalService.js.map +0 -1
  577. package/dist/server/terminals/terminalSize.js +0 -17
  578. package/dist/server/terminals/terminalSize.js.map +0 -1
  579. package/dist/server/workspaces/gitWorktreeDiscovery.js +0 -43
  580. package/dist/server/workspaces/gitWorktreeDiscovery.js.map +0 -1
  581. package/dist/server/workspaces/workspaceService.js +0 -52
  582. package/dist/server/workspaces/workspaceService.js.map +0 -1
  583. /package/dist/{pi-web-plugins → pi-packages}/relays/vendor/README.md +0 -0
  584. /package/dist/{pi-web-plugins → pi-packages}/relays/vendor/marked.esm.js +0 -0
@@ -1,4 +1,5 @@
1
1
  // Generated from pi-web-plugins/git/browser/git-panel.ts. Do not edit directly.
2
+ import { t } from "./i18n.js";
2
3
  import { GIT_DIFF_OPERATION, GIT_STATUS_OPERATION, parseGitDiffResponse, parseGitStatusResponse, } from "./git-contract.js";
3
4
  import { buildGitFileList } from "./gitFileList.js";
4
5
  import { buildGitFileTree, collectGitFileTreeDirectoryPaths } from "./gitFileTree.js";
@@ -7,19 +8,22 @@ import { createGitDiffRoute } from "./gitRoute.js";
7
8
  import { parseUnifiedDiff } from "./unifiedDiff.js";
8
9
  const GIT_PANEL_LOCAL_ID = "workspace.git";
9
10
  const GIT_POLL_INTERVAL_MS = 8_000;
11
+ const LARGE_GIT_POLL_INTERVAL_MS = 30_000;
12
+ const LARGE_GIT_FILE_COUNT = 1_000;
13
+ const GIT_FILE_RENDER_BATCH = 500;
10
14
  // Keep navigation state for a few recent workspaces; heavy diff views are
11
15
  // released as soon as another machine/workspace becomes active.
12
16
  const GIT_WORKSPACE_STATE_LIMIT = 8;
13
17
  const activityElementTag = "pi-web-git-panel-activity";
14
18
  const EMPTY_LIST_MODEL = { submodules: [], files: [] };
15
19
  const EMPTY_VIEW_STATE = { nodes: [], listModel: EMPTY_LIST_MODEL, expandablePaths: [] };
16
- export function createGitBrowserContributions(sourcePluginId, runtimePluginId, html, svg) {
20
+ export function createGitBrowserContributions(sourcePluginId, runtimePluginId, html, svg, stylesheetIntegration = () => undefined) {
17
21
  const panelId = `${runtimePluginId}:${GIT_PANEL_LOCAL_ID}`;
18
22
  const controller = new GitUiController(sourcePluginId, createGitDiffRoute(panelId));
19
23
  defineGitPanelActivityElement();
20
24
  return {
21
25
  actions: createGitActions(panelId, controller),
22
- workspacePanels: [createGitPanel(html, svg, controller)],
26
+ workspacePanels: [createGitPanel(html, svg, controller, stylesheetIntegration)],
23
27
  };
24
28
  }
25
29
  class GitUiController {
@@ -34,8 +38,8 @@ class GitUiController {
34
38
  this.sourcePluginId = sourcePluginId;
35
39
  this.route = route;
36
40
  }
37
- isOwnedWorkspace(workspace) {
38
- return workspace?.provider?.pluginId === this.sourcePluginId;
41
+ canInspectWorkspace(workspace) {
42
+ return workspace !== undefined && (workspace.provider === undefined || workspace.provider.pluginId === this.sourcePluginId);
39
43
  }
40
44
  state(context) {
41
45
  return this.stateFor(context);
@@ -51,8 +55,8 @@ class GitUiController {
51
55
  this.synchronizeRoute(state, changedWorkspace);
52
56
  if (state.status === undefined && state.statusRequest === undefined)
53
57
  void this.refresh(context);
54
- else if (state.selectedDiffPath !== undefined && (state.selectedDiff === undefined || state.selectedStagedDiff === undefined) && !state.diffLoading) {
55
- if (state.status?.files.some((file) => file.path === state.selectedDiffPath) === true)
58
+ else if (state.status !== undefined && state.selectedDiffPath !== undefined && (state.selectedDiff === undefined || state.selectedStagedDiff === undefined) && !state.diffLoading) {
59
+ if (state.status.files.some((file) => file.path === state.selectedDiffPath))
56
60
  void this.refreshDiff(state, state.selectedDiffPath, context);
57
61
  else
58
62
  this.clearSelection(state, true);
@@ -70,37 +74,63 @@ class GitUiController {
70
74
  this.requestRender(this.stateFor(context));
71
75
  }
72
76
  poll(context) {
73
- void this.refresh(context);
77
+ if (typeof document !== "undefined" && document.visibilityState !== "visible")
78
+ return;
79
+ const state = this.stateFor(context);
80
+ const interval = (state.status?.files.length ?? 0) > LARGE_GIT_FILE_COUNT ? LARGE_GIT_POLL_INTERVAL_MS : GIT_POLL_INTERVAL_MS;
81
+ if (Date.now() - state.lastStatusRefreshAt < interval)
82
+ return;
83
+ void this.refresh(context, false);
74
84
  }
75
85
  invalidate(context) {
76
- if (!this.isOwnedWorkspace(context.workspace))
86
+ if (!this.canInspectWorkspace(context.workspace))
77
87
  return Promise.resolve();
78
88
  const state = this.stateFor(context);
79
89
  state.stale = state.status !== undefined;
80
90
  this.requestRender(state);
81
91
  return this.refresh(context);
82
92
  }
83
- refresh(context) {
93
+ refresh(context, force = true) {
84
94
  const state = this.stateFor(context);
85
- if (state.statusRequest !== undefined)
95
+ const background = !force;
96
+ if (state.statusRequest !== undefined) {
97
+ if (!background && !state.statusLoading) {
98
+ state.statusLoading = true;
99
+ this.requestRender(state);
100
+ }
86
101
  return state.statusRequest;
87
- state.statusLoading = true;
88
- this.requestRender(state);
89
- const request = requestGitBackend(context, GIT_STATUS_OPERATION, null)
102
+ }
103
+ const previousStatus = state.status;
104
+ const previousError = state.error;
105
+ const previousStale = state.stale;
106
+ const previousPath = state.selectedDiffPath;
107
+ const showLoading = !background || state.status === undefined;
108
+ if (showLoading) {
109
+ state.statusLoading = true;
110
+ this.requestRender(state);
111
+ }
112
+ state.lastStatusRefreshAt = Date.now();
113
+ const request = requestGitBackend(context, GIT_STATUS_OPERATION, force ? { refresh: true } : null)
90
114
  .then(parseGitStatusResponse)
91
115
  .then(async (status) => {
92
116
  if (!state.retained)
93
117
  return;
94
- state.status = state.status?.hash === status.hash ? state.status : status;
118
+ if (state.status?.hash !== status.hash) {
119
+ state.status = status;
120
+ state.visibleFileLimit = GIT_FILE_RENDER_BATCH;
121
+ revealSelectedFile(state, this.view);
122
+ }
95
123
  state.stale = false;
96
- state.error = undefined;
97
124
  const path = state.selectedDiffPath;
98
- if (path === undefined)
99
- return;
100
- if (!status.files.some((file) => file.path === path))
101
- this.clearSelection(state, true);
102
- else if (this.connectedWorkspaceKey === workspaceContextKey(context))
103
- await this.refreshDiff(state, path, context);
125
+ if (path !== undefined && status.files.some((file) => file.path === path)
126
+ && this.connectedWorkspaceKey === workspaceContextKey(context)) {
127
+ await this.refreshDiff(state, path, context, background);
128
+ }
129
+ else {
130
+ state.error = undefined;
131
+ if (path !== undefined && !status.files.some((file) => file.path === path))
132
+ this.clearSelection(state, true);
133
+ }
104
134
  })
105
135
  .catch((error) => {
106
136
  if (state.retained)
@@ -110,8 +140,11 @@ class GitUiController {
110
140
  if (state.statusRequest !== request)
111
141
  return;
112
142
  state.statusRequest = undefined;
143
+ const wasLoading = state.statusLoading;
113
144
  state.statusLoading = false;
114
- this.requestRender(state);
145
+ if (wasLoading || previousStatus !== state.status || previousError !== state.error
146
+ || previousStale !== state.stale || previousPath !== state.selectedDiffPath)
147
+ this.requestRender(state);
115
148
  });
116
149
  state.statusRequest = request;
117
150
  return request;
@@ -119,6 +152,7 @@ class GitUiController {
119
152
  selectDiff(context, path) {
120
153
  const state = this.stateFor(context);
121
154
  state.selectedDiffPath = path;
155
+ revealSelectedFile(state, this.view);
122
156
  state.selectedDiff = undefined;
123
157
  state.selectedStagedDiff = undefined;
124
158
  state.diffLoading = true;
@@ -144,12 +178,18 @@ class GitUiController {
144
178
  }
145
179
  viewState(state) {
146
180
  const cached = state.viewStateCache;
147
- if (cached !== undefined && cached.status === state.status && cached.view === this.view)
181
+ if (cached !== undefined && cached.status === state.status && cached.view === this.view && cached.visibleFileLimit === state.visibleFileLimit)
148
182
  return cached.viewState;
149
183
  const viewState = buildViewState(state.status, this.view);
150
- state.viewStateCache = { status: state.status, view: this.view, viewState };
184
+ state.viewStateCache = { status: state.status, view: this.view, viewState, visibleFileLimit: state.visibleFileLimit };
151
185
  return viewState;
152
186
  }
187
+ showMore(context) {
188
+ const state = this.stateFor(context);
189
+ state.visibleFileLimit += GIT_FILE_RENDER_BATCH;
190
+ state.viewStateCache = undefined;
191
+ this.requestRender(state);
192
+ }
153
193
  toggleDirectory(context, path) {
154
194
  const state = this.stateFor(context);
155
195
  const next = new Set(state.expandedDirectories);
@@ -191,6 +231,10 @@ class GitUiController {
191
231
  statusRequest: undefined,
192
232
  diffRequestSequence: 0,
193
233
  viewStateCache: undefined,
234
+ visibleFileLimit: GIT_FILE_RENDER_BATCH,
235
+ remainingRows: GIT_FILE_RENDER_BATCH,
236
+ hasMoreRows: false,
237
+ lastStatusRefreshAt: 0,
194
238
  };
195
239
  this.states.set(key, created);
196
240
  return created;
@@ -237,6 +281,7 @@ class GitUiController {
237
281
  if (state.selectedDiffPath === path)
238
282
  return;
239
283
  state.selectedDiffPath = path;
284
+ revealSelectedFile(state, this.view);
240
285
  state.selectedDiff = undefined;
241
286
  state.selectedStagedDiff = undefined;
242
287
  state.diffLoading = false;
@@ -248,11 +293,17 @@ class GitUiController {
248
293
  this.route.write(undefined, { replace: true });
249
294
  }
250
295
  }
251
- async refreshDiff(state, path, context) {
296
+ async refreshDiff(state, path, context, background = false) {
252
297
  const sequence = state.diffRequestSequence + 1;
253
298
  state.diffRequestSequence = sequence;
254
- state.diffLoading = true;
255
- this.requestRender(state);
299
+ const previousDiff = state.selectedDiff;
300
+ const previousStagedDiff = state.selectedStagedDiff;
301
+ const previousError = state.error;
302
+ const showLoading = !background || previousDiff === undefined || previousStagedDiff === undefined;
303
+ if (showLoading) {
304
+ state.diffLoading = true;
305
+ this.requestRender(state);
306
+ }
256
307
  try {
257
308
  const [selectedDiff, selectedStagedDiff] = await Promise.all([
258
309
  requestGitBackend(context, GIT_DIFF_OPERATION, { path }).then(parseGitDiffResponse),
@@ -271,8 +322,11 @@ class GitUiController {
271
322
  }
272
323
  finally {
273
324
  if (state.retained && state.diffRequestSequence === sequence && state.selectedDiffPath === path) {
325
+ const wasLoading = state.diffLoading;
274
326
  state.diffLoading = false;
275
- this.requestRender(state);
327
+ if (wasLoading || previousDiff !== state.selectedDiff || previousStagedDiff !== state.selectedStagedDiff
328
+ || previousError !== state.error)
329
+ this.requestRender(state);
276
330
  }
277
331
  }
278
332
  }
@@ -282,29 +336,29 @@ class GitUiController {
282
336
  }
283
337
  }
284
338
  function createGitActions(panelId, controller) {
285
- const hasGitWorkspace = (context) => controller.isOwnedWorkspace(context.state.selectedWorkspace);
339
+ const hasGitWorkspace = (context) => controller.canInspectWorkspace(context.state.selectedWorkspace);
286
340
  return [
287
341
  {
288
342
  id: "view.git",
289
- title: "转到 Git",
343
+ title: t("client.actions.go.to.git.0d4886", "Go to Git"),
290
344
  shortcut: "mod+3",
291
345
  shortcutAliases: ["core:view.git"],
292
- group: "导航",
346
+ group: t("client.actions.navigation.e72622", "Navigation"),
293
347
  enabled: hasGitWorkspace,
294
- run: (context) => { context.selectMainView(panelId); },
348
+ run: (context) => { context.selectWorkspaceTool(panelId); },
295
349
  },
296
350
  {
297
351
  id: "workspace.refresh-git",
298
- title: "刷新 Git",
352
+ title: t("client.actions.refresh.git.496f8a", "Refresh Git"),
299
353
  shortcut: "mod+shift+g",
300
354
  shortcutAliases: ["core:workspace.refresh-git"],
301
- group: "工作区",
355
+ group: t("bundled.workspace-tasks.workspace.379798", "Workspace"),
302
356
  enabled: hasGitWorkspace,
303
- run: (context) => context.refreshWorkspacePanels?.(panelId),
357
+ run: (context) => context.refreshWorkspacePanels(panelId),
304
358
  },
305
359
  ];
306
360
  }
307
- function createGitPanel(html, svg, controller) {
361
+ function createGitPanel(html, svg, controller, stylesheetIntegration) {
308
362
  return {
309
363
  id: GIT_PANEL_LOCAL_ID,
310
364
  title: "Git",
@@ -320,36 +374,38 @@ function createGitPanel(html, svg, controller) {
320
374
  `,
321
375
  order: 20,
322
376
  routeAliases: ["git", "core:workspace.git"],
323
- visible: (context) => controller.isOwnedWorkspace(context.workspace),
377
+ navigationAliases: ["core:workspace.git"],
378
+ visible: (context) => controller.canInspectWorkspace(context.workspace),
324
379
  onInvalidate: (context) => controller.invalidate(context),
325
- render: (context) => renderGitPanel(html, controller, context),
380
+ render: (context) => renderGitPanel(html, controller, context, stylesheetIntegration()),
326
381
  };
327
382
  }
328
383
  function requestGitBackend(context, operation, input) {
329
- if (context.backend === undefined || context.workspace.provider?.capabilities.request === false) {
330
- return Promise.reject(new Error("Git 工作区后端不可用。请更新并重启此机器上的 PI WEB,然后重新加载浏览器。"));
384
+ if (context.peer?.request === undefined) {
385
+ return Promise.reject(new Error(t("ui.main.fc3b27465765", "Git workspace backend is unavailable. Update and restart PI WEB on this machine, then reload the browser.")));
331
386
  }
332
- return context.backend.request(operation, input);
387
+ return context.peer.request(operation, input);
333
388
  }
334
- function renderGitPanel(html, controller, context) {
389
+ function renderGitPanel(html, controller, context, stylesheetIntegration) {
335
390
  const state = controller.state(context);
336
391
  const viewState = controller.viewState(state);
337
392
  return html `
338
393
  <section class="git-panel">
339
- <style .textContent=${gitPanelStyles}></style>
340
- <pi-web-git-panel-activity .controller=${controller} .context=${context}></pi-web-git-panel-activity>
341
- <section class="git-toolbar">
394
+ <style data-git-styles .textContent=${gitPanelStyles}></style>
395
+ <pi-web-git-panel-activity .stylesheetIntegration=${stylesheetIntegration} .controller=${controller} .context=${context}></pi-web-git-panel-activity>
396
+ <section class="ui-toolbar git-toolbar">
342
397
  <strong>Git</strong>
343
- ${state.stale ? html `<span class="git-stale">数据已过期</span>` : null}
344
- <div class="git-toolbar-actions">
398
+ ${state.stale ? html `<span class="git-stale">${t("ui.main.3468df3f1fe9", "stale")}</span>` : null}
399
+ <div class="ui-toolbar-group git-toolbar-actions">
345
400
  ${viewState.expandablePaths.length === 0 ? null : renderExpandCollapseAll(html, controller, context, state, viewState.expandablePaths)}
346
401
  ${renderViewToggle(html, controller, context)}
347
- <button type="button" ?disabled=${state.statusLoading} @click=${() => { void controller.refresh(context); }}>刷新</button>
402
+ <button class="ui-button" type="button" ?disabled=${state.statusLoading} @click=${() => { void controller.refresh(context); }}>${t("bundled.relays.refresh.aee887", "Refresh")}</button>
348
403
  </div>
349
404
  </section>
350
405
  ${state.error === undefined ? null : html `<div class="git-error" role="alert">${state.error}</div>`}
406
+ ${state.status?.truncated === true ? html `<div class="git-warning" role="status">${t("ui.main.1634590c49b8", "Git status output was too large; the file list was truncated.")}</div>` : null}
351
407
  <section class="git-split">
352
- <div class="git-file-list">${renderFileList(html, controller, context, state, viewState)}</div>
408
+ <div class="ui-file-list git-file-list">${renderFileList(html, controller, context, state, viewState)}</div>
353
409
  <div class="git-viewer">${renderDiffViewer(html, state)}</div>
354
410
  </section>
355
411
  </section>
@@ -357,33 +413,39 @@ function renderGitPanel(html, controller, context) {
357
413
  }
358
414
  function renderViewToggle(html, controller, context) {
359
415
  return html `
360
- <div class="git-view-toggle" role="group" aria-label="已更改文件视图">
361
- ${renderViewToggleButton(html, controller, context, "list", "列表")}
362
- ${renderViewToggleButton(html, controller, context, "tree", "树形")}
416
+ <div class="ui-toolbar-group git-view-toggle" role="group" aria-label="${t("ui.main.898449210b9d", "Changed files view")}">
417
+ ${renderViewToggleButton(html, controller, context, "list", t("ui.workspaceGitPanel.list", "List"))}
418
+ ${renderViewToggleButton(html, controller, context, "tree", t("ui.main.7f32c63d2d35", "Tree"))}
363
419
  </div>
364
420
  `;
365
421
  }
366
422
  function renderViewToggleButton(html, controller, context, view, label) {
367
423
  const active = controller.currentView() === view;
368
- return html `<button type="button" class=${active ? "is-selected" : ""} aria-pressed=${String(active)} @click=${() => { controller.setView(context, view); }}>${label}</button>`;
424
+ return html `<button type="button" class="ui-button" aria-pressed=${String(active)} @click=${() => { controller.setView(context, view); }}>${label}</button>`;
369
425
  }
370
426
  function renderExpandCollapseAll(html, controller, context, state, expandablePaths) {
371
427
  const allExpanded = expandablePaths.every((path) => state.expandedDirectories.has(path));
372
- return html `<button type="button" @click=${() => { controller.toggleExpandAll(context, expandablePaths, allExpanded); }}>${allExpanded ? "全部折叠" : "全部展开"}</button>`;
428
+ return html `<button class="ui-button" type="button" @click=${() => { controller.toggleExpandAll(context, expandablePaths, allExpanded); }}>${allExpanded ? t("ui.workspaceGitPanel.collapseAll", "Collapse all") : t("ui.workspaceGitPanel.expandAll", "Expand all")}</button>`;
373
429
  }
374
430
  function renderFileList(html, controller, context, state, viewState) {
375
431
  const status = state.status;
376
432
  if (status === undefined)
377
- return html `<p class="git-muted">${state.error === undefined ? "正在加载状态…" : "状态不可用。"}</p>`;
433
+ return html `<p class="git-muted">${state.error === undefined ? t("ui.main.f2cb84a98270", "Loading status…") : t("ui.main.d2302e08b20b", "Status unavailable.")}</p>`;
378
434
  if (!status.isGitRepo)
379
- return html `<p class="git-muted">当前工作区不是 Git 仓库。</p>`;
435
+ return html `<p class="git-muted">${t("ui.main.b4b1ea928fc3", "Not a git repository.")}</p>`;
380
436
  const summary = html `<p class="git-summary">${gitSummary(status)}</p>`;
381
437
  if (status.files.length === 0)
382
- return html `${summary}<p class="git-muted">没有更改。</p>`;
438
+ return html `${summary}<p class="git-muted">${t("ui.workspaceGitPanel.noChanges", "No changes.")}</p>`;
439
+ state.remainingRows = state.visibleFileLimit;
440
+ state.hasMoreRows = status.files.length > state.visibleFileLimit;
383
441
  const body = controller.currentView() === "tree"
384
442
  ? viewState.nodes.map((node) => renderTreeNode(html, controller, context, state, node, 0))
385
443
  : renderListBody(html, controller, context, state, viewState.listModel);
386
- return html `${summary}${body}`;
444
+ const rendered = Math.min(state.visibleFileLimit, status.files.length);
445
+ const more = state.hasMoreRows || rendered < status.files.length
446
+ ? html `<button type="button" class="git-load-more" @click=${() => { controller.showMore(context); }}>${t("ui.main.34f2d3bdae3d", "Show more (")}${String(rendered)}/${String(status.files.length)})</button>`
447
+ : null;
448
+ return html `${summary}${body}${more}`;
387
449
  }
388
450
  function renderListBody(html, controller, context, state, model) {
389
451
  return html `
@@ -392,11 +454,13 @@ function renderListBody(html, controller, context, state, model) {
392
454
  `;
393
455
  }
394
456
  function renderSubmoduleGroup(html, controller, context, state, group) {
457
+ if (!consumeGitRow(state))
458
+ return html ``;
395
459
  const expanded = state.expandedDirectories.has(group.path);
396
460
  return html `
397
- <button type="button" class="git-row" style="--depth:0" aria-expanded=${String(expanded)} @click=${() => { controller.toggleDirectory(context, group.path); }}>
398
- <span class="git-twisty">${expanded ? "▾" : "▸"}</span>
399
- <span>${group.name}${submoduleBadge(html)}</span>
461
+ <button type="button" class="ui-button ui-file-row" style="--depth:0" title=${group.path} aria-expanded=${String(expanded)} @click=${() => { controller.toggleDirectory(context, group.path); }}>
462
+ <span class="ui-file-leading" aria-hidden="true">${expanded ? "▾" : "▸"}</span>
463
+ <span class="ui-file-label">${group.name}${submoduleBadge(html)}</span>
400
464
  </button>
401
465
  ${expanded ? html `
402
466
  ${group.pointer === undefined ? null : renderSelectableRow(html, controller, context, state, group.path, group.pointer.name, group.pointer.file, 1)}
@@ -409,11 +473,13 @@ function renderSubmoduleFileRow(html, controller, context, state, entry) {
409
473
  }
410
474
  function renderTreeNode(html, controller, context, state, node, depth) {
411
475
  if (node.kind === "directory") {
476
+ if (!consumeGitRow(state))
477
+ return html ``;
412
478
  const expanded = state.expandedDirectories.has(node.path);
413
479
  return html `
414
- <button type="button" class="git-row" style=${`--depth:${String(depth)}`} aria-expanded=${String(expanded)} @click=${() => { controller.toggleDirectory(context, node.path); }}>
415
- <span class="git-twisty">${expanded ? "▾" : "▸"}</span>
416
- <span>${node.name}${node.isSubmodule === true ? submoduleBadge(html) : null}</span>
480
+ <button type="button" class="ui-button ui-file-row" style=${`--depth:${String(depth)}`} title=${node.path} aria-expanded=${String(expanded)} @click=${() => { controller.toggleDirectory(context, node.path); }}>
481
+ <span class="ui-file-leading" aria-hidden="true">${expanded ? "▾" : "▸"}</span>
482
+ <span class="ui-file-label">${node.name}${node.isSubmodule === true ? submoduleBadge(html) : null}</span>
417
483
  </button>
418
484
  ${expanded ? node.children.map((child) => renderTreeNode(html, controller, context, state, child, depth + 1)) : null}
419
485
  `;
@@ -424,35 +490,46 @@ function renderFileRow(html, controller, context, state, file) {
424
490
  return renderSelectableRow(html, controller, context, state, file.path, file.path, file, 0);
425
491
  }
426
492
  function renderSelectableRow(html, controller, context, state, path, label, file, depth) {
493
+ if (!consumeGitRow(state))
494
+ return html ``;
427
495
  const selected = state.selectedDiffPath === path;
428
496
  return html `
429
- <button type="button" class=${selected ? "git-row is-selected" : "git-row"} style=${`--depth:${String(depth)}`} @click=${() => { controller.selectDiff(context, path); }}>
430
- <span>${stateLabel(file.index, file.workingTree)}</span>
431
- <span>${label}</span>
497
+ <button type="button" class=${selected ? "ui-button ui-file-row selected" : "ui-button ui-file-row"} style=${`--depth:${String(depth)}`} title=${path} aria-current=${selected ? "page" : "false"} @click=${() => { controller.selectDiff(context, path); }}>
498
+ <span class="ui-file-leading" aria-hidden="true"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"></path><path d="M14 2v6h6"></path></svg></span>
499
+ <span class="ui-file-label">${label}</span>
500
+ <span class="ui-file-meta">${stateLabel(file.index, file.workingTree)}</span>
432
501
  </button>
433
502
  `;
434
503
  }
435
504
  function renderDiffViewer(html, state) {
436
505
  if (state.selectedDiffPath === undefined)
437
- return html `<p class="git-muted">请选择一个已更改文件。</p>`;
506
+ return html `<p class="git-muted">${t("ui.main.77ed4aee3792", "Select a changed file.")}</p>`;
438
507
  const unstaged = state.selectedDiff;
439
508
  const staged = state.selectedStagedDiff;
440
509
  if (unstaged === undefined || staged === undefined)
441
- return html `<p class="git-muted">正在加载差异…</p>`;
510
+ return html `<p class="git-muted">${t("ui.workspaceGitPanel.loadingDiff", "Loading diff…")}</p>`;
442
511
  const diffs = [staged, unstaged].filter((diff) => diff.response.diff !== "");
443
512
  if (diffs.length === 0)
444
- return html `<p class="git-muted">没有已暂存或未暂存的差异。</p>`;
513
+ return html `<p class="git-muted">${t("ui.workspaceGitPanel.noStagedOrUnstagedDiff", "No staged or unstaged diff.")}</p>`;
445
514
  return html `<div class=${diffs.length === 1 ? "git-diffs is-single" : "git-diffs"}>${diffs.map((diff) => renderDiffSection(html, diff))}</div>`;
446
515
  }
516
+ function consumeGitRow(state) {
517
+ if (state.remainingRows > 0) {
518
+ state.remainingRows -= 1;
519
+ return true;
520
+ }
521
+ state.hasMoreRows = true;
522
+ return false;
523
+ }
447
524
  function renderDiffSection(html, view) {
448
525
  const diff = view.response;
449
526
  const lines = view.lines ??= parseUnifiedDiff(diff.diff);
450
527
  return html `
451
528
  <section class="git-diff-section">
452
- <div class="git-viewer-header"><strong>${diff.path ?? "差异"}</strong><small>${diff.staged ? "已暂存" : "未暂存"}${diff.truncated ? " · 已截断" : ""}</small></div>
453
- ${lines.length === 0 ? html `<p class="git-muted">没有差异。</p>` : html `
529
+ <div class="git-viewer-header"><strong>${diff.path ?? t("ui.workspaceGitPanel.diff", "Diff")}</strong><small>${diff.staged ? t("ui.workspaceGitPanel.staged", "Staged") : t("ui.workspaceGitPanel.unstaged", "Unstaged")}${diff.truncated ? t("ui.workspaceGitPanel.truncated", " · Truncated") : ""}</small></div>
530
+ ${lines.length === 0 ? html `<p class="git-muted">${t("ui.unifiedDiffViewer.noDiff", "No diff.")}</p>` : html `
454
531
  <div class="git-diff-scroller">
455
- <div class="git-diff-grid" role="table" aria-label="统一差异">
532
+ <div class="git-diff-grid" role="table" aria-label="${t("ui.unifiedDiffViewer.unifiedDiff", "Unified diff")}">
456
533
  ${lines.map((line) => renderDiffLine(html, line))}
457
534
  </div>
458
535
  </div>
@@ -476,13 +553,38 @@ function renderDiffSpans(html, spans) {
476
553
  function buildViewState(status, view) {
477
554
  if (status === undefined || !status.isGitRepo || status.files.length === 0)
478
555
  return EMPTY_VIEW_STATE;
556
+ const visibleStatus = status;
479
557
  if (view === "tree") {
480
- const nodes = buildGitFileTree(status.files, status.submodules);
558
+ const nodes = buildGitFileTree(visibleStatus.files, visibleStatus.submodules);
481
559
  return { nodes, listModel: EMPTY_LIST_MODEL, expandablePaths: collectGitFileTreeDirectoryPaths(nodes) };
482
560
  }
483
- const listModel = buildGitFileList(status.files, status.submodules);
561
+ const listModel = buildGitFileList(visibleStatus.files, visibleStatus.submodules);
484
562
  return { nodes: [], listModel, expandablePaths: listModel.submodules.map((group) => group.path) };
485
563
  }
564
+ function revealSelectedFile(state, view) {
565
+ const path = state.selectedDiffPath;
566
+ if (path === undefined || state.status === undefined)
567
+ return;
568
+ let selectedRow = state.status.files.findIndex((file) => file.path === path) + state.status.submodules.length + 1;
569
+ if (view === "tree") {
570
+ const nodes = buildGitFileTree(state.status.files, state.status.submodules);
571
+ for (const directory of collectGitFileTreeDirectoryPaths(nodes))
572
+ if (path.startsWith(`${directory}/`))
573
+ state.expandedDirectories.add(directory);
574
+ let row = 0;
575
+ const visit = (children) => {
576
+ for (const node of children) {
577
+ row += 1;
578
+ if (node.path === path)
579
+ selectedRow = row;
580
+ if (node.kind === "directory" && state.expandedDirectories.has(node.path))
581
+ visit(node.children);
582
+ }
583
+ };
584
+ visit(nodes);
585
+ }
586
+ state.visibleFileLimit = Math.max(state.visibleFileLimit, Math.ceil(selectedRow / GIT_FILE_RENDER_BATCH) * GIT_FILE_RENDER_BATCH);
587
+ }
486
588
  function defineGitPanelActivityElement() {
487
589
  if (typeof customElements === "undefined" || typeof HTMLElement === "undefined" || customElements.get(activityElementTag) !== undefined)
488
590
  return;
@@ -490,6 +592,24 @@ function defineGitPanelActivityElement() {
490
592
  controllerValue;
491
593
  contextValue;
492
594
  pollTimer;
595
+ integration;
596
+ releaseStyles;
597
+ set stylesheetIntegration(value) {
598
+ if (this.integration === value)
599
+ return;
600
+ this.releaseStyles?.();
601
+ this.releaseStyles = undefined;
602
+ this.integration = value;
603
+ this.registerStyles();
604
+ }
605
+ registerStyles() {
606
+ if (!this.isConnected || this.releaseStyles !== undefined)
607
+ return;
608
+ const root = this.getRootNode();
609
+ // The activity element shares the host panel's root; it owns only this opt-in.
610
+ if (root instanceof ShadowRoot)
611
+ this.releaseStyles = this.integration?.registerRoot(root, { sharedUi: true });
612
+ }
493
613
  set controller(value) {
494
614
  if (this.controllerValue === value)
495
615
  return;
@@ -503,18 +623,23 @@ function defineGitPanelActivityElement() {
503
623
  this.restart();
504
624
  }
505
625
  connectedCallback() {
626
+ this.registerStyles();
506
627
  window.addEventListener("popstate", this.onPopState);
628
+ document.addEventListener("visibilitychange", this.onVisibilityChange);
507
629
  this.restart();
508
630
  }
509
631
  disconnectedCallback() {
632
+ this.releaseStyles?.();
633
+ this.releaseStyles = undefined;
510
634
  window.removeEventListener("popstate", this.onPopState);
635
+ document.removeEventListener("visibilitychange", this.onVisibilityChange);
511
636
  if (this.controllerValue !== undefined && this.contextValue !== undefined)
512
637
  this.controllerValue.disconnect(this.contextValue);
513
638
  this.stopTimer();
514
639
  }
515
640
  restart() {
516
641
  this.stopTimer();
517
- if (!this.isConnected || this.controllerValue === undefined || this.contextValue === undefined)
642
+ if (!this.isConnected || document.visibilityState !== "visible" || this.controllerValue === undefined || this.contextValue === undefined)
518
643
  return;
519
644
  this.controllerValue.connect(this.contextValue);
520
645
  this.pollTimer = window.setInterval(() => {
@@ -531,14 +656,21 @@ function defineGitPanelActivityElement() {
531
656
  if (this.controllerValue !== undefined && this.contextValue !== undefined)
532
657
  this.controllerValue.handlePopState(this.contextValue);
533
658
  };
659
+ onVisibilityChange = () => {
660
+ this.stopTimer();
661
+ if (document.visibilityState === "visible" && this.controllerValue !== undefined && this.contextValue !== undefined) {
662
+ this.restart();
663
+ void this.controllerValue.refresh(this.contextValue);
664
+ }
665
+ };
534
666
  }
535
667
  customElements.define(activityElementTag, GitPanelActivityElement);
536
668
  }
537
669
  function submoduleBadge(html) {
538
- return html `<span class="submodule-badge">子模块</span>`;
670
+ return html `<span class="submodule-badge">${t("ui.workspaceGitPanel.submodule", "Submodule")}</span>`;
539
671
  }
540
672
  function gitSummary(status) {
541
- const branch = status.branch ?? "游离 HEAD";
673
+ const branch = status.branch ?? t("ui.workspaceGitPanel.detachedHead", "Detached HEAD");
542
674
  const ahead = status.ahead ?? 0;
543
675
  const behind = status.behind ?? 0;
544
676
  return ahead === 0 && behind === 0 ? branch : `${branch} · ↑${String(ahead)} ↓${String(behind)}`;
@@ -551,10 +683,12 @@ function formatLineNumber(lineNumber) {
551
683
  return lineNumber === undefined ? "" : String(lineNumber);
552
684
  }
553
685
  function createDiffView(response, previous) {
554
- return {
555
- response,
556
- lines: previous?.response.hash === response.hash ? previous.lines : undefined,
557
- };
686
+ if (previous?.response.hash !== response.hash)
687
+ return { response, lines: undefined };
688
+ if (previous.response.path === response.path && previous.response.staged === response.staged
689
+ && previous.response.truncated === response.truncated)
690
+ return previous;
691
+ return { response, lines: previous.lines };
558
692
  }
559
693
  function workspaceContextKey(context) {
560
694
  return JSON.stringify([context.machine.id, context.workspace.projectId, context.workspace.id]);
@@ -563,28 +697,22 @@ function errorMessage(error) {
563
697
  return error instanceof Error ? error.message : String(error);
564
698
  }
565
699
  const gitPanelStyles = `
566
- .git-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; color: var(--pi-text); background: var(--pi-bg); font: 13px system-ui, sans-serif; }
700
+ .git-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; color: var(--pi-text); background: var(--pi-bg); font: 13px var(--pi-font, system-ui, sans-serif); }
567
701
  .git-panel ${activityElementTag} { display: none; }
568
- .git-panel button { display: inline-flex; align-items: center; gap: 5px; border: 1px solid var(--pi-border); border-radius: 7px; background: var(--pi-surface); color: var(--pi-text); padding: 5px 7px; cursor: pointer; }
569
- .git-panel button:disabled { cursor: wait; opacity: .65; }
570
702
  .git-panel small, .git-panel .git-muted { color: var(--pi-muted); }
571
703
  .git-panel p { margin: 10px; }
572
- .git-panel .git-toolbar { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; padding: 8px; border-bottom: 1px solid var(--pi-border-muted); }
573
- .git-panel .git-toolbar-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
574
- .git-panel .git-view-toggle { display: inline-flex; }
575
- .git-panel .git-view-toggle button { border-radius: 0; }
576
- .git-panel .git-view-toggle button:first-child { border-top-left-radius: 7px; border-bottom-left-radius: 7px; }
577
- .git-panel .git-view-toggle button:last-child { margin-left: -1px; border-top-right-radius: 7px; border-bottom-right-radius: 7px; }
578
- .git-panel .git-view-toggle button.is-selected { position: relative; z-index: 1; border-color: var(--pi-accent); background: var(--pi-selection-bg); }
579
- .git-panel .git-stale { border: 1px solid var(--pi-warning-border); border-radius: 999px; color: var(--pi-warning); padding: 1px 6px; font-size: 12px; }
704
+ .git-panel .git-toolbar { flex: 0 0 auto; border-bottom: 1px solid var(--pi-border-muted); font-size: 12px; color: var(--pi-muted); }
705
+ .git-panel .git-toolbar-actions { margin-left: auto; }
706
+ .git-panel .git-toolbar > strong { display: flex; align-items: center; padding-inline: 10px; font-weight: 500; }
707
+ .git-panel .git-toolbar .ui-button { white-space: nowrap; }
708
+ .git-panel .git-toolbar .ui-button[aria-pressed="true"] { background: var(--pi-surface-hover); color: var(--pi-text); }
709
+ .git-panel .git-stale { border: 1px solid var(--pi-warning-border); border-radius: 999px; color: var(--pi-warning); padding: 1px 6px; font-size: 12px; align-self: center; }
580
710
  .git-panel .git-error { flex: 0 0 auto; margin: 8px; border: 1px solid var(--pi-danger); border-radius: 7px; color: var(--pi-danger); padding: 8px; }
711
+ .git-panel .git-warning { flex: 0 0 auto; margin: 8px; border: 1px solid var(--pi-warning-border); border-radius: 7px; color: var(--pi-warning); padding: 8px; }
712
+ .git-panel .git-load-more { margin: 8px auto; }
581
713
  .git-panel .git-split { flex: 1 1 auto; min-height: 0; display: grid; grid-template-rows: minmax(160px, 34%) minmax(0, 1fr); }
582
- .git-panel .git-file-list { min-height: 0; overflow: auto; border-bottom: 1px solid var(--pi-border); padding: 6px; }
583
- .git-panel .git-row { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 4px; width: 100%; border: 0; border-radius: 5px; background: transparent; text-align: left; padding: 4px 6px 4px calc(6px + var(--depth, 0) * 14px); }
584
- .git-panel .git-row:hover, .git-panel .git-row.is-selected { background: var(--pi-selection-bg); }
585
- .git-panel .git-row span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
586
- .git-panel .git-twisty { color: var(--pi-dim, var(--pi-muted)); }
587
- .git-panel .git-summary { margin: 4px 6px 8px; color: var(--pi-muted); }
714
+ .git-panel .git-file-list { border-bottom: 1px solid var(--pi-border); }
715
+ .git-panel .git-summary { margin: 10px 12px 8px; color: var(--pi-muted); }
588
716
  .git-panel .submodule-badge { display: inline-block; margin-left: 6px; border: 1px solid var(--pi-border); border-radius: 999px; color: var(--pi-muted); padding: 0 5px; font-size: 11px; font-weight: 400; vertical-align: baseline; }
589
717
  .git-panel .git-viewer { min-height: 0; overflow: auto; display: flex; flex-direction: column; }
590
718
  .git-panel .git-diffs { flex: 1 1 auto; min-height: 0; overflow: auto; display: grid; grid-template-rows: minmax(120px, 1fr) minmax(120px, 1fr); }
@@ -594,7 +722,7 @@ const gitPanelStyles = `
594
722
  .git-panel .git-viewer-header { position: sticky; top: 0; display: flex; justify-content: space-between; gap: 8px; padding: 8px; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-bg); }
595
723
  .git-panel .git-viewer-header strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
596
724
  .git-panel .git-diff-scroller { flex: 1 1 auto; min-height: 0; overflow: auto; background: var(--pi-bg); }
597
- .git-panel .git-diff-grid { display: grid; grid-template-columns: max-content max-content 2ch max-content; width: max-content; min-width: 100%; padding: 6px 0; font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; line-height: 1.45; }
725
+ .git-panel .git-diff-grid { display: grid; grid-template-columns: max-content max-content 2ch max-content; width: max-content; min-width: 100%; padding: 6px 0; font: 12px var(--pi-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); line-height: 1.45; }
598
726
  .git-panel .git-diff-line { display: contents; }
599
727
  .git-panel .git-diff-cell { min-height: 1.45em; white-space: pre; }
600
728
  .git-panel .git-line-number { min-width: 4ch; padding: 0 8px; border-right: 1px solid var(--pi-border-muted); color: var(--pi-dim); text-align: right; user-select: none; }
@@ -0,0 +1,7 @@
1
+ // Generated from pi-web-plugins/git/browser/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));