@vincenthanxiaodu/pi-web 1.202608.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 (376) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/dist/cli.js +1149 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/client/apple-touch-icon.png +0 -0
  6. package/dist/client/assets/CodeViewer-D_Q6ljLV.js +4 -0
  7. package/dist/client/assets/TerminalPanel-CTGixJIz.js +187 -0
  8. package/dist/client/assets/index-C2phil_t.js +5637 -0
  9. package/dist/client/assets/vendor-editor-core-CXO8gGab.js +12 -0
  10. package/dist/client/assets/vendor-editor-languages-CpW4sJsX.js +46 -0
  11. package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +1 -0
  12. package/dist/client/assets/vendor-terminal-BrP-ENHg.css +1 -0
  13. package/dist/client/assets/vendor-terminal-D8k4UKM2.js +35 -0
  14. package/dist/client/favicon.svg +11 -0
  15. package/dist/client/index.html +124 -0
  16. package/dist/client/manifest.webmanifest +24 -0
  17. package/dist/client/pwa-icon-192.png +0 -0
  18. package/dist/client/pwa-icon-512.png +0 -0
  19. package/dist/config.js +505 -0
  20. package/dist/config.js.map +1 -0
  21. package/dist/docker/piWebDockerCommandPlan.js +212 -0
  22. package/dist/docker/piWebDockerCommandPlan.js.map +1 -0
  23. package/dist/environment.js +4 -0
  24. package/dist/environment.js.map +1 -0
  25. package/dist/nativeServices/installedServiceDefinitions.js +602 -0
  26. package/dist/nativeServices/installedServiceDefinitions.js.map +1 -0
  27. package/dist/nativeServices/serviceAction.js +174 -0
  28. package/dist/nativeServices/serviceAction.js.map +1 -0
  29. package/dist/nativeServices/serviceDoctor.js +783 -0
  30. package/dist/nativeServices/serviceDoctor.js.map +1 -0
  31. package/dist/nativeServices/serviceInstall.js +35 -0
  32. package/dist/nativeServices/serviceInstall.js.map +1 -0
  33. package/dist/nativeServices/servicePlan.js +358 -0
  34. package/dist/nativeServices/servicePlan.js.map +1 -0
  35. package/dist/nativeServices/serviceProbe.js +447 -0
  36. package/dist/nativeServices/serviceProbe.js.map +1 -0
  37. package/dist/nativeServices/serviceRendering.js +132 -0
  38. package/dist/nativeServices/serviceRendering.js.map +1 -0
  39. package/dist/pi-web-plugins/git/browser/git-contract.js +108 -0
  40. package/dist/pi-web-plugins/git/browser/git-panel.js +609 -0
  41. package/dist/pi-web-plugins/git/browser/gitFileList.js +43 -0
  42. package/dist/pi-web-plugins/git/browser/gitFileShared.js +16 -0
  43. package/dist/pi-web-plugins/git/browser/gitFileTree.js +81 -0
  44. package/dist/pi-web-plugins/git/browser/gitFileViewPreference.js +35 -0
  45. package/dist/pi-web-plugins/git/browser/gitRoute.js +42 -0
  46. package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +10 -0
  47. package/dist/pi-web-plugins/git/browser/unifiedDiff.js +301 -0
  48. package/dist/pi-web-plugins/git/git-backend.js +439 -0
  49. package/dist/pi-web-plugins/git/package.json +16 -0
  50. package/dist/pi-web-plugins/git/server-plugin.js +176 -0
  51. package/dist/pi-web-plugins/info/infoInternals.js +222 -0
  52. package/dist/pi-web-plugins/info/package.json +9 -0
  53. package/dist/pi-web-plugins/info/pi-web-plugin.js +48 -0
  54. package/dist/pi-web-plugins/relays/markdownDocument.js +81 -0
  55. package/dist/pi-web-plugins/relays/package.json +9 -0
  56. package/dist/pi-web-plugins/relays/pi-web-plugin.js +44 -0
  57. package/dist/pi-web-plugins/relays/relayDiscovery.js +228 -0
  58. package/dist/pi-web-plugins/relays/relaysPanelElement.js +550 -0
  59. package/dist/pi-web-plugins/relays/vendor/README.md +24 -0
  60. package/dist/pi-web-plugins/relays/vendor/marked.esm.js +76 -0
  61. package/dist/pi-web-plugins/updates/package.json +9 -0
  62. package/dist/pi-web-plugins/updates/pi-web-plugin.js +185 -0
  63. package/dist/pi-web-plugins/updates/updatesLogic.js +97 -0
  64. package/dist/pi-web-plugins/workspace-tasks/config.js +91 -0
  65. package/dist/pi-web-plugins/workspace-tasks/package.json +9 -0
  66. package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +48 -0
  67. package/dist/pi-web-plugins/workspace-tasks/taskRunner.js +12 -0
  68. package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +288 -0
  69. package/dist/pi-web-plugins/workspace-tasks/workspaceTasksClient.js +47 -0
  70. package/dist/piWebVersionReport.js +278 -0
  71. package/dist/piWebVersionReport.js.map +1 -0
  72. package/dist/plugin-api.d.ts +222 -0
  73. package/dist/pluginRecoveryCli.js +172 -0
  74. package/dist/pluginRecoveryCli.js.map +1 -0
  75. package/dist/server/activeAgentProfileProvider.js +25 -0
  76. package/dist/server/activeAgentProfileProvider.js.map +1 -0
  77. package/dist/server/activity/workspaceActivityService.js +106 -0
  78. package/dist/server/activity/workspaceActivityService.js.map +1 -0
  79. package/dist/server/app.js +218 -0
  80. package/dist/server/app.js.map +1 -0
  81. package/dist/server/browserMessageProjection.js +54 -0
  82. package/dist/server/browserMessageProjection.js.map +1 -0
  83. package/dist/server/configRoutes.js +293 -0
  84. package/dist/server/configRoutes.js.map +1 -0
  85. package/dist/server/diagnostics/nodePtyNativeModule.js +36 -0
  86. package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -0
  87. package/dist/server/diagnostics/nodePtySpawnHelper.js +135 -0
  88. package/dist/server/diagnostics/nodePtySpawnHelper.js.map +1 -0
  89. package/dist/server/git/gitEnv.js +15 -0
  90. package/dist/server/git/gitEnv.js.map +1 -0
  91. package/dist/server/goals/goalArchive.js +184 -0
  92. package/dist/server/goals/goalArchive.js.map +1 -0
  93. package/dist/server/goals/goalFile.js +200 -0
  94. package/dist/server/goals/goalFile.js.map +1 -0
  95. package/dist/server/goals/goalStore.js +65 -0
  96. package/dist/server/goals/goalStore.js.map +1 -0
  97. package/dist/server/index.js +7 -0
  98. package/dist/server/index.js.map +1 -0
  99. package/dist/server/machines/machineClient.js +191 -0
  100. package/dist/server/machines/machineClient.js.map +1 -0
  101. package/dist/server/machines/machinePluginProxyRoutes.js +247 -0
  102. package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -0
  103. package/dist/server/machines/machineProxyRoutes.js +318 -0
  104. package/dist/server/machines/machineProxyRoutes.js.map +1 -0
  105. package/dist/server/machines/machineRoutes.js +56 -0
  106. package/dist/server/machines/machineRoutes.js.map +1 -0
  107. package/dist/server/machines/machineService.js +274 -0
  108. package/dist/server/machines/machineService.js.map +1 -0
  109. package/dist/server/machines/machineStore.js +143 -0
  110. package/dist/server/machines/machineStore.js.map +1 -0
  111. package/dist/server/piPackageRoutes.js +91 -0
  112. package/dist/server/piPackageRoutes.js.map +1 -0
  113. package/dist/server/piPackageService.js +101 -0
  114. package/dist/server/piPackageService.js.map +1 -0
  115. package/dist/server/piWebPluginCatalog.js +584 -0
  116. package/dist/server/piWebPluginCatalog.js.map +1 -0
  117. package/dist/server/piWebPluginLifecycle.js +162 -0
  118. package/dist/server/piWebPluginLifecycle.js.map +1 -0
  119. package/dist/server/piWebPluginService.js +224 -0
  120. package/dist/server/piWebPluginService.js.map +1 -0
  121. package/dist/server/piWebReleaseLookupCache.js +37 -0
  122. package/dist/server/piWebReleaseLookupCache.js.map +1 -0
  123. package/dist/server/piWebStatus.js +624 -0
  124. package/dist/server/piWebStatus.js.map +1 -0
  125. package/dist/server/piWebStatusCache.js +45 -0
  126. package/dist/server/piWebStatusCache.js.map +1 -0
  127. package/dist/server/plugins/pluginBackendProxyRoutes.js +69 -0
  128. package/dist/server/plugins/pluginBackendProxyRoutes.js.map +1 -0
  129. package/dist/server/plugins/serverPluginExec.js +184 -0
  130. package/dist/server/plugins/serverPluginExec.js.map +1 -0
  131. package/dist/server/plugins/serverPluginRuntime.js +480 -0
  132. package/dist/server/plugins/serverPluginRuntime.js.map +1 -0
  133. package/dist/server/projectTrustRoutes.js +80 -0
  134. package/dist/server/projectTrustRoutes.js.map +1 -0
  135. package/dist/server/projects/directorySuggestions.js +207 -0
  136. package/dist/server/projects/directorySuggestions.js.map +1 -0
  137. package/dist/server/projects/projectService.js +33 -0
  138. package/dist/server/projects/projectService.js.map +1 -0
  139. package/dist/server/realtime/sessionEventHub.js +93 -0
  140. package/dist/server/realtime/sessionEventHub.js.map +1 -0
  141. package/dist/server/requestCancellation.js +32 -0
  142. package/dist/server/requestCancellation.js.map +1 -0
  143. package/dist/server/sessiond/agentHttpDispatcher.js +108 -0
  144. package/dist/server/sessiond/agentHttpDispatcher.js.map +1 -0
  145. package/dist/server/sessiond/agentProcessEnvironment.js +61 -0
  146. package/dist/server/sessiond/agentProcessEnvironment.js.map +1 -0
  147. package/dist/server/sessiond/pluginBackendRoutes.js +64 -0
  148. package/dist/server/sessiond/pluginBackendRoutes.js.map +1 -0
  149. package/dist/server/sessiond/sessionDaemonShutdown.js +31 -0
  150. package/dist/server/sessiond/sessionDaemonShutdown.js.map +1 -0
  151. package/dist/server/sessiond/sessionProxyRoutes.js +61 -0
  152. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -0
  153. package/dist/server/sessiond/sessionServiceDependencies.js +34 -0
  154. package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -0
  155. package/dist/server/sessiond/sessiondStateOwnership.js +235 -0
  156. package/dist/server/sessiond/sessiondStateOwnership.js.map +1 -0
  157. package/dist/server/sessiond/workspaceCatalogRoutes.js +31 -0
  158. package/dist/server/sessiond/workspaceCatalogRoutes.js.map +1 -0
  159. package/dist/server/sessiond/workspaceRemovalRoutes.js +41 -0
  160. package/dist/server/sessiond/workspaceRemovalRoutes.js.map +1 -0
  161. package/dist/server/sessiond.js +387 -0
  162. package/dist/server/sessiond.js.map +1 -0
  163. package/dist/server/sessions/askUserTool.js +102 -0
  164. package/dist/server/sessions/askUserTool.js.map +1 -0
  165. package/dist/server/sessions/attachmentService.js +119 -0
  166. package/dist/server/sessions/attachmentService.js.map +1 -0
  167. package/dist/server/sessions/authProviderOptions.js +50 -0
  168. package/dist/server/sessions/authProviderOptions.js.map +1 -0
  169. package/dist/server/sessions/authRoutes.js +59 -0
  170. package/dist/server/sessions/authRoutes.js.map +1 -0
  171. package/dist/server/sessions/authService.js +122 -0
  172. package/dist/server/sessions/authService.js.map +1 -0
  173. package/dist/server/sessions/builtinCommands.js +27 -0
  174. package/dist/server/sessions/builtinCommands.js.map +1 -0
  175. package/dist/server/sessions/dockerEnvironmentFacts.js +254 -0
  176. package/dist/server/sessions/dockerEnvironmentFacts.js.map +1 -0
  177. package/dist/server/sessions/editPreview.js +196 -0
  178. package/dist/server/sessions/editPreview.js.map +1 -0
  179. package/dist/server/sessions/extensionDialogWaiters.js +76 -0
  180. package/dist/server/sessions/extensionDialogWaiters.js.map +1 -0
  181. package/dist/server/sessions/globalProviderPolicy.js +167 -0
  182. package/dist/server/sessions/globalProviderPolicy.js.map +1 -0
  183. package/dist/server/sessions/interruptedRunStore.js +147 -0
  184. package/dist/server/sessions/interruptedRunStore.js.map +1 -0
  185. package/dist/server/sessions/messagePaging.js +43 -0
  186. package/dist/server/sessions/messagePaging.js.map +1 -0
  187. package/dist/server/sessions/modelCatalogRefresher.js +193 -0
  188. package/dist/server/sessions/modelCatalogRefresher.js.map +1 -0
  189. package/dist/server/sessions/oauthLoginFlowService.js +346 -0
  190. package/dist/server/sessions/oauthLoginFlowService.js.map +1 -0
  191. package/dist/server/sessions/pendingAskStore.js +275 -0
  192. package/dist/server/sessions/pendingAskStore.js.map +1 -0
  193. package/dist/server/sessions/pendingExtensionDialogStore.js +196 -0
  194. package/dist/server/sessions/pendingExtensionDialogStore.js.map +1 -0
  195. package/dist/server/sessions/piSessionManagerGateway.js +246 -0
  196. package/dist/server/sessions/piSessionManagerGateway.js.map +1 -0
  197. package/dist/server/sessions/piSessionService.js +4059 -0
  198. package/dist/server/sessions/piSessionService.js.map +1 -0
  199. package/dist/server/sessions/plainTextTheme.js +112 -0
  200. package/dist/server/sessions/plainTextTheme.js.map +1 -0
  201. package/dist/server/sessions/sessionArchiveStore.js +273 -0
  202. package/dist/server/sessions/sessionArchiveStore.js.map +1 -0
  203. package/dist/server/sessions/sessionArchiveTree.js +35 -0
  204. package/dist/server/sessions/sessionArchiveTree.js.map +1 -0
  205. package/dist/server/sessions/sessionCleanup.js +157 -0
  206. package/dist/server/sessions/sessionCleanup.js.map +1 -0
  207. package/dist/server/sessions/sessionCommandService.js +336 -0
  208. package/dist/server/sessions/sessionCommandService.js.map +1 -0
  209. package/dist/server/sessions/sessionEnvironmentFacts.js +48 -0
  210. package/dist/server/sessions/sessionEnvironmentFacts.js.map +1 -0
  211. package/dist/server/sessions/sessionFileFormat.js +27 -0
  212. package/dist/server/sessions/sessionFileFormat.js.map +1 -0
  213. package/dist/server/sessions/sessionFileHeader.js +104 -0
  214. package/dist/server/sessions/sessionFileHeader.js.map +1 -0
  215. package/dist/server/sessions/sessionModelScope.js +141 -0
  216. package/dist/server/sessions/sessionModelScope.js.map +1 -0
  217. package/dist/server/sessions/sessionNameGenerator.js +90 -0
  218. package/dist/server/sessions/sessionNameGenerator.js.map +1 -0
  219. package/dist/server/sessions/sessionNotificationStore.js +484 -0
  220. package/dist/server/sessions/sessionNotificationStore.js.map +1 -0
  221. package/dist/server/sessions/sessionRoutes.js +744 -0
  222. package/dist/server/sessions/sessionRoutes.js.map +1 -0
  223. package/dist/server/sessions/sessionRuntimeStore.js +2 -0
  224. package/dist/server/sessions/sessionRuntimeStore.js.map +1 -0
  225. package/dist/server/sessions/sessionService.js +2 -0
  226. package/dist/server/sessions/sessionService.js.map +1 -0
  227. package/dist/server/sessions/sessionSummaryScanner.js +491 -0
  228. package/dist/server/sessions/sessionSummaryScanner.js.map +1 -0
  229. package/dist/server/sessions/sessionTreeProjection.js +250 -0
  230. package/dist/server/sessions/sessionTreeProjection.js.map +1 -0
  231. package/dist/server/sessions/sessionUnreadStore.js +520 -0
  232. package/dist/server/sessions/sessionUnreadStore.js.map +1 -0
  233. package/dist/server/sessions/shutdownDrain.js +73 -0
  234. package/dist/server/sessions/shutdownDrain.js.map +1 -0
  235. package/dist/server/sessions/spawnSessionTool.js +48 -0
  236. package/dist/server/sessions/spawnSessionTool.js.map +1 -0
  237. package/dist/server/sessions/spawnSubsessionTool.js +216 -0
  238. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -0
  239. package/dist/server/sessions/spawnTargetResolver.js +23 -0
  240. package/dist/server/sessions/spawnTargetResolver.js.map +1 -0
  241. package/dist/server/sessions/subsessionTranscript.js +235 -0
  242. package/dist/server/sessions/subsessionTranscript.js.map +1 -0
  243. package/dist/server/status/machineStatusRoutes.js +8 -0
  244. package/dist/server/status/machineStatusRoutes.js.map +1 -0
  245. package/dist/server/status/machineStatusService.js +181 -0
  246. package/dist/server/status/machineStatusService.js.map +1 -0
  247. package/dist/server/status/workspaceAttribution.js +87 -0
  248. package/dist/server/status/workspaceAttribution.js.map +1 -0
  249. package/dist/server/storage/projectStore.js +88 -0
  250. package/dist/server/storage/projectStore.js.map +1 -0
  251. package/dist/server/terminalProxyRoutes.js +141 -0
  252. package/dist/server/terminalProxyRoutes.js.map +1 -0
  253. package/dist/server/terminals/terminalRoutes.js +155 -0
  254. package/dist/server/terminals/terminalRoutes.js.map +1 -0
  255. package/dist/server/terminals/terminalService.js +305 -0
  256. package/dist/server/terminals/terminalService.js.map +1 -0
  257. package/dist/server/terminals/terminalSize.js +17 -0
  258. package/dist/server/terminals/terminalSize.js.map +1 -0
  259. package/dist/server/types.js +2 -0
  260. package/dist/server/types.js.map +1 -0
  261. package/dist/server/updates/fleetRoutes.js +111 -0
  262. package/dist/server/updates/fleetRoutes.js.map +1 -0
  263. package/dist/server/updates/restartRoutes.js +48 -0
  264. package/dist/server/updates/restartRoutes.js.map +1 -0
  265. package/dist/server/updates/selfUpdateRoutes.js +145 -0
  266. package/dist/server/updates/selfUpdateRoutes.js.map +1 -0
  267. package/dist/server/webSocketBridge.js +32 -0
  268. package/dist/server/webSocketBridge.js.map +1 -0
  269. package/dist/server/workingDirectory.js +44 -0
  270. package/dist/server/workingDirectory.js.map +1 -0
  271. package/dist/server/workspaceExplorerRoutes.js +147 -0
  272. package/dist/server/workspaceExplorerRoutes.js.map +1 -0
  273. package/dist/server/workspaces/effectivePathAccess.js +8 -0
  274. package/dist/server/workspaces/effectivePathAccess.js.map +1 -0
  275. package/dist/server/workspaces/fileContentService.js +190 -0
  276. package/dist/server/workspaces/fileContentService.js.map +1 -0
  277. package/dist/server/workspaces/filePreviewResponseHeaders.js +18 -0
  278. package/dist/server/workspaces/filePreviewResponseHeaders.js.map +1 -0
  279. package/dist/server/workspaces/filePreviewResponsePolicy.js +55 -0
  280. package/dist/server/workspaces/filePreviewResponsePolicy.js.map +1 -0
  281. package/dist/server/workspaces/filePreviewService.js +81 -0
  282. package/dist/server/workspaces/filePreviewService.js.map +1 -0
  283. package/dist/server/workspaces/fileSuggestions.js +520 -0
  284. package/dist/server/workspaces/fileSuggestions.js.map +1 -0
  285. package/dist/server/workspaces/fileTreeService.js +35 -0
  286. package/dist/server/workspaces/fileTreeService.js.map +1 -0
  287. package/dist/server/workspaces/pathAccessPolicy.js +90 -0
  288. package/dist/server/workspaces/pathAccessPolicy.js.map +1 -0
  289. package/dist/server/workspaces/pathSafety.js +45 -0
  290. package/dist/server/workspaces/pathSafety.js.map +1 -0
  291. package/dist/server/workspaces/projectPiWebConfig.js +61 -0
  292. package/dist/server/workspaces/projectPiWebConfig.js.map +1 -0
  293. package/dist/server/workspaces/projectWorkspaceCwds.js +17 -0
  294. package/dist/server/workspaces/projectWorkspaceCwds.js.map +1 -0
  295. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js +402 -0
  296. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js.map +1 -0
  297. package/dist/server/workspaces/workspaceCatalog.js +47 -0
  298. package/dist/server/workspaces/workspaceCatalog.js.map +1 -0
  299. package/dist/server/workspaces/workspaceContext.js +6 -0
  300. package/dist/server/workspaces/workspaceContext.js.map +1 -0
  301. package/dist/server/workspaces/workspaceDeletionRoutes.js +49 -0
  302. package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -0
  303. package/dist/server/workspaces/workspaceProviderRegistry.js +651 -0
  304. package/dist/server/workspaces/workspaceProviderRegistry.js.map +1 -0
  305. package/dist/server/workspaces/workspaceRemovalService.js +256 -0
  306. package/dist/server/workspaces/workspaceRemovalService.js.map +1 -0
  307. package/dist/server/workspaces/workspaceRouteErrors.js +7 -0
  308. package/dist/server/workspaces/workspaceRouteErrors.js.map +1 -0
  309. package/dist/server/workspaces/worktreePreRemoveHook.js +39 -0
  310. package/dist/server/workspaces/worktreePreRemoveHook.js.map +1 -0
  311. package/dist/server-plugin-api.d.ts +140 -0
  312. package/dist/server-plugin-api.js +2 -0
  313. package/dist/server-plugin-api.js.map +1 -0
  314. package/dist/serverPluginRecovery.js +138 -0
  315. package/dist/serverPluginRecovery.js.map +1 -0
  316. package/dist/sessiond/activeAgentProfile.js +12 -0
  317. package/dist/sessiond/activeAgentProfile.js.map +1 -0
  318. package/dist/sessiond/config.js +20 -0
  319. package/dist/sessiond/config.js.map +1 -0
  320. package/dist/sessiond/sessionDaemonClient.js +105 -0
  321. package/dist/sessiond/sessionDaemonClient.js.map +1 -0
  322. package/dist/shared/activeAgentProfile.js +37 -0
  323. package/dist/shared/activeAgentProfile.js.map +1 -0
  324. package/dist/shared/activity.js +16 -0
  325. package/dist/shared/activity.js.map +1 -0
  326. package/dist/shared/apiTypes.js +41 -0
  327. package/dist/shared/apiTypes.js.map +1 -0
  328. package/dist/shared/capabilities.js +37 -0
  329. package/dist/shared/capabilities.js.map +1 -0
  330. package/dist/shared/federatedRoutes.js +127 -0
  331. package/dist/shared/federatedRoutes.js.map +1 -0
  332. package/dist/shared/machinePluginIds.js +43 -0
  333. package/dist/shared/machinePluginIds.js.map +1 -0
  334. package/dist/shared/machineStatus.js +94 -0
  335. package/dist/shared/machineStatus.js.map +1 -0
  336. package/dist/shared/piWebStatusParsing.js +141 -0
  337. package/dist/shared/piWebStatusParsing.js.map +1 -0
  338. package/dist/shared/pluginApiTypes.d.ts +150 -0
  339. package/dist/shared/pluginApiTypes.js +3 -0
  340. package/dist/shared/pluginApiTypes.js.map +1 -0
  341. package/dist/shared/pluginBackendProtocol.js +110 -0
  342. package/dist/shared/pluginBackendProtocol.js.map +1 -0
  343. package/dist/shared/pluginIds.js +10 -0
  344. package/dist/shared/pluginIds.js.map +1 -0
  345. package/dist/shared/pluginRecoveryCommands.js +14 -0
  346. package/dist/shared/pluginRecoveryCommands.js.map +1 -0
  347. package/dist/shared/promptAttachments.js +92 -0
  348. package/dist/shared/promptAttachments.js.map +1 -0
  349. package/dist/shared/selfUpdate.js +3 -0
  350. package/dist/shared/selfUpdate.js.map +1 -0
  351. package/dist/shared/thinkingLevels.js +31 -0
  352. package/dist/shared/thinkingLevels.js.map +1 -0
  353. package/dist/shared/workspaceDeletion.js +12 -0
  354. package/dist/shared/workspaceDeletion.js.map +1 -0
  355. package/dist/shared/workspaceFiles.js +42 -0
  356. package/dist/shared/workspaceFiles.js.map +1 -0
  357. package/dist/shared/workspaceRemovalProtocol.js +24 -0
  358. package/dist/shared/workspaceRemovalProtocol.js.map +1 -0
  359. package/docs/assets/favicon.svg +11 -0
  360. package/docs/assets/pi-web-banner.png +0 -0
  361. package/docs/assets/pi-web-desktop.png +0 -0
  362. package/docs/assets/pi-web-mobile.png +0 -0
  363. package/docs/assets/pi-web-tablet.png +0 -0
  364. package/docs/config.md +444 -0
  365. package/docs/plugins.md +1305 -0
  366. package/examples/workspace-provider-plugin/README.md +52 -0
  367. package/examples/workspace-provider-plugin/package.json +25 -0
  368. package/examples/workspace-provider-plugin/src/browser/index.ts +69 -0
  369. package/examples/workspace-provider-plugin/src/server.ts +64 -0
  370. package/examples/workspace-provider-plugin/tsconfig.json +21 -0
  371. package/extensions/README-pi-web-restart-migration.md +45 -0
  372. package/extensions/pi-web.ts +324 -0
  373. package/install.sh +5 -0
  374. package/package.json +173 -0
  375. package/plugin-api.d.ts +1 -0
  376. package/server-plugin-api.d.ts +1 -0
@@ -0,0 +1,275 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { ASK_USER_ID_MAX_LENGTH, ASK_USER_OPTION_LIMIT, ASK_USER_OTHER_TEXT_MAX_LENGTH, ASK_USER_QUESTION_LIMIT, ASK_USER_TEXT_MAX_LENGTH, } from "../../shared/apiTypes.js";
3
+ /** Rejected input: a question set is malformed, or an answer does not fit its question. */
4
+ export class PendingAskValidationError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "PendingAskValidationError";
8
+ }
9
+ }
10
+ /**
11
+ * Daemon-owned open-ask state: one unanswered question set per session.
12
+ *
13
+ * The store is pure domain logic — no Fastify, no Pi session, no I/O, no timers.
14
+ * It validates asks and answers, owns the open/supersede/submit/cancel
15
+ * transitions, and computes the answered-versus-unanswered outcome that both the
16
+ * model-facing message and the browser record are rendered from. Callers publish
17
+ * the returned asks and outcomes; the store never emits anything itself.
18
+ *
19
+ * State is deliberately daemon-lifetime and in-memory. An open ask is meaningful
20
+ * only while the session runtime that posted it exists, and browsers rehydrate it
21
+ * from `SessionStatus` rather than from disk.
22
+ */
23
+ export class PendingAskStore {
24
+ constructor(options = {}) {
25
+ this.openBySessionId = new Map();
26
+ this.now = options.now ?? (() => new Date());
27
+ this.createAskId = options.createAskId ?? randomUUID;
28
+ }
29
+ /** The session's open ask, for {@link SessionStatus} projection. */
30
+ pendingAsk(sessionId) {
31
+ const ask = this.openBySessionId.get(requireSessionId(sessionId));
32
+ return ask === undefined ? undefined : cloneAsk(ask);
33
+ }
34
+ open(input) {
35
+ const sessionId = requireSessionId(input.sessionId);
36
+ const questions = validateQuestions(input.questions);
37
+ const askedAt = this.timestamp();
38
+ const superseded = this.close(sessionId, "superseded", askedAt, new Map());
39
+ const ask = {
40
+ askId: requireId(this.createAskId(), "askId"),
41
+ askedAt,
42
+ questions,
43
+ };
44
+ this.openBySessionId.set(sessionId, ask);
45
+ return {
46
+ ask: cloneAsk(ask),
47
+ ...(superseded === undefined ? {} : { superseded }),
48
+ };
49
+ }
50
+ /**
51
+ * Record what the user replied and close the ask. Answers are validated against
52
+ * the open ask, so a submission that does not fit its questions is rejected
53
+ * rather than silently truncated; the ask stays open in that case.
54
+ */
55
+ submit(sessionId, askId, submission) {
56
+ const ask = this.openBySessionId.get(requireSessionId(sessionId));
57
+ if (ask?.askId !== askId)
58
+ return { status: "stale" };
59
+ // Validate before closing so a submission that does not fit its questions
60
+ // leaves the ask open for the browser to correct.
61
+ const answers = validateSubmission(ask, submission);
62
+ return { status: "closed", outcome: this.requireClose(sessionId, "submitted", answers) };
63
+ }
64
+ /**
65
+ * Close the session's open ask without a submission. The outcome reports every question as
66
+ * unanswered, because answers only ever reach the daemon through a submit.
67
+ */
68
+ cancel(sessionId, askId) {
69
+ const ask = this.openBySessionId.get(requireSessionId(sessionId));
70
+ if (ask?.askId !== askId)
71
+ return { status: "stale" };
72
+ return { status: "closed", outcome: this.requireClose(sessionId, "cancelled", new Map()) };
73
+ }
74
+ /**
75
+ * Close whatever ask the session currently has open, e.g. because the user sent
76
+ * an ordinary chat message instead of answering the form. Returns the outcome,
77
+ * or `undefined` when the session has no open ask.
78
+ */
79
+ cancelOpen(sessionId) {
80
+ return this.close(requireSessionId(sessionId), "cancelled", this.timestamp(), new Map());
81
+ }
82
+ /** Drop the open ask of a session that is going away, without reporting an outcome. */
83
+ forgetSession(sessionId) {
84
+ this.openBySessionId.delete(requireSessionId(sessionId));
85
+ }
86
+ requireClose(sessionId, reason, answers) {
87
+ const outcome = this.close(sessionId, reason, this.timestamp(), answers);
88
+ if (outcome === undefined)
89
+ throw new Error(`Pending ask of session ${sessionId} disappeared while closing`);
90
+ return outcome;
91
+ }
92
+ close(sessionId, reason, closedAt, answers) {
93
+ const ask = this.openBySessionId.get(sessionId);
94
+ if (ask === undefined)
95
+ return undefined;
96
+ this.openBySessionId.delete(sessionId);
97
+ return askUserOutcome(ask, answers, reason, closedAt);
98
+ }
99
+ timestamp() {
100
+ return this.now().toISOString();
101
+ }
102
+ }
103
+ /**
104
+ * Model-facing text of a closed ask. The model reads this, so it must name the
105
+ * unanswered questions as plainly as the answered ones.
106
+ */
107
+ export function renderAskUserAnswersText(outcome) {
108
+ const lead = outcome.reason === "submitted"
109
+ ? "The user submitted answers to your questions."
110
+ : `The question set was closed (${outcome.reason}) before it was fully answered.`;
111
+ return [lead, "", ...outcome.questions.map(questionLines).flat(), "", outcome.summary].join("\n");
112
+ }
113
+ /**
114
+ * Notice for the model when a new ask replaced one the user never answered, so a
115
+ * supersede is never a silent loss of the earlier questions.
116
+ */
117
+ export function renderSupersededAskText(outcome) {
118
+ return [
119
+ `This replaced an earlier question set (${outcome.askId}) that the user never submitted.`,
120
+ `Left unanswered: ${outcome.unansweredIds.join(", ")}.`,
121
+ ].join("\n");
122
+ }
123
+ function questionLines(record) {
124
+ const header = `- ${record.question.id}: ${record.question.question}`;
125
+ if (!record.answered)
126
+ return [header, " Unanswered."];
127
+ const parts = [...record.values.map((value) => `selected ${value}`)];
128
+ if (record.otherText !== undefined)
129
+ parts.push(`custom: ${JSON.stringify(record.otherText)}`);
130
+ return [header, ` Answered: ${parts.join("; ")}`];
131
+ }
132
+ function askUserOutcome(ask, answers, reason, closedAt) {
133
+ const questions = ask.questions.map((question) => questionRecord(question, answers.get(question.id)));
134
+ const unansweredIds = questions.filter((record) => !record.answered).map((record) => record.question.id);
135
+ const answeredCount = questions.length - unansweredIds.length;
136
+ return {
137
+ askId: ask.askId,
138
+ reason,
139
+ askedAt: ask.askedAt,
140
+ closedAt,
141
+ questions,
142
+ answeredCount,
143
+ unansweredIds,
144
+ summary: summaryLine(questions.length, answeredCount, unansweredIds),
145
+ };
146
+ }
147
+ function questionRecord(question, answer) {
148
+ const values = answer?.values ?? [];
149
+ const otherText = answer?.otherText;
150
+ return {
151
+ question: cloneQuestion(question),
152
+ answered: values.length > 0 || otherText !== undefined,
153
+ values: [...values],
154
+ ...(otherText === undefined ? {} : { otherText }),
155
+ };
156
+ }
157
+ function summaryLine(total, answeredCount, unansweredIds) {
158
+ const answered = `Answered ${answeredCount.toString()} of ${total.toString()}`;
159
+ return unansweredIds.length === 0 ? `${answered}; none left unanswered` : `${answered}; unanswered: ${unansweredIds.join(", ")}`;
160
+ }
161
+ function validateQuestions(questions) {
162
+ if (questions.length === 0)
163
+ throw new PendingAskValidationError("An ask must contain at least one question");
164
+ if (questions.length > ASK_USER_QUESTION_LIMIT) {
165
+ throw new PendingAskValidationError(`An ask must not contain more than ${ASK_USER_QUESTION_LIMIT.toString()} questions`);
166
+ }
167
+ const seenIds = new Set();
168
+ return questions.map((question) => {
169
+ const id = requireId(question.id, "question id");
170
+ if (seenIds.has(id))
171
+ throw new PendingAskValidationError(`Duplicate question id ${id}`);
172
+ seenIds.add(id);
173
+ return validateQuestion(question, id);
174
+ });
175
+ }
176
+ function validateQuestion(question, id) {
177
+ if (question.options.length > ASK_USER_OPTION_LIMIT) {
178
+ throw new PendingAskValidationError(`Question ${id} must not offer more than ${ASK_USER_OPTION_LIMIT.toString()} options`);
179
+ }
180
+ const seenValues = new Set();
181
+ const options = question.options.map((option) => {
182
+ const value = requireId(option.value, `option value of question ${id}`);
183
+ if (seenValues.has(value))
184
+ throw new PendingAskValidationError(`Duplicate option value ${value} in question ${id}`);
185
+ seenValues.add(value);
186
+ return validateOption(option, value, id);
187
+ });
188
+ const detail = question.detail;
189
+ return {
190
+ id,
191
+ question: requireText(question.question, `text of question ${id}`),
192
+ ...(detail === undefined ? {} : { detail: requireText(detail, `detail of question ${id}`) }),
193
+ options,
194
+ ...(question.multiple === true ? { multiple: true } : {}),
195
+ };
196
+ }
197
+ function validateOption(option, value, questionId) {
198
+ const detail = option.detail;
199
+ return {
200
+ value,
201
+ label: requireText(option.label, `label of option ${value} in question ${questionId}`),
202
+ ...(detail === undefined ? {} : { detail: requireText(detail, `detail of option ${value} in question ${questionId}`) }),
203
+ };
204
+ }
205
+ function validateSubmission(ask, submission) {
206
+ const questionsById = new Map(ask.questions.map((question) => [question.id, question]));
207
+ const answers = new Map();
208
+ for (const answer of submission.answers) {
209
+ const question = questionsById.get(answer.id);
210
+ if (question === undefined)
211
+ throw new PendingAskValidationError(`Unknown question id ${answer.id}`);
212
+ if (answers.has(answer.id))
213
+ throw new PendingAskValidationError(`Duplicate answer for question ${answer.id}`);
214
+ const validated = validateAnswer(question, answer);
215
+ // Untouched questions and explicitly empty answers are the same thing, so an
216
+ // empty answer is dropped rather than recorded as answered.
217
+ if (validated !== undefined)
218
+ answers.set(answer.id, validated);
219
+ }
220
+ return answers;
221
+ }
222
+ function validateAnswer(question, answer) {
223
+ const optionValues = new Set(question.options.map((option) => option.value));
224
+ const values = [];
225
+ for (const value of answer.values) {
226
+ if (!optionValues.has(value))
227
+ throw new PendingAskValidationError(`Question ${question.id} has no option ${value}`);
228
+ if (values.includes(value))
229
+ throw new PendingAskValidationError(`Duplicate value ${value} for question ${question.id}`);
230
+ values.push(value);
231
+ }
232
+ const otherText = normalizeOtherText(question, answer.otherText);
233
+ const selectionCount = values.length + (otherText === undefined ? 0 : 1);
234
+ if (question.multiple !== true && selectionCount > 1) {
235
+ throw new PendingAskValidationError(`Question ${question.id} accepts a single answer`);
236
+ }
237
+ if (selectionCount === 0)
238
+ return undefined;
239
+ return { id: question.id, values, ...(otherText === undefined ? {} : { otherText }) };
240
+ }
241
+ function normalizeOtherText(question, otherText) {
242
+ if (otherText === undefined)
243
+ return undefined;
244
+ if (otherText.length > ASK_USER_OTHER_TEXT_MAX_LENGTH) {
245
+ throw new PendingAskValidationError(`Other text of question ${question.id} exceeds its length limit`);
246
+ }
247
+ const trimmed = otherText.trim();
248
+ return trimmed === "" ? undefined : trimmed;
249
+ }
250
+ function cloneAsk(ask) {
251
+ return { askId: ask.askId, askedAt: ask.askedAt, questions: ask.questions.map(cloneQuestion) };
252
+ }
253
+ function cloneQuestion(question) {
254
+ return { ...question, options: question.options.map((option) => ({ ...option })) };
255
+ }
256
+ function requireSessionId(sessionId) {
257
+ if (sessionId === "")
258
+ throw new Error("sessionId must not be empty");
259
+ return sessionId;
260
+ }
261
+ function requireId(value, field) {
262
+ if (value.trim() === "")
263
+ throw new PendingAskValidationError(`${field} must not be empty`);
264
+ if (value.length > ASK_USER_ID_MAX_LENGTH)
265
+ throw new PendingAskValidationError(`${field} exceeds its length limit`);
266
+ return value;
267
+ }
268
+ function requireText(value, field) {
269
+ if (value.trim() === "")
270
+ throw new PendingAskValidationError(`${field} must not be empty`);
271
+ if (value.length > ASK_USER_TEXT_MAX_LENGTH)
272
+ throw new PendingAskValidationError(`${field} exceeds its length limit`);
273
+ return value;
274
+ }
275
+ //# sourceMappingURL=pendingAskStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pendingAskStore.js","sourceRoot":"","sources":["../../../src/server/sessions/pendingAskStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,8BAA8B,EAC9B,uBAAuB,EACvB,wBAAwB,GASzB,MAAM,0BAA0B,CAAC;AAkClC,2FAA2F;AAC3F,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AAID;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,eAAe;IAK1B,YAAY,UAAkC,EAAE;QAF/B,oBAAe,GAAG,IAAI,GAAG,EAA0B,CAAC;QAGnE,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,UAAU,CAAC;IACvD,CAAC;IAED,oEAAoE;IACpE,UAAU,CAAC,SAAiB;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;QAClE,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,CAAC,KAA0B;QAC7B,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAC3E,MAAM,GAAG,GAAmB;YAC1B,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC;YAC7C,OAAO;YACP,SAAS;SACV,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACzC,OAAO;YACL,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC;YAClB,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;SACpD,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,SAAiB,EAAE,KAAa,EAAE,UAA6B;QACpE,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;QAClE,IAAI,GAAG,EAAE,KAAK,KAAK,KAAK;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACrD,0EAA0E;QAC1E,kDAAkD;QAClD,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACpD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,CAAC;IAC3F,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,SAAiB,EAAE,KAAa;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;QAClE,IAAI,GAAG,EAAE,KAAK,KAAK,KAAK;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACrD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC;IAC7F,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,uFAAuF;IACvF,aAAa,CAAC,SAAiB;QAC7B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3D,CAAC;IAEO,YAAY,CAAC,SAAiB,EAAE,MAA0B,EAAE,OAAwB;QAC1F,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;QACzE,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,SAAS,4BAA4B,CAAC,CAAC;QAC5G,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,KAAK,CACX,SAAiB,EACjB,MAA0B,EAC1B,QAAgB,EAChB,OAAwB;QAExB,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACxC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACvC,OAAO,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACxD,CAAC;IAEO,SAAS;QACf,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAuB;IAC9D,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,WAAW;QACzC,CAAC,CAAC,+CAA+C;QACjD,CAAC,CAAC,gCAAgC,OAAO,CAAC,MAAM,iCAAiC,CAAC;IACpF,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAuB;IAC7D,OAAO;QACL,0CAA0C,OAAO,CAAC,KAAK,kCAAkC;QACzF,oBAAoB,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;KACxD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,MAA6B;IAClD,MAAM,MAAM,GAAG,KAAK,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IACtE,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC,CAAC;IACrE,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC9F,OAAO,CAAC,MAAM,EAAE,eAAe,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,cAAc,CACrB,GAAmB,EACnB,OAAwB,EACxB,MAA0B,EAC1B,QAAgB;IAEhB,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACtG,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACzG,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC;IAC9D,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM;QACN,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,QAAQ;QACR,SAAS;QACT,aAAa;QACb,aAAa;QACb,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,EAAE,aAAa,CAAC;KACrE,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,QAAyB,EAAE,MAAiC;IAClF,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,MAAM,EAAE,SAAS,CAAC;IACpC,OAAO;QACL,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC;QACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,KAAK,SAAS;QACtD,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC;QACnB,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;KAClD,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,KAAa,EAAE,aAAqB,EAAE,aAAuB;IAChF,MAAM,QAAQ,GAAG,YAAY,aAAa,CAAC,QAAQ,EAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC/E,OAAO,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,wBAAwB,CAAC,CAAC,CAAC,GAAG,QAAQ,iBAAiB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACnI,CAAC;AAED,SAAS,iBAAiB,CAAC,SAA4B;IACrD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,yBAAyB,CAAC,2CAA2C,CAAC,CAAC;IAC7G,IAAI,SAAS,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;QAC/C,MAAM,IAAI,yBAAyB,CAAC,qCAAqC,uBAAuB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC3H,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAChC,MAAM,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QACjD,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,yBAAyB,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;QACxF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,gBAAgB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAyB,EAAE,EAAU;IAC7D,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACpD,MAAM,IAAI,yBAAyB,CAAC,YAAY,EAAE,6BAA6B,qBAAqB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC7H,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,4BAA4B,EAAE,EAAE,CAAC,CAAC;QACxE,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,yBAAyB,CAAC,0BAA0B,KAAK,gBAAgB,EAAE,EAAE,CAAC,CAAC;QACpH,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtB,OAAO,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC/B,OAAO;QACL,EAAE;QACF,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,EAAE,EAAE,CAAC;QAClE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,sBAAsB,EAAE,EAAE,CAAC,EAAE,CAAC;QAC5F,OAAO;QACP,GAAG,CAAC,QAAQ,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1D,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,MAA6B,EAAE,KAAa,EAAE,UAAkB;IACtF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,OAAO;QACL,KAAK;QACL,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,mBAAmB,KAAK,gBAAgB,UAAU,EAAE,CAAC;QACtF,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,KAAK,gBAAgB,UAAU,EAAE,CAAC,EAAE,CAAC;KACxH,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAmB,EAAE,UAA6B;IAC5E,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxF,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IACjD,KAAK,MAAM,MAAM,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC9C,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,IAAI,yBAAyB,CAAC,uBAAuB,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QACpG,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,yBAAyB,CAAC,iCAAiC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9G,MAAM,SAAS,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACnD,6EAA6E;QAC7E,4DAA4D;QAC5D,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,cAAc,CAAC,QAAyB,EAAE,MAAqB;IACtE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7E,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,yBAAyB,CAAC,YAAY,QAAQ,CAAC,EAAE,kBAAkB,KAAK,EAAE,CAAC,CAAC;QACpH,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,yBAAyB,CAAC,mBAAmB,KAAK,iBAAiB,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QACxH,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IACD,MAAM,SAAS,GAAG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IACjE,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,IAAI,QAAQ,CAAC,QAAQ,KAAK,IAAI,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,yBAAyB,CAAC,YAAY,QAAQ,CAAC,EAAE,0BAA0B,CAAC,CAAC;IACzF,CAAC;IACD,IAAI,cAAc,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AACxF,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAyB,EAAE,SAA6B;IAClF,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC9C,IAAI,SAAS,CAAC,MAAM,GAAG,8BAA8B,EAAE,CAAC;QACtD,MAAM,IAAI,yBAAyB,CAAC,0BAA0B,QAAQ,CAAC,EAAE,2BAA2B,CAAC,CAAC;IACxG,CAAC;IACD,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IACjC,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AAC9C,CAAC;AAED,SAAS,QAAQ,CAAC,GAAmB;IACnC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;AACjG,CAAC;AAED,SAAS,aAAa,CAAC,QAAyB;IAC9C,OAAO,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;AACrF,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAiB;IACzC,IAAI,SAAS,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACrE,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,SAAS,CAAC,KAAa,EAAE,KAAa;IAC7C,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,MAAM,IAAI,yBAAyB,CAAC,GAAG,KAAK,oBAAoB,CAAC,CAAC;IAC3F,IAAI,KAAK,CAAC,MAAM,GAAG,sBAAsB;QAAE,MAAM,IAAI,yBAAyB,CAAC,GAAG,KAAK,2BAA2B,CAAC,CAAC;IACpH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,KAAa,EAAE,KAAa;IAC/C,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,MAAM,IAAI,yBAAyB,CAAC,GAAG,KAAK,oBAAoB,CAAC,CAAC;IAC3F,IAAI,KAAK,CAAC,MAAM,GAAG,wBAAwB;QAAE,MAAM,IAAI,yBAAyB,CAAC,GAAG,KAAK,2BAA2B,CAAC,CAAC;IACtH,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,196 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { EXTENSION_DIALOG_ID_MAX_LENGTH, EXTENSION_DIALOG_INPUT_MAX_LENGTH, EXTENSION_DIALOG_OPTION_LIMIT, EXTENSION_DIALOG_TEXT_MAX_LENGTH, } from "../../shared/apiTypes.js";
3
+ /** Rejected input: the dialog is malformed, or an answer does not fit its kind. */
4
+ export class PendingExtensionDialogValidationError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "PendingExtensionDialogValidationError";
8
+ }
9
+ }
10
+ /**
11
+ * Daemon-owned open-dialog state: the extension dialogs of every session,
12
+ * several per session because each dialog is an independent blocking wait
13
+ * inside extension code — opening one must never supersede another.
14
+ *
15
+ * The store is pure domain logic — no Fastify, no Pi session, no I/O, no
16
+ * timers. It validates dialogs and answers and owns the open/answer/cancel
17
+ * transitions; callers hold the waiting Promise resolvers, publish the
18
+ * returned records and outcomes, and own the timers that turn `timeoutAt`
19
+ * into a `"timeout"` cancel.
20
+ *
21
+ * State is deliberately daemon-lifetime and in-memory. An open dialog is
22
+ * meaningful only while the session runtime whose extension is waiting on it
23
+ * exists, and browsers rehydrate open dialogs from `SessionStatus` rather
24
+ * than from disk.
25
+ */
26
+ export class PendingExtensionDialogStore {
27
+ constructor(options = {}) {
28
+ /** Per-session open dialogs in insertion order, so `pendingDialogs` reads oldest first. */
29
+ this.openBySessionId = new Map();
30
+ this.now = options.now ?? (() => new Date());
31
+ this.createDialogId = options.createDialogId ?? randomUUID;
32
+ }
33
+ /** The session's open dialogs, oldest first, for {@link SessionStatus} projection. */
34
+ pendingDialogs(sessionId) {
35
+ const dialogs = this.openBySessionId.get(requireSessionId(sessionId));
36
+ if (dialogs === undefined)
37
+ return [];
38
+ return [...dialogs.values()].map(cloneDialog);
39
+ }
40
+ open(input) {
41
+ const sessionId = requireSessionId(input.sessionId);
42
+ const kind = requireKind(input.kind);
43
+ const now = this.now();
44
+ const dialog = {
45
+ dialogId: requireId(this.createDialogId(), "dialogId"),
46
+ kind,
47
+ title: requireText(input.title, "dialog title"),
48
+ ...kindFields(kind, input),
49
+ askedAt: now.toISOString(),
50
+ ...timeoutField(input.timeoutMs, now),
51
+ runScoped: input.runScoped,
52
+ };
53
+ const dialogs = this.openBySessionId.get(sessionId) ?? new Map();
54
+ if (dialogs.has(dialog.dialogId)) {
55
+ throw new Error(`Dialog id ${dialog.dialogId} is already open in session ${sessionId}`);
56
+ }
57
+ dialogs.set(dialog.dialogId, dialog);
58
+ this.openBySessionId.set(sessionId, dialogs);
59
+ return cloneDialog(dialog);
60
+ }
61
+ /**
62
+ * Record the user's answer and close the dialog. The answer is validated
63
+ * against the dialog's kind first, so an answer that does not fit leaves the
64
+ * dialog open for the browser to correct.
65
+ */
66
+ answer(sessionId, dialogId, value) {
67
+ const dialog = this.openBySessionId.get(requireSessionId(sessionId))?.get(dialogId);
68
+ if (dialog === undefined)
69
+ return { status: "stale" };
70
+ const answer = validateAnswer(dialog, value);
71
+ return { status: "closed", outcome: this.requireClose(sessionId, dialog, "answered", answer) };
72
+ }
73
+ /** Close the dialog without an answer; the extension's wait settles with its kind's cancel value. */
74
+ cancel(sessionId, dialogId, reason) {
75
+ const dialog = this.openBySessionId.get(requireSessionId(sessionId))?.get(dialogId);
76
+ if (dialog === undefined)
77
+ return { status: "stale" };
78
+ return { status: "closed", outcome: this.requireClose(sessionId, dialog, reason, undefined) };
79
+ }
80
+ requireClose(sessionId, dialog, reason, answer) {
81
+ const dialogs = this.openBySessionId.get(sessionId);
82
+ if (dialogs?.delete(dialog.dialogId) !== true) {
83
+ throw new Error(`Dialog ${dialog.dialogId} of session ${sessionId} disappeared while closing`);
84
+ }
85
+ if (dialogs.size === 0)
86
+ this.openBySessionId.delete(sessionId);
87
+ return {
88
+ dialogId: dialog.dialogId,
89
+ reason,
90
+ ...(answer === undefined ? {} : { answer }),
91
+ askedAt: dialog.askedAt,
92
+ closedAt: this.timestamp(),
93
+ };
94
+ }
95
+ timestamp() {
96
+ return this.now().toISOString();
97
+ }
98
+ }
99
+ function validateAnswer(dialog, value) {
100
+ switch (dialog.kind) {
101
+ case "confirm":
102
+ if (typeof value !== "boolean")
103
+ throw new PendingExtensionDialogValidationError(`Dialog ${dialog.dialogId} expects a boolean answer`);
104
+ return value;
105
+ case "select":
106
+ if (typeof value !== "string" || dialog.options?.includes(value) !== true) {
107
+ throw new PendingExtensionDialogValidationError(`Dialog ${dialog.dialogId} has no option ${String(value)}`);
108
+ }
109
+ return value;
110
+ case "input":
111
+ if (typeof value !== "string")
112
+ throw new PendingExtensionDialogValidationError(`Dialog ${dialog.dialogId} expects a text answer`);
113
+ if (value.length > EXTENSION_DIALOG_INPUT_MAX_LENGTH) {
114
+ throw new PendingExtensionDialogValidationError(`Answer of dialog ${dialog.dialogId} exceeds its length limit`);
115
+ }
116
+ return value;
117
+ }
118
+ }
119
+ /** Kind-specific fields of a validated record; irrelevant fields are dropped rather than rejected. */
120
+ function kindFields(kind, input) {
121
+ switch (kind) {
122
+ case "confirm": {
123
+ const message = optionalText(input.message, "dialog message");
124
+ return message === undefined ? {} : { message };
125
+ }
126
+ case "select":
127
+ return { options: validateOptions(input.options) };
128
+ case "input": {
129
+ const placeholder = optionalText(input.placeholder, "dialog placeholder");
130
+ return placeholder === undefined ? {} : { placeholder };
131
+ }
132
+ }
133
+ }
134
+ function validateOptions(options) {
135
+ if (options === undefined || options.length === 0) {
136
+ throw new PendingExtensionDialogValidationError("A select dialog must offer at least one option");
137
+ }
138
+ if (options.length > EXTENSION_DIALOG_OPTION_LIMIT) {
139
+ throw new PendingExtensionDialogValidationError(`A select dialog must not offer more than ${EXTENSION_DIALOG_OPTION_LIMIT.toString()} options`);
140
+ }
141
+ const seen = new Set();
142
+ return options.map((option) => {
143
+ const validated = requireText(option, "select option");
144
+ if (seen.has(validated))
145
+ throw new PendingExtensionDialogValidationError(`Duplicate select option ${validated}`);
146
+ seen.add(validated);
147
+ return validated;
148
+ });
149
+ }
150
+ function timeoutField(timeoutMs, now) {
151
+ if (timeoutMs === undefined)
152
+ return {};
153
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
154
+ throw new PendingExtensionDialogValidationError("A dialog timeout must be a positive number of milliseconds");
155
+ }
156
+ return { timeoutAt: new Date(now.getTime() + timeoutMs).toISOString() };
157
+ }
158
+ function cloneDialog(dialog) {
159
+ return { ...dialog, ...(dialog.options === undefined ? {} : { options: [...dialog.options] }) };
160
+ }
161
+ function requireSessionId(sessionId) {
162
+ if (sessionId === "")
163
+ throw new Error("sessionId must not be empty");
164
+ return sessionId;
165
+ }
166
+ /** Runtime guard: the input crosses extension code, so the declared kind is checked despite its type. */
167
+ function requireKind(kind) {
168
+ if (kind !== "confirm" && kind !== "select" && kind !== "input") {
169
+ throw new PendingExtensionDialogValidationError(`Unknown dialog kind ${kind}`);
170
+ }
171
+ return kind;
172
+ }
173
+ function requireId(value, field) {
174
+ if (value.trim() === "")
175
+ throw new PendingExtensionDialogValidationError(`${field} must not be empty`);
176
+ if (value.length > EXTENSION_DIALOG_ID_MAX_LENGTH)
177
+ throw new PendingExtensionDialogValidationError(`${field} exceeds its length limit`);
178
+ return value;
179
+ }
180
+ function requireText(value, field) {
181
+ if (value.trim() === "")
182
+ throw new PendingExtensionDialogValidationError(`${field} must not be empty`);
183
+ if (value.length > EXTENSION_DIALOG_TEXT_MAX_LENGTH)
184
+ throw new PendingExtensionDialogValidationError(`${field} exceeds its length limit`);
185
+ return value;
186
+ }
187
+ /** Optional cosmetic prose: blank means absent rather than being a validation error. */
188
+ function optionalText(value, field) {
189
+ if (value === undefined || value.trim() === "")
190
+ return undefined;
191
+ if (value.length > EXTENSION_DIALOG_TEXT_MAX_LENGTH) {
192
+ throw new PendingExtensionDialogValidationError(`${field} exceeds its length limit`);
193
+ }
194
+ return value;
195
+ }
196
+ //# sourceMappingURL=pendingExtensionDialogStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pendingExtensionDialogStore.js","sourceRoot":"","sources":["../../../src/server/sessions/pendingExtensionDialogStore.ts"],"names":[],"mappings":"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"}