@chainingintention/pi-web-cn 1.202610.4 → 2.202610.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.js +31 -7
  3. package/dist/cli.js.map +1 -1
  4. package/dist/client/assets/PiWebApp-BXSziMEg.js +4921 -0
  5. package/dist/client/assets/classic-CyM97Akm.css +54 -0
  6. package/dist/client/assets/external-B9K8duyP.js +2 -0
  7. package/dist/client/assets/graphite-DquaqFXU.css +54 -0
  8. package/dist/client/assets/index-cdtUOfOW.js +2 -0
  9. package/dist/client/assets/paper-CB1oLuRr.css +54 -0
  10. package/dist/client/assets/pi-web-dark-D_KtbM95.css +54 -0
  11. package/dist/client/assets/pi-web-light-DSNLMIBI.css +54 -0
  12. package/dist/client/assets/vendor-editor-core-BfnHL1Dg.js +10 -0
  13. package/dist/client/assets/{vendor-editor-languages-DOCw3vc9.js → vendor-editor-languages-bNquDJP0.js} +1 -1
  14. package/dist/client/index.html +3 -47
  15. package/dist/config.js +11 -2
  16. package/dist/config.js.map +1 -1
  17. package/dist/nativeServices/installedServiceDefinitions.js +10 -7
  18. package/dist/nativeServices/installedServiceDefinitions.js.map +1 -1
  19. package/dist/pi-packages/captains-log/dist/browser/index.js +43 -47
  20. package/dist/pi-packages/captains-log/dist/browser/panel.js +6 -10
  21. package/dist/pi-packages/captains-log/dist/companion.js +1 -1
  22. package/dist/pi-packages/captains-log/package.json +4 -4
  23. package/dist/pi-packages/relays/extensions/index.js +61 -0
  24. package/dist/pi-packages/relays/package.json +10 -1
  25. package/dist/pi-packages/relays/pi-web-plugin.js +52 -2
  26. package/dist/pi-packages/relays/prompts/relay-worktree.md +6 -16
  27. package/dist/pi-packages/relays/prompts/relay.md +6 -33
  28. package/dist/pi-packages/relays/relayDispatch.js +67 -0
  29. package/dist/pi-packages/relays/relayIdentity.js +37 -0
  30. package/dist/pi-packages/relays/relaysPanelElement.js +75 -37
  31. package/dist/pi-packages/relays/skills/relay/SKILL.md +24 -68
  32. package/dist/pi-packages/relays/skills/relay-runner/SKILL.md +40 -219
  33. package/dist/pi-packages/workflows/browser/pi-web-plugin.js +42 -0
  34. package/dist/pi-packages/workflows/browser/worktreeDialog.js +170 -0
  35. package/dist/pi-packages/workflows/package.json +23 -0
  36. package/dist/pi-packages/workflows/prompts/worktree.md +21 -0
  37. package/dist/pi-packages/workflows/server-plugin.js +586 -0
  38. package/dist/pi-packages/workflows/vite.config.mjs +17 -0
  39. package/dist/pi-web-plugins/code-highlight/browser/pi-web-plugin.js +22 -0
  40. package/dist/pi-web-plugins/code-highlight/package.json +13 -0
  41. package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +115 -105
  42. package/dist/pi-web-plugins/git/browser/git-panel.js +60 -46
  43. package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +23 -3
  44. package/dist/pi-web-plugins/git/git-backend.js +20 -1
  45. package/dist/pi-web-plugins/git/server-plugin.js +20 -3
  46. package/dist/pi-web-plugins/git/workspace-discovery-notify.cjs +14 -0
  47. package/dist/pi-web-plugins/git/workspaceDiscoveryHooks.js +186 -0
  48. package/dist/pi-web-plugins/info/infoInternals.js +3 -3
  49. package/dist/pi-web-plugins/info/pi-web-plugin.js +1 -1
  50. package/dist/pi-web-plugins/mermaid/browser/mermaid-engine.js +1087 -422
  51. package/dist/pi-web-plugins/mermaid/browser/pi-web-plugin.js +8 -3
  52. package/dist/pi-web-plugins/terminal/browser/pi-web-plugin.js +39 -33
  53. package/dist/pi-web-plugins/updates/pi-web-plugin.js +13 -13
  54. package/dist/pi-web-plugins/updates/updatesLogic.js +4 -5
  55. package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +21 -1
  56. package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +39 -22
  57. package/dist/pi-web-plugins/zh-cn/bundled.json +44 -1
  58. package/dist/pi-web-plugins/zh-cn/cli.json +60 -1
  59. package/dist/pi-web-plugins/zh-cn/client.json +7 -1
  60. package/dist/pi-web-plugins/zh-cn/components.json +252 -2
  61. package/dist/pi-web-plugins/zh-cn/config-errors.json +17 -1
  62. package/dist/pi-web-plugins/zh-cn/files.json +10 -1
  63. package/dist/pi-web-plugins/zh-cn/main.json +1 -1
  64. package/dist/pi-web-plugins/zh-cn/provider-auth.json +2 -1
  65. package/dist/pi-web-plugins/zh-cn/server.json +83 -1
  66. package/dist/piAi.js +4 -0
  67. package/dist/piAi.js.map +1 -0
  68. package/dist/piRuntime.js +150 -0
  69. package/dist/piRuntime.js.map +1 -0
  70. package/dist/piSdk.js +5 -0
  71. package/dist/piSdk.js.map +1 -0
  72. package/dist/piWebUpdate.js +508 -0
  73. package/dist/piWebUpdate.js.map +1 -0
  74. package/dist/piWebVersionReport.js +43 -1
  75. package/dist/piWebVersionReport.js.map +1 -1
  76. package/dist/plugin-api.d.ts +393 -51
  77. package/dist/server/activity/workspaceActivityService.js +8 -1
  78. package/dist/server/activity/workspaceActivityService.js.map +1 -1
  79. package/dist/server/app.js +19 -4
  80. package/dist/server/app.js.map +1 -1
  81. package/dist/server/browserMessageProjection.js +39 -20
  82. package/dist/server/browserMessageProjection.js.map +1 -1
  83. package/dist/server/configRoutes.js +8 -0
  84. package/dist/server/configRoutes.js.map +1 -1
  85. package/dist/server/index.js +10 -1
  86. package/dist/server/index.js.map +1 -1
  87. package/dist/server/knownAutoInstallPiPackages.js +6 -0
  88. package/dist/server/knownAutoInstallPiPackages.js.map +1 -1
  89. package/dist/server/machines/machineProxyRoutes.js +37 -2
  90. package/dist/server/machines/machineProxyRoutes.js.map +1 -1
  91. package/dist/server/navigationPreferenceRoutes.js +59 -0
  92. package/dist/server/navigationPreferenceRoutes.js.map +1 -0
  93. package/dist/server/piPackageService.js +1 -1
  94. package/dist/server/piPackageService.js.map +1 -1
  95. package/dist/server/piWebPluginCatalog.js +1 -1
  96. package/dist/server/piWebPluginCatalog.js.map +1 -1
  97. package/dist/server/piWebPluginService.js +7 -1
  98. package/dist/server/piWebPluginService.js.map +1 -1
  99. package/dist/server/piWebStatus.js +17 -56
  100. package/dist/server/piWebStatus.js.map +1 -1
  101. package/dist/server/plugins/pluginBackendChannelProxyAdmission.js +1 -1
  102. package/dist/server/plugins/pluginBackendChannelProxyAdmission.js.map +1 -1
  103. package/dist/server/plugins/pluginBackendChannelProxyRoutes.js +40 -42
  104. package/dist/server/plugins/pluginBackendChannelProxyRoutes.js.map +1 -1
  105. package/dist/server/plugins/pluginBackendProxyRoutes.js +40 -44
  106. package/dist/server/plugins/pluginBackendProxyRoutes.js.map +1 -1
  107. package/dist/server/plugins/pluginBackendRegistry.js +66 -35
  108. package/dist/server/plugins/pluginBackendRegistry.js.map +1 -1
  109. package/dist/server/plugins/projectPluginSettings.js +95 -0
  110. package/dist/server/plugins/projectPluginSettings.js.map +1 -0
  111. package/dist/server/plugins/serverPluginCatalogCapability.js +106 -0
  112. package/dist/server/plugins/serverPluginCatalogCapability.js.map +1 -0
  113. package/dist/server/plugins/serverPluginRuntime.js +47 -11
  114. package/dist/server/plugins/serverPluginRuntime.js.map +1 -1
  115. package/dist/server/projectTrustRoutes.js +1 -1
  116. package/dist/server/projectTrustRoutes.js.map +1 -1
  117. package/dist/server/projects/projectLifecycleService.js +17 -7
  118. package/dist/server/projects/projectLifecycleService.js.map +1 -1
  119. package/dist/server/realtime/sessionEventHub.js +22 -9
  120. package/dist/server/realtime/sessionEventHub.js.map +1 -1
  121. package/dist/server/sessiond/agentHttpDispatcher.js +1 -1
  122. package/dist/server/sessiond/agentHttpDispatcher.js.map +1 -1
  123. package/dist/server/sessiond/autoInstallPiPackages.js +3 -3
  124. package/dist/server/sessiond/pluginBackendChannelRoutes.js +27 -14
  125. package/dist/server/sessiond/pluginBackendChannelRoutes.js.map +1 -1
  126. package/dist/server/sessiond/pluginBackendRoutes.js +56 -49
  127. package/dist/server/sessiond/pluginBackendRoutes.js.map +1 -1
  128. package/dist/server/sessiond/pluginCatalogRoutes.js +41 -0
  129. package/dist/server/sessiond/pluginCatalogRoutes.js.map +1 -0
  130. package/dist/server/sessiond/sessionProxyRoutes.js +46 -1
  131. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
  132. package/dist/server/sessiond/sessionServiceDependencies.js +1 -0
  133. package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -1
  134. package/dist/server/sessiond/workspaceCatalogRoutes.js +6 -2
  135. package/dist/server/sessiond/workspaceCatalogRoutes.js.map +1 -1
  136. package/dist/server/sessiond/workspaceNotificationRoutes.js +55 -0
  137. package/dist/server/sessiond/workspaceNotificationRoutes.js.map +1 -0
  138. package/dist/server/sessiond.js +58 -8
  139. package/dist/server/sessiond.js.map +1 -1
  140. package/dist/server/sessions/askUserDomain.js +232 -0
  141. package/dist/server/sessions/askUserDomain.js.map +1 -0
  142. package/dist/server/sessions/askUserTool.js +18 -18
  143. package/dist/server/sessions/askUserTool.js.map +1 -1
  144. package/dist/server/sessions/attachmentService.js +1 -1
  145. package/dist/server/sessions/attachmentService.js.map +1 -1
  146. package/dist/server/sessions/authRoutes.js +12 -0
  147. package/dist/server/sessions/authRoutes.js.map +1 -1
  148. package/dist/server/sessions/authService.js +11 -1
  149. package/dist/server/sessions/authService.js.map +1 -1
  150. package/dist/server/sessions/builtinExtensionFactories.js +36 -0
  151. package/dist/server/sessions/builtinExtensionFactories.js.map +1 -0
  152. package/dist/server/sessions/companionBackend.js +286 -0
  153. package/dist/server/sessions/companionBackend.js.map +1 -0
  154. package/dist/server/sessions/dockerEnvironmentFacts.js +16 -1
  155. package/dist/server/sessions/dockerEnvironmentFacts.js.map +1 -1
  156. package/dist/server/sessions/extensionSessionDispatch.js +76 -0
  157. package/dist/server/sessions/extensionSessionDispatch.js.map +1 -0
  158. package/dist/server/sessions/globalProviderPolicy.js +88 -19
  159. package/dist/server/sessions/globalProviderPolicy.js.map +1 -1
  160. package/dist/server/sessions/managementAgentTools.js +2 -2
  161. package/dist/server/sessions/managementAgentTools.js.map +1 -1
  162. package/dist/server/sessions/mcpAuthFlowService.js +289 -0
  163. package/dist/server/sessions/mcpAuthFlowService.js.map +1 -0
  164. package/dist/server/sessions/mcpAuthRoutes.js +104 -0
  165. package/dist/server/sessions/mcpAuthRoutes.js.map +1 -0
  166. package/dist/server/sessions/mcpOAuthCredentialAdapter.js +92 -0
  167. package/dist/server/sessions/mcpOAuthCredentialAdapter.js.map +1 -0
  168. package/dist/server/sessions/messageHistoryTarget.js +79 -0
  169. package/dist/server/sessions/messageHistoryTarget.js.map +1 -0
  170. package/dist/server/sessions/piSessionEventConnections.js +5 -2
  171. package/dist/server/sessions/piSessionEventConnections.js.map +1 -1
  172. package/dist/server/sessions/piSessionManagerGateway.js +32 -27
  173. package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
  174. package/dist/server/sessions/piSessionService.js +1296 -341
  175. package/dist/server/sessions/piSessionService.js.map +1 -1
  176. package/dist/server/sessions/plainTextTheme.js +1 -1
  177. package/dist/server/sessions/plainTextTheme.js.map +1 -1
  178. package/dist/server/sessions/projectAuthService.js +1 -1
  179. package/dist/server/sessions/projectAuthService.js.map +1 -1
  180. package/dist/server/sessions/projectSettingsScope.js +1 -1
  181. package/dist/server/sessions/projectSettingsScope.js.map +1 -1
  182. package/dist/server/sessions/projectTrust.js +1 -1
  183. package/dist/server/sessions/projectTrust.js.map +1 -1
  184. package/dist/server/sessions/queuedMessageMutation.js +170 -0
  185. package/dist/server/sessions/queuedMessageMutation.js.map +1 -0
  186. package/dist/server/sessions/relaySkill.js +57 -7
  187. package/dist/server/sessions/relaySkill.js.map +1 -1
  188. package/dist/server/sessions/sessionArchiveMapping.js +6 -0
  189. package/dist/server/sessions/sessionArchiveMapping.js.map +1 -1
  190. package/dist/server/sessions/sessionArchiveStore.js +5 -1
  191. package/dist/server/sessions/sessionArchiveStore.js.map +1 -1
  192. package/dist/server/sessions/sessionArchiveTree.js +2 -2
  193. package/dist/server/sessions/sessionArchiveTree.js.map +1 -1
  194. package/dist/server/sessions/sessionCommandService.js +11 -24
  195. package/dist/server/sessions/sessionCommandService.js.map +1 -1
  196. package/dist/server/sessions/sessionImageDimensions.js +31 -0
  197. package/dist/server/sessions/sessionImageDimensions.js.map +1 -0
  198. package/dist/server/sessions/sessionMediaIndex.js +191 -0
  199. package/dist/server/sessions/sessionMediaIndex.js.map +1 -0
  200. package/dist/server/sessions/sessionMetadata.js +51 -0
  201. package/dist/server/sessions/sessionMetadata.js.map +1 -0
  202. package/dist/server/sessions/sessionModelScope.js +2 -2
  203. package/dist/server/sessions/sessionModelScope.js.map +1 -1
  204. package/dist/server/sessions/sessionNameGenerator.js +13 -33
  205. package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
  206. package/dist/server/sessions/sessionReadAccess.js +41 -0
  207. package/dist/server/sessions/sessionReadAccess.js.map +1 -0
  208. package/dist/server/sessions/sessionRoutes.js +61 -6
  209. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  210. package/dist/server/sessions/sessionSummaryScanner.js +62 -5
  211. package/dist/server/sessions/sessionSummaryScanner.js.map +1 -1
  212. package/dist/server/sessions/sessionUiEvents.js +17 -4
  213. package/dist/server/sessions/sessionUiEvents.js.map +1 -1
  214. package/dist/server/sessions/spawnSessionTool.js +11 -3
  215. package/dist/server/sessions/spawnSessionTool.js.map +1 -1
  216. package/dist/server/sessions/spawnSubsessionTool.js +35 -19
  217. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
  218. package/dist/server/sessions/subsessionCompletionDelivery.js +15 -0
  219. package/dist/server/sessions/subsessionCompletionDelivery.js.map +1 -0
  220. package/dist/server/sessions/subsessionCompletionInbox.js +134 -0
  221. package/dist/server/sessions/subsessionCompletionInbox.js.map +1 -0
  222. package/dist/server/sessions/subsessionProvenance.js +27 -0
  223. package/dist/server/sessions/subsessionProvenance.js.map +1 -0
  224. package/dist/server/sessions/transcriptMarkdown.js +48 -0
  225. package/dist/server/sessions/transcriptMarkdown.js.map +1 -0
  226. package/dist/server/sessions/transcriptMessages.js +3 -0
  227. package/dist/server/sessions/transcriptMessages.js.map +1 -1
  228. package/dist/server/startupLogger.js +13 -0
  229. package/dist/server/startupLogger.js.map +1 -0
  230. package/dist/server/startupUrls.js +27 -0
  231. package/dist/server/startupUrls.js.map +1 -0
  232. package/dist/server/status/machineStatusService.js +15 -9
  233. package/dist/server/status/machineStatusService.js.map +1 -1
  234. package/dist/server/storage/navigationPreferenceStore.js +138 -0
  235. package/dist/server/storage/navigationPreferenceStore.js.map +1 -0
  236. package/dist/server/webSocketBridge.js +9 -0
  237. package/dist/server/webSocketBridge.js.map +1 -1
  238. package/dist/server/workbench/skillSync.js +1 -1
  239. package/dist/server/workbench/skillSync.js.map +1 -1
  240. package/dist/server/workbench/workbenchTools.js +2 -2
  241. package/dist/server/workbench/workbenchTools.js.map +1 -1
  242. package/dist/server/workspaces/filePreviewService.js +5 -2
  243. package/dist/server/workspaces/filePreviewService.js.map +1 -1
  244. package/dist/server/workspaces/projectPiWebConfig.js +87 -6
  245. package/dist/server/workspaces/projectPiWebConfig.js.map +1 -1
  246. package/dist/server/workspaces/workspaceChangeNotifier.js +12 -0
  247. package/dist/server/workspaces/workspaceChangeNotifier.js.map +1 -0
  248. package/dist/server/workspaces/workspaceNotificationCommand.js +64 -0
  249. package/dist/server/workspaces/workspaceNotificationCommand.js.map +1 -0
  250. package/dist/server/workspaces/workspaceProviderRegistry.js +53 -0
  251. package/dist/server/workspaces/workspaceProviderRegistry.js.map +1 -1
  252. package/dist/server-plugin-api.d.ts +83 -15
  253. package/dist/server-plugin-api.js +25 -0
  254. package/dist/server-plugin-api.js.map +1 -1
  255. package/dist/sessiond/sessionDaemonClient.js +27 -3
  256. package/dist/sessiond/sessionDaemonClient.js.map +1 -1
  257. package/dist/shared/apiTypes.js +3 -2
  258. package/dist/shared/apiTypes.js.map +1 -1
  259. package/dist/shared/capabilities.js +3 -0
  260. package/dist/shared/capabilities.js.map +1 -1
  261. package/dist/shared/federatedRoutes.js +25 -5
  262. package/dist/shared/federatedRoutes.js.map +1 -1
  263. package/dist/shared/machineStatus.js +11 -2
  264. package/dist/shared/machineStatus.js.map +1 -1
  265. package/dist/shared/navigationPreferences.js +6 -0
  266. package/dist/shared/navigationPreferences.js.map +1 -0
  267. package/dist/shared/piWebConfigParsing.js +54 -0
  268. package/dist/shared/piWebConfigParsing.js.map +1 -1
  269. package/dist/shared/pluginApiTypes.d.ts +55 -0
  270. package/dist/shared/pluginBackendProtocol.js +56 -1
  271. package/dist/shared/pluginBackendProtocol.js.map +1 -1
  272. package/dist/shared/pluginCatalogTypes.d.ts +49 -0
  273. package/dist/shared/pluginCatalogTypes.js +156 -0
  274. package/dist/shared/pluginCatalogTypes.js.map +1 -0
  275. package/dist/shared/sessionMedia.js +12 -0
  276. package/dist/shared/sessionMedia.js.map +1 -0
  277. package/dist/shared/streamingBehavior.js +8 -0
  278. package/dist/shared/streamingBehavior.js.map +1 -0
  279. package/dist/shared/themePreference.js +24 -0
  280. package/dist/shared/themePreference.js.map +1 -0
  281. package/dist/workspaceNotificationCli.js +95 -0
  282. package/dist/workspaceNotificationCli.js.map +1 -0
  283. package/docs/README.md +31 -0
  284. package/docs/config.md +77 -4
  285. package/docs/plugins.md +60 -11
  286. package/examples/session-bridge-plugin/package.json +2 -2
  287. package/examples/session-bridge-plugin/src/browser/index.ts +1 -1
  288. package/examples/session-bridge-plugin/src/companion.ts +1 -1
  289. package/extensions/pi-web.ts +3 -1
  290. package/package.json +46 -34
  291. package/skills/README.md +10 -9
  292. package/skills/relay/SKILL.md +24 -68
  293. package/skills/relay-runner/SKILL.md +40 -219
  294. package/dist/client/assets/PiWebApp-CN3g7SqA.js +0 -4362
  295. package/dist/client/assets/external-DUGCSDhZ.js +0 -2
  296. package/dist/client/assets/index-JduZlbIF.js +0 -2
  297. package/dist/client/assets/vendor-editor-core-YWog6mAR.js +0 -10
  298. package/dist/server/sessions/pendingAskStore.js +0 -275
  299. package/dist/server/sessions/pendingAskStore.js.map +0 -1
@@ -0,0 +1,289 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { randomUUID } from "node:crypto";
3
+ import { createTranslator, UserFacingError, userFacingErrorMessage } from "../../shared/i18n.js";
4
+ import { normalizeRequestCwd } from "../workingDirectory.js";
5
+ const execution = new AsyncLocalStorage();
6
+ const MAX_TEXT = 32 * 1024;
7
+ const MAX_PROGRESS = 100;
8
+ function normalizeOwner(owner) {
9
+ return { ...owner, cwd: normalizeRequestCwd(owner.cwd), ...(owner.projectPath === undefined ? {} : { projectPath: normalizeRequestCwd(owner.projectPath) }) };
10
+ }
11
+ function ownerKey(owner) {
12
+ const normalized = normalizeOwner(owner);
13
+ return JSON.stringify([normalized.scope, normalized.sessionId, normalized.cwd, normalized.projectPath]);
14
+ }
15
+ /** Operation transport only. Pi owns config, credentials, OAuth and reconnect. */
16
+ export class McpAuthFlowService {
17
+ constructor(options = {}) {
18
+ this.options = options;
19
+ this.flows = new Map();
20
+ this.active = new Map();
21
+ this.sessions = new Map();
22
+ this.disposed = false;
23
+ this.t = options.translator ?? createTranslator("en", {});
24
+ }
25
+ start(options) {
26
+ if (this.disposed)
27
+ throw new UserFacingError("mcpAuth.disposed", "MCP authentication service is disposed");
28
+ const owner = normalizeOwner(options.owner);
29
+ if (this.sessions.has(ownerKey(owner)))
30
+ throw new UserFacingError("mcpAuth.sessionAlreadyRunning", "MCP authentication is already running for this session");
31
+ // Pi persisted OAuth state is shared across sessions. Do not race two scoped logins against the same credentials.
32
+ if (this.sessions.size > 0)
33
+ throw new UserFacingError("mcpAuth.machineBusy", "Another MCP authentication operation is running on this machine. Finish it before starting another.");
34
+ if (this.flows.size >= 100)
35
+ throw new UserFacingError("mcpAuth.tooManyFlows", "Too many MCP authentication flows");
36
+ const flow = {
37
+ state: { flowId: randomUUID(), target: "mcp", providerId: "mcp", providerName: this.t("mcpAuth.server", "MCP server"), status: "running", progress: [], ...(options.mode === undefined ? {} : { mcpMode: options.mode }) },
38
+ identity: options.identity, owner, token: Symbol(), isCurrent: () => options.isCurrent(),
39
+ };
40
+ this.flows.set(flow.state.flowId, flow);
41
+ this.active.set(flow.token, flow);
42
+ this.sessions.set(ownerKey(flow.owner), flow);
43
+ flow.timer = setTimeout(() => { this.requestCancel(flow); }, this.options.runningTtlMs ?? 30 * 60_000);
44
+ flow.timer.unref();
45
+ // Keep the real command promise in this scope, not its submission receipt.
46
+ void execution.run({ service: this, token: flow.token }, async () => {
47
+ try {
48
+ await options.run();
49
+ if (flow.commandError !== undefined)
50
+ throw new Error(flow.commandError);
51
+ flow.state.status = "complete";
52
+ }
53
+ catch (error) {
54
+ flow.state.status = "error";
55
+ flow.state.error = userFacingErrorMessage(error, this.t).slice(0, MAX_TEXT);
56
+ }
57
+ finally {
58
+ this.active.delete(flow.token);
59
+ this.sessions.delete(ownerKey(flow.owner));
60
+ flow.pending?.settle(undefined);
61
+ clearTimeout(flow.timer);
62
+ if (!this.disposed) {
63
+ flow.timer = setTimeout(() => { this.flows.delete(flow.state.flowId); }, this.options.terminalTtlMs ?? 5 * 60_000);
64
+ flow.timer.unref();
65
+ }
66
+ }
67
+ });
68
+ return this.snapshot(flow);
69
+ }
70
+ /** Public /mcp waits for startup; its status UI must never escape into chat. */
71
+ async discover(options) {
72
+ if (this.disposed)
73
+ throw new UserFacingError("mcpAuth.disposed", "MCP authentication service is disposed");
74
+ const owner = normalizeOwner(options.owner);
75
+ const scope = execution.getStore();
76
+ const own = scope?.service === this ? this.active.get(scope.token) : undefined;
77
+ if (own && (own.identity !== options.identity || ownerKey(own.owner) !== ownerKey(owner) || !own.isCurrent()))
78
+ throw new UserFacingError("mcpAuth.ownerChanged", "MCP authentication owner is no longer current");
79
+ if (!own && this.sessions.size > 0)
80
+ throw new UserFacingError("mcpAuth.machineBusyShort", "Another MCP authentication operation is running on this machine");
81
+ const flow = own ?? {
82
+ state: { flowId: randomUUID(), providerId: "mcp", providerName: this.t("mcpAuth.server", "MCP server"), status: "running", progress: [] },
83
+ identity: options.identity, owner, token: Symbol(), isCurrent: () => options.isCurrent(),
84
+ };
85
+ if (!own) {
86
+ this.active.set(flow.token, flow);
87
+ this.sessions.set(ownerKey(flow.owner), flow);
88
+ }
89
+ try {
90
+ return await execution.run({ service: this, token: flow.token, discovery: true }, async () => {
91
+ const result = await options.run();
92
+ if (flow.commandError !== undefined)
93
+ throw new UserFacingError("mcpAuth.discoveryFailed", "MCP server discovery failed");
94
+ return result;
95
+ });
96
+ }
97
+ finally {
98
+ if (!own) {
99
+ this.active.delete(flow.token);
100
+ this.sessions.delete(ownerKey(flow.owner));
101
+ }
102
+ }
103
+ }
104
+ assertSessionAvailable(owner) {
105
+ const active = this.sessions.get(ownerKey(owner));
106
+ const scope = execution.getStore();
107
+ if (active && (scope?.service !== this || scope.token !== active.token))
108
+ throw new UserFacingError("mcpAuth.sessionBusy", "MCP authentication operation is running for this session");
109
+ }
110
+ owner(flowId, scope) {
111
+ const flow = this.flows.get(flowId);
112
+ if (flow?.owner.scope !== scope)
113
+ throw new UserFacingError("mcpAuth.flowNotFound", "MCP authentication flow not found");
114
+ return structuredClone(flow.owner);
115
+ }
116
+ get(flowId, owner) { return this.snapshot(this.requireFlow(flowId, owner)); }
117
+ respond(flowId, requestId, value, owner) {
118
+ const flow = this.requireFlow(flowId, owner);
119
+ const pending = flow.pending;
120
+ if (flow.state.status !== "running" || pending?.id !== requestId)
121
+ throw new UserFacingError("mcpAuth.requestNotPending", "MCP authentication request is no longer pending");
122
+ if (typeof value !== "string" || value.length > MAX_TEXT || (pending.values?.includes(value) === false))
123
+ throw new UserFacingError("mcpAuth.invalidResponse", "Invalid MCP authentication response");
124
+ pending.settle(value);
125
+ return this.snapshot(flow);
126
+ }
127
+ cancel(flowId, owner) {
128
+ const flow = this.requireFlow(flowId, owner);
129
+ if (flow.state.status === "running")
130
+ this.requestCancel(flow);
131
+ return this.snapshot(flow);
132
+ }
133
+ cancelSession(owner) {
134
+ const flow = this.sessions.get(ownerKey(owner));
135
+ if (flow)
136
+ this.requestCancel(flow);
137
+ }
138
+ dispose() {
139
+ this.disposed = true;
140
+ for (const flow of new Set([...this.flows.values(), ...this.active.values()])) {
141
+ this.requestCancel(flow);
142
+ clearTimeout(flow.timer);
143
+ }
144
+ this.flows.clear();
145
+ }
146
+ /** Invocation-time lookup: stale socket ancestry must use the ordinary bridge. */
147
+ static current(identity) {
148
+ const scope = execution.getStore();
149
+ const flow = scope?.service.active.get(scope.token);
150
+ if (!scope || !flow || (identity !== undefined && identity !== flow.identity))
151
+ return undefined;
152
+ const isCurrent = () => {
153
+ if (scope.service.disposed || !flow.isCurrent()) {
154
+ scope.service.requestCancel(flow);
155
+ return false;
156
+ }
157
+ return true;
158
+ };
159
+ // An active command must retain its private sink even after its runtime is
160
+ // closed; falling back to the ordinary bridge can expose late OAuth data.
161
+ isCurrent();
162
+ return new McpAuthDispatcher(scope.service, flow, scope.discovery === true, isCurrent, scope.service.t);
163
+ }
164
+ requireFlow(id, owner) {
165
+ const flow = this.flows.get(id);
166
+ if (!flow || ownerKey(flow.owner) !== ownerKey(owner))
167
+ throw new UserFacingError("mcpAuth.flowNotFound", "MCP authentication flow not found");
168
+ return flow;
169
+ }
170
+ snapshot(flow) { return structuredClone(flow.state); }
171
+ requestCancel(flow) {
172
+ flow.state.cancelRequested = true;
173
+ flow.pending?.settle(undefined);
174
+ }
175
+ wait(flow, title, options, values, placeholder) {
176
+ if (flow.state.cancelRequested === true || options?.signal?.aborted === true)
177
+ return Promise.resolve(undefined);
178
+ if (flow.pending)
179
+ return Promise.reject(new UserFacingError("mcpAuth.promptPending", "An MCP authentication request is already pending"));
180
+ if (title.length > MAX_TEXT || (placeholder?.length ?? 0) > MAX_TEXT || (values && (values.length > 200 || values.some((value) => value.length > MAX_TEXT))))
181
+ return Promise.reject(new UserFacingError("mcpAuth.promptTooLarge", "MCP authentication prompt is too large"));
182
+ const id = randomUUID();
183
+ if (values)
184
+ flow.state.select = { requestId: id, message: title, options: values.map((value) => ({ value, label: value })) };
185
+ else
186
+ flow.state.prompt = { requestId: id, message: title, promptType: "text", ...(placeholder === undefined ? {} : { placeholder }) };
187
+ return new Promise((resolve) => {
188
+ let timer;
189
+ const settle = (value) => {
190
+ if (flow.pending?.id !== id)
191
+ return;
192
+ clearTimeout(timer);
193
+ options?.signal?.removeEventListener("abort", abort);
194
+ delete flow.pending;
195
+ delete flow.state.prompt;
196
+ delete flow.state.select;
197
+ resolve(value);
198
+ };
199
+ // Pi aborts the losing input when its browser callback wins. This only
200
+ // dismisses the prompt; it is not cancellation of the auth operation.
201
+ const abort = () => { settle(undefined); };
202
+ flow.pending = { id, settle, ...(values === undefined ? {} : { values }) };
203
+ if (options?.timeout !== undefined && options.timeout > 0) {
204
+ timer = setTimeout(abort, options.timeout);
205
+ timer.unref();
206
+ }
207
+ options?.signal?.addEventListener("abort", abort, { once: true });
208
+ if (options?.signal?.aborted === true)
209
+ abort();
210
+ });
211
+ }
212
+ }
213
+ /** Narrow adapter used by the stable session proxy and builtin openUrl hook. */
214
+ class McpAuthDispatcher {
215
+ constructor(service, flow, discovery, isCurrent, t) {
216
+ this.service = service;
217
+ this.flow = flow;
218
+ this.discovery = discovery;
219
+ this.isCurrent = isCurrent;
220
+ this.t = t;
221
+ }
222
+ selectServer(servers) {
223
+ const result = this.select(this.t("mcpAuth.chooseServer", "Choose an MCP server"), servers.map((server) => server.name));
224
+ if (this.flow.state.select)
225
+ this.flow.state.select.options = servers.map((server) => ({ value: server.name, label: server.name, ...(server.description === undefined ? {} : { description: server.description }) }));
226
+ return result;
227
+ }
228
+ setServer(name) { if (this.isCurrent())
229
+ this.flow.state.providerName = name; }
230
+ isCancelled() { return !this.isCurrent() || this.flow.state.cancelRequested === true; }
231
+ notify(message) {
232
+ if (!this.isCurrent() || this.discovery)
233
+ return;
234
+ const url = this.flow.state.auth?.url;
235
+ if (url !== undefined && message.includes(url))
236
+ return;
237
+ this.flow.state.progress.push(message.slice(0, MAX_TEXT));
238
+ this.flow.state.progress = this.flow.state.progress.slice(-MAX_PROGRESS);
239
+ }
240
+ openUrl(url) {
241
+ if (!this.isCurrent() || this.discovery)
242
+ return;
243
+ if (url.length > MAX_TEXT)
244
+ throw new UserFacingError("mcpAuth.authUrlTooLarge", "MCP authorization URL is too large");
245
+ let parsed;
246
+ try {
247
+ parsed = new URL(url);
248
+ }
249
+ catch {
250
+ throw new UserFacingError("mcpAuth.invalidAuthUrl", "Invalid MCP authorization URL");
251
+ }
252
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:")
253
+ throw new UserFacingError("mcpAuth.authUrlProtocol", "Unsupported MCP authorization URL");
254
+ this.flow.state.auth = { url };
255
+ this.flow.state.progress = this.flow.state.progress.filter((message) => !message.includes(url));
256
+ }
257
+ error(message) { if (this.isCurrent()) {
258
+ this.flow.commandError = message.slice(0, MAX_TEXT);
259
+ this.notify(message);
260
+ } }
261
+ input(title, placeholder, options) {
262
+ if (!this.isCurrent())
263
+ return Promise.resolve(undefined);
264
+ if (this.discovery) {
265
+ this.flow.commandError = "MCP discovery cannot request input";
266
+ return Promise.reject(new UserFacingError("mcpAuth.discoveryInput", "MCP discovery cannot request input"));
267
+ }
268
+ return this.service.wait(this.flow, title, options, undefined, placeholder);
269
+ }
270
+ select(title, values, options) {
271
+ if (!this.isCurrent())
272
+ return Promise.resolve(undefined);
273
+ if (this.discovery) {
274
+ this.flow.commandError = "MCP discovery cannot request input";
275
+ return Promise.reject(new UserFacingError("mcpAuth.discoveryInput", "MCP discovery cannot request input"));
276
+ }
277
+ return this.service.wait(this.flow, title, options, values);
278
+ }
279
+ async confirm(title, message, options) {
280
+ const selected = this.select(`${title}\n${message}`, ["Yes", "No"], options);
281
+ if (this.flow.state.select)
282
+ this.flow.state.select.options = [
283
+ { value: "Yes", label: this.t("mcpAuth.yes", "Yes") },
284
+ { value: "No", label: this.t("mcpAuth.no", "No") },
285
+ ];
286
+ return await selected === "Yes";
287
+ }
288
+ }
289
+ //# sourceMappingURL=mcpAuthFlowService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpAuthFlowService.js","sourceRoot":"","sources":["../../../src/server/sessions/mcpAuthFlowService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ import { normalizeRequestCwd } from "../workingDirectory.js";
2
+ import { attachWorkbenchAccessHandle, decodeManagementContext, MANAGEMENT_EMBED_CONTEXT_HEADER, WORKBENCH_ACCESS_HANDLE_HEADER } from "../managementEmbed.js";
3
+ import { UserFacingError, userFacingErrorMessage } from "../../shared/i18n.js";
4
+ import { loadNodeTranslator } from "../../localization.js";
5
+ export function registerMcpAuthRoutes(app, sessions, prefix = "", translator = loadNodeTranslator("server")) {
6
+ app.get(`${prefix}/sessions/:sessionId/mcp/auth/servers`, async (request, reply) => {
7
+ reply.header("cache-control", "no-store");
8
+ try {
9
+ const query = record(request.query);
10
+ onlyKeys(query, ["cwd", "embed", "token"]);
11
+ const cwd = string(query, "cwd");
12
+ if (!cwd)
13
+ throw new UserFacingError("mcpAuth.cwdEmpty", "cwd must not be empty");
14
+ return await sessions.mcpAuthServers({ id: identifier(request.params.sessionId), cwd: normalizeRequestCwd(cwd) }, managementContext(request.headers));
15
+ }
16
+ catch (error) {
17
+ return reply.code(400).send({ error: userFacingErrorMessage(error, translator) });
18
+ }
19
+ });
20
+ app.post(`${prefix}/sessions/:sessionId/mcp/auth`, async (request, reply) => {
21
+ reply.header("cache-control", "no-store");
22
+ try {
23
+ onlyKeys(record(request.query), ["embed", "token"]);
24
+ const body = record(request.body);
25
+ onlyKeys(body, ["cwd", "mode", "serverName"]);
26
+ const cwd = string(body, "cwd");
27
+ if (!cwd)
28
+ throw new UserFacingError("mcpAuth.cwdEmpty", "cwd must not be empty");
29
+ const mode = body["mode"];
30
+ if (mode !== "login" && mode !== "logout")
31
+ throw new UserFacingError("mcpAuth.invalidMode", "mode must be login or logout");
32
+ const serverName = body["serverName"] === undefined ? undefined : string(body, "serverName");
33
+ return await sessions.startMcpAuth({ id: identifier(request.params.sessionId), cwd: normalizeRequestCwd(cwd) }, mode, serverName, managementContext(request.headers));
34
+ }
35
+ catch (error) {
36
+ return reply.code(400).send({ error: userFacingErrorMessage(error, translator) });
37
+ }
38
+ });
39
+ app.get(`${prefix}/auth/mcp/:flowId`, async (request, reply) => {
40
+ reply.header("cache-control", "no-store");
41
+ try {
42
+ onlyKeys(record(request.query), ["embed", "token"]);
43
+ return await sessions.mcpAuthFlow(identifier(request.params.flowId), managementContext(request.headers));
44
+ }
45
+ catch (error) {
46
+ return reply.code(404).send({ error: userFacingErrorMessage(error, translator) });
47
+ }
48
+ });
49
+ app.post(`${prefix}/auth/mcp/:flowId/respond`, async (request, reply) => {
50
+ reply.header("cache-control", "no-store");
51
+ try {
52
+ onlyKeys(record(request.query), ["embed", "token"]);
53
+ const body = record(request.body);
54
+ onlyKeys(body, ["requestId", "value"]);
55
+ return await sessions.respondToMcpAuthFlow(identifier(request.params.flowId), string(body, "requestId"), string(body, "value"), managementContext(request.headers));
56
+ }
57
+ catch (error) {
58
+ return reply.code(400).send({ error: userFacingErrorMessage(error, translator) });
59
+ }
60
+ });
61
+ app.post(`${prefix}/auth/mcp/:flowId/cancel`, async (request, reply) => {
62
+ reply.header("cache-control", "no-store");
63
+ try {
64
+ onlyKeys(record(request.query), ["embed", "token"]);
65
+ if (request.body !== undefined)
66
+ onlyKeys(record(request.body), []);
67
+ return await sessions.cancelMcpAuthFlow(identifier(request.params.flowId), managementContext(request.headers));
68
+ }
69
+ catch (error) {
70
+ return reply.code(400).send({ error: userFacingErrorMessage(error, translator) });
71
+ }
72
+ });
73
+ }
74
+ function record(value) {
75
+ if (typeof value !== "object" || value === null || Array.isArray(value))
76
+ throw new UserFacingError("mcpAuth.requestObject", "Expected a request object");
77
+ return Object.fromEntries(Object.entries(value));
78
+ }
79
+ function string(body, key) {
80
+ const value = body[key];
81
+ if (typeof value !== "string" || value.length > 32 * 1024)
82
+ throw new UserFacingError("mcpAuth.invalidString", "{field} must be a string of at most 32768 characters", { field: key });
83
+ return value;
84
+ }
85
+ function onlyKeys(body, keys) {
86
+ if (Object.keys(body).some((key) => !keys.includes(key)))
87
+ throw new UserFacingError("mcpAuth.unexpectedField", "Unexpected MCP authentication field");
88
+ }
89
+ function identifier(value) {
90
+ if (!value || value.length > 512)
91
+ throw new UserFacingError("mcpAuth.invalidIdentifier", "Invalid MCP authentication identifier");
92
+ return value;
93
+ }
94
+ function managementContext(headers) {
95
+ const raw = headers[MANAGEMENT_EMBED_CONTEXT_HEADER];
96
+ if (raw === undefined)
97
+ return undefined;
98
+ const context = decodeManagementContext(Array.isArray(raw) ? raw[0] : raw);
99
+ if (context === undefined)
100
+ throw new UserFacingError("mcpAuth.invalidManagementContext", "Invalid management context");
101
+ const handle = headers[WORKBENCH_ACCESS_HANDLE_HEADER];
102
+ return attachWorkbenchAccessHandle(context, Array.isArray(handle) ? handle[0] : handle);
103
+ }
104
+ //# sourceMappingURL=mcpAuthRoutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpAuthRoutes.js","sourceRoot":"","sources":["../../../src/server/sessions/mcpAuthRoutes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import { chmod, lstat, mkdir, realpath } from "node:fs/promises";
2
+ import { isAbsolute, join, relative, resolve } from "node:path";
3
+ import { pathToFileURL } from "node:url";
4
+ import { createHash } from "node:crypto";
5
+ import { getAgentDir, VERSION } from "../../piSdk.js";
6
+ import { piRuntimePackageInfo } from "../../piRuntime.js";
7
+ export function mcpOAuthStorageDirectory(projectScopeDirectory, managementScope) {
8
+ const root = join(projectScopeDirectory, "mcp");
9
+ return managementScope === undefined ? root : join(root, "identities", createHash("sha256").update(managementScope).digest("hex"));
10
+ }
11
+ /**
12
+ * Pi 1.3.0 exposes credential injection but not its constructor. These three
13
+ * version-pinned internal modules must come from the same selected host SDK.
14
+ */
15
+ export async function createMcpOAuthCredentialOptions(options, dependencies = {}) {
16
+ const info = await (dependencies.packageInfo ?? piRuntimePackageInfo)();
17
+ if (info.version !== "1.3.0" || (dependencies.sdkVersion ?? VERSION) !== info.version) {
18
+ throw new Error("Scoped MCP authentication requires the selected Pi SDK version 1.3.0 with a matching package identity");
19
+ }
20
+ const importModule = dependencies.importModule ?? ((url) => import(url));
21
+ const modules = await Promise.all([
22
+ loadInternal(info.directory, "dist/extensions/mcp/oauth.js", importModule),
23
+ loadInternal(info.directory, "dist/core/auth-storage.js", importModule),
24
+ loadInternal(info.directory, "dist/extensions/mcp/config.js", importModule),
25
+ ]);
26
+ const [credentials, backend, config] = modules;
27
+ if (!isCredentialModule(credentials) || !isBackendModule(backend) || !isConfigModule(config)) {
28
+ throw new Error("The selected Pi 1.3.0 SDK does not expose the expected MCP credential adapter contracts");
29
+ }
30
+ const directory = resolve(options.directory);
31
+ const lockDir = join(directory, "refresh-locks");
32
+ await privateDirectory(directory);
33
+ await privateDirectory(lockDir);
34
+ const authPath = join(directory, "mcp-auth.json");
35
+ const logPath = join(directory, "mcp.log");
36
+ await privateFileIfPresent(authPath);
37
+ await privateFileIfPresent(logPath);
38
+ const store = new credentials.McpOAuthCredentialStore(new backend.FileAuthStorageBackend(authPath), lockDir);
39
+ const configAgentDir = options.configAgentDir ?? getAgentDir();
40
+ return {
41
+ credentials: store,
42
+ logPath,
43
+ loadConfig: (ctx) => config.loadMcpConfig({ agentDir: configAgentDir, cwd: ctx.cwd, projectTrusted: ctx.isProjectTrusted() }),
44
+ };
45
+ }
46
+ async function loadInternal(root, file, importModule) {
47
+ const canonicalRoot = await realpath(root);
48
+ const path = await realpath(join(root, file));
49
+ const child = relative(canonicalRoot, path);
50
+ if (isAbsolute(child) || child === ".." || child.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`)) {
51
+ throw new Error("The MCP credential adapter module is outside the selected Pi SDK");
52
+ }
53
+ return importModule(pathToFileURL(path).href);
54
+ }
55
+ async function privateDirectory(path) {
56
+ await mkdir(path, { recursive: true, mode: 0o700 });
57
+ const entry = await lstat(path);
58
+ if (entry.isSymbolicLink() || !entry.isDirectory())
59
+ throw new Error("MCP private storage must be a directory, not a symbolic link");
60
+ await chmod(path, 0o700);
61
+ }
62
+ async function privateFileIfPresent(path) {
63
+ let entry;
64
+ try {
65
+ entry = await lstat(path);
66
+ }
67
+ catch (error) {
68
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
69
+ return;
70
+ throw error;
71
+ }
72
+ if (entry.isSymbolicLink() || !entry.isFile())
73
+ throw new Error("MCP private storage must be a regular file");
74
+ await chmod(path, 0o600);
75
+ }
76
+ function isRecord(value) { return typeof value === "object" && value !== null; }
77
+ function hasConstructor(value, methods) {
78
+ if (typeof value !== "function" || !("prototype" in value))
79
+ return false;
80
+ const prototype = value.prototype;
81
+ return isRecord(prototype) && methods.every((method) => typeof prototype[method] === "function");
82
+ }
83
+ function isCredentialModule(value) {
84
+ return isRecord(value) && hasConstructor(value["McpOAuthCredentialStore"], ["forServer", "tokens", "remove"]);
85
+ }
86
+ function isBackendModule(value) {
87
+ return isRecord(value) && hasConstructor(value["FileAuthStorageBackend"], ["withLock", "withLockAsync"]);
88
+ }
89
+ function isConfigModule(value) {
90
+ return isRecord(value) && typeof value["loadMcpConfig"] === "function";
91
+ }
92
+ //# sourceMappingURL=mcpOAuthCredentialAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpOAuthCredentialAdapter.js","sourceRoot":"","sources":["../../../src/server/sessions/mcpOAuthCredentialAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import { UserFacingError } from "../../shared/i18n.js";
2
+ /**
3
+ * Resolve a message shortcut against the current root-to-leaf branch. Non-user
4
+ * checkpoints retain the intervening history up to, but not including, the next
5
+ * distinct user/assistant checkpoint, or through a question but not its answer.
6
+ * Pi still owns the actual tree mutation.
7
+ * Exact-entry tree operations do not use this resolver.
8
+ */
9
+ export function messageHistoryTargetId(branch, entryId) {
10
+ const index = branch.findIndex((entry) => isRecord(entry) && entry["id"] === entryId);
11
+ if (index < 0)
12
+ throw new UserFacingError("session.checkpointUnavailable", "This message is no longer available on the active session branch.");
13
+ const entry = branch[index];
14
+ // A question is answered from its durable tool result, without retaining any
15
+ // earlier answer (custom messages are otherwise part of a checkpoint's tail).
16
+ if (isQuestionResult(entry))
17
+ return entryId;
18
+ // Pi restores a selected user message to the editor by positioning before it.
19
+ if (isRecord(entry) && entry["type"] === "message" && isRecord(entry["message"])
20
+ && entry["message"]["role"] === "user")
21
+ return entryId;
22
+ let targetId = entryId;
23
+ for (let nextIndex = index + 1; nextIndex < branch.length; nextIndex += 1) {
24
+ const next = branch[nextIndex];
25
+ if (!isRecord(next) || typeof next["id"] !== "string" || isConversationCheckpoint(next))
26
+ break;
27
+ targetId = next["id"];
28
+ // The agent message that produced a question retains the request, not any
29
+ // later answer, just like selecting the question itself.
30
+ if (isQuestionResult(next))
31
+ break;
32
+ }
33
+ return targetId;
34
+ }
35
+ function isQuestionResult(entry) {
36
+ if (!isRecord(entry) || entry["type"] !== "message" || !isRecord(entry["message"]))
37
+ return false;
38
+ const message = entry["message"];
39
+ const details = message["details"];
40
+ return message["role"] === "toolResult" && message["toolName"] === "ask_user" && message["isError"] === false
41
+ && isRecord(details) && isRecord(details["ask"]);
42
+ }
43
+ /**
44
+ * Boundaries are intrinsic conversation checkpoints, not transient plugin
45
+ * availability (busy/archived/disabled buttons must not change the cutoff).
46
+ * Tool-only assistant entries have no core history header and stay in the
47
+ * preceding checkpoint along with their results and other technical entries.
48
+ */
49
+ function isConversationCheckpoint(entry) {
50
+ if (entry["type"] !== "message" || !isRecord(entry["message"]))
51
+ return false;
52
+ const message = entry["message"];
53
+ if (message["role"] === "user")
54
+ return true;
55
+ if (message["role"] !== "assistant")
56
+ return false;
57
+ const content = message["content"];
58
+ if (typeof content === "string")
59
+ return content !== "";
60
+ if (!Array.isArray(content))
61
+ return content != null;
62
+ return content.some((part) => {
63
+ if (!isRecord(part))
64
+ return true;
65
+ if (part["type"] === "toolCall")
66
+ return false;
67
+ if (part["type"] === "text")
68
+ return typeof part["text"] === "string" && part["text"] !== "";
69
+ if (part["type"] === "thinking") {
70
+ const text = part["thinking"] ?? part["text"];
71
+ return typeof text === "string" && text !== "";
72
+ }
73
+ return true;
74
+ });
75
+ }
76
+ function isRecord(value) {
77
+ return typeof value === "object" && value !== null && !Array.isArray(value);
78
+ }
79
+ //# sourceMappingURL=messageHistoryTarget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messageHistoryTarget.js","sourceRoot":"","sources":["../../../src/server/sessions/messageHistoryTarget.ts"],"names":[],"mappings":"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"}