@chainingintention/pi-web-cn 1.202610.1 → 1.202610.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -106
- package/dist/.plugins-ready +1 -0
- package/dist/cli.js +161 -45
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/index-CFhaGb5m.js +4357 -0
- package/dist/client/assets/vendor-editor-core-YWog6mAR.js +10 -0
- package/dist/client/assets/vendor-editor-languages-DOCw3vc9.js +28 -0
- package/dist/client/index.html +5 -5
- package/dist/config.js +30 -6
- package/dist/config.js.map +1 -1
- package/dist/docker/piWebDockerCommandPlan.js +13 -4
- package/dist/docker/piWebDockerCommandPlan.js.map +1 -1
- package/dist/nativeServices/installedServiceDefinitions.js +23 -10
- package/dist/nativeServices/installedServiceDefinitions.js.map +1 -1
- package/dist/nativeServices/serviceAction.js +78 -20
- package/dist/nativeServices/serviceAction.js.map +1 -1
- package/dist/nativeServices/serviceDoctor.js +339 -67
- package/dist/nativeServices/serviceDoctor.js.map +1 -1
- package/dist/nativeServices/servicePlan.js +2 -2
- package/dist/nativeServices/servicePlan.js.map +1 -1
- package/dist/pi-packages/captains-log/README.md +11 -0
- package/dist/pi-packages/captains-log/dist/browser/channelProtocol.js +29 -0
- package/dist/pi-packages/captains-log/dist/browser/index.js +146 -0
- package/dist/pi-packages/captains-log/dist/browser/markdown.js +67 -0
- package/dist/pi-packages/captains-log/dist/browser/panel.js +151 -0
- package/dist/pi-packages/captains-log/dist/browser/protocol.js +26 -0
- package/dist/pi-packages/captains-log/dist/companion.js +126 -0
- package/dist/pi-packages/captains-log/dist/roundtrip.js +62 -0
- package/dist/pi-packages/captains-log/dist/server.js +210 -0
- package/dist/pi-packages/captains-log/dist/store.js +75 -0
- package/dist/pi-packages/captains-log/docs/usage.md +29 -0
- package/dist/pi-packages/captains-log/package.json +35 -0
- package/dist/pi-packages/captains-log/tsconfig.json +21 -0
- package/dist/pi-packages/captains-log/vite.config.mjs +28 -0
- package/dist/pi-packages/relays/pi-web-plugin.js +9 -9
- package/dist/pi-packages/relays/prompts/relay.md +1 -1
- package/dist/pi-packages/relays/relaysPanelElement.js +8 -8
- package/dist/pi-packages/relays/skills/relay-runner/SKILL.md +21 -13
- package/dist/pi-web-plugins/files/browser/assets/files-icon-DZObYhxb.svg +3 -0
- package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +456 -0
- package/dist/pi-web-plugins/files/package.json +15 -0
- package/dist/pi-web-plugins/git/browser/git-panel.js +55 -32
- package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +2 -2
- package/dist/pi-web-plugins/git/git-backend.js +19 -26
- package/dist/pi-web-plugins/git/gitStatusCache.js +48 -0
- package/dist/pi-web-plugins/git/package.json +1 -0
- package/dist/pi-web-plugins/git/server-plugin.js +11 -10
- package/dist/pi-web-plugins/info/infoInternals.js +4 -1
- package/dist/pi-web-plugins/info/package.json +1 -1
- package/dist/pi-web-plugins/info/pi-web-plugin.js +8 -8
- package/dist/pi-web-plugins/mermaid/browser/mermaid-engine.js +3590 -0
- package/dist/pi-web-plugins/mermaid/browser/pi-web-plugin.js +6 -0
- package/dist/pi-web-plugins/mermaid/package.json +13 -0
- package/dist/pi-web-plugins/terminal/browser/pi-web-plugin.js +210 -0
- package/dist/pi-web-plugins/terminal/package.json +16 -0
- package/dist/pi-web-plugins/terminal/server-plugin.js +365 -0
- package/dist/pi-web-plugins/terminal/terminalService.js +435 -0
- package/dist/pi-web-plugins/updates/package.json +1 -1
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +69 -68
- package/dist/pi-web-plugins/workspace-tasks/package.json +1 -1
- package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +3 -3
- package/dist/piWebVersionReport.js +47 -24
- package/dist/piWebVersionReport.js.map +1 -1
- package/dist/plugin-api.d.ts +260 -25
- package/dist/plugin-api.js +1 -0
- package/dist/pluginRecoveryCli.js +3 -2
- package/dist/pluginRecoveryCli.js.map +1 -1
- package/dist/server/activity/workspaceActivityService.js +5 -5
- package/dist/server/activity/workspaceActivityService.js.map +1 -1
- package/dist/server/app.js +71 -44
- package/dist/server/app.js.map +1 -1
- package/dist/server/audit/managementAuditStore.js +1 -1
- package/dist/server/browserMessageProjection.js +0 -2
- package/dist/server/browserMessageProjection.js.map +1 -1
- package/dist/server/configRoutes.js +1 -2
- package/dist/server/configRoutes.js.map +1 -1
- package/dist/server/knownPiPackages.js +12 -0
- package/dist/server/knownPiPackages.js.map +1 -0
- package/dist/server/machines/machineClient.js +2 -2
- package/dist/server/machines/machineClient.js.map +1 -1
- package/dist/server/machines/machinePluginProxyRoutes.js +120 -21
- package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineProxyRoutes.js +80 -22
- package/dist/server/machines/machineProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineService.js +22 -0
- package/dist/server/machines/machineService.js.map +1 -1
- package/dist/server/managementEmbed.js +1 -1
- package/dist/server/managementEmbed.js.map +1 -1
- package/dist/server/managementPrivileges.js +7 -1
- package/dist/server/managementPrivileges.js.map +1 -1
- package/dist/server/managementTerminalProxyRoutes.js +124 -0
- package/dist/server/managementTerminalProxyRoutes.js.map +1 -0
- package/dist/server/normalAuth.js +5 -1
- package/dist/server/normalAuth.js.map +1 -1
- package/dist/server/notices/serverNoticeStore.js +50 -6
- package/dist/server/notices/serverNoticeStore.js.map +1 -1
- package/dist/server/piPackageService.js +5 -5
- package/dist/server/piPackageService.js.map +1 -1
- package/dist/server/piWebPluginCatalog.js +211 -34
- package/dist/server/piWebPluginCatalog.js.map +1 -1
- package/dist/server/piWebPluginLifecycle.js +29 -3
- package/dist/server/piWebPluginLifecycle.js.map +1 -1
- package/dist/server/piWebPluginService.js +176 -291
- package/dist/server/piWebPluginService.js.map +1 -1
- package/dist/server/piWebStatus.js +45 -55
- package/dist/server/piWebStatus.js.map +1 -1
- package/dist/server/pluginCallbackDrain.js +35 -0
- package/dist/server/pluginCallbackDrain.js.map +1 -0
- package/dist/server/plugins/pluginBackendChannelProxyAdmission.js +84 -0
- package/dist/server/plugins/pluginBackendChannelProxyAdmission.js.map +1 -0
- package/dist/server/plugins/pluginBackendChannelProxyCoordinator.js +234 -0
- package/dist/server/plugins/pluginBackendChannelProxyCoordinator.js.map +1 -0
- package/dist/server/plugins/pluginBackendChannelProxyRoutes.js +63 -0
- package/dist/server/plugins/pluginBackendChannelProxyRoutes.js.map +1 -0
- package/dist/server/plugins/pluginBackendProxyRoutes.js +7 -4
- package/dist/server/plugins/pluginBackendProxyRoutes.js.map +1 -1
- package/dist/server/plugins/pluginBackendRegistry.js +773 -0
- package/dist/server/plugins/pluginBackendRegistry.js.map +1 -0
- package/dist/server/plugins/serverPluginPiSessionEventsCapability.js +34 -0
- package/dist/server/plugins/serverPluginPiSessionEventsCapability.js.map +1 -0
- package/dist/server/plugins/serverPluginPiSessionsCapability.js +185 -0
- package/dist/server/plugins/serverPluginPiSessionsCapability.js.map +1 -0
- package/dist/server/plugins/serverPluginRuntime.js +1049 -107
- package/dist/server/plugins/serverPluginRuntime.js.map +1 -1
- package/dist/server/plugins/serverPluginWorkspacesCapability.js +114 -0
- package/dist/server/plugins/serverPluginWorkspacesCapability.js.map +1 -0
- package/dist/server/projectTrustRoutes.js +86 -0
- package/dist/server/projectTrustRoutes.js.map +1 -0
- package/dist/server/projects/projectLifecycleService.js +84 -0
- package/dist/server/projects/projectLifecycleService.js.map +1 -0
- package/dist/server/projects/projectService.js +2 -0
- package/dist/server/projects/projectService.js.map +1 -1
- package/dist/server/realtime/sessionEventHub.js +35 -41
- package/dist/server/realtime/sessionEventHub.js.map +1 -1
- package/dist/server/sessiond/agentHttpDispatcher.js +108 -0
- package/dist/server/sessiond/agentHttpDispatcher.js.map +1 -0
- package/dist/server/sessiond/pluginBackendChannelRoutes.js +397 -0
- package/dist/server/sessiond/pluginBackendChannelRoutes.js.map +1 -0
- package/dist/server/sessiond/pluginBackendRoutes.js +19 -9
- package/dist/server/sessiond/pluginBackendRoutes.js.map +1 -1
- package/dist/server/sessiond/projectMutationRoutes.js +38 -0
- package/dist/server/sessiond/projectMutationRoutes.js.map +1 -0
- package/dist/server/sessiond/sessionDaemonShutdown.js +36 -0
- package/dist/server/sessiond/sessionDaemonShutdown.js.map +1 -0
- package/dist/server/sessiond/sessionDaemonStartup.js +30 -4
- package/dist/server/sessiond/sessionDaemonStartup.js.map +1 -1
- package/dist/server/sessiond/sessionProxyRoutes.js +47 -15
- package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
- package/dist/server/sessiond/sessionServiceDependencies.js +4 -0
- package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -1
- package/dist/server/sessiond/sessiondStateOwnership.js +174 -39
- package/dist/server/sessiond/sessiondStateOwnership.js.map +1 -1
- package/dist/server/sessiond/workspaceRemovalRoutes.js +1 -1
- package/dist/server/sessiond/workspaceRemovalRoutes.js.map +1 -1
- package/dist/server/sessiond.js +226 -56
- package/dist/server/sessiond.js.map +1 -1
- package/dist/server/sessions/askUserTool.js +0 -3
- package/dist/server/sessions/askUserTool.js.map +1 -1
- package/dist/server/sessions/attachmentService.js +0 -1
- package/dist/server/sessions/attachmentService.js.map +1 -1
- package/dist/server/sessions/authService.js +8 -1
- package/dist/server/sessions/authService.js.map +1 -1
- package/dist/server/sessions/builtinCommands.js +2 -2
- package/dist/server/sessions/builtinCommands.js.map +1 -1
- package/dist/server/sessions/clientSessionPreview.js +14 -0
- package/dist/server/sessions/clientSessionPreview.js.map +1 -0
- package/dist/server/sessions/dockerEnvironmentFacts.js +82 -9
- package/dist/server/sessions/dockerEnvironmentFacts.js.map +1 -1
- package/dist/server/sessions/managementAgentTools.js +11 -6
- package/dist/server/sessions/managementAgentTools.js.map +1 -1
- package/dist/server/sessions/managementPermissionSystem.js +16 -4
- package/dist/server/sessions/managementPermissionSystem.js.map +1 -1
- package/dist/server/sessions/messagePaging.js +2 -2
- package/dist/server/sessions/messagePaging.js.map +1 -1
- package/dist/server/sessions/modelCatalogRefresher.js +4 -3
- package/dist/server/sessions/modelCatalogRefresher.js.map +1 -1
- package/dist/server/sessions/oauthLoginFlowService.js +2 -5
- package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
- package/dist/server/sessions/pendingAskStore.js +0 -3
- package/dist/server/sessions/pendingAskStore.js.map +1 -1
- package/dist/server/sessions/piSessionEventConnections.js +65 -0
- package/dist/server/sessions/piSessionEventConnections.js.map +1 -0
- package/dist/server/sessions/piSessionManagerGateway.js +56 -3
- package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
- package/dist/server/sessions/piSessionService.js +774 -448
- package/dist/server/sessions/piSessionService.js.map +1 -1
- package/dist/server/sessions/projectAuthService.js +29 -2
- package/dist/server/sessions/projectAuthService.js.map +1 -1
- package/dist/server/sessions/projectSettingsScope.js +12 -4
- package/dist/server/sessions/projectSettingsScope.js.map +1 -1
- package/dist/server/sessions/projectTrust.js +119 -0
- package/dist/server/sessions/projectTrust.js.map +1 -0
- package/dist/server/sessions/sessionActivityMarker.js +105 -0
- package/dist/server/sessions/sessionActivityMarker.js.map +1 -0
- package/dist/server/sessions/sessionArchiveMapping.js +2 -8
- package/dist/server/sessions/sessionArchiveMapping.js.map +1 -1
- package/dist/server/sessions/sessionCommandService.js +12 -10
- package/dist/server/sessions/sessionCommandService.js.map +1 -1
- package/dist/server/sessions/sessionEnvironmentFacts.js +5 -4
- package/dist/server/sessions/sessionEnvironmentFacts.js.map +1 -1
- package/dist/server/sessions/sessionModelScope.js +42 -5
- package/dist/server/sessions/sessionModelScope.js.map +1 -1
- package/dist/server/sessions/sessionNameGenerator.js +6 -6
- package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
- package/dist/server/sessions/sessionRoutes.js +63 -15
- package/dist/server/sessions/sessionRoutes.js.map +1 -1
- package/dist/server/sessions/sessionTreeProjection.js +29 -29
- package/dist/server/sessions/sessionTreeProjection.js.map +1 -1
- package/dist/server/sessions/sessionUiEvents.js +6 -7
- package/dist/server/sessions/sessionUiEvents.js.map +1 -1
- package/dist/server/sessions/sessionUnreadStore.js +26 -1
- package/dist/server/sessions/sessionUnreadStore.js.map +1 -1
- package/dist/server/sessions/spawnSessionTool.js +3 -3
- package/dist/server/sessions/spawnSessionTool.js.map +1 -1
- package/dist/server/sessions/spawnSubsessionTool.js +5 -5
- package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
- package/dist/server/sessions/spawnTargetResolver.js +1 -1
- package/dist/server/sessions/transcriptMessages.js +54 -0
- package/dist/server/sessions/transcriptMessages.js.map +1 -0
- package/dist/server/status/machineStatusService.js +3 -1
- package/dist/server/status/machineStatusService.js.map +1 -1
- package/dist/server/terminals/{terminalService.js → managementCommandRunService.js} +79 -107
- package/dist/server/terminals/managementCommandRunService.js.map +1 -0
- package/dist/server/terminals/managementTerminalRoutes.js +91 -0
- package/dist/server/terminals/managementTerminalRoutes.js.map +1 -0
- package/dist/server/terminals/requiredTerminalService.js +103 -0
- package/dist/server/terminals/requiredTerminalService.js.map +1 -0
- package/dist/server/webSocketBridge.js +339 -0
- package/dist/server/webSocketBridge.js.map +1 -1
- package/dist/server/workbench/gatewayIntegration.js +4 -1
- package/dist/server/workbench/gatewayIntegration.js.map +1 -1
- package/dist/server/workspaceExplorerRoutes.js +13 -12
- package/dist/server/workspaceExplorerRoutes.js.map +1 -1
- package/dist/server/workspaces/fileContentService.js +9 -7
- package/dist/server/workspaces/fileContentService.js.map +1 -1
- package/dist/server/workspaces/fileOperationService.js +4 -3
- package/dist/server/workspaces/fileOperationService.js.map +1 -1
- package/dist/server/workspaces/projectWorkspaceCwds.js +0 -5
- package/dist/server/workspaces/projectWorkspaceCwds.js.map +1 -1
- package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js +36 -12
- package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js.map +1 -1
- package/dist/server/workspaces/workspaceCatalog.js +6 -4
- package/dist/server/workspaces/workspaceCatalog.js.map +1 -1
- package/dist/server/workspaces/workspaceDeletionRoutes.js +5 -57
- package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -1
- package/dist/server/workspaces/workspaceProviderRegistry.js +75 -24
- package/dist/server/workspaces/workspaceProviderRegistry.js.map +1 -1
- package/dist/server/workspaces/workspaceRemovalService.js +25 -3
- package/dist/server/workspaces/workspaceRemovalService.js.map +1 -1
- package/dist/server-plugin-api.d.ts +274 -44
- package/dist/server-plugin-api.js +319 -2
- package/dist/server-plugin-api.js.map +1 -1
- package/dist/serverPluginRecovery.js +4 -0
- package/dist/serverPluginRecovery.js.map +1 -1
- package/dist/sessiond/activeAgentProfile.js +27 -2
- package/dist/sessiond/activeAgentProfile.js.map +1 -1
- package/dist/sessiond/config.js +4 -3
- package/dist/sessiond/config.js.map +1 -1
- package/dist/sessiond/sessionDaemonClient.js +29 -8
- package/dist/sessiond/sessionDaemonClient.js.map +1 -1
- package/dist/shared/activeAgentProfile.js +2 -34
- package/dist/shared/activeAgentProfile.js.map +1 -1
- package/dist/shared/activity.js +0 -3
- package/dist/shared/activity.js.map +1 -1
- package/dist/shared/apiTypes.js +7 -2
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/capabilities.js +5 -0
- package/dist/shared/capabilities.js.map +1 -1
- package/dist/shared/federatedRoutes.js +49 -9
- package/dist/shared/federatedRoutes.js.map +1 -1
- package/dist/shared/machinePluginIds.js +30 -7
- package/dist/shared/machinePluginIds.js.map +1 -1
- package/dist/shared/machineStatus.js +35 -1
- package/dist/shared/machineStatus.js.map +1 -1
- package/dist/shared/piWebStatusParsing.js +29 -0
- package/dist/shared/piWebStatusParsing.js.map +1 -1
- package/dist/shared/pluginApiTypes.d.ts +24 -9
- package/dist/shared/pluginApiTypes.js +2 -0
- package/dist/shared/pluginApiTypes.js.map +1 -0
- package/dist/shared/pluginBackendProtocol.js +163 -2
- package/dist/shared/pluginBackendProtocol.js.map +1 -1
- package/dist/shared/pluginIds.js +10 -1
- package/dist/shared/pluginIds.js.map +1 -1
- package/dist/shared/requiredTerminalPlugin.js +6 -0
- package/dist/shared/requiredTerminalPlugin.js.map +1 -0
- package/dist/shared/serverNoticeContract.js +88 -0
- package/dist/shared/serverNoticeContract.js.map +1 -0
- package/dist/shared/sessionDefaults.js +41 -0
- package/dist/shared/sessionDefaults.js.map +1 -0
- package/dist/shared/workspaceFiles.js.map +1 -1
- package/docs/config.md +270 -323
- package/docs/plugins.md +171 -956
- package/examples/session-bridge-plugin/README.md +20 -0
- package/examples/session-bridge-plugin/docs/usage.md +54 -0
- package/examples/session-bridge-plugin/package.json +26 -0
- package/examples/session-bridge-plugin/src/browser/index.ts +87 -0
- package/examples/session-bridge-plugin/src/browser/protocol.ts +24 -0
- package/examples/session-bridge-plugin/src/companion.ts +65 -0
- package/examples/session-bridge-plugin/src/reviewRun.ts +39 -0
- package/examples/session-bridge-plugin/src/server.ts +85 -0
- package/examples/session-bridge-plugin/src/store.ts +80 -0
- package/examples/session-bridge-plugin/tsconfig.json +21 -0
- package/examples/workspace-provider-plugin/README.md +39 -0
- package/examples/workspace-provider-plugin/package.json +25 -0
- package/examples/workspace-provider-plugin/src/browser/index.ts +69 -0
- package/examples/workspace-provider-plugin/src/server.ts +68 -0
- package/examples/workspace-provider-plugin/tsconfig.json +21 -0
- package/package.json +22 -13
- package/skills/README.md +27 -2
- package/skills/relay-runner/SKILL.md +21 -13
- package/dist/client/assets/CodeViewer-CZHnKRwQ.js +0 -4
- package/dist/client/assets/TerminalPanel-B_EaRPHY.js +0 -187
- package/dist/client/assets/index-Bv1v-Jz7.js +0 -4717
- package/dist/client/assets/vendor-editor-core-vUi74DnD.js +0 -12
- package/dist/client/assets/vendor-editor-languages-DoaXUodB.js +0 -46
- package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +0 -1
- package/dist/client/assets/vendor-terminal-BrP-ENHg.css +0 -1
- package/dist/client/assets/vendor-terminal-D8k4UKM2.js +0 -35
- package/dist/server/git/gitService.js +0 -316
- package/dist/server/git/gitService.js.map +0 -1
- package/dist/server/gitRoutes.js +0 -23
- package/dist/server/gitRoutes.js.map +0 -1
- package/dist/server/terminalProxyRoutes.js +0 -181
- package/dist/server/terminalProxyRoutes.js.map +0 -1
- package/dist/server/terminals/terminalRoutes.js +0 -164
- package/dist/server/terminals/terminalRoutes.js.map +0 -1
- package/dist/server/terminals/terminalService.js.map +0 -1
- package/dist/server/terminals/terminalSize.js +0 -17
- package/dist/server/terminals/terminalSize.js.map +0 -1
- package/dist/server/workspaces/gitWorktreeDiscovery.js +0 -43
- package/dist/server/workspaces/gitWorktreeDiscovery.js.map +0 -1
- package/dist/server/workspaces/workspaceService.js +0 -52
- package/dist/server/workspaces/workspaceService.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,49 +1,41 @@
|
|
|
1
1
|
# PI WEB
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
PI WEB 的中文本地化分支,保留上游功能,并将核心界面与内置插件的显示内容本地化为中文。
|
|
4
4
|
|
|
5
|
-
[](https://github.com/nayuto-wakusei/pi-web-ChineseTranslation/actions/workflows/ci.yml)
|
|
6
6
|
[](https://www.npmjs.com/package/@chainingintention/pi-web-cn)
|
|
7
7
|
[](package.json)
|
|
8
8
|
[](LICENSE)
|
|
9
9
|
|
|
10
|
-
**PI WEB
|
|
10
|
+
**PI WEB 是 [Pi Coding Agent](https://github.com/earendil-works/pi/tree/main/packages/coding-agent) 的 Web 界面,让代理会话持续运行在机器或服务器的真实工作区中。**
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
内置运行时支持已测试的 Pi `0.86.1` 或 `0.87.0`。每个会话守护进程独占 `PI_WEB_DATA_DIR`,并发实例必须使用独立数据目录和 daemon endpoint。
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
让代理在代码、工具、凭据和构建缓存所在的机器工作,从任何浏览器监督。
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
上游网站与文档:<https://pi-web.dev/>。本分支的包名、项目认证与管理隔离等差异以仓库中的[配置参考](docs/config.md)和[插件指南](docs/plugins.md)为准。
|
|
17
17
|
|
|
18
18
|

|
|
19
|
+

|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
## 为什么使用 PI WEB?
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
持久的工作环境适合代理开发。PI WEB 可以:
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
- 浏览器断开后继续运行代理会话;
|
|
26
|
+
- 在真实仓库与 Git 工作树中工作;
|
|
27
|
+
- 并行监督多个会话;
|
|
28
|
+
- 在电脑、手机和平板间切换;
|
|
29
|
+
- 使用服务器、工作站或远端开发机运行代理;
|
|
30
|
+
- 从一个界面管理项目、工作区、文件、终端、会话及远端机器。
|
|
25
31
|
|
|
26
|
-
|
|
32
|
+
浏览器负责监督,工作留在能够持续运行的机器。
|
|
27
33
|
|
|
28
|
-
|
|
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
|
-
|
|
36
|
+
需要 Node.js 22.19.0 或更新版本、npm、为当前用户配置的 Pi Coding Agent `0.86.1` 或 `0.87.0`,以及 Git 和项目所需开发工具。
|
|
36
37
|
|
|
37
|
-
|
|
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
|
-
|
|
46
|
+
npm 12 的限定开关只允许 node-pty 准备所需原生模块,不为其他依赖开启安装脚本。
|
|
55
47
|
|
|
56
|
-
|
|
48
|
+
打开:
|
|
57
49
|
|
|
58
50
|
```text
|
|
59
51
|
http://127.0.0.1:8504
|
|
60
52
|
```
|
|
61
53
|
|
|
62
|
-
|
|
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
|
-
|
|
74
|
-
configuration, and operational details in docs/, then link from here. -->
|
|
65
|
+
安装变体、Pi 包安装、WSL/手动启动与远端访问见[安装指南](https://pi-web.dev/install)。
|
|
75
66
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
## Core model
|
|
79
|
-
|
|
80
|
-
PI WEB organizes work like this:
|
|
67
|
+
## 核心模型
|
|
81
68
|
|
|
82
69
|
```text
|
|
83
|
-
Machine
|
|
84
|
-
Project
|
|
85
|
-
Workspace
|
|
86
|
-
Session
|
|
70
|
+
Machine 本地或远端 PI WEB 运行时
|
|
71
|
+
Project 该机器上的项目目录
|
|
72
|
+
Workspace 提供器拥有的工作目录;内置 Git 发现工作树,无提供器时使用项目目录
|
|
73
|
+
Session 工作区中运行的 Pi Coding Agent 对话
|
|
87
74
|
```
|
|
88
75
|
|
|
89
|
-
|
|
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
|
-
|
|
78
|
+
## 远端优先
|
|
110
79
|
|
|
111
|
-
|
|
80
|
+
让代理运行在保持在线的服务器、桌面机、云主机、家用实验室或远端开发机,不依赖笔记本浏览器会话。远端连接使用私有网络、SSH 隧道、可信反向代理或 PI WEB 机器联邦。
|
|
112
81
|
|
|
113
|
-
|
|
82
|
+
详见[远端优先开发](https://pi-web.dev/remote-first)。
|
|
114
83
|
|
|
115
|
-
##
|
|
84
|
+
## 机器与联邦
|
|
116
85
|
|
|
117
|
-
|
|
86
|
+
一个浏览器网关可代理可信远端机器的项目、工作区、文件、Git、会话、终端、活动、Pi 包与设置。设置页标明目标机器:包、插件、daemon 能力、文件访问和上传默认值针对所选机器;网关监听地址/端口/允许主机、机器注册/令牌和快捷键仍在网关。
|
|
118
87
|
|
|
119
|
-
|
|
88
|
+
详见[机器指南](https://pi-web.dev/machines)。
|
|
120
89
|
|
|
121
|
-
|
|
90
|
+
## PI WEB 插件
|
|
122
91
|
|
|
123
|
-
|
|
92
|
+
可信插件可提供面板、工具和工作区工作流,从 **设置 → PI WEB 插件** 管理所选机器的启用状态。Pi 包的安装与插件启用是独立操作。服务端插件变更需手动重启会话守护进程,再刷新浏览器;仅 Web 重启或 `/reload` 不会激活。
|
|
124
93
|
|
|
125
|
-
|
|
94
|
+
详见[插件指南](docs/plugins.md)。
|
|
126
95
|
|
|
127
|
-
|
|
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
|
-
|
|
98
|
+
机器配置在 `$PI_WEB_CONFIG` 或 `~/.config/pi-web/config.json`,项目配置在 `<project>/.pi-web/config.json`。包括网络、路径访问、上传/附件、插件、快捷键和会话工具。普通模型认证与默认值按项目托管,管理嵌入独立,详见[配置参考](docs/config.md)。
|
|
139
99
|
|
|
140
|
-
|
|
100
|
+
## 开发
|
|
141
101
|
|
|
142
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
125
|
+
交付构建与产物检查见[开发检查](docs/development-checks.md)。
|
|
172
126
|
|
|
173
|
-
|
|
127
|
+
## 安全模型
|
|
174
128
|
|
|
175
|
-
|
|
129
|
+
普通模式假定用户、仓库与服务器路径可信,不是多租户平台或代理沙箱。不要在没有可信网络、防火墙、VPN、SSH 隧道或认证代理时直接暴露到公网。管理嵌入使用独立授权资源、受控工具、沙箱与审计,不与普通模式共享权限。
|
|
176
130
|
|
|
177
|
-
##
|
|
131
|
+
## 文档
|
|
178
132
|
|
|
179
|
-
- [
|
|
180
|
-
- [
|
|
181
|
-
- [
|
|
182
|
-
- [
|
|
183
|
-
- [
|
|
184
|
-
- [
|
|
185
|
-
- [
|
|
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
|
-
##
|
|
141
|
+
## 许可
|
|
188
142
|
|
|
189
|
-
MIT © 2026 Federico Jaramillo Martinez
|
|
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,
|
|
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 {
|
|
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((
|
|
309
|
-
setTimeout(
|
|
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
|
|
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
|
|
687
|
+
if (!truthyEnvValue(ownEnvironmentValue(env, "PI_WEB_DOCKER_RUNTIME")))
|
|
683
688
|
return undefined;
|
|
684
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
792
|
-
|
|
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
|
-
|
|
886
|
-
|
|
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
|
-
|
|
899
|
-
|
|
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(
|
|
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
|
-
|
|
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 (
|
|
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 === "
|
|
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")
|