@chainingintention/pi-web-cn 2.0.0 → 2.202610.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (584) hide show
  1. package/README.md +61 -106
  2. package/dist/.plugins-ready +1 -0
  3. package/dist/cli.js +331 -174
  4. package/dist/cli.js.map +1 -1
  5. package/dist/client/apple-touch-icon-dev.png +0 -0
  6. package/dist/client/assets/PiWebApp-vueV4eKR.js +4938 -0
  7. package/dist/client/assets/classic-CyM97Akm.css +54 -0
  8. package/dist/client/assets/external-B9K8duyP.js +2 -0
  9. package/dist/client/assets/graphite-DquaqFXU.css +54 -0
  10. package/dist/client/assets/index-C8f0d0CR.js +2 -0
  11. package/dist/client/assets/paper-CB1oLuRr.css +54 -0
  12. package/dist/client/assets/pi-web-dark-D_KtbM95.css +54 -0
  13. package/dist/client/assets/pi-web-light-DSNLMIBI.css +54 -0
  14. package/dist/client/assets/vendor-editor-core-BfnHL1Dg.js +10 -0
  15. package/dist/client/assets/vendor-editor-languages-bNquDJP0.js +28 -0
  16. package/dist/client/favicon-dev.svg +8 -0
  17. package/dist/client/index.html +7 -51
  18. package/dist/client/manifest.webmanifest +2 -1
  19. package/dist/client/pwa-icon-dev-192.png +0 -0
  20. package/dist/client/pwa-icon-dev-512.png +0 -0
  21. package/dist/config.js +55 -8
  22. package/dist/config.js.map +1 -1
  23. package/dist/docker/piWebDockerCommandPlan.js +13 -4
  24. package/dist/docker/piWebDockerCommandPlan.js.map +1 -1
  25. package/dist/environment.js +4 -0
  26. package/dist/environment.js.map +1 -0
  27. package/dist/localization.js +24 -0
  28. package/dist/localization.js.map +1 -0
  29. package/dist/nativeServices/installedServiceDefinitions.js +617 -0
  30. package/dist/nativeServices/installedServiceDefinitions.js.map +1 -0
  31. package/dist/nativeServices/serviceAction.js +78 -20
  32. package/dist/nativeServices/serviceAction.js.map +1 -1
  33. package/dist/nativeServices/serviceDoctor.js +418 -114
  34. package/dist/nativeServices/serviceDoctor.js.map +1 -1
  35. package/dist/nativeServices/servicePlan.js +2 -2
  36. package/dist/nativeServices/servicePlan.js.map +1 -1
  37. package/dist/pi-packages/captains-log/README.md +11 -0
  38. package/dist/pi-packages/captains-log/dist/browser/channelProtocol.js +29 -0
  39. package/dist/pi-packages/captains-log/dist/browser/index.js +143 -0
  40. package/dist/pi-packages/captains-log/dist/browser/markdown.js +68 -0
  41. package/dist/pi-packages/captains-log/dist/browser/panel.js +148 -0
  42. package/dist/pi-packages/captains-log/dist/browser/protocol.js +26 -0
  43. package/dist/pi-packages/captains-log/dist/companion.js +126 -0
  44. package/dist/pi-packages/captains-log/dist/roundtrip.js +62 -0
  45. package/dist/pi-packages/captains-log/dist/server.js +210 -0
  46. package/dist/pi-packages/captains-log/dist/store.js +75 -0
  47. package/dist/pi-packages/captains-log/docs/usage.md +29 -0
  48. package/dist/pi-packages/captains-log/i18n.js +7 -0
  49. package/dist/pi-packages/captains-log/package.json +35 -0
  50. package/dist/pi-packages/captains-log/tsconfig.json +21 -0
  51. package/dist/pi-packages/captains-log/vite.config.mjs +28 -0
  52. package/dist/pi-packages/relays/extensions/index.js +61 -0
  53. package/dist/pi-packages/relays/i18n.js +7 -0
  54. package/dist/{pi-web-plugins → pi-packages}/relays/markdownDocument.js +3 -2
  55. package/dist/pi-packages/relays/package.json +20 -0
  56. package/dist/pi-packages/relays/pi-web-plugin.js +96 -0
  57. package/dist/pi-packages/relays/prompts/relay-worktree.md +18 -0
  58. package/dist/pi-packages/relays/prompts/relay.md +18 -0
  59. package/dist/{pi-web-plugins → pi-packages}/relays/relayDiscovery.js +2 -2
  60. package/dist/pi-packages/relays/relayDispatch.js +67 -0
  61. package/dist/pi-packages/relays/relayIdentity.js +37 -0
  62. package/dist/{pi-web-plugins → pi-packages}/relays/relaysPanelElement.js +98 -59
  63. package/dist/pi-packages/relays/skills/relay/SKILL.md +50 -0
  64. package/dist/pi-packages/relays/skills/relay-runner/SKILL.md +74 -0
  65. package/dist/pi-packages/workflows/browser/pi-web-plugin.js +42 -0
  66. package/dist/pi-packages/workflows/browser/worktreeDialog.js +170 -0
  67. package/dist/pi-packages/workflows/package.json +23 -0
  68. package/dist/pi-packages/workflows/prompts/worktree.md +21 -0
  69. package/dist/pi-packages/workflows/server-plugin.js +586 -0
  70. package/dist/pi-packages/workflows/vite.config.mjs +17 -0
  71. package/dist/pi-web-plugins/code-highlight/browser/pi-web-plugin.js +22 -0
  72. package/dist/pi-web-plugins/code-highlight/package.json +13 -0
  73. package/dist/pi-web-plugins/files/browser/assets/files-icon-DZObYhxb.svg +3 -0
  74. package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +466 -0
  75. package/dist/pi-web-plugins/files/package.json +15 -0
  76. package/dist/pi-web-plugins/git/browser/git-contract.js +22 -11
  77. package/dist/pi-web-plugins/git/browser/git-panel.js +228 -100
  78. package/dist/pi-web-plugins/git/browser/i18n.js +7 -0
  79. package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +28 -4
  80. package/dist/pi-web-plugins/git/git-backend.js +61 -21
  81. package/dist/pi-web-plugins/git/gitStatusCache.js +48 -0
  82. package/dist/pi-web-plugins/git/i18n.js +7 -0
  83. package/dist/pi-web-plugins/git/package.json +1 -0
  84. package/dist/pi-web-plugins/git/server-plugin.js +45 -24
  85. package/dist/pi-web-plugins/git/workspace-discovery-notify.cjs +14 -0
  86. package/dist/pi-web-plugins/git/workspaceDiscoveryHooks.js +186 -0
  87. package/dist/pi-web-plugins/info/i18n.js +7 -0
  88. package/dist/pi-web-plugins/info/infoInternals.js +76 -65
  89. package/dist/pi-web-plugins/info/package.json +1 -1
  90. package/dist/pi-web-plugins/info/pi-web-plugin.js +40 -42
  91. package/dist/pi-web-plugins/mermaid/browser/mermaid-engine.js +4255 -0
  92. package/dist/pi-web-plugins/mermaid/browser/pi-web-plugin.js +11 -0
  93. package/dist/pi-web-plugins/mermaid/package.json +13 -0
  94. package/dist/pi-web-plugins/terminal/browser/pi-web-plugin.js +219 -0
  95. package/dist/pi-web-plugins/terminal/i18n.js +7 -0
  96. package/dist/pi-web-plugins/terminal/package.json +16 -0
  97. package/dist/pi-web-plugins/terminal/server-plugin.js +367 -0
  98. package/dist/pi-web-plugins/terminal/terminalService.js +436 -0
  99. package/dist/pi-web-plugins/updates/i18n.js +7 -0
  100. package/dist/pi-web-plugins/updates/package.json +1 -1
  101. package/dist/pi-web-plugins/updates/pi-web-plugin.js +143 -140
  102. package/dist/pi-web-plugins/updates/updatesLogic.js +24 -24
  103. package/dist/pi-web-plugins/workspace-tasks/config.js +12 -11
  104. package/dist/pi-web-plugins/workspace-tasks/i18n.js +7 -0
  105. package/dist/pi-web-plugins/workspace-tasks/package.json +1 -1
  106. package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +31 -9
  107. package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +54 -36
  108. package/dist/pi-web-plugins/workspace-tasks/workspaceTasksClient.js +12 -11
  109. package/dist/pi-web-plugins/zh-cn/auth.json +9 -0
  110. package/dist/pi-web-plugins/zh-cn/bundled.json +219 -0
  111. package/dist/pi-web-plugins/zh-cn/cli.json +230 -0
  112. package/dist/pi-web-plugins/zh-cn/client.json +225 -0
  113. package/dist/pi-web-plugins/zh-cn/components.json +1252 -0
  114. package/dist/pi-web-plugins/zh-cn/config-errors.json +188 -0
  115. package/dist/pi-web-plugins/zh-cn/files.json +50 -0
  116. package/dist/pi-web-plugins/zh-cn/machines.json +28 -0
  117. package/dist/pi-web-plugins/zh-cn/main.json +459 -0
  118. package/dist/pi-web-plugins/zh-cn/management-errors.json +23 -0
  119. package/dist/pi-web-plugins/zh-cn/manifest.webmanifest +25 -0
  120. package/dist/pi-web-plugins/zh-cn/metadata.json +3 -0
  121. package/dist/pi-web-plugins/zh-cn/package.json +10 -0
  122. package/dist/pi-web-plugins/zh-cn/pi-web-plugin.js +16 -0
  123. package/dist/pi-web-plugins/zh-cn/projects.json +6 -0
  124. package/dist/pi-web-plugins/zh-cn/provider-auth.json +18 -0
  125. package/dist/pi-web-plugins/zh-cn/routing.json +68 -0
  126. package/dist/pi-web-plugins/zh-cn/server-main.json +99 -0
  127. package/dist/pi-web-plugins/zh-cn/server.json +256 -0
  128. package/dist/piAi.js +4 -0
  129. package/dist/piAi.js.map +1 -0
  130. package/dist/piRuntime.js +150 -0
  131. package/dist/piRuntime.js.map +1 -0
  132. package/dist/piSdk.js +5 -0
  133. package/dist/piSdk.js.map +1 -0
  134. package/dist/piWebUpdate.js +508 -0
  135. package/dist/piWebUpdate.js.map +1 -0
  136. package/dist/piWebVersionReport.js +109 -41
  137. package/dist/piWebVersionReport.js.map +1 -1
  138. package/dist/plugin-api.d.ts +609 -29
  139. package/dist/plugin-api.js +1 -0
  140. package/dist/pluginRecoveryCli.js +27 -25
  141. package/dist/pluginRecoveryCli.js.map +1 -1
  142. package/dist/server/activity/workspaceActivityService.js +13 -6
  143. package/dist/server/activity/workspaceActivityService.js.map +1 -1
  144. package/dist/server/app.js +158 -89
  145. package/dist/server/app.js.map +1 -1
  146. package/dist/server/audit/managementAuditStore.js +6 -1
  147. package/dist/server/audit/managementAuditStore.js.map +1 -1
  148. package/dist/server/audit/normalToolAuditCli.js +45 -43
  149. package/dist/server/audit/normalToolAuditCli.js.map +1 -1
  150. package/dist/server/browserMessageProjection.js +39 -22
  151. package/dist/server/browserMessageProjection.js.map +1 -1
  152. package/dist/server/configRoutes.js +54 -33
  153. package/dist/server/configRoutes.js.map +1 -1
  154. package/dist/server/deploymentIdentity.js +67 -0
  155. package/dist/server/deploymentIdentity.js.map +1 -0
  156. package/dist/server/deploymentIdentityRoutes.js +22 -0
  157. package/dist/server/deploymentIdentityRoutes.js.map +1 -0
  158. package/dist/server/diagnostics/nodePtyNativeModule.js +7 -6
  159. package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -1
  160. package/dist/server/diagnostics/nodePtySpawnHelper.js +21 -20
  161. package/dist/server/diagnostics/nodePtySpawnHelper.js.map +1 -1
  162. package/dist/server/index.js +10 -1
  163. package/dist/server/index.js.map +1 -1
  164. package/dist/server/knownAutoInstallPiPackages.js +36 -0
  165. package/dist/server/knownAutoInstallPiPackages.js.map +1 -0
  166. package/dist/server/knownPiPackages.js +12 -0
  167. package/dist/server/knownPiPackages.js.map +1 -0
  168. package/dist/server/machines/machineClient.js +23 -19
  169. package/dist/server/machines/machineClient.js.map +1 -1
  170. package/dist/server/machines/machinePluginProxyRoutes.js +131 -31
  171. package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
  172. package/dist/server/machines/machineProxyRoutes.js +138 -47
  173. package/dist/server/machines/machineProxyRoutes.js.map +1 -1
  174. package/dist/server/machines/machineRoutes.js +18 -13
  175. package/dist/server/machines/machineRoutes.js.map +1 -1
  176. package/dist/server/machines/machineService.js +40 -18
  177. package/dist/server/machines/machineService.js.map +1 -1
  178. package/dist/server/managementEmbed.js +149 -30
  179. package/dist/server/managementEmbed.js.map +1 -1
  180. package/dist/server/managementPrivileges.js +21 -0
  181. package/dist/server/managementPrivileges.js.map +1 -0
  182. package/dist/server/managementTerminalProxyRoutes.js +124 -0
  183. package/dist/server/managementTerminalProxyRoutes.js.map +1 -0
  184. package/dist/server/navigationPreferenceRoutes.js +59 -0
  185. package/dist/server/navigationPreferenceRoutes.js.map +1 -0
  186. package/dist/server/normalAuth.js +77 -53
  187. package/dist/server/normalAuth.js.map +1 -1
  188. package/dist/server/notices/serverNoticeRoutes.js +43 -0
  189. package/dist/server/notices/serverNoticeRoutes.js.map +1 -0
  190. package/dist/server/notices/serverNoticeService.js +26 -0
  191. package/dist/server/notices/serverNoticeService.js.map +1 -0
  192. package/dist/server/notices/serverNoticeStore.js +122 -0
  193. package/dist/server/notices/serverNoticeStore.js.map +1 -0
  194. package/dist/server/passwordVerifier.js +91 -0
  195. package/dist/server/passwordVerifier.js.map +1 -0
  196. package/dist/server/piPackageIdentity.js +25 -0
  197. package/dist/server/piPackageIdentity.js.map +1 -0
  198. package/dist/server/piPackageService.js +72 -9
  199. package/dist/server/piPackageService.js.map +1 -1
  200. package/dist/server/piWebPluginCatalog.js +212 -35
  201. package/dist/server/piWebPluginCatalog.js.map +1 -1
  202. package/dist/server/piWebPluginLifecycle.js +29 -3
  203. package/dist/server/piWebPluginLifecycle.js.map +1 -1
  204. package/dist/server/piWebPluginService.js +199 -292
  205. package/dist/server/piWebPluginService.js.map +1 -1
  206. package/dist/server/piWebStatus.js +57 -100
  207. package/dist/server/piWebStatus.js.map +1 -1
  208. package/dist/server/pluginCallbackDrain.js +35 -0
  209. package/dist/server/pluginCallbackDrain.js.map +1 -0
  210. package/dist/server/plugins/pluginBackendChannelProxyAdmission.js +84 -0
  211. package/dist/server/plugins/pluginBackendChannelProxyAdmission.js.map +1 -0
  212. package/dist/server/plugins/pluginBackendChannelProxyCoordinator.js +234 -0
  213. package/dist/server/plugins/pluginBackendChannelProxyCoordinator.js.map +1 -0
  214. package/dist/server/plugins/pluginBackendChannelProxyRoutes.js +61 -0
  215. package/dist/server/plugins/pluginBackendChannelProxyRoutes.js.map +1 -0
  216. package/dist/server/plugins/pluginBackendProxyRoutes.js +47 -57
  217. package/dist/server/plugins/pluginBackendProxyRoutes.js.map +1 -1
  218. package/dist/server/plugins/pluginBackendRegistry.js +804 -0
  219. package/dist/server/plugins/pluginBackendRegistry.js.map +1 -0
  220. package/dist/server/plugins/projectPluginSettings.js +95 -0
  221. package/dist/server/plugins/projectPluginSettings.js.map +1 -0
  222. package/dist/server/plugins/serverPluginCatalogCapability.js +106 -0
  223. package/dist/server/plugins/serverPluginCatalogCapability.js.map +1 -0
  224. package/dist/server/plugins/serverPluginPiSessionEventsCapability.js +34 -0
  225. package/dist/server/plugins/serverPluginPiSessionEventsCapability.js.map +1 -0
  226. package/dist/server/plugins/serverPluginPiSessionsCapability.js +185 -0
  227. package/dist/server/plugins/serverPluginPiSessionsCapability.js.map +1 -0
  228. package/dist/server/plugins/serverPluginRuntime.js +1088 -108
  229. package/dist/server/plugins/serverPluginRuntime.js.map +1 -1
  230. package/dist/server/plugins/serverPluginWorkspacesCapability.js +114 -0
  231. package/dist/server/plugins/serverPluginWorkspacesCapability.js.map +1 -0
  232. package/dist/server/projectTrustRoutes.js +86 -0
  233. package/dist/server/projectTrustRoutes.js.map +1 -0
  234. package/dist/server/projects/projectLifecycleService.js +94 -0
  235. package/dist/server/projects/projectLifecycleService.js.map +1 -0
  236. package/dist/server/projects/projectService.js +7 -4
  237. package/dist/server/projects/projectService.js.map +1 -1
  238. package/dist/server/realtime/sessionEventHub.js +58 -39
  239. package/dist/server/realtime/sessionEventHub.js.map +1 -1
  240. package/dist/server/realtime/sessionEventScope.js +4 -0
  241. package/dist/server/realtime/sessionEventScope.js.map +1 -1
  242. package/dist/server/requestCancellation.js +15 -1
  243. package/dist/server/requestCancellation.js.map +1 -1
  244. package/dist/server/sessiond/agentHttpDispatcher.js +108 -0
  245. package/dist/server/sessiond/agentHttpDispatcher.js.map +1 -0
  246. package/dist/server/sessiond/autoInstallPiPackages.js +63 -0
  247. package/dist/server/sessiond/autoInstallPiPackages.js.map +1 -0
  248. package/dist/server/sessiond/pluginBackendChannelRoutes.js +410 -0
  249. package/dist/server/sessiond/pluginBackendChannelRoutes.js.map +1 -0
  250. package/dist/server/sessiond/pluginBackendRoutes.js +64 -47
  251. package/dist/server/sessiond/pluginBackendRoutes.js.map +1 -1
  252. package/dist/server/sessiond/pluginCatalogRoutes.js +41 -0
  253. package/dist/server/sessiond/pluginCatalogRoutes.js.map +1 -0
  254. package/dist/server/sessiond/projectMutationRoutes.js +39 -0
  255. package/dist/server/sessiond/projectMutationRoutes.js.map +1 -0
  256. package/dist/server/sessiond/sessionDaemonShutdown.js +36 -0
  257. package/dist/server/sessiond/sessionDaemonShutdown.js.map +1 -0
  258. package/dist/server/sessiond/sessionDaemonStartup.js +30 -4
  259. package/dist/server/sessiond/sessionDaemonStartup.js.map +1 -1
  260. package/dist/server/sessiond/sessionProxyRoutes.js +263 -91
  261. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
  262. package/dist/server/sessiond/sessionServiceDependencies.js +5 -0
  263. package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -1
  264. package/dist/server/sessiond/sessiondStateOwnership.js +174 -39
  265. package/dist/server/sessiond/sessiondStateOwnership.js.map +1 -1
  266. package/dist/server/sessiond/workspaceCatalogRoutes.js +11 -5
  267. package/dist/server/sessiond/workspaceCatalogRoutes.js.map +1 -1
  268. package/dist/server/sessiond/workspaceNotificationRoutes.js +55 -0
  269. package/dist/server/sessiond/workspaceNotificationRoutes.js.map +1 -0
  270. package/dist/server/sessiond/workspaceRemovalRoutes.js +1 -1
  271. package/dist/server/sessiond/workspaceRemovalRoutes.js.map +1 -1
  272. package/dist/server/sessiond.js +313 -69
  273. package/dist/server/sessiond.js.map +1 -1
  274. package/dist/server/sessions/askUserDomain.js +232 -0
  275. package/dist/server/sessions/askUserDomain.js.map +1 -0
  276. package/dist/server/sessions/askUserTool.js +18 -21
  277. package/dist/server/sessions/askUserTool.js.map +1 -1
  278. package/dist/server/sessions/attachmentService.js +2 -6
  279. package/dist/server/sessions/attachmentService.js.map +1 -1
  280. package/dist/server/sessions/authRoutes.js +32 -19
  281. package/dist/server/sessions/authRoutes.js.map +1 -1
  282. package/dist/server/sessions/authService.js +31 -11
  283. package/dist/server/sessions/authService.js.map +1 -1
  284. package/dist/server/sessions/builtinCommands.js +28 -21
  285. package/dist/server/sessions/builtinCommands.js.map +1 -1
  286. package/dist/server/sessions/builtinExtensionFactories.js +36 -0
  287. package/dist/server/sessions/builtinExtensionFactories.js.map +1 -0
  288. package/dist/server/sessions/clientSessionPreview.js +14 -0
  289. package/dist/server/sessions/clientSessionPreview.js.map +1 -0
  290. package/dist/server/sessions/companionBackend.js +286 -0
  291. package/dist/server/sessions/companionBackend.js.map +1 -0
  292. package/dist/server/sessions/dockerEnvironmentFacts.js +98 -10
  293. package/dist/server/sessions/dockerEnvironmentFacts.js.map +1 -1
  294. package/dist/server/sessions/extensionSessionDispatch.js +76 -0
  295. package/dist/server/sessions/extensionSessionDispatch.js.map +1 -0
  296. package/dist/server/sessions/globalProviderPolicy.js +88 -19
  297. package/dist/server/sessions/globalProviderPolicy.js.map +1 -1
  298. package/dist/server/sessions/managementAgentTools.js +116 -6
  299. package/dist/server/sessions/managementAgentTools.js.map +1 -1
  300. package/dist/server/sessions/managementPermissionSystem.js +36 -14
  301. package/dist/server/sessions/managementPermissionSystem.js.map +1 -1
  302. package/dist/server/sessions/managementSandbox.js +7 -18
  303. package/dist/server/sessions/managementSandbox.js.map +1 -1
  304. package/dist/server/sessions/mcpAuthFlowService.js +289 -0
  305. package/dist/server/sessions/mcpAuthFlowService.js.map +1 -0
  306. package/dist/server/sessions/mcpAuthRoutes.js +104 -0
  307. package/dist/server/sessions/mcpAuthRoutes.js.map +1 -0
  308. package/dist/server/sessions/mcpOAuthCredentialAdapter.js +92 -0
  309. package/dist/server/sessions/mcpOAuthCredentialAdapter.js.map +1 -0
  310. package/dist/server/sessions/messageHistoryTarget.js +79 -0
  311. package/dist/server/sessions/messageHistoryTarget.js.map +1 -0
  312. package/dist/server/sessions/messagePaging.js +2 -2
  313. package/dist/server/sessions/messagePaging.js.map +1 -1
  314. package/dist/server/sessions/modelCatalogRefresher.js +4 -3
  315. package/dist/server/sessions/modelCatalogRefresher.js.map +1 -1
  316. package/dist/server/sessions/oauthLoginFlowService.js +19 -20
  317. package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
  318. package/dist/server/sessions/piSessionEventConnections.js +68 -0
  319. package/dist/server/sessions/piSessionEventConnections.js.map +1 -0
  320. package/dist/server/sessions/piSessionManagerGateway.js +206 -27
  321. package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
  322. package/dist/server/sessions/piSessionService.js +2508 -991
  323. package/dist/server/sessions/piSessionService.js.map +1 -1
  324. package/dist/server/sessions/plainTextTheme.js +1 -1
  325. package/dist/server/sessions/plainTextTheme.js.map +1 -1
  326. package/dist/server/sessions/projectAuthService.js +35 -6
  327. package/dist/server/sessions/projectAuthService.js.map +1 -1
  328. package/dist/server/sessions/projectSettingsScope.js +88 -33
  329. package/dist/server/sessions/projectSettingsScope.js.map +1 -1
  330. package/dist/server/sessions/projectTrust.js +119 -0
  331. package/dist/server/sessions/projectTrust.js.map +1 -0
  332. package/dist/server/sessions/queuedMessageMutation.js +170 -0
  333. package/dist/server/sessions/queuedMessageMutation.js.map +1 -0
  334. package/dist/server/sessions/relaySkill.js +169 -0
  335. package/dist/server/sessions/relaySkill.js.map +1 -0
  336. package/dist/server/sessions/sessionActivityMarker.js +105 -0
  337. package/dist/server/sessions/sessionActivityMarker.js.map +1 -0
  338. package/dist/server/sessions/sessionArchiveMapping.js +16 -15
  339. package/dist/server/sessions/sessionArchiveMapping.js.map +1 -1
  340. package/dist/server/sessions/sessionArchiveStore.js +5 -1
  341. package/dist/server/sessions/sessionArchiveStore.js.map +1 -1
  342. package/dist/server/sessions/sessionArchiveTree.js +2 -2
  343. package/dist/server/sessions/sessionArchiveTree.js.map +1 -1
  344. package/dist/server/sessions/sessionCleanup.js +4 -3
  345. package/dist/server/sessions/sessionCleanup.js.map +1 -1
  346. package/dist/server/sessions/sessionCommandService.js +79 -87
  347. package/dist/server/sessions/sessionCommandService.js.map +1 -1
  348. package/dist/server/sessions/sessionEnvironmentFacts.js +5 -4
  349. package/dist/server/sessions/sessionEnvironmentFacts.js.map +1 -1
  350. package/dist/server/sessions/sessionFileHeader.js +41 -0
  351. package/dist/server/sessions/sessionFileHeader.js.map +1 -1
  352. package/dist/server/sessions/sessionImageDimensions.js +31 -0
  353. package/dist/server/sessions/sessionImageDimensions.js.map +1 -0
  354. package/dist/server/sessions/sessionMediaIndex.js +191 -0
  355. package/dist/server/sessions/sessionMediaIndex.js.map +1 -0
  356. package/dist/server/sessions/sessionMetadata.js +51 -0
  357. package/dist/server/sessions/sessionMetadata.js.map +1 -0
  358. package/dist/server/sessions/sessionModelScope.js +160 -0
  359. package/dist/server/sessions/sessionModelScope.js.map +1 -0
  360. package/dist/server/sessions/sessionNameGenerator.js +16 -35
  361. package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
  362. package/dist/server/sessions/sessionNotificationStore.js +14 -11
  363. package/dist/server/sessions/sessionNotificationStore.js.map +1 -1
  364. package/dist/server/sessions/sessionReadAccess.js +41 -0
  365. package/dist/server/sessions/sessionReadAccess.js.map +1 -0
  366. package/dist/server/sessions/sessionRoutes.js +221 -78
  367. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  368. package/dist/server/sessions/sessionSummaryScanner.js +62 -5
  369. package/dist/server/sessions/sessionSummaryScanner.js.map +1 -1
  370. package/dist/server/sessions/sessionTreeProjection.js +50 -49
  371. package/dist/server/sessions/sessionTreeProjection.js.map +1 -1
  372. package/dist/server/sessions/sessionUiEvents.js +22 -10
  373. package/dist/server/sessions/sessionUiEvents.js.map +1 -1
  374. package/dist/server/sessions/sessionUnreadStore.js +53 -3
  375. package/dist/server/sessions/sessionUnreadStore.js.map +1 -1
  376. package/dist/server/sessions/spawnSessionTool.js +14 -6
  377. package/dist/server/sessions/spawnSessionTool.js.map +1 -1
  378. package/dist/server/sessions/spawnSubsessionTool.js +40 -24
  379. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
  380. package/dist/server/sessions/spawnTargetResolver.js +1 -1
  381. package/dist/server/sessions/subsessionCompletionDelivery.js +15 -0
  382. package/dist/server/sessions/subsessionCompletionDelivery.js.map +1 -0
  383. package/dist/server/sessions/subsessionCompletionInbox.js +134 -0
  384. package/dist/server/sessions/subsessionCompletionInbox.js.map +1 -0
  385. package/dist/server/sessions/subsessionProvenance.js +27 -0
  386. package/dist/server/sessions/subsessionProvenance.js.map +1 -0
  387. package/dist/server/sessions/transcriptBranchCache.js +81 -0
  388. package/dist/server/sessions/transcriptBranchCache.js.map +1 -0
  389. package/dist/server/sessions/transcriptMarkdown.js +48 -0
  390. package/dist/server/sessions/transcriptMarkdown.js.map +1 -0
  391. package/dist/server/sessions/transcriptMessages.js +57 -0
  392. package/dist/server/sessions/transcriptMessages.js.map +1 -0
  393. package/dist/server/startupLogger.js +13 -0
  394. package/dist/server/startupLogger.js.map +1 -0
  395. package/dist/server/startupUrls.js +27 -0
  396. package/dist/server/startupUrls.js.map +1 -0
  397. package/dist/server/status/machineStatusService.js +15 -7
  398. package/dist/server/status/machineStatusService.js.map +1 -1
  399. package/dist/server/storage/navigationPreferenceStore.js +138 -0
  400. package/dist/server/storage/navigationPreferenceStore.js.map +1 -0
  401. package/dist/server/storage/piPackageDismissalStore.js +78 -0
  402. package/dist/server/storage/piPackageDismissalStore.js.map +1 -0
  403. package/dist/server/terminals/{terminalService.js → managementCommandRunService.js} +98 -102
  404. package/dist/server/terminals/managementCommandRunService.js.map +1 -0
  405. package/dist/server/terminals/managementTerminalRoutes.js +91 -0
  406. package/dist/server/terminals/managementTerminalRoutes.js.map +1 -0
  407. package/dist/server/terminals/requiredTerminalService.js +103 -0
  408. package/dist/server/terminals/requiredTerminalService.js.map +1 -0
  409. package/dist/server/webSocketBridge.js +348 -0
  410. package/dist/server/webSocketBridge.js.map +1 -1
  411. package/dist/server/workbench/accessStateStore.js +33 -5
  412. package/dist/server/workbench/accessStateStore.js.map +1 -1
  413. package/dist/server/workbench/capabilitySearch.js +3 -2
  414. package/dist/server/workbench/capabilitySearch.js.map +1 -1
  415. package/dist/server/workbench/gatewayIntegration.js +40 -13
  416. package/dist/server/workbench/gatewayIntegration.js.map +1 -1
  417. package/dist/server/workbench/knowledgeSearch.js +100 -0
  418. package/dist/server/workbench/knowledgeSearch.js.map +1 -0
  419. package/dist/server/workbench/mcpClient.js +41 -8
  420. package/dist/server/workbench/mcpClient.js.map +1 -1
  421. package/dist/server/workbench/skillSync.js +11 -3
  422. package/dist/server/workbench/skillSync.js.map +1 -1
  423. package/dist/server/workbench/workbenchClient.js +130 -7
  424. package/dist/server/workbench/workbenchClient.js.map +1 -1
  425. package/dist/server/workbench/workbenchTools.js +196 -14
  426. package/dist/server/workbench/workbenchTools.js.map +1 -1
  427. package/dist/server/workingDirectory.js +3 -2
  428. package/dist/server/workingDirectory.js.map +1 -1
  429. package/dist/server/workspaceExplorerRoutes.js +53 -21
  430. package/dist/server/workspaceExplorerRoutes.js.map +1 -1
  431. package/dist/server/workspaces/fileContentService.js +31 -16
  432. package/dist/server/workspaces/fileContentService.js.map +1 -1
  433. package/dist/server/workspaces/fileOperationService.js +11 -9
  434. package/dist/server/workspaces/fileOperationService.js.map +1 -1
  435. package/dist/server/workspaces/filePreviewService.js +10 -6
  436. package/dist/server/workspaces/filePreviewService.js.map +1 -1
  437. package/dist/server/workspaces/fileSuggestions.js +77 -10
  438. package/dist/server/workspaces/fileSuggestions.js.map +1 -1
  439. package/dist/server/workspaces/fileTreeService.js +103 -15
  440. package/dist/server/workspaces/fileTreeService.js.map +1 -1
  441. package/dist/server/workspaces/normalProjectCwdResolver.js +35 -0
  442. package/dist/server/workspaces/normalProjectCwdResolver.js.map +1 -0
  443. package/dist/server/workspaces/pathAccessPolicy.js +24 -18
  444. package/dist/server/workspaces/pathAccessPolicy.js.map +1 -1
  445. package/dist/server/workspaces/pathSafety.js +6 -5
  446. package/dist/server/workspaces/pathSafety.js.map +1 -1
  447. package/dist/server/workspaces/projectPiWebConfig.js +95 -8
  448. package/dist/server/workspaces/projectPiWebConfig.js.map +1 -1
  449. package/dist/server/workspaces/projectWorkspaceCwds.js +0 -5
  450. package/dist/server/workspaces/projectWorkspaceCwds.js.map +1 -1
  451. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js +37 -22
  452. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js.map +1 -1
  453. package/dist/server/workspaces/workspaceCatalog.js +6 -4
  454. package/dist/server/workspaces/workspaceCatalog.js.map +1 -1
  455. package/dist/server/workspaces/workspaceChangeNotifier.js +12 -0
  456. package/dist/server/workspaces/workspaceChangeNotifier.js.map +1 -0
  457. package/dist/server/workspaces/workspaceDeletionRoutes.js +9 -70
  458. package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -1
  459. package/dist/server/workspaces/workspaceNotificationCommand.js +64 -0
  460. package/dist/server/workspaces/workspaceNotificationCommand.js.map +1 -0
  461. package/dist/server/workspaces/workspaceProviderRegistry.js +128 -24
  462. package/dist/server/workspaces/workspaceProviderRegistry.js.map +1 -1
  463. package/dist/server/workspaces/workspaceRemovalService.js +41 -7
  464. package/dist/server/workspaces/workspaceRemovalService.js.map +1 -1
  465. package/dist/server/workspaces/workspaceRouteContext.js +1 -1
  466. package/dist/server/workspaces/workspaceRouteContext.js.map +1 -1
  467. package/dist/server/workspaces/workspaceRouteErrors.js +4 -2
  468. package/dist/server/workspaces/workspaceRouteErrors.js.map +1 -1
  469. package/dist/server/workspaces/workspaceUserError.js +18 -0
  470. package/dist/server/workspaces/workspaceUserError.js.map +1 -0
  471. package/dist/server-plugin-api.d.ts +349 -49
  472. package/dist/server-plugin-api.js +344 -2
  473. package/dist/server-plugin-api.js.map +1 -1
  474. package/dist/serverPluginRecovery.js +6 -1
  475. package/dist/serverPluginRecovery.js.map +1 -1
  476. package/dist/sessiond/activeAgentProfile.js +27 -2
  477. package/dist/sessiond/activeAgentProfile.js.map +1 -1
  478. package/dist/sessiond/config.js +4 -3
  479. package/dist/sessiond/config.js.map +1 -1
  480. package/dist/sessiond/sessionDaemonClient.js +75 -19
  481. package/dist/sessiond/sessionDaemonClient.js.map +1 -1
  482. package/dist/sessiond/sessionDaemonErrors.js +49 -0
  483. package/dist/sessiond/sessionDaemonErrors.js.map +1 -0
  484. package/dist/shared/activeAgentProfile.js +2 -34
  485. package/dist/shared/activeAgentProfile.js.map +1 -1
  486. package/dist/shared/activity.js +0 -3
  487. package/dist/shared/activity.js.map +1 -1
  488. package/dist/shared/apiTypes.js +10 -3
  489. package/dist/shared/apiTypes.js.map +1 -1
  490. package/dist/shared/capabilities.js +8 -0
  491. package/dist/shared/capabilities.js.map +1 -1
  492. package/dist/shared/federatedRoutes.js +77 -11
  493. package/dist/shared/federatedRoutes.js.map +1 -1
  494. package/dist/shared/i18n.js +41 -0
  495. package/dist/shared/i18n.js.map +1 -0
  496. package/dist/shared/machinePluginIds.js +30 -7
  497. package/dist/shared/machinePluginIds.js.map +1 -1
  498. package/dist/shared/machineStatus.js +46 -3
  499. package/dist/shared/machineStatus.js.map +1 -1
  500. package/dist/shared/navigationPreferences.js +6 -0
  501. package/dist/shared/navigationPreferences.js.map +1 -0
  502. package/dist/shared/piWebConfigParsing.js +118 -49
  503. package/dist/shared/piWebConfigParsing.js.map +1 -1
  504. package/dist/shared/piWebStatusParsing.js +33 -0
  505. package/dist/shared/piWebStatusParsing.js.map +1 -1
  506. package/dist/shared/pluginApiTypes.d.ts +87 -8
  507. package/dist/shared/pluginApiTypes.js +2 -0
  508. package/dist/shared/pluginApiTypes.js.map +1 -0
  509. package/dist/shared/pluginBackendProtocol.js +218 -2
  510. package/dist/shared/pluginBackendProtocol.js.map +1 -1
  511. package/dist/shared/pluginCatalogTypes.d.ts +49 -0
  512. package/dist/shared/pluginCatalogTypes.js +156 -0
  513. package/dist/shared/pluginCatalogTypes.js.map +1 -0
  514. package/dist/shared/pluginIds.js +10 -1
  515. package/dist/shared/pluginIds.js.map +1 -1
  516. package/dist/shared/requiredTerminalPlugin.js +6 -0
  517. package/dist/shared/requiredTerminalPlugin.js.map +1 -0
  518. package/dist/shared/serverNoticeContract.js +88 -0
  519. package/dist/shared/serverNoticeContract.js.map +1 -0
  520. package/dist/shared/sessionDefaults.js +42 -0
  521. package/dist/shared/sessionDefaults.js.map +1 -0
  522. package/dist/shared/sessionMedia.js +12 -0
  523. package/dist/shared/sessionMedia.js.map +1 -0
  524. package/dist/shared/streamingBehavior.js +8 -0
  525. package/dist/shared/streamingBehavior.js.map +1 -0
  526. package/dist/shared/themePreference.js +24 -0
  527. package/dist/shared/themePreference.js.map +1 -0
  528. package/dist/shared/thinkingLevels.js +17 -16
  529. package/dist/shared/thinkingLevels.js.map +1 -1
  530. package/dist/shared/workspaceFiles.js.map +1 -1
  531. package/dist/workspaceNotificationCli.js +95 -0
  532. package/dist/workspaceNotificationCli.js.map +1 -0
  533. package/docs/README.md +31 -0
  534. package/docs/config.md +344 -277
  535. package/docs/plugins.md +204 -930
  536. package/examples/session-bridge-plugin/README.md +20 -0
  537. package/examples/session-bridge-plugin/docs/usage.md +54 -0
  538. package/examples/session-bridge-plugin/package.json +26 -0
  539. package/examples/session-bridge-plugin/src/browser/index.ts +87 -0
  540. package/examples/session-bridge-plugin/src/browser/protocol.ts +24 -0
  541. package/examples/session-bridge-plugin/src/companion.ts +65 -0
  542. package/examples/session-bridge-plugin/src/reviewRun.ts +39 -0
  543. package/examples/session-bridge-plugin/src/server.ts +85 -0
  544. package/examples/session-bridge-plugin/src/store.ts +80 -0
  545. package/examples/session-bridge-plugin/tsconfig.json +21 -0
  546. package/examples/workspace-provider-plugin/README.md +39 -0
  547. package/examples/workspace-provider-plugin/package.json +25 -0
  548. package/examples/workspace-provider-plugin/src/browser/index.ts +69 -0
  549. package/examples/workspace-provider-plugin/src/server.ts +68 -0
  550. package/examples/workspace-provider-plugin/tsconfig.json +21 -0
  551. package/extensions/pi-web.ts +3 -1
  552. package/package.json +59 -36
  553. package/skills/README.md +28 -2
  554. package/skills/relay/SKILL.md +24 -89
  555. package/skills/relay-runner/SKILL.md +74 -0
  556. package/dist/client/assets/CodeViewer-DCl56K0Z.js +0 -4
  557. package/dist/client/assets/TerminalPanel-DCvoEjUF.js +0 -187
  558. package/dist/client/assets/index-CMvms5cF.js +0 -4325
  559. package/dist/client/assets/vendor-editor-core-vUi74DnD.js +0 -12
  560. package/dist/client/assets/vendor-editor-languages-DoaXUodB.js +0 -46
  561. package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +0 -1
  562. package/dist/client/assets/vendor-terminal-BrP-ENHg.css +0 -1
  563. package/dist/client/assets/vendor-terminal-D8k4UKM2.js +0 -35
  564. package/dist/pi-web-plugins/relays/package.json +0 -9
  565. package/dist/pi-web-plugins/relays/pi-web-plugin.js +0 -44
  566. package/dist/server/git/gitService.js +0 -290
  567. package/dist/server/git/gitService.js.map +0 -1
  568. package/dist/server/gitRoutes.js +0 -23
  569. package/dist/server/gitRoutes.js.map +0 -1
  570. package/dist/server/sessions/pendingAskStore.js +0 -278
  571. package/dist/server/sessions/pendingAskStore.js.map +0 -1
  572. package/dist/server/terminalProxyRoutes.js +0 -178
  573. package/dist/server/terminalProxyRoutes.js.map +0 -1
  574. package/dist/server/terminals/terminalRoutes.js +0 -164
  575. package/dist/server/terminals/terminalRoutes.js.map +0 -1
  576. package/dist/server/terminals/terminalService.js.map +0 -1
  577. package/dist/server/terminals/terminalSize.js +0 -17
  578. package/dist/server/terminals/terminalSize.js.map +0 -1
  579. package/dist/server/workspaces/gitWorktreeDiscovery.js +0 -43
  580. package/dist/server/workspaces/gitWorktreeDiscovery.js.map +0 -1
  581. package/dist/server/workspaces/workspaceService.js +0 -52
  582. package/dist/server/workspaces/workspaceService.js.map +0 -1
  583. /package/dist/{pi-web-plugins → pi-packages}/relays/vendor/README.md +0 -0
  584. /package/dist/{pi-web-plugins → pi-packages}/relays/vendor/marked.esm.js +0 -0
@@ -0,0 +1,75 @@
1
+ // Generated from pi-packages/captains-log/src/store.ts. Do not edit directly.
2
+ import { createHash, randomUUID } from "node:crypto";
3
+ import { constants } from "node:fs";
4
+ import { lstat, mkdir, open, readdir, rename, rm } from "node:fs/promises";
5
+ import { join } from "node:path";
6
+ import { isLogEntry } from "./browser/protocol.js";
7
+ /** Only host-resolved ids enter the scope hash; peer input is never a filesystem path. */
8
+ export function logScope(projectId, workspaceId) {
9
+ return createHash("sha256").update(JSON.stringify([projectId, workspaceId])).digest("hex");
10
+ }
11
+ export class LogStore {
12
+ dataDirectory;
13
+ constructor(dataDirectory) {
14
+ this.dataDirectory = dataDirectory;
15
+ }
16
+ async directory(scope) {
17
+ if (!/^[a-f0-9]{64}$/.test(scope))
18
+ throw new Error("Invalid captain scope");
19
+ const directory = join(this.dataDirectory, scope);
20
+ await mkdir(directory, { recursive: true, mode: 0o700 });
21
+ if (!(await lstat(directory)).isDirectory())
22
+ throw new Error("LogEntry directory must not be a symlink");
23
+ return directory;
24
+ }
25
+ async save(scope, captain) {
26
+ if (!isLogEntry(captain))
27
+ throw new Error("Invalid captain record");
28
+ const directory = await this.directory(scope);
29
+ const temporary = join(directory, `.${randomUUID()}.tmp`);
30
+ try {
31
+ const file = await open(temporary, "wx", 0o600);
32
+ try {
33
+ await file.writeFile(JSON.stringify(captain));
34
+ await file.sync();
35
+ }
36
+ finally {
37
+ await file.close();
38
+ }
39
+ await rename(temporary, join(directory, `${captain.id}.json`));
40
+ }
41
+ finally {
42
+ await rm(temporary, { force: true });
43
+ }
44
+ }
45
+ async read(scope, id) {
46
+ if (typeof id !== "string" || !/^[a-f0-9-]{36}$/.test(id))
47
+ throw new Error("Invalid captain id");
48
+ const path = join(await this.directory(scope), `${id}.json`);
49
+ // O_NOFOLLOW is not enforced on Windows; reject existing links there too.
50
+ if (!(await lstat(path)).isFile())
51
+ throw new Error("Invalid captain file");
52
+ const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
53
+ try {
54
+ const stat = await file.stat();
55
+ if (!stat.isFile() || stat.size > 300_000)
56
+ throw new Error("Invalid captain file");
57
+ const value = JSON.parse(await file.readFile("utf8"));
58
+ if (!isLogEntry(value) || value.id !== id)
59
+ throw new Error("Invalid saved captain");
60
+ return value;
61
+ }
62
+ finally {
63
+ await file.close();
64
+ }
65
+ }
66
+ async list(scope) {
67
+ const names = await readdir(await this.directory(scope));
68
+ const captains = [];
69
+ for (const name of names) {
70
+ if (/^[a-f0-9-]{36}\.json$/.test(name))
71
+ captains.push(await this.read(scope, name.slice(0, -5)));
72
+ }
73
+ return captains.sort((a, b) => b.createdAt.localeCompare(a.createdAt) || b.id.localeCompare(a.id));
74
+ }
75
+ }
@@ -0,0 +1,29 @@
1
+ # 使用船长日志
2
+
3
+ 在当前机器和工作区选择普通会话,打开“船长日志”,点击“让船长转述”。伴随扩展读取源会话当前分支最新已完成的助手文本回复,不发送提示、不修改源转录。独立的船长会话使用你配置的模型转述文本,以海盗船长的风格保留事实、警告、下一步以及原始代码和命令。
4
+
5
+ 船长首次收到角色介绍;后续请求复用仍由 daemon 承载的船长会话。只有在发送请求前明确确认旧船长未被承载时才自动创建新会话,不因超时或任意连接失败重试、重发或替换会话。daemon 重启后,如需保留旧船长的上下文,先在会话列表打开最近的船长日志会话,等待加载完成,再选择需要转述的源会话。
6
+
7
+ ## 结果与连接
8
+
9
+ - “打开源会话”按照记录的机器、项目、工作区和源会话 ID 返回聊天。目标不可用时显示常规错误,不自动创建替代会话。
10
+ - 结果支持 Markdown 标题、列表、强调、链接、表格和代码块。内嵌 HTML 按文本显示,危险链接不可点击,图片不会自动加载。“历史转述”和“诊断”默认折叠。
11
+ - 打开面板或选择“打开船长转述”不会消耗模型令牌。只有点击转述按钮才提交任务。
12
+ - 浏览器使用双向 peer 通道接收后端进度,无轮询。连接或重连会读取快照;进度不是逐令牌输出,船长完成后才收到最终转述。
13
+ - 关闭面板或浏览器不会取消已被后端接收的工作。重新连接可恢复结果;接收状态不确定时绝不自动重发。
14
+
15
+ ## 无法运行时
16
+
17
+ 源会话必须属于当前机器和工作区,未归档、非临时会话,且不是船长本身。等待源会话空闲,并确保当前分支存在已完成的助手文本回复;未完成、中止、失败及仅包含工具调用的回复不能转述。现有会话缺少伴随扩展时,执行 `/reload` 后重试。
18
+
19
+ 每个工作区同时只运行一个面板转述任务。船长忙碌、转述时直接向其发送其他消息、提供方错误、中止或截断回复、运行时替换均报告失败,不当作成功。接收超时或完成超时仅移除监听,不停止 Pi;不确定请求须先检查船长会话再手动重试。过大的源回复或结果会被拒绝,不静默截断。
20
+
21
+ 转述和元数据保存在宿主提供的插件数据目录,按项目和工作区隔离。会话转录仍由 Pi 管理。中断记录保留,但没有持久任务恢复或自动清理策略。源文本会发送给船长使用的模型提供方;此代码受信任,不提供工具沙箱。
22
+
23
+ ## 安装与激活
24
+
25
+ 在目标机器“设置 → Pi 包 → 可用包”中安装,再到“设置 → PI WEB 插件”显式启用。本包已编译;手动安装可用 `pi install /absolute/path/to/dist/pi-packages/captains-log`。
26
+
27
+ 从承载会话之外手动重启目标 session daemon,再刷新浏览器。仅重启 Web/API 不能激活后端。现有会话执行 `/reload` 加载或更新伴随扩展;项目级包仍须经过正常的项目信任流程。
28
+
29
+ 禁用 PI WEB 插件仅控制面板和后端,不移除原生扩展。移除 Pi 包会移除两种资源声明,但保留会话与插件数据。旧 Workspace Reviews 示例拥有独立插件 ID,须另外禁用或移除。
@@ -0,0 +1,7 @@
1
+ // Generated from pi-packages/captains-log/i18n.ts. Do not edit directly.
2
+ let translate;
3
+ export function setTranslator(value) {
4
+ translate = value;
5
+ }
6
+ export const t = (key, fallback, params) => translate?.(key, fallback, params)
7
+ ?? fallback.replace(/\{([A-Za-z0-9_]+)\}/g, (match, name) => String(params?.[name] ?? match));
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@chainingintention/pi-captains-log",
3
+ "version": "0.1.0",
4
+ "description": "可选船长日志:通过原生 Pi 伴随扩展和 PI WEB 面板转述选中会话的最后一条回复",
5
+ "private": true,
6
+ "type": "module",
7
+ "keywords": ["pi-package"],
8
+ "files": ["dist", "src", "docs", "test", "tsconfig.json", "vite.config.mjs"],
9
+ "scripts": { "build": "tsc -p tsconfig.json && vite build", "test": "node --test test/*.test.mjs" },
10
+ "dependencies": {
11
+ "marked": "^18.1.1"
12
+ },
13
+ "devDependencies": {
14
+ "@chainingintention/pi-web-cn": "^1.202609.1",
15
+ "@earendil-works/pi-coding-agent": "1.3.0",
16
+ "@types/node": "^24.19.2",
17
+ "typescript": "^6.0.3",
18
+ "vite": "^8.3.4"
19
+ },
20
+ "peerDependencies": {
21
+ "@earendil-works/pi-coding-agent": "*",
22
+ "@chainingintention/pi-web-cn": "^1.202609.1"
23
+ },
24
+ "pi": { "extensions": ["./dist/companion.js"] },
25
+ "piWeb": {
26
+ "plugins": [{
27
+ "id": "captains-log",
28
+ "defaultEnabled": false,
29
+ "browserRoot": "dist/browser",
30
+ "module": "dist/browser/index.js",
31
+ "serverModule": "dist/server.js",
32
+ "machineSpecific": true
33
+ }]
34
+ }
35
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "lib": ["ES2022", "DOM"],
7
+ "types": ["node"],
8
+ "rootDir": "src",
9
+ "outDir": "dist",
10
+ "strict": true,
11
+ "exactOptionalPropertyTypes": true,
12
+ "noUncheckedIndexedAccess": true,
13
+ "noImplicitReturns": true,
14
+ "noFallthroughCasesInSwitch": true,
15
+ "forceConsistentCasingInFileNames": true,
16
+ "verbatimModuleSyntax": true,
17
+ "skipLibCheck": true,
18
+ "noEmitOnError": true
19
+ },
20
+ "include": ["src/**/*.ts"]
21
+ }
@@ -0,0 +1,28 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { defineConfig } from "vite";
3
+
4
+ const packageDir = fileURLToPath(new URL(".", import.meta.url));
5
+
6
+ export default defineConfig({
7
+ root: packageDir,
8
+ base: "./",
9
+ publicDir: false,
10
+ build: {
11
+ outDir: "dist/browser",
12
+ // Retain the transpiled filenames for existing package/install consumers.
13
+ emptyOutDir: false,
14
+ copyPublicDir: false,
15
+ target: "es2022",
16
+ sourcemap: false,
17
+ rollupOptions: {
18
+ input: fileURLToPath(new URL("src/browser/index.ts", import.meta.url)),
19
+ preserveEntrySignatures: "strict",
20
+ output: {
21
+ format: "es",
22
+ entryFileNames: "index.js",
23
+ chunkFileNames: "assets/[name]-[hash].js",
24
+ assetFileNames: "assets/[name]-[hash][extname]",
25
+ },
26
+ },
27
+ },
28
+ });
@@ -0,0 +1,61 @@
1
+ // Generated from pi-packages/relays/extensions/index.ts. Do not edit directly.
2
+ import { Type } from "@earendil-works/pi-ai";
3
+ import { defineTool } from "@earendil-works/pi-coding-agent";
4
+ import { prepareRelayDispatch } from "../relayDispatch.js";
5
+ import { requireRelayLeg } from "../relayIdentity.js";
6
+ const DispatchParams = Type.Object({
7
+ packet: Type.String({ description: "Saved Relay packet directory containing charter.md, status.md and log.md. Relative paths resolve in the target workspace." }),
8
+ leg: Type.String({
9
+ pattern: "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,31}$",
10
+ description: 'String identity of the leg being dispatched, for example "2" or "R1-a". Numbers and other non-string values are rejected, not converted.',
11
+ }),
12
+ cwd: Type.Optional(Type.String({ description: "Target workspace of the same registered project. Omit to use this session's workspace." })),
13
+ model: Type.Optional(Type.String({ description: 'Exact provider/model-id override. Set only when instructed to select a specific model or choose an appropriate one; otherwise omit to inherit.' })),
14
+ thinkingLevel: Type.Optional(Type.Enum(["off", "minimal", "low", "medium", "high", "xhigh", "max"], {
15
+ type: "string",
16
+ description: "Thinking-level override. Set only when instructed to select a level or choose an appropriate one; otherwise omit to inherit. Pi clamps valid levels to the selected model.",
17
+ })),
18
+ }, { additionalProperties: false });
19
+ export default function relayExtension(pi) {
20
+ pi.registerTool(defineTool({
21
+ name: "dispatch_relay",
22
+ label: "Dispatch Relay",
23
+ description: "Start one independent Relay leg from its saved packet. Requires explicit human approval before initial dispatch. Save the actual baton in status.md first; this tool generates the handover and records Relay identity itself. There is no free-form prompt parameter. Use once as the final operational action, then report a brief summary.",
24
+ promptSnippet: "dispatch_relay: dispatch one Relay leg from its saved packet; approval before initial dispatch; final operational action",
25
+ exposure: "model-only",
26
+ parameters: DispatchParams,
27
+ prepareArguments(args) {
28
+ const leg = typeof args === "object" && args !== null && !Array.isArray(args) ? Reflect.get(args, "leg") : undefined;
29
+ requireRelayLeg(leg);
30
+ // Guard identity before Pi's coercion. Its schema validation checks the
31
+ // remaining fields next; retain the raw object, including unknown keys.
32
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
33
+ return args;
34
+ },
35
+ async execute(_toolCallId, params, signal, _onUpdate, ctx) {
36
+ signal?.throwIfAborted();
37
+ const prepared = await prepareRelayDispatch(ctx.cwd, params);
38
+ signal?.throwIfAborted();
39
+ const result = await dispatchThroughHost(pi, prepared, {
40
+ ...(params.model === undefined ? {} : { model: params.model }),
41
+ ...(params.thinkingLevel === undefined ? {} : { thinkingLevel: params.thinkingLevel }),
42
+ });
43
+ const modelNote = result.model === undefined ? "" : ` using model ${result.model}`;
44
+ return {
45
+ content: [{ type: "text", text: `Started Relay ${JSON.stringify(prepared.identity.relayName)} leg ${prepared.identity.leg} as independent session ${result.sessionId} in ${result.cwd}${modelNote}. The saved packet is the handover.` }],
46
+ details: result,
47
+ };
48
+ },
49
+ }));
50
+ }
51
+ /** Documented generic in-process host protocol; unavailable hosts reject before dispatch. */
52
+ async function dispatchThroughHost(pi, prepared, overrides) {
53
+ let accepted;
54
+ pi.events.emit("pi-web:session-dispatch:v1", {
55
+ input: { prompt: prepared.prompt, cwd: prepared.cwd, name: prepared.name, metadata: prepared.metadata, ...overrides },
56
+ accept: (result) => { accepted = result; },
57
+ });
58
+ if (accepted === undefined)
59
+ throw new Error("Relay dispatch requires PI WEB's session dispatch bridge. Update PI WEB and restart the session daemon when safe; no session was dispatched.");
60
+ return accepted;
61
+ }
@@ -0,0 +1,7 @@
1
+ // Generated from pi-packages/relays/i18n.ts. Do not edit directly.
2
+ let translate;
3
+ export function setTranslator(value) {
4
+ translate = value;
5
+ }
6
+ export const t = (key, fallback, params) => translate?.(key, fallback, params)
7
+ ?? fallback.replace(/\{([A-Za-z0-9_]+)\}/g, (match, name) => String(params?.[name] ?? match));
@@ -1,4 +1,5 @@
1
- // Generated from pi-web-plugins/relays/markdownDocument.ts. Do not edit directly.
1
+ // Generated from pi-packages/relays/markdownDocument.ts. Do not edit directly.
2
+ import { t } from "./i18n.js";
2
3
  import { marked } from "./vendor/marked.esm.js";
3
4
  // Raw HTML inside relay documents is escaped before sanitizing, so the
4
5
  // sanitizer only ever sees marked-generated markup. This mirrors the safety
@@ -63,7 +64,7 @@ function wrapTablesInScrollRegions(root) {
63
64
  const wrapper = document.createElement("div");
64
65
  wrapper.className = TABLE_SCROLL_CLASS;
65
66
  wrapper.setAttribute("role", "region");
66
- wrapper.setAttribute("aria-label", "表格");
67
+ wrapper.setAttribute("aria-label", t("bundled.relays.table.22d9e7", "Table"));
67
68
  wrapper.setAttribute("tabindex", "0");
68
69
  table.before(wrapper);
69
70
  wrapper.append(table);
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@jmfederico/pi-relay",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "description": "Goal-led Relay method, durable baton and history, and human-approved preparation prompts for independent Pi session chains.",
6
+ "peerDependencies": {
7
+ "@earendil-works/pi-ai": "*",
8
+ "@earendil-works/pi-coding-agent": "*"
9
+ },
10
+ "pi": {
11
+ "extensions": ["./extensions/index.js"],
12
+ "skills": ["./skills"],
13
+ "prompts": ["./prompts"]
14
+ },
15
+ "piWeb": {
16
+ "plugins": [
17
+ { "id": "relays", "browserRoot": ".", "module": "pi-web-plugin.js" }
18
+ ]
19
+ }
20
+ }
@@ -0,0 +1,96 @@
1
+ // Generated from pi-packages/relays/pi-web-plugin.ts. Do not edit directly.
2
+ import { t, setTranslator } from "./i18n.js";
3
+ import { RELAYS_ROOT } from "./relayDiscovery.js";
4
+ import { relayIdentityFromMetadata } from "./relayIdentity.js";
5
+ import { defineRelaysPanelElement, RELAY_SELECTION_QUERY_KEY } from "./relaysPanelElement.js";
6
+ const stylesheetIntegrationCapability = {
7
+ pluginId: "pi-web", id: "stylesheet-integration", version: 1,
8
+ parse(value) {
9
+ if (!isStylesheetIntegration(value)) {
10
+ throw new Error("Stylesheet integration capability v1 requires registerRoot and createController");
11
+ }
12
+ return value;
13
+ },
14
+ };
15
+ function isStylesheetIntegration(value) {
16
+ return typeof value === "object" && value !== null
17
+ && "registerRoot" in value && typeof value.registerRoot === "function"
18
+ && "createController" in value && typeof value.createController === "function"
19
+ && "subscribe" in value && typeof value.subscribe === "function";
20
+ }
21
+ const plugin = {
22
+ apiVersion: 4,
23
+ name: t("bundled.relays.relays.715ce8", "Relays"),
24
+ requires: [stylesheetIntegrationCapability],
25
+ activate: ({ runtimePluginId, html, svg, translate }) => {
26
+ setTranslator(translate);
27
+ defineRelaysPanelElement();
28
+ let stylesheetIntegration;
29
+ return {
30
+ start: ({ capabilities }) => {
31
+ stylesheetIntegration = capabilities.resolve(stylesheetIntegrationCapability);
32
+ },
33
+ contributions: {
34
+ actions: [
35
+ {
36
+ id: "workspace.open-relays",
37
+ title: t("bundled.relays.open.workspace.relays.ead958", "Open workspace relays"),
38
+ description: t("bundled.relays.open.the.workspace.relays.tab.relays.are.stored.in.3d8901", "Open the workspace relays tab. Relays are stored in {value1}.", { value1: RELAYS_ROOT }),
39
+ group: t("bundled.workspace-tasks.workspace.379798", "Workspace"),
40
+ enabled: (context) => context.state.selectedWorkspace !== undefined,
41
+ run: (context) => {
42
+ if (context.state.selectedWorkspace === undefined)
43
+ return;
44
+ context.selectWorkspaceTool(`${runtimePluginId}:workspace.relays`);
45
+ },
46
+ },
47
+ ],
48
+ sessionLabels: [
49
+ {
50
+ id: "session.relay",
51
+ items: (context) => {
52
+ const identity = relayIdentityFromMetadata(context.session.metadata);
53
+ if (identity === undefined)
54
+ return [];
55
+ return [{
56
+ type: "render",
57
+ render: () => html `
58
+ <button
59
+ type="button"
60
+ style="border:0; padding:0; background:transparent; color:var(--pi-accent); font:inherit; text-align:start; overflow-wrap:anywhere; cursor:pointer"
61
+ title=${identity.packetPath}
62
+ aria-label=${t("bundled.relays.open.packet", "Open Relay {name}, leg {leg}", { name: identity.relayName, leg: identity.leg })}
63
+ @click=${() => context.navigate({
64
+ machineId: context.machine.id,
65
+ projectId: context.workspace.projectId,
66
+ workspaceId: context.workspace.id,
67
+ view: "workspace",
68
+ tool: `${runtimePluginId}:workspace.relays`,
69
+ query: { [RELAY_SELECTION_QUERY_KEY]: identity.packetPath },
70
+ }, { mode: "patch" })}
71
+ >${t("bundled.relays.label", "relay")}</button>
72
+ `,
73
+ }];
74
+ },
75
+ },
76
+ ],
77
+ workspacePanels: [
78
+ {
79
+ id: "workspace.relays",
80
+ title: t("bundled.relays.relays.715ce8", "Relays"),
81
+ icon: svg `
82
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
83
+ <path d="M9 17H7A5 5 0 0 1 7 7h2"></path>
84
+ <path d="M15 7h2a5 5 0 1 1 0 10h-2"></path>
85
+ <line x1="8" y1="12" x2="16" y2="12"></line>
86
+ </svg>
87
+ `,
88
+ order: 50,
89
+ render: (context) => html `<pi-web-relays-panel .stylesheetIntegration=${stylesheetIntegration} .context=${context}></pi-web-relays-panel>`,
90
+ },
91
+ ],
92
+ },
93
+ };
94
+ },
95
+ };
96
+ export default plugin;
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: Clarify a goal with the human, then dispatch a Relay in a fresh worktree
3
+ argument-hint: "<what the relay should achieve>"
4
+ ---
5
+
6
+ Prepare a Relay from the request below in a fresh worktree. Load the `relay` and `relay-runner` skills. This differs from `/relay` only in working location; if the request names an existing target, resolve that choice with the human.
7
+
8
+ Help the human put into words what they want built, what counts as done, and the relay-specific boundaries, limitations, and conditions. Read supplied specifications and inspect the project only as needed to understand that intent. If the request is empty, ask what they want to achieve with `ask_user`.
9
+
10
+ Draft `.pi-web/relays/<name>/charter.md`, `status.md`, and `log.md` in this checkout under the runner skill's packet convention. Mark status **Draft — awaiting approval; not dispatched**. Capture the requested outcome and any details the human explicitly asks to include, not an agent-invented implementation plan. Leave project rules and skill discovery to each runner; do not turn them into relay instructions. The first runner chooses the first useful slice.
11
+
12
+ Point the human to the draft, summarize the goal, boundaries, and proposed working location, and resolve material questions together through `ask_user`. Once the goal is understood, ask **Approve and dispatch**, **Revise**, or **Do not dispatch** against the final draft. Drafting and the initial request are not dispatch approval.
13
+
14
+ On revision, update the draft and obtain approval. On refusal, record that it was not dispatched and stop. After explicit approval, create the worktree and move the packet there as described in the runner skill. Record approval, mark status **Active**, seed leg 1, and finalize the packet with the actual baton saved in `status.md`. Call the dedicated `dispatch_relay` tool once with the moved directory as `packet`, `leg: "1"`, and the new worktree as `cwd`, following the runner skill's handoff mechanics. The tool generates the handover; do not supply a free-form prompt. Dispatch is the final operational action; afterward provide only a brief summary.
15
+
16
+ <relay_task>
17
+ $ARGUMENTS
18
+ </relay_task>
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: Clarify a goal with the human, then dispatch a Relay
3
+ argument-hint: "<what the relay should achieve>"
4
+ ---
5
+
6
+ Prepare a Relay from the request below. Load the `relay` and `relay-runner` skills. Use the current checkout unless the human chooses another working location.
7
+
8
+ Help the human put into words what they want built, what counts as done, and the relay-specific boundaries, limitations, and conditions. Read supplied specifications and inspect the project only as needed to understand that intent. If the request is empty, ask what they want to achieve with `ask_user`.
9
+
10
+ Draft `.pi-web/relays/<name>/charter.md`, `status.md`, and `log.md` under the runner skill's packet convention. Mark status **Draft — awaiting approval; not dispatched**. Capture the requested outcome and any details the human explicitly asks to include, not an agent-invented implementation plan. Leave project rules and skill discovery to each runner; do not turn them into relay instructions. The first runner chooses the first useful slice.
11
+
12
+ Point the human to the draft, summarize the goal and boundaries, and resolve material questions together through `ask_user`. Once the goal is understood, ask **Approve and dispatch**, **Revise**, or **Do not dispatch** against the final draft. Drafting and the initial request are not dispatch approval.
13
+
14
+ On revision, update the draft and obtain approval. On refusal, record that it was not dispatched and stop. After explicit approval, record it, mark status **Active**, seed leg 1, and finalize the packet with the actual baton saved in `status.md`. Call the dedicated `dispatch_relay` tool once with the saved directory as `packet`, `leg: "1"`, and the target checkout as `cwd`, following the runner skill's handoff mechanics. The tool generates the handover; do not supply a free-form prompt. Dispatch is the final operational action; afterward provide only a brief summary.
15
+
16
+ <relay_task>
17
+ $ARGUMENTS
18
+ </relay_task>
@@ -1,7 +1,7 @@
1
- // Generated from pi-web-plugins/relays/relayDiscovery.ts. Do not edit directly.
1
+ // Generated from pi-packages/relays/relayDiscovery.ts. Do not edit directly.
2
2
  export const RELAYS_ROOT = ".pi-web/relays";
3
3
  /** Documents that anchor a relay packet, in display order. Any other files follow alphabetically. */
4
- export const RELAY_ANCHOR_DOCUMENTS = ["status.md", "charter.md", "log.md"];
4
+ export const RELAY_ANCHOR_DOCUMENTS = ["status.md", "charter.md", "operations.md", "log.md"];
5
5
  /** Deepest node depth listed below the relay root; direct children are depth 0. */
6
6
  export const MAX_RELAY_TREE_DEPTH = 5;
7
7
  /** Most documents listed across one relay. */
@@ -0,0 +1,67 @@
1
+ // Generated from pi-packages/relays/relayDispatch.ts. Do not edit directly.
2
+ import { open, realpath, stat } from "node:fs/promises";
3
+ import { basename, isAbsolute, join, relative, resolve, sep } from "node:path";
4
+ import { isRelayPacketPath, RELAY_METADATA_NAMESPACE, relaySessionName, requireRelayLeg } from "./relayIdentity.js";
5
+ const MAX_PACKET_DOCUMENT_BYTES = 256 * 1024;
6
+ const PACKET_DOCUMENTS = ["charter.md", "status.md", "log.md"];
7
+ /** Validate the durable packet on disk, not handover prose authored by the caller. */
8
+ export async function prepareRelayDispatch(spawningCwd, request) {
9
+ const leg = requireRelayLeg(request.leg);
10
+ const cwd = await realpath(resolve(spawningCwd, request.cwd ?? "."));
11
+ if (typeof request.packet !== "string" || request.packet.trim() === "")
12
+ throw new Error("A saved Relay packet directory is required");
13
+ const packet = await realpath(resolve(cwd, request.packet));
14
+ const packetPath = relative(cwd, packet).split(sep).join("/");
15
+ if (!isRelayPacketPath(packetPath))
16
+ throw new Error("Relay packet must be a directory inside the target workspace");
17
+ for (const document of PACKET_DOCUMENTS)
18
+ await validateDocument(packet, document);
19
+ const identity = { version: 1, packetPath, relayName: basename(packet), leg };
20
+ return {
21
+ cwd,
22
+ identity,
23
+ name: relaySessionName(identity),
24
+ metadata: { [RELAY_METADATA_NAMESPACE]: identity },
25
+ prompt: relayHandoverInstructions(cwd, packet, identity),
26
+ };
27
+ }
28
+ function relayHandoverInstructions(cwd, packet, identity) {
29
+ return [
30
+ `Continue Relay ${JSON.stringify(identity.relayName)}, leg ${identity.leg}, in ${JSON.stringify(cwd)}.`,
31
+ "Load the `relay` and `relay-runner` skills.",
32
+ `Read ${JSON.stringify(join(packet, "charter.md"))} and ${JSON.stringify(join(packet, "status.md"))}.`,
33
+ "The charter is the agreed goal and status.md is the actual baton. Consult the saved history and supporting documents only as needed; do not substitute dispatch prose for the packet.",
34
+ "Check the finish line against the current work and choose the next useful slice.",
35
+ "Make progress and the record durable, then hand off once, complete, or signal that you need help.",
36
+ ].join("\n");
37
+ }
38
+ async function validateDocument(packet, document) {
39
+ const path = await realpath(join(packet, document));
40
+ const inside = relative(packet, path);
41
+ if (isAbsolute(inside) || inside === ".." || inside.startsWith(`..${sep}`))
42
+ throw new Error(`Relay ${document} must stay inside the packet`);
43
+ const info = await stat(path);
44
+ if (!info.isFile() || info.size === 0 || info.size > MAX_PACKET_DOCUMENT_BYTES) {
45
+ throw new Error(`Relay ${document} must be a non-empty regular file of at most ${String(MAX_PACKET_DOCUMENT_BYTES)} bytes`);
46
+ }
47
+ const file = await open(path, "r");
48
+ try {
49
+ // Bound reads even if another process grows the document after stat.
50
+ const buffer = Buffer.alloc(MAX_PACKET_DOCUMENT_BYTES + 1);
51
+ const { bytesRead } = await file.read(buffer, 0, buffer.length, 0);
52
+ if (bytesRead > MAX_PACKET_DOCUMENT_BYTES)
53
+ throw new Error(`Relay ${document} exceeds the document size limit`);
54
+ let text;
55
+ try {
56
+ text = new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0, bytesRead));
57
+ }
58
+ catch {
59
+ throw new Error(`Relay ${document} must be UTF-8 text`);
60
+ }
61
+ if (text.trim() === "" || text.includes("\0"))
62
+ throw new Error(`Relay ${document} must contain saved text`);
63
+ }
64
+ finally {
65
+ await file.close();
66
+ }
67
+ }
@@ -0,0 +1,37 @@
1
+ // Generated from pi-packages/relays/relayIdentity.ts. Do not edit directly.
2
+ /** Relay owns this schema; core treats it as opaque browser-public JSON. */
3
+ export const RELAY_METADATA_NAMESPACE = "@jmfederico/pi-relay";
4
+ export function relayIdentityFromMetadata(metadata) {
5
+ const value = metadata?.[RELAY_METADATA_NAMESPACE];
6
+ if (value?.["version"] !== 1)
7
+ return undefined;
8
+ const packetPath = value["packetPath"];
9
+ const relayName = value["relayName"];
10
+ const leg = value["leg"];
11
+ if (typeof packetPath !== "string" || !isRelayPacketPath(packetPath)
12
+ || typeof relayName !== "string" || relayName !== packetPath.split("/").at(-1)
13
+ || typeof leg !== "string" || !isRelayLeg(leg))
14
+ return undefined;
15
+ return { version: 1, packetPath, relayName, leg };
16
+ }
17
+ export function isRelayPacketPath(value) {
18
+ // eslint-disable-next-line no-control-regex -- packet paths must not contain control characters.
19
+ return value.length > 0 && value.length <= 4096 && !/[\\\u0000-\u001f\u007f]/u.test(value)
20
+ && value.split("/").every((segment) => segment !== "" && segment !== "." && segment !== ".." && segment === segment.trim());
21
+ }
22
+ export function isRelayLeg(value) {
23
+ return /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,31}$/u.test(value);
24
+ }
25
+ export function requireRelayLeg(value) {
26
+ if (typeof value !== "string" || !isRelayLeg(value)) {
27
+ throw new Error("Relay leg must be a string of 1–32 letters, digits, dots, underscores or hyphens, starting with a letter or digit");
28
+ }
29
+ return value;
30
+ }
31
+ /** Keep the leg first so host and sidebar truncation only shorten the Relay name. */
32
+ export function relaySessionName(identity) {
33
+ const prefix = `Leg ${identity.leg} – Relay `;
34
+ const room = 60 - prefix.length;
35
+ const name = identity.relayName.slice(0, room).replace(/[\s._-]+$/u, "") || identity.relayName.slice(0, room);
36
+ return `${prefix}${name}`;
37
+ }