@chainingintention/pi-web-cn 1.202610.1 → 1.202610.3

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 (333) hide show
  1. package/README.md +60 -106
  2. package/dist/.plugins-ready +1 -0
  3. package/dist/cli.js +161 -45
  4. package/dist/cli.js.map +1 -1
  5. package/dist/client/assets/index-CFhaGb5m.js +4357 -0
  6. package/dist/client/assets/vendor-editor-core-YWog6mAR.js +10 -0
  7. package/dist/client/assets/vendor-editor-languages-DOCw3vc9.js +28 -0
  8. package/dist/client/index.html +5 -5
  9. package/dist/config.js +30 -6
  10. package/dist/config.js.map +1 -1
  11. package/dist/docker/piWebDockerCommandPlan.js +13 -4
  12. package/dist/docker/piWebDockerCommandPlan.js.map +1 -1
  13. package/dist/nativeServices/installedServiceDefinitions.js +23 -10
  14. package/dist/nativeServices/installedServiceDefinitions.js.map +1 -1
  15. package/dist/nativeServices/serviceAction.js +78 -20
  16. package/dist/nativeServices/serviceAction.js.map +1 -1
  17. package/dist/nativeServices/serviceDoctor.js +339 -67
  18. package/dist/nativeServices/serviceDoctor.js.map +1 -1
  19. package/dist/nativeServices/servicePlan.js +2 -2
  20. package/dist/nativeServices/servicePlan.js.map +1 -1
  21. package/dist/pi-packages/captains-log/README.md +11 -0
  22. package/dist/pi-packages/captains-log/dist/browser/channelProtocol.js +29 -0
  23. package/dist/pi-packages/captains-log/dist/browser/index.js +146 -0
  24. package/dist/pi-packages/captains-log/dist/browser/markdown.js +67 -0
  25. package/dist/pi-packages/captains-log/dist/browser/panel.js +151 -0
  26. package/dist/pi-packages/captains-log/dist/browser/protocol.js +26 -0
  27. package/dist/pi-packages/captains-log/dist/companion.js +126 -0
  28. package/dist/pi-packages/captains-log/dist/roundtrip.js +62 -0
  29. package/dist/pi-packages/captains-log/dist/server.js +210 -0
  30. package/dist/pi-packages/captains-log/dist/store.js +75 -0
  31. package/dist/pi-packages/captains-log/docs/usage.md +29 -0
  32. package/dist/pi-packages/captains-log/package.json +35 -0
  33. package/dist/pi-packages/captains-log/tsconfig.json +21 -0
  34. package/dist/pi-packages/captains-log/vite.config.mjs +28 -0
  35. package/dist/pi-packages/relays/pi-web-plugin.js +9 -9
  36. package/dist/pi-packages/relays/prompts/relay.md +1 -1
  37. package/dist/pi-packages/relays/relaysPanelElement.js +8 -8
  38. package/dist/pi-packages/relays/skills/relay-runner/SKILL.md +21 -13
  39. package/dist/pi-web-plugins/files/browser/assets/files-icon-DZObYhxb.svg +3 -0
  40. package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +456 -0
  41. package/dist/pi-web-plugins/files/package.json +15 -0
  42. package/dist/pi-web-plugins/git/browser/git-panel.js +55 -32
  43. package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +2 -2
  44. package/dist/pi-web-plugins/git/git-backend.js +19 -26
  45. package/dist/pi-web-plugins/git/gitStatusCache.js +48 -0
  46. package/dist/pi-web-plugins/git/package.json +1 -0
  47. package/dist/pi-web-plugins/git/server-plugin.js +11 -10
  48. package/dist/pi-web-plugins/info/infoInternals.js +4 -1
  49. package/dist/pi-web-plugins/info/package.json +1 -1
  50. package/dist/pi-web-plugins/info/pi-web-plugin.js +8 -8
  51. package/dist/pi-web-plugins/mermaid/browser/mermaid-engine.js +3590 -0
  52. package/dist/pi-web-plugins/mermaid/browser/pi-web-plugin.js +6 -0
  53. package/dist/pi-web-plugins/mermaid/package.json +13 -0
  54. package/dist/pi-web-plugins/terminal/browser/pi-web-plugin.js +210 -0
  55. package/dist/pi-web-plugins/terminal/package.json +16 -0
  56. package/dist/pi-web-plugins/terminal/server-plugin.js +365 -0
  57. package/dist/pi-web-plugins/terminal/terminalService.js +435 -0
  58. package/dist/pi-web-plugins/updates/package.json +1 -1
  59. package/dist/pi-web-plugins/updates/pi-web-plugin.js +69 -68
  60. package/dist/pi-web-plugins/workspace-tasks/package.json +1 -1
  61. package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +3 -3
  62. package/dist/piWebVersionReport.js +47 -24
  63. package/dist/piWebVersionReport.js.map +1 -1
  64. package/dist/plugin-api.d.ts +260 -25
  65. package/dist/plugin-api.js +1 -0
  66. package/dist/pluginRecoveryCli.js +3 -2
  67. package/dist/pluginRecoveryCli.js.map +1 -1
  68. package/dist/server/activity/workspaceActivityService.js +5 -5
  69. package/dist/server/activity/workspaceActivityService.js.map +1 -1
  70. package/dist/server/app.js +71 -44
  71. package/dist/server/app.js.map +1 -1
  72. package/dist/server/audit/managementAuditStore.js +1 -1
  73. package/dist/server/browserMessageProjection.js +0 -2
  74. package/dist/server/browserMessageProjection.js.map +1 -1
  75. package/dist/server/configRoutes.js +1 -2
  76. package/dist/server/configRoutes.js.map +1 -1
  77. package/dist/server/knownPiPackages.js +12 -0
  78. package/dist/server/knownPiPackages.js.map +1 -0
  79. package/dist/server/machines/machineClient.js +2 -2
  80. package/dist/server/machines/machineClient.js.map +1 -1
  81. package/dist/server/machines/machinePluginProxyRoutes.js +120 -21
  82. package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
  83. package/dist/server/machines/machineProxyRoutes.js +80 -22
  84. package/dist/server/machines/machineProxyRoutes.js.map +1 -1
  85. package/dist/server/machines/machineService.js +22 -0
  86. package/dist/server/machines/machineService.js.map +1 -1
  87. package/dist/server/managementEmbed.js +1 -1
  88. package/dist/server/managementEmbed.js.map +1 -1
  89. package/dist/server/managementPrivileges.js +7 -1
  90. package/dist/server/managementPrivileges.js.map +1 -1
  91. package/dist/server/managementTerminalProxyRoutes.js +124 -0
  92. package/dist/server/managementTerminalProxyRoutes.js.map +1 -0
  93. package/dist/server/normalAuth.js +5 -1
  94. package/dist/server/normalAuth.js.map +1 -1
  95. package/dist/server/notices/serverNoticeStore.js +50 -6
  96. package/dist/server/notices/serverNoticeStore.js.map +1 -1
  97. package/dist/server/piPackageService.js +5 -5
  98. package/dist/server/piPackageService.js.map +1 -1
  99. package/dist/server/piWebPluginCatalog.js +211 -34
  100. package/dist/server/piWebPluginCatalog.js.map +1 -1
  101. package/dist/server/piWebPluginLifecycle.js +29 -3
  102. package/dist/server/piWebPluginLifecycle.js.map +1 -1
  103. package/dist/server/piWebPluginService.js +176 -291
  104. package/dist/server/piWebPluginService.js.map +1 -1
  105. package/dist/server/piWebStatus.js +45 -55
  106. package/dist/server/piWebStatus.js.map +1 -1
  107. package/dist/server/pluginCallbackDrain.js +35 -0
  108. package/dist/server/pluginCallbackDrain.js.map +1 -0
  109. package/dist/server/plugins/pluginBackendChannelProxyAdmission.js +84 -0
  110. package/dist/server/plugins/pluginBackendChannelProxyAdmission.js.map +1 -0
  111. package/dist/server/plugins/pluginBackendChannelProxyCoordinator.js +234 -0
  112. package/dist/server/plugins/pluginBackendChannelProxyCoordinator.js.map +1 -0
  113. package/dist/server/plugins/pluginBackendChannelProxyRoutes.js +63 -0
  114. package/dist/server/plugins/pluginBackendChannelProxyRoutes.js.map +1 -0
  115. package/dist/server/plugins/pluginBackendProxyRoutes.js +7 -4
  116. package/dist/server/plugins/pluginBackendProxyRoutes.js.map +1 -1
  117. package/dist/server/plugins/pluginBackendRegistry.js +773 -0
  118. package/dist/server/plugins/pluginBackendRegistry.js.map +1 -0
  119. package/dist/server/plugins/serverPluginPiSessionEventsCapability.js +34 -0
  120. package/dist/server/plugins/serverPluginPiSessionEventsCapability.js.map +1 -0
  121. package/dist/server/plugins/serverPluginPiSessionsCapability.js +185 -0
  122. package/dist/server/plugins/serverPluginPiSessionsCapability.js.map +1 -0
  123. package/dist/server/plugins/serverPluginRuntime.js +1049 -107
  124. package/dist/server/plugins/serverPluginRuntime.js.map +1 -1
  125. package/dist/server/plugins/serverPluginWorkspacesCapability.js +114 -0
  126. package/dist/server/plugins/serverPluginWorkspacesCapability.js.map +1 -0
  127. package/dist/server/projectTrustRoutes.js +86 -0
  128. package/dist/server/projectTrustRoutes.js.map +1 -0
  129. package/dist/server/projects/projectLifecycleService.js +84 -0
  130. package/dist/server/projects/projectLifecycleService.js.map +1 -0
  131. package/dist/server/projects/projectService.js +2 -0
  132. package/dist/server/projects/projectService.js.map +1 -1
  133. package/dist/server/realtime/sessionEventHub.js +35 -41
  134. package/dist/server/realtime/sessionEventHub.js.map +1 -1
  135. package/dist/server/sessiond/agentHttpDispatcher.js +108 -0
  136. package/dist/server/sessiond/agentHttpDispatcher.js.map +1 -0
  137. package/dist/server/sessiond/pluginBackendChannelRoutes.js +397 -0
  138. package/dist/server/sessiond/pluginBackendChannelRoutes.js.map +1 -0
  139. package/dist/server/sessiond/pluginBackendRoutes.js +19 -9
  140. package/dist/server/sessiond/pluginBackendRoutes.js.map +1 -1
  141. package/dist/server/sessiond/projectMutationRoutes.js +38 -0
  142. package/dist/server/sessiond/projectMutationRoutes.js.map +1 -0
  143. package/dist/server/sessiond/sessionDaemonShutdown.js +36 -0
  144. package/dist/server/sessiond/sessionDaemonShutdown.js.map +1 -0
  145. package/dist/server/sessiond/sessionDaemonStartup.js +30 -4
  146. package/dist/server/sessiond/sessionDaemonStartup.js.map +1 -1
  147. package/dist/server/sessiond/sessionProxyRoutes.js +47 -15
  148. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
  149. package/dist/server/sessiond/sessionServiceDependencies.js +4 -0
  150. package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -1
  151. package/dist/server/sessiond/sessiondStateOwnership.js +174 -39
  152. package/dist/server/sessiond/sessiondStateOwnership.js.map +1 -1
  153. package/dist/server/sessiond/workspaceRemovalRoutes.js +1 -1
  154. package/dist/server/sessiond/workspaceRemovalRoutes.js.map +1 -1
  155. package/dist/server/sessiond.js +226 -56
  156. package/dist/server/sessiond.js.map +1 -1
  157. package/dist/server/sessions/askUserTool.js +0 -3
  158. package/dist/server/sessions/askUserTool.js.map +1 -1
  159. package/dist/server/sessions/attachmentService.js +0 -1
  160. package/dist/server/sessions/attachmentService.js.map +1 -1
  161. package/dist/server/sessions/authService.js +8 -1
  162. package/dist/server/sessions/authService.js.map +1 -1
  163. package/dist/server/sessions/builtinCommands.js +2 -2
  164. package/dist/server/sessions/builtinCommands.js.map +1 -1
  165. package/dist/server/sessions/clientSessionPreview.js +14 -0
  166. package/dist/server/sessions/clientSessionPreview.js.map +1 -0
  167. package/dist/server/sessions/dockerEnvironmentFacts.js +82 -9
  168. package/dist/server/sessions/dockerEnvironmentFacts.js.map +1 -1
  169. package/dist/server/sessions/managementAgentTools.js +11 -6
  170. package/dist/server/sessions/managementAgentTools.js.map +1 -1
  171. package/dist/server/sessions/managementPermissionSystem.js +16 -4
  172. package/dist/server/sessions/managementPermissionSystem.js.map +1 -1
  173. package/dist/server/sessions/messagePaging.js +2 -2
  174. package/dist/server/sessions/messagePaging.js.map +1 -1
  175. package/dist/server/sessions/modelCatalogRefresher.js +4 -3
  176. package/dist/server/sessions/modelCatalogRefresher.js.map +1 -1
  177. package/dist/server/sessions/oauthLoginFlowService.js +2 -5
  178. package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
  179. package/dist/server/sessions/pendingAskStore.js +0 -3
  180. package/dist/server/sessions/pendingAskStore.js.map +1 -1
  181. package/dist/server/sessions/piSessionEventConnections.js +65 -0
  182. package/dist/server/sessions/piSessionEventConnections.js.map +1 -0
  183. package/dist/server/sessions/piSessionManagerGateway.js +56 -3
  184. package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
  185. package/dist/server/sessions/piSessionService.js +774 -448
  186. package/dist/server/sessions/piSessionService.js.map +1 -1
  187. package/dist/server/sessions/projectAuthService.js +29 -2
  188. package/dist/server/sessions/projectAuthService.js.map +1 -1
  189. package/dist/server/sessions/projectSettingsScope.js +12 -4
  190. package/dist/server/sessions/projectSettingsScope.js.map +1 -1
  191. package/dist/server/sessions/projectTrust.js +119 -0
  192. package/dist/server/sessions/projectTrust.js.map +1 -0
  193. package/dist/server/sessions/sessionActivityMarker.js +105 -0
  194. package/dist/server/sessions/sessionActivityMarker.js.map +1 -0
  195. package/dist/server/sessions/sessionArchiveMapping.js +2 -8
  196. package/dist/server/sessions/sessionArchiveMapping.js.map +1 -1
  197. package/dist/server/sessions/sessionCommandService.js +12 -10
  198. package/dist/server/sessions/sessionCommandService.js.map +1 -1
  199. package/dist/server/sessions/sessionEnvironmentFacts.js +5 -4
  200. package/dist/server/sessions/sessionEnvironmentFacts.js.map +1 -1
  201. package/dist/server/sessions/sessionModelScope.js +42 -5
  202. package/dist/server/sessions/sessionModelScope.js.map +1 -1
  203. package/dist/server/sessions/sessionNameGenerator.js +6 -6
  204. package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
  205. package/dist/server/sessions/sessionRoutes.js +63 -15
  206. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  207. package/dist/server/sessions/sessionTreeProjection.js +29 -29
  208. package/dist/server/sessions/sessionTreeProjection.js.map +1 -1
  209. package/dist/server/sessions/sessionUiEvents.js +6 -7
  210. package/dist/server/sessions/sessionUiEvents.js.map +1 -1
  211. package/dist/server/sessions/sessionUnreadStore.js +26 -1
  212. package/dist/server/sessions/sessionUnreadStore.js.map +1 -1
  213. package/dist/server/sessions/spawnSessionTool.js +3 -3
  214. package/dist/server/sessions/spawnSessionTool.js.map +1 -1
  215. package/dist/server/sessions/spawnSubsessionTool.js +5 -5
  216. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
  217. package/dist/server/sessions/spawnTargetResolver.js +1 -1
  218. package/dist/server/sessions/transcriptMessages.js +54 -0
  219. package/dist/server/sessions/transcriptMessages.js.map +1 -0
  220. package/dist/server/status/machineStatusService.js +3 -1
  221. package/dist/server/status/machineStatusService.js.map +1 -1
  222. package/dist/server/terminals/{terminalService.js → managementCommandRunService.js} +79 -107
  223. package/dist/server/terminals/managementCommandRunService.js.map +1 -0
  224. package/dist/server/terminals/managementTerminalRoutes.js +91 -0
  225. package/dist/server/terminals/managementTerminalRoutes.js.map +1 -0
  226. package/dist/server/terminals/requiredTerminalService.js +103 -0
  227. package/dist/server/terminals/requiredTerminalService.js.map +1 -0
  228. package/dist/server/webSocketBridge.js +339 -0
  229. package/dist/server/webSocketBridge.js.map +1 -1
  230. package/dist/server/workbench/gatewayIntegration.js +4 -1
  231. package/dist/server/workbench/gatewayIntegration.js.map +1 -1
  232. package/dist/server/workspaceExplorerRoutes.js +13 -12
  233. package/dist/server/workspaceExplorerRoutes.js.map +1 -1
  234. package/dist/server/workspaces/fileContentService.js +9 -7
  235. package/dist/server/workspaces/fileContentService.js.map +1 -1
  236. package/dist/server/workspaces/fileOperationService.js +4 -3
  237. package/dist/server/workspaces/fileOperationService.js.map +1 -1
  238. package/dist/server/workspaces/projectWorkspaceCwds.js +0 -5
  239. package/dist/server/workspaces/projectWorkspaceCwds.js.map +1 -1
  240. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js +36 -12
  241. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js.map +1 -1
  242. package/dist/server/workspaces/workspaceCatalog.js +6 -4
  243. package/dist/server/workspaces/workspaceCatalog.js.map +1 -1
  244. package/dist/server/workspaces/workspaceDeletionRoutes.js +5 -57
  245. package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -1
  246. package/dist/server/workspaces/workspaceProviderRegistry.js +75 -24
  247. package/dist/server/workspaces/workspaceProviderRegistry.js.map +1 -1
  248. package/dist/server/workspaces/workspaceRemovalService.js +25 -3
  249. package/dist/server/workspaces/workspaceRemovalService.js.map +1 -1
  250. package/dist/server-plugin-api.d.ts +274 -44
  251. package/dist/server-plugin-api.js +319 -2
  252. package/dist/server-plugin-api.js.map +1 -1
  253. package/dist/serverPluginRecovery.js +4 -0
  254. package/dist/serverPluginRecovery.js.map +1 -1
  255. package/dist/sessiond/activeAgentProfile.js +27 -2
  256. package/dist/sessiond/activeAgentProfile.js.map +1 -1
  257. package/dist/sessiond/config.js +4 -3
  258. package/dist/sessiond/config.js.map +1 -1
  259. package/dist/sessiond/sessionDaemonClient.js +29 -8
  260. package/dist/sessiond/sessionDaemonClient.js.map +1 -1
  261. package/dist/shared/activeAgentProfile.js +2 -34
  262. package/dist/shared/activeAgentProfile.js.map +1 -1
  263. package/dist/shared/activity.js +0 -3
  264. package/dist/shared/activity.js.map +1 -1
  265. package/dist/shared/apiTypes.js +7 -2
  266. package/dist/shared/apiTypes.js.map +1 -1
  267. package/dist/shared/capabilities.js +5 -0
  268. package/dist/shared/capabilities.js.map +1 -1
  269. package/dist/shared/federatedRoutes.js +49 -9
  270. package/dist/shared/federatedRoutes.js.map +1 -1
  271. package/dist/shared/machinePluginIds.js +30 -7
  272. package/dist/shared/machinePluginIds.js.map +1 -1
  273. package/dist/shared/machineStatus.js +35 -1
  274. package/dist/shared/machineStatus.js.map +1 -1
  275. package/dist/shared/piWebStatusParsing.js +29 -0
  276. package/dist/shared/piWebStatusParsing.js.map +1 -1
  277. package/dist/shared/pluginApiTypes.d.ts +24 -9
  278. package/dist/shared/pluginApiTypes.js +2 -0
  279. package/dist/shared/pluginApiTypes.js.map +1 -0
  280. package/dist/shared/pluginBackendProtocol.js +163 -2
  281. package/dist/shared/pluginBackendProtocol.js.map +1 -1
  282. package/dist/shared/pluginIds.js +10 -1
  283. package/dist/shared/pluginIds.js.map +1 -1
  284. package/dist/shared/requiredTerminalPlugin.js +6 -0
  285. package/dist/shared/requiredTerminalPlugin.js.map +1 -0
  286. package/dist/shared/serverNoticeContract.js +88 -0
  287. package/dist/shared/serverNoticeContract.js.map +1 -0
  288. package/dist/shared/sessionDefaults.js +41 -0
  289. package/dist/shared/sessionDefaults.js.map +1 -0
  290. package/dist/shared/workspaceFiles.js.map +1 -1
  291. package/docs/config.md +270 -323
  292. package/docs/plugins.md +171 -956
  293. package/examples/session-bridge-plugin/README.md +20 -0
  294. package/examples/session-bridge-plugin/docs/usage.md +54 -0
  295. package/examples/session-bridge-plugin/package.json +26 -0
  296. package/examples/session-bridge-plugin/src/browser/index.ts +87 -0
  297. package/examples/session-bridge-plugin/src/browser/protocol.ts +24 -0
  298. package/examples/session-bridge-plugin/src/companion.ts +65 -0
  299. package/examples/session-bridge-plugin/src/reviewRun.ts +39 -0
  300. package/examples/session-bridge-plugin/src/server.ts +85 -0
  301. package/examples/session-bridge-plugin/src/store.ts +80 -0
  302. package/examples/session-bridge-plugin/tsconfig.json +21 -0
  303. package/examples/workspace-provider-plugin/README.md +39 -0
  304. package/examples/workspace-provider-plugin/package.json +25 -0
  305. package/examples/workspace-provider-plugin/src/browser/index.ts +69 -0
  306. package/examples/workspace-provider-plugin/src/server.ts +68 -0
  307. package/examples/workspace-provider-plugin/tsconfig.json +21 -0
  308. package/package.json +22 -13
  309. package/skills/README.md +27 -2
  310. package/skills/relay-runner/SKILL.md +21 -13
  311. package/dist/client/assets/CodeViewer-CZHnKRwQ.js +0 -4
  312. package/dist/client/assets/TerminalPanel-B_EaRPHY.js +0 -187
  313. package/dist/client/assets/index-Bv1v-Jz7.js +0 -4717
  314. package/dist/client/assets/vendor-editor-core-vUi74DnD.js +0 -12
  315. package/dist/client/assets/vendor-editor-languages-DoaXUodB.js +0 -46
  316. package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +0 -1
  317. package/dist/client/assets/vendor-terminal-BrP-ENHg.css +0 -1
  318. package/dist/client/assets/vendor-terminal-D8k4UKM2.js +0 -35
  319. package/dist/server/git/gitService.js +0 -316
  320. package/dist/server/git/gitService.js.map +0 -1
  321. package/dist/server/gitRoutes.js +0 -23
  322. package/dist/server/gitRoutes.js.map +0 -1
  323. package/dist/server/terminalProxyRoutes.js +0 -181
  324. package/dist/server/terminalProxyRoutes.js.map +0 -1
  325. package/dist/server/terminals/terminalRoutes.js +0 -164
  326. package/dist/server/terminals/terminalRoutes.js.map +0 -1
  327. package/dist/server/terminals/terminalService.js.map +0 -1
  328. package/dist/server/terminals/terminalSize.js +0 -17
  329. package/dist/server/terminals/terminalSize.js.map +0 -1
  330. package/dist/server/workspaces/gitWorktreeDiscovery.js +0 -43
  331. package/dist/server/workspaces/gitWorktreeDiscovery.js.map +0 -1
  332. package/dist/server/workspaces/workspaceService.js +0 -52
  333. package/dist/server/workspaces/workspaceService.js.map +0 -1
package/README.md CHANGED
@@ -1,49 +1,41 @@
1
1
  # PI WEB
2
2
 
3
- This fork is a translation plan for PI WEB. Its goal is to translate the plugin's displayed content into Chinese while preserving the upstream functionality.
3
+ PI WEB 的中文本地化分支,保留上游功能,并将核心界面与内置插件的显示内容本地化为中文。
4
4
 
5
- [![CI](https://github.com/jmfederico/pi-web/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/jmfederico/pi-web/actions/workflows/ci.yml)
5
+ [![CI](https://github.com/nayuto-wakusei/pi-web-ChineseTranslation/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/nayuto-wakusei/pi-web-ChineseTranslation/actions/workflows/ci.yml)
6
6
  [![npm version](https://img.shields.io/npm/v/%40chainingintention%2Fpi-web-cn)](https://www.npmjs.com/package/@chainingintention/pi-web-cn)
7
7
  [![Node.js](https://img.shields.io/node/v/%40chainingintention%2Fpi-web-cn)](package.json)
8
8
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
9
9
 
10
- **PI WEB is a web UI for [Pi Coding Agent](https://github.com/earendil-works/pi/tree/main/packages/coding-agent) that keeps agent sessions running in real workspaces on your machine or server.**
10
+ **PI WEB 是 [Pi Coding Agent](https://github.com/earendil-works/pi/tree/main/packages/coding-agent) 的 Web 界面,让代理会话持续运行在机器或服务器的真实工作区中。**
11
11
 
12
- The bundled runtime requires Pi `0.84.x` compatible packages. The session daemon owns its `PI_WEB_DATA_DIR`; use a separate data directory and session endpoint for each concurrently running instance.
12
+ 内置运行时支持已测试的 Pi `0.86.1` 或 `0.87.0`。每个会话守护进程独占 `PI_WEB_DATA_DIR`,并发实例必须使用独立数据目录和 daemon endpoint。
13
13
 
14
- Run agents where your code, tools, credentials, and build caches live. Supervise them from any browser.
14
+ 让代理在代码、工具、凭据和构建缓存所在的机器工作,从任何浏览器监督。
15
15
 
16
- Website and docs: <https://pi-web.dev/>
16
+ 上游网站与文档:<https://pi-web.dev/>。本分支的包名、项目认证与管理隔离等差异以仓库中的[配置参考](docs/config.md)和[插件指南](docs/plugins.md)为准。
17
17
 
18
18
  ![PI WEB](docs/assets/pi-web-banner.png)
19
+ ![PI WEB 桌面截图](docs/assets/pi-web-desktop.png)
19
20
 
20
- ![PI WEB desktop screenshot](docs/assets/pi-web-desktop.png)
21
+ ## 为什么使用 PI WEB?
21
22
 
22
- ## Why PI WEB?
23
+ 持久的工作环境适合代理开发。PI WEB 可以:
23
24
 
24
- Agentic development works better when the work environment is persistent.
25
+ - 浏览器断开后继续运行代理会话;
26
+ - 在真实仓库与 Git 工作树中工作;
27
+ - 并行监督多个会话;
28
+ - 在电脑、手机和平板间切换;
29
+ - 使用服务器、工作站或远端开发机运行代理;
30
+ - 从一个界面管理项目、工作区、文件、终端、会话及远端机器。
25
31
 
26
- PI WEB lets you:
32
+ 浏览器负责监督,工作留在能够持续运行的机器。
27
33
 
28
- - keep Pi Coding Agent sessions alive after browser disconnects;
29
- - run agents inside real repositories and git worktrees;
30
- - supervise multiple sessions in parallel;
31
- - switch between laptop, phone, tablet, and desktop;
32
- - use a server, workstation, or remote dev box as your agent runtime;
33
- - manage projects, workspaces, files, terminals, sessions, and remote machines from one web UI.
34
+ ## 快速开始
34
35
 
35
- Your browser is the control surface. The work stays where it can keep running.
36
+ 需要 Node.js 22.19.0 或更新版本、npm、为当前用户配置的 Pi Coding Agent `0.86.1` 或 `0.87.0`,以及 Git 和项目所需开发工具。
36
37
 
37
- ## Quick start
38
-
39
- Requirements:
40
-
41
- - Node.js 22.19.0 or newer
42
- - npm
43
- - Pi Coding Agent `>=0.82.1 <0.83`, configured for your user
44
- - git and the development tools your agents need
45
-
46
- Install and start PI WEB as per-user services:
38
+ 安装并启动用户服务:
47
39
 
48
40
  ```bash
49
41
  npm install -g @chainingintention/pi-web-cn --allow-scripts=node-pty
@@ -51,15 +43,15 @@ pi-web install
51
43
  pi-web doctor
52
44
  ```
53
45
 
54
- On npm 12, the scoped flag lets `node-pty` prepare its required native module without enabling install scripts for other dependencies.
46
+ npm 12 的限定开关只允许 node-pty 准备所需原生模块,不为其他依赖开启安装脚本。
55
47
 
56
- Then open:
48
+ 打开:
57
49
 
58
50
  ```text
59
51
  http://127.0.0.1:8504
60
52
  ```
61
53
 
62
- Useful commands:
54
+ 常用命令:
63
55
 
64
56
  ```bash
65
57
  pi-web status
@@ -70,120 +62,82 @@ pi-web version
70
62
  pi-web uninstall
71
63
  ```
72
64
 
73
- <!-- Keep README guidance concise. Put install variants, troubleshooting,
74
- configuration, and operational details in docs/, then link from here. -->
65
+ 安装变体、Pi 包安装、WSL/手动启动与远端访问见[安装指南](https://pi-web.dev/install)。
75
66
 
76
- For more install options, including one-line install, Pi package install, WSL/manual usage, and remote access, see the [installation guide](https://pi-web.dev/install).
77
-
78
- ## Core model
79
-
80
- PI WEB organizes work like this:
67
+ ## 核心模型
81
68
 
82
69
  ```text
83
- Machine a local or remote PI WEB runtime endpoint
84
- Project a folder on that machine
85
- Workspace a git worktree, or the project folder for non-git projects
86
- Session a Pi Coding Agent chat running inside a workspace
70
+ Machine 本地或远端 PI WEB 运行时
71
+ Project 该机器上的项目目录
72
+ Workspace 提供器拥有的工作目录;内置 Git 发现工作树,无提供器时使用项目目录
73
+ Session 工作区中运行的 Pi Coding Agent 对话
87
74
  ```
88
75
 
89
- A typical flow:
90
-
91
- 1. Add a project.
92
- 2. Choose a workspace or git worktree.
93
- 3. Start a session.
94
- 4. Let the agent work.
95
- 5. Come back later from any browser.
96
-
97
- ## Remote-first development
98
-
99
- PI WEB is designed for remote AI-driven development.
100
-
101
- Instead of tying agent work to your laptop session, run PI WEB on a machine that stays available: a server, desktop, cloud VM, home lab machine, or remote dev box.
102
-
103
- Use a private network, SSH tunnel, trusted reverse proxy, or federated PI WEB machine setup when accessing it remotely.
104
-
105
- Read more: [Remote-first development](https://pi-web.dev/remote-first)
106
-
107
- ## Machines and fleets
76
+ 典型流程:添加项目 → 选择工作区 → 启动会话 → 让代理工作 → 稍后从任何浏览器返回。
108
77
 
109
- PI WEB can register other PI WEB runtimes as remote machines. One browser-facing PI WEB instance can proxy projects, files, git state, sessions, terminals, activity, Pi package management, and selected-machine settings from trusted remote machines.
78
+ ## 远端优先
110
79
 
111
- When a remote machine is selected, Settings tabs label their target. Pi packages, PI WEB plugin enablement, session daemon toggles, external file access, and upload defaults target the selected machine. Gateway/server settings such as host, port, allowed hosts, registered machines/tokens, and keyboard shortcuts stay local to the gateway/browser.
80
+ 让代理运行在保持在线的服务器、桌面机、云主机、家用实验室或远端开发机,不依赖笔记本浏览器会话。远端连接使用私有网络、SSH 隧道、可信反向代理或 PI WEB 机器联邦。
112
81
 
113
- Read more: [Fleet and machines guide](https://pi-web.dev/machines)
82
+ 详见[远端优先开发](https://pi-web.dev/remote-first)。
114
83
 
115
- ## PI WEB plugins
84
+ ## 机器与联邦
116
85
 
117
- PI WEB supports trusted browser-side plugins that can add actions, workspace panels, and workspace metadata. Use **Settings → PI WEB plugins** to enable or disable them on the selected machine.
86
+ 一个浏览器网关可代理可信远端机器的项目、工作区、文件、Git、会话、终端、活动、Pi 包与设置。设置页标明目标机器:包、插件、daemon 能力、文件访问和上传默认值针对所选机器;网关监听地址/端口/允许主机、机器注册/令牌和快捷键仍在网关。
118
87
 
119
- Pi packages are a separate Pi package-manager concept. A Pi package may include a PI WEB browser plugin, but installing a package and enabling its browser plugin are different operations.
88
+ 详见[机器指南](https://pi-web.dev/machines)。
120
89
 
121
- Read more: [PI WEB plugin guide and API](https://pi-web.dev/plugins)
90
+ ## PI WEB 插件
122
91
 
123
- ## Configuration
92
+ 可信插件可提供面板、工具和工作区工作流,从 **设置 → PI WEB 插件** 管理所选机器的启用状态。Pi 包的安装与插件启用是独立操作。服务端插件变更需手动重启会话守护进程,再刷新浏览器;仅 Web 重启或 `/reload` 不会激活。
124
93
 
125
- Global config lives at:
94
+ 详见[插件指南](docs/plugins.md)。
126
95
 
127
- ```text
128
- $PI_WEB_CONFIG
129
- ~/.config/pi-web/config.json
130
- ```
131
-
132
- Project-local PI WEB config lives at:
133
-
134
- ```text
135
- <project>/.pi-web/config.json
136
- ```
96
+ ## 配置
137
97
 
138
- Common configuration includes host/port, path access, uploads, PI WEB plugin enablement, shortcuts, and session daemon options. In Settings, machine-affecting config targets the selected machine; gateway host/port/allowed-hosts, remote machine registration, tokens, and keyboard shortcuts stay local.
98
+ 机器配置在 `$PI_WEB_CONFIG` 或 `~/.config/pi-web/config.json`,项目配置在 `<project>/.pi-web/config.json`。包括网络、路径访问、上传/附件、插件、快捷键和会话工具。普通模型认证与默认值按项目托管,管理嵌入独立,详见[配置参考](docs/config.md)。
139
99
 
140
- Read more: [Configuration reference](https://pi-web.dev/config)
100
+ ## 开发
141
101
 
142
- ## Development
143
-
144
- Clone the repository and run:
102
+ 克隆仓库后:
145
103
 
146
104
  ```bash
147
105
  npm install
148
106
  npm run dev
149
107
  ```
150
108
 
151
- Open the Vite URL, usually:
152
-
153
- ```text
154
- http://localhost:8505
155
- ```
156
-
157
- For the split development setup:
109
+ 打开 Vite URL,通常为 `http://localhost:8505`。拆分开发启动使用三个独立终端,先启动 Web:
158
110
 
159
111
  ```bash
160
- npm run dev:sessiond
161
112
  npm run dev:web
113
+ npm run start:sessiond
162
114
  npm run dev:client
163
115
  ```
164
116
 
165
- Validate changes with:
117
+ daemon 等待 Web 拥有的插件构建就绪,不自动重载。构建/重启顺序见[服务启动说明](https://pi-web.dev/install#manage-services)。
118
+
119
+ 验证改动:
166
120
 
167
121
  ```bash
168
122
  npm run verify
169
123
  ```
170
124
 
171
- ## Security model
125
+ 交付构建与产物检查见[开发检查](docs/development-checks.md)。
172
126
 
173
- PI WEB assumes trusted users, trusted repositories, and trusted server paths.
127
+ ## 安全模型
174
128
 
175
- It is not a sandbox, permission system, or multi-tenant platform. Do not expose it directly to the public internet without a trusted network, firewall, VPN, SSH tunnel, or authenticated reverse proxy.
129
+ 普通模式假定用户、仓库与服务器路径可信,不是多租户平台或代理沙箱。不要在没有可信网络、防火墙、VPN、SSH 隧道或认证代理时直接暴露到公网。管理嵌入使用独立授权资源、受控工具、沙箱与审计,不与普通模式共享权限。
176
130
 
177
- ## Documentation
131
+ ## 文档
178
132
 
179
- - [Website](https://pi-web.dev/)
180
- - [Install](https://pi-web.dev/install)
181
- - [Remote-first development](https://pi-web.dev/remote-first)
182
- - [Machines / fleet](https://pi-web.dev/machines)
183
- - [Configuration](https://pi-web.dev/config)
184
- - [Plugins](https://pi-web.dev/plugins)
185
- - [FAQ](https://pi-web.dev/faq)
133
+ - [上游网站](https://pi-web.dev/)
134
+ - [安装](https://pi-web.dev/install)
135
+ - [远端优先](https://pi-web.dev/remote-first)
136
+ - [机器](https://pi-web.dev/machines)
137
+ - [配置](docs/config.md)
138
+ - [插件](docs/plugins.md)
139
+ - [常见问题](https://pi-web.dev/faq)
186
140
 
187
- ## License
141
+ ## 许可
188
142
 
189
- MIT © 2026 Federico Jaramillo Martinez. See [LICENSE](LICENSE).
143
+ MIT © 2026 Federico Jaramillo Martinez,见 [LICENSE](LICENSE)。
@@ -0,0 +1 @@
1
+ ready
package/dist/cli.js CHANGED
@@ -5,19 +5,20 @@ import { mkdir, rm, writeFile } from "node:fs/promises";
5
5
  import { homedir, userInfo } from "node:os";
6
6
  import { basename, dirname, join, resolve } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
- import { defaultPiWebConfigPath, defaultPiWebDataDir, effectivePiWebConfig, examplePiWebConfig } from "./config.js";
8
+ import { defaultPiWebConfigPath, defaultPiWebDataDir, examplePiWebConfig } from "./config.js";
9
9
  import { piWebDockerCommand } from "./docker/piWebDockerCommandPlan.js";
10
+ import { ownEnvironmentValue } from "./environment.js";
10
11
  import { runPluginRecoveryCli } from "./pluginRecoveryCli.js";
11
- import { packageVersion, printPiWebVersionReport, probeRunningComponentReady, runningComponentsReady } from "./piWebVersionReport.js";
12
+ import { packageVersion, printPiWebVersionReport, probeRunningComponentReady, runningComponentsReady, } from "./piWebVersionReport.js";
12
13
  import { checkNodePtyDarwinSpawnHelper, formatNodePtyDarwinSpawnHelperCheck } from "./server/diagnostics/nodePtySpawnHelper.js";
13
14
  import { checkNodePtyNativeModule, formatNodePtyNativeModuleCheck } from "./server/diagnostics/nodePtyNativeModule.js";
14
- import { launchdBootoutArgs, launchdServiceTarget, orderServices, performServiceAction, serviceStartOrder, serviceStopOrder, settleLaunchdServiceUnload, startLaunchdService, } from "./nativeServices/serviceAction.js";
15
15
  import { installNativeServiceCandidate, nativeServiceInstallFailureNeedsPathAdvice, } from "./nativeServices/serviceInstall.js";
16
+ import { launchdBootoutArgs, launchdServiceTarget, orderServices, performServiceAction, serviceStartOrder, serviceStopOrder, settleLaunchdServiceUnload, startLaunchdService, } from "./nativeServices/serviceAction.js";
16
17
  import { minimumSupportedNodeVersion, nativeServiceManagerRefs, productionNativeServiceIds, } from "./nativeServices/servicePlan.js";
17
- import { formatNativeServiceDoctorResult, inferInstalledNativeServiceMode, inspectInstalledDevelopmentServiceInput, inspectInstalledProductionServiceContext, runNativeServiceDoctor, } from "./nativeServices/serviceDoctor.js";
18
+ import { inspectInstalledNativeServiceDefinitions, } from "./nativeServices/installedServiceDefinitions.js";
19
+ import { formatNativeServiceDoctorResult, inferInstalledNativeServiceMode, inspectInstalledDevelopmentServiceInput, inspectInstalledProductionServiceContext, runNativeServiceDoctor, selectManagedNativeServiceConfig, } from "./nativeServices/serviceDoctor.js";
18
20
  import { createNativeServiceAuthoritativeProbe, nativeServicePrerequisiteShellCheck, } from "./nativeServices/serviceProbe.js";
19
21
  import { renderLaunchdPlist, renderSystemdUnit } from "./nativeServices/serviceRendering.js";
20
- import { inspectInstalledNativeServiceDefinitions, } from "./nativeServices/installedServiceDefinitions.js";
21
22
  const PI_WEB_PACKAGE_NAME = "@chainingintention/pi-web-cn";
22
23
  const systemdServiceDir = join(homedir(), ".config", "systemd", "user");
23
24
  const launchdServiceDir = join(homedir(), "Library", "LaunchAgents");
@@ -53,9 +54,6 @@ function requireServiceBackend(command) {
53
54
  return backend;
54
55
  throw new Error(`\`${command}\` requires a supported per-user service manager (systemd user services or LaunchAgents) and is not supported on ${platformLabel()}.\n\n${manualRunAdvice()}`);
55
56
  }
56
- function supportsSystemdUserServices() {
57
- return currentServiceBackend()?.kind === "systemd";
58
- }
59
57
  function manualRunAdvice() {
60
58
  return [
61
59
  "Run PI WEB manually from a checkout:",
@@ -301,15 +299,15 @@ function currentLaunchdServiceTarget(ref) {
301
299
  function launchdActionContext() {
302
300
  return { domain: launchdDomain(), plistPath: launchdPlistPath };
303
301
  }
304
- function serviceActionDeps(backend) {
302
+ function serviceActionDeps(backend, probeEnvironment = process.env) {
305
303
  return {
306
304
  run: (command, args) => run(command, args),
307
305
  runQuiet,
308
- sleep: (ms) => new Promise((resolvePromise) => {
309
- setTimeout(resolvePromise, ms);
306
+ sleep: (ms) => new Promise((resolve) => {
307
+ setTimeout(resolve, ms);
310
308
  }),
311
309
  isServiceRunning: (ref) => runtimeStatus(backend, ref).health === "running",
312
- isComponentReady: probeRunningComponentReady,
310
+ isComponentReady: (component) => probeRunningComponentReady(component, { configEnv: probeEnvironment }),
313
311
  };
314
312
  }
315
313
  async function installLaunchdServices(plan) {
@@ -326,8 +324,11 @@ async function installLaunchdServices(plan) {
326
324
  const plistPath = join(launchdServiceDir, service.manager.launchdPlistName);
327
325
  await writeFile(plistPath, renderLaunchdPlist(plan, service, logDir));
328
326
  }
327
+ // Settle each bootout before deciding bootstrap vs kickstart: acting on a
328
+ // label launchd is still asynchronously unloading races the teardown and can
329
+ // lose the service entirely (the same defect the restart path had).
329
330
  const context = launchdActionContext();
330
- const deps = serviceActionDeps(plan.backend);
331
+ const deps = serviceActionDeps(plan.backend, { ...process.env, ...plan.services[0]?.environment });
331
332
  for (const service of plan.services) {
332
333
  const ref = serviceRefFromPlan(service.id, service.manager);
333
334
  await settleLaunchdServiceUnload(currentLaunchdServiceTarget(ref), deps);
@@ -619,9 +620,12 @@ async function serviceAction(action) {
619
620
  process.exitCode = 1;
620
621
  return;
621
622
  }
623
+ await performLifecycleServiceAction(backend, action, process.env);
624
+ }
625
+ async function performLifecycleServiceAction(backend, action, probeEnvironment) {
622
626
  const refs = installedServiceRefs(backend);
623
627
  const input = { backend, action, refs, launchdContext: launchdActionContext() };
624
- const result = await performServiceAction(input, serviceActionDeps(backend));
628
+ const result = await performServiceAction(input, serviceActionDeps(backend, probeEnvironment));
625
629
  if (result.unreadyServices.length > 0) {
626
630
  for (const ref of result.unreadyServices) {
627
631
  const target = backend.kind === "systemd" ? ref.systemdName : currentLaunchdServiceTarget(ref);
@@ -643,9 +647,10 @@ export function sessionDaemonRestartPlan(options = {}) {
643
647
  const dockerMode = activeDockerMode(env);
644
648
  const runCommand = options.runCommand ?? ((command, args) => { run(command, args, { check: true }); });
645
649
  if (dockerMode !== undefined) {
650
+ const command = piWebDockerCommand(dockerMode, "restart-sessiond");
646
651
  return {
647
652
  kind: "automatic",
648
- command: piWebDockerCommand(dockerMode, "restart-sessiond"),
653
+ command,
649
654
  guidance: "Run the Docker control command from the PI WEB Docker host.",
650
655
  perform: () => {
651
656
  runCommand("pi-web-docker", [...(dockerMode === "dev" ? ["--dev"] : []), "restart-sessiond"]);
@@ -679,9 +684,11 @@ export function sessionDaemonRestartPlan(options = {}) {
679
684
  };
680
685
  }
681
686
  function activeDockerMode(env) {
682
- if (!truthyEnvValue(env["PI_WEB_DOCKER_RUNTIME"]))
687
+ if (!truthyEnvValue(ownEnvironmentValue(env, "PI_WEB_DOCKER_RUNTIME")))
683
688
  return undefined;
684
- return env["PI_WEB_DOCKER_MODE"] === "dev" ? "dev" : "runtime";
689
+ if (ownEnvironmentValue(env, "PI_WEB_DOCKER_MODE") === "dev")
690
+ return "dev";
691
+ return "runtime";
685
692
  }
686
693
  function truthyEnvValue(value) {
687
694
  return value !== undefined && value !== "" && value !== "0" && value.toLowerCase() !== "false";
@@ -718,16 +725,14 @@ export function nodeVersionCheck() {
718
725
  description: `node >= ${minimumSupportedNodeVersion}`,
719
726
  });
720
727
  }
721
- export function agentCommandForChecks(env = process.env) {
722
- return effectivePiWebConfig({ env }).config.agent.command;
723
- }
724
- function generalDoctorChecks() {
728
+ export function generalDoctorChecks() {
725
729
  const shell = serviceShellLabel();
726
- const agentCommand = agentCommandForChecks();
727
730
  return [
728
731
  [`Caller login ${shell} can find node >= ${minimumSupportedNodeVersion}`, serviceShellCommand(nodeVersionCheck())],
729
732
  [`Caller login ${shell} can find npm`, serviceShellCommand(commandWithVersionCheck("npm"))],
730
- [`Caller login ${shell} can find ${agentCommand}`, serviceShellCommand(commandWithVersionCheck(agentCommand))],
733
+ // Sessions run on the bundled pi SDK; the only CLI check is a hardcoded
734
+ // `pi` PATH probe — nothing names or locates a configurable command.
735
+ [`Caller login ${shell} can find pi`, serviceShellCommand(commandWithVersionCheck("pi"))],
731
736
  ];
732
737
  }
733
738
  function runChecks(checks) {
@@ -775,7 +780,7 @@ function printOptionalDoctorChecks() {
775
780
  console.log(" PI WEB falls back to a bounded filesystem scan when rg is unavailable.");
776
781
  }
777
782
  }
778
- function installedServiceDefinitions(backend, ids) {
783
+ function installedServiceDefinitions(backend, ids, purpose, warn = (message) => { console.warn(`! ${message}`); }) {
779
784
  const sources = ids.map((id) => ({
780
785
  id,
781
786
  path: serviceFilePath(backend, serviceRefs[id]),
@@ -786,10 +791,107 @@ function installedServiceDefinitions(backend, ids) {
786
791
  readFile: (path) => readFileSync(path),
787
792
  realpath: realpathSync,
788
793
  capture: captureInstalledServiceDefinitionCommand,
789
- }, "doctor");
794
+ warn,
795
+ }, purpose);
796
+ }
797
+ /** Build an isolated probe environment without mutating the caller or process. */
798
+ export function managedServiceProbeEnvironment(backend, definitions, callerEnvironment) {
799
+ const selection = selectManagedNativeServiceConfig(backend, definitions, ownEnvironmentValue(callerEnvironment, "PI_WEB_CONFIG"));
800
+ if (!selection.ok)
801
+ return selection;
802
+ if (selection.value.source === "installed") {
803
+ return {
804
+ ok: true,
805
+ value: { ...callerEnvironment, PI_WEB_CONFIG: selection.value.configPath },
806
+ };
807
+ }
808
+ if (selection.value.source === "default" && definitions.length > 0) {
809
+ // An own empty value preserves default resolution while masking any
810
+ // prototype-inherited PI_WEB_CONFIG from downstream environment lookups.
811
+ return { ok: true, value: { ...callerEnvironment, PI_WEB_CONFIG: "" } };
812
+ }
813
+ return { ok: true, value: callerEnvironment };
814
+ }
815
+ export function installedServiceProbeEnvironment(backend, ids, callerEnvironment, purpose, inspectDefinitions = installedServiceDefinitions) {
816
+ // The explicit caller override wins without requiring installed definitions
817
+ // to be readable or canonical.
818
+ const callerConfigPath = ownEnvironmentValue(callerEnvironment, "PI_WEB_CONFIG");
819
+ if (callerConfigPath !== undefined && callerConfigPath !== "") {
820
+ return { ok: true, value: callerEnvironment };
821
+ }
822
+ if (ids.size === 0)
823
+ return { ok: true, value: callerEnvironment };
824
+ const definitions = inspectDefinitions(backend, [...ids], purpose);
825
+ if (!definitions.ok)
826
+ return definitions;
827
+ return managedServiceProbeEnvironment(backend, definitions.value, callerEnvironment);
790
828
  }
791
- function nativeServiceDoctorTarget(backend) {
792
- const ids = installedServiceIds(backend);
829
+ function managedServiceProbeFailure(backend, message) {
830
+ return [
831
+ `Could not select managed PI_WEB_CONFIG from installed ${backend.label}: ${message}`,
832
+ "Repair the reported service-manager override or definition, then re-run `pi-web install` (or `pi-web install --dev`); a nonempty PI_WEB_CONFIG explicitly overrides managed config selection for this command.",
833
+ ].join("\n");
834
+ }
835
+ /**
836
+ * Dispatch commands whose probes may need managed config. The service-manager,
837
+ * definition, lifecycle, doctor, and version boundaries are injected so this
838
+ * exact orchestration can be tested without mutating live services or process
839
+ * environment.
840
+ */
841
+ export async function runReadinessCliCommand(command, dependencies) {
842
+ if (command === "version") {
843
+ await dependencies.printVersion();
844
+ return;
845
+ }
846
+ const environment = dependencies.environment;
847
+ if (command === "start" || command === "restart") {
848
+ const backend = dependencies.requireBackend(`pi-web ${command}`);
849
+ const installedIds = dependencies.installedServiceIds(backend);
850
+ const probeEnvironment = installedServiceProbeEnvironment(backend, installedIds, environment, command, dependencies.inspectDefinitions);
851
+ if (!probeEnvironment.ok)
852
+ throw new Error(managedServiceProbeFailure(backend, probeEnvironment.message));
853
+ await dependencies.runLifecycle(backend, command, probeEnvironment.value);
854
+ return;
855
+ }
856
+ const backend = dependencies.currentBackend();
857
+ const installedIds = backend === undefined
858
+ ? new Set()
859
+ : dependencies.installedServiceIds(backend);
860
+ let versionReportOptions = { configEnv: environment };
861
+ let managedInspectionFailed = false;
862
+ if (backend !== undefined && activeDockerMode(environment) === undefined) {
863
+ const probeEnvironment = installedServiceProbeEnvironment(backend, installedIds, environment, "doctor", dependencies.inspectDefinitions);
864
+ if (probeEnvironment.ok) {
865
+ versionReportOptions = { configEnv: probeEnvironment.value };
866
+ }
867
+ else {
868
+ managedInspectionFailed = true;
869
+ versionReportOptions = { webEndpointError: managedServiceProbeFailure(backend, probeEnvironment.message) };
870
+ }
871
+ }
872
+ await dependencies.runDoctor({
873
+ backend,
874
+ installedIds,
875
+ environment,
876
+ versionReportOptions,
877
+ managedInspectionFailed,
878
+ });
879
+ }
880
+ function readinessCliCommandDependencies() {
881
+ return {
882
+ environment: process.env,
883
+ currentBackend: currentServiceBackend,
884
+ requireBackend: requireServiceBackend,
885
+ installedServiceIds,
886
+ // Doctor inspects again when building its native-service checks. Report
887
+ // warnings there, including when an explicit config bypasses selection here.
888
+ inspectDefinitions: (backend, ids, purpose) => installedServiceDefinitions(backend, ids, purpose, purpose === "doctor" ? () => { } : undefined),
889
+ runLifecycle: performLifecycleServiceAction,
890
+ runDoctor: doctor,
891
+ printVersion: async () => { await printPiWebVersionReport(); },
892
+ };
893
+ }
894
+ function nativeServiceDoctorTarget(backend, ids) {
793
895
  const mode = inferInstalledNativeServiceMode(ids);
794
896
  if (mode === "ambiguous") {
795
897
  return {
@@ -814,7 +916,7 @@ function nativeServiceDoctorTarget(backend) {
814
916
  message: `installed ${mode} service set is incomplete; ${missingId} is missing.`,
815
917
  };
816
918
  }
817
- const definitions = installedServiceDefinitions(backend, expectedIds);
919
+ const definitions = installedServiceDefinitions(backend, expectedIds, "doctor");
818
920
  if (!definitions.ok)
819
921
  return { kind: "inspection-failure", message: definitions.message };
820
922
  if (mode === "development") {
@@ -832,8 +934,8 @@ function nativeServiceDoctorTarget(backend) {
832
934
  }
833
935
  : { kind: "inspection-failure", message: inspection.message };
834
936
  }
835
- async function printNativeServiceDoctorChecks(backend) {
836
- const result = await runNativeServiceDoctor(nativeServiceDoctorTarget(backend), {
937
+ async function printNativeServiceDoctorChecks(backend, installedIds) {
938
+ const result = await runNativeServiceDoctor(nativeServiceDoctorTarget(backend, installedIds), {
837
939
  probe: createNativeServiceAuthoritativeProbe(),
838
940
  fileExists: regularFileExists,
839
941
  });
@@ -882,9 +984,15 @@ function printPathSetupAdvice(shell = detectServiceShell()) {
882
984
  console.log(" Avoid relying on prompt hooks; PI WEB services run non-interactive login shells.");
883
985
  }
884
986
  }
885
- export function doctorExitCode(generalReadinessOk, nativeServicePlanOk, nodePtyRuntimeOk, runningComponentsOk) {
886
- return generalReadinessOk && nativeServicePlanOk && nodePtyRuntimeOk && runningComponentsOk ? 0 : 1;
887
- }
987
+ /**
988
+ * Running components an installed deployment must keep ready: the API-serving
989
+ * component whenever the web or UI dev service file is installed (the version
990
+ * endpoint probes the API port in both modes), and the session daemon whenever
991
+ * its service file is installed. Docker deployments have no native service
992
+ * files, so the Docker runtime marker expects both components. A machine with
993
+ * nothing installed expects nothing: doctor's manual-run guidance stays a
994
+ * passing outcome there.
995
+ */
888
996
  export function expectedRunningComponents(installedServices, env) {
889
997
  if (activeDockerMode(env) !== undefined)
890
998
  return ["web", "sessiond"];
@@ -895,8 +1003,11 @@ export function expectedRunningComponents(installedServices, env) {
895
1003
  expected.push("sessiond");
896
1004
  return expected;
897
1005
  }
898
- async function doctor() {
899
- const backend = currentServiceBackend();
1006
+ export function doctorExitCode(generalReadinessOk, nativeServicePlanOk, nodePtyRuntimeOk, runningComponentsOk) {
1007
+ return generalReadinessOk && nativeServicePlanOk && nodePtyRuntimeOk && runningComponentsOk ? 0 : 1;
1008
+ }
1009
+ async function doctor(context) {
1010
+ const { backend, installedIds, environment, versionReportOptions, managedInspectionFailed } = context;
900
1011
  console.log(`Platform: ${platformLabel()}`);
901
1012
  console.log(`Service backend: ${backend?.label ?? "manual run only"}`);
902
1013
  console.log(`Service shell: ${describeServiceShell()}`);
@@ -904,8 +1015,8 @@ async function doctor() {
904
1015
  console.log(`- Native user service plan checks skipped on ${platformLabel()}; no native-service drift is reported.`);
905
1016
  }
906
1017
  console.log("");
907
- const runningVersionInfo = await printPiWebVersionReport();
908
- const expectedComponents = expectedRunningComponents(backend === undefined ? new Set() : installedServiceIds(backend), process.env);
1018
+ const runningVersionInfo = await printPiWebVersionReport(versionReportOptions);
1019
+ const expectedComponents = expectedRunningComponents(installedIds, environment);
909
1020
  const runningComponentsOk = runningComponentsReady(runningVersionInfo, expectedComponents);
910
1021
  if (!runningComponentsOk) {
911
1022
  console.log("\n✗ Installed PI WEB services are unavailable or stale (see \"Running services\" above).");
@@ -920,9 +1031,15 @@ async function doctor() {
920
1031
  let nativeServiceReport = null;
921
1032
  if (backend !== undefined) {
922
1033
  console.log("\nNative service plan checks (service-manager context):");
923
- nativeServiceReport = await printNativeServiceDoctorChecks(backend);
1034
+ if (managedInspectionFailed) {
1035
+ console.log("✗ Installed native-service plan could not be inspected consistently with the readiness probe (see \"Running services\" above).");
1036
+ console.log(" Repair the reported service-manager definition before relying on doctor results.");
1037
+ }
1038
+ else {
1039
+ nativeServiceReport = await printNativeServiceDoctorChecks(backend, installedIds);
1040
+ }
924
1041
  }
925
- if (supportsSystemdUserServices()) {
1042
+ if (backend?.kind === "systemd") {
926
1043
  const linger = isLingerEnabled();
927
1044
  if (linger === true) {
928
1045
  console.log("✓ systemd user lingering enabled");
@@ -942,7 +1059,7 @@ async function doctor() {
942
1059
  else {
943
1060
  console.log(`- systemd user lingering skipped on ${platformLabel()}`);
944
1061
  }
945
- const nativeServicePlanOk = nativeServiceReport?.ok ?? true;
1062
+ const nativeServicePlanOk = !managedInspectionFailed && (nativeServiceReport?.ok ?? true);
946
1063
  const pathFailure = !generalReadinessOk || nativeServiceReport?.pathAdviceRecommended === true;
947
1064
  if (pathFailure) {
948
1065
  console.log("\nIf a command works in your terminal but fails in the service-manager check, compare the caller and manager contexts above.");
@@ -1002,7 +1119,10 @@ async function main() {
1002
1119
  await install(args);
1003
1120
  else if (command === "uninstall")
1004
1121
  await uninstall();
1005
- else if (command === "start" || command === "stop" || command === "restart" || command === "status")
1122
+ else if (command === "start" || command === "restart" || command === "doctor" || command === "version") {
1123
+ await runReadinessCliCommand(command, readinessCliCommandDependencies());
1124
+ }
1125
+ else if (command === "stop" || command === "status")
1006
1126
  await serviceAction(command);
1007
1127
  else if (command === "logs")
1008
1128
  logs();
@@ -1012,10 +1132,6 @@ async function main() {
1012
1132
  }
1013
1133
  else if (command === "plugins")
1014
1134
  runPluginRecoveryCli(args, { restartPlan: (context) => sessionDaemonRestartPlan(context) });
1015
- else if (command === "doctor")
1016
- await doctor();
1017
- else if (command === "version")
1018
- await printPiWebVersionReport();
1019
1135
  else if (command === "--version" || command === "-v")
1020
1136
  console.log(packageVersion());
1021
1137
  else if (command === "help" || command === "--help" || command === "-h")