@agimon-ai/po-core 0.0.0-alpha.2 → 0.0.0-alpha.21

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 (1149) hide show
  1. package/LICENSE +149 -21
  2. package/NOTICE +41 -0
  3. package/dist/agentModel.cjs +1 -1
  4. package/dist/agentModel.d.mts +2 -2
  5. package/dist/agentModel.mjs +1 -2
  6. package/dist/apiContracts.cjs +623 -802
  7. package/dist/apiContracts.cjs.map +1 -1
  8. package/dist/apiContracts.d.mts +277 -615
  9. package/dist/apiContracts.d.mts.map +1 -1
  10. package/dist/apiContracts.mjs +617 -794
  11. package/dist/apiContracts.mjs.map +1 -1
  12. package/dist/askUser.cjs +2 -2
  13. package/dist/askUser.d.mts +2 -2
  14. package/dist/askUser.mjs +1 -2
  15. package/dist/authorTools.mjs +1 -2
  16. package/dist/backgroundWork.cjs +3 -3
  17. package/dist/backgroundWork.d.mts +2 -2
  18. package/dist/backgroundWork.mjs +1 -2
  19. package/dist/bundleAssetPolicy.mjs +1 -2
  20. package/dist/chatgptAuth.cjs +3 -2
  21. package/dist/chatgptAuth.d.mts +3 -2
  22. package/dist/chatgptAuth.mjs +2 -1
  23. package/dist/childProcess.cjs +1 -1
  24. package/dist/childProcess.d.mts +2 -2
  25. package/dist/childProcess.mjs +1 -2
  26. package/dist/childSession.cjs +11 -6
  27. package/dist/childSession.d.mts +3 -3
  28. package/dist/childSession.mjs +3 -3
  29. package/dist/cockpitContainer.mjs +1 -2
  30. package/dist/config.cjs +1 -1
  31. package/dist/config.d.mts +3 -3
  32. package/dist/config.mjs +1 -2
  33. package/dist/contextApi.cjs +1 -0
  34. package/dist/contextApi.d.mts +2 -2
  35. package/dist/contextApi.mjs +2 -2
  36. package/dist/contextContributions.cjs +4 -4
  37. package/dist/contextContributions.d.mts +3 -3
  38. package/dist/contextContributions.mjs +3 -3
  39. package/dist/contextDetailStore.cjs +7 -5
  40. package/dist/contextDetailStore.cjs.map +1 -1
  41. package/dist/contextDetailStore.d.mts +2 -1
  42. package/dist/contextDetailStore.d.mts.map +1 -1
  43. package/dist/contextDetailStore.mjs +6 -4
  44. package/dist/contextDetailStore.mjs.map +1 -1
  45. package/dist/contextProjection.cjs +7 -2
  46. package/dist/contextProjection.cjs.map +1 -1
  47. package/dist/contextProjection.d.mts +4 -1
  48. package/dist/contextProjection.d.mts.map +1 -1
  49. package/dist/contextProjection.mjs +5 -2
  50. package/dist/contextProjection.mjs.map +1 -1
  51. package/dist/cordisHost.cjs +11 -11
  52. package/dist/cordisHost.d.mts +2 -2
  53. package/dist/cordisHost.mjs +1 -2
  54. package/dist/delegation.cjs +8 -8
  55. package/dist/delegation.d.mts +2 -2
  56. package/dist/delegation.mjs +1 -2
  57. package/dist/executionBudget.cjs +4 -3
  58. package/dist/executionBudget.cjs.map +1 -1
  59. package/dist/executionBudget.d.mts +2 -2
  60. package/dist/executionBudget.d.mts.map +1 -1
  61. package/dist/executionBudget.mjs +4 -3
  62. package/dist/executionBudget.mjs.map +1 -1
  63. package/dist/extensionFile.cjs +5 -0
  64. package/dist/extensionFile.d.mts +4 -2
  65. package/dist/extensionFile.mjs +4 -2
  66. package/dist/footer.d.mts +2 -2
  67. package/dist/footer.mjs +1 -2
  68. package/dist/headless.cjs +14 -14
  69. package/dist/headless.d.mts +2 -2
  70. package/dist/headless.mjs +1 -2
  71. package/dist/headlessHub.cjs +308 -109
  72. package/dist/headlessHub.cjs.map +1 -1
  73. package/dist/headlessHub.d.mts +71 -36
  74. package/dist/headlessHub.d.mts.map +1 -1
  75. package/dist/headlessHub.mjs +309 -110
  76. package/dist/headlessHub.mjs.map +1 -1
  77. package/dist/headlessProtocol.cjs +327 -0
  78. package/dist/headlessProtocol.cjs.map +1 -0
  79. package/dist/headlessProtocol.d.mts +30 -0
  80. package/dist/headlessProtocol.d.mts.map +1 -0
  81. package/dist/headlessProtocol.mjs +326 -0
  82. package/dist/headlessProtocol.mjs.map +1 -0
  83. package/dist/headlessServer.cjs +166 -151
  84. package/dist/headlessServer.cjs.map +1 -1
  85. package/dist/headlessServer.d.mts +13 -5
  86. package/dist/headlessServer.d.mts.map +1 -1
  87. package/dist/headlessServer.mjs +166 -151
  88. package/dist/headlessServer.mjs.map +1 -1
  89. package/dist/headlessSessionHost.d.mts +58 -21
  90. package/dist/headlessSessionHost.d.mts.map +1 -1
  91. package/dist/help.cjs +20 -20
  92. package/dist/help.d.mts +2 -2
  93. package/dist/help.mjs +2 -2
  94. package/dist/history.cjs +16 -20
  95. package/dist/history.d.mts +9 -7
  96. package/dist/history.mjs +6 -7
  97. package/dist/historyOwnership.cjs.map +1 -1
  98. package/dist/historyOwnership.d.mts +1 -1
  99. package/dist/historyOwnership.mjs.map +1 -1
  100. package/dist/hubChannel.cjs +9 -0
  101. package/dist/hubChannel.d.mts +3 -2
  102. package/dist/hubChannel.mjs +3 -2
  103. package/dist/index.cjs +26 -28
  104. package/dist/index.d.mts +6 -6
  105. package/dist/index.mjs +6 -6
  106. package/dist/interop/chord.mjs +1 -0
  107. package/dist/interop/chordContext.mjs +1 -0
  108. package/dist/json.cjs +11 -5
  109. package/dist/json.d.mts +4 -2
  110. package/dist/json.mjs +4 -2
  111. package/dist/kernel.cjs +1 -1
  112. package/dist/kernel.d.mts +3 -3
  113. package/dist/kernel.mjs +1 -2
  114. package/dist/leader.d.mts +2 -2
  115. package/dist/leader.mjs +1 -2
  116. package/dist/logSinkTelemetry.mjs +1 -2
  117. package/dist/machineApi.cjs +80 -74
  118. package/dist/machineApi.cjs.map +1 -1
  119. package/dist/machineApi.d.mts +5 -2
  120. package/dist/machineApi.d.mts.map +1 -1
  121. package/dist/machineApi.mjs +78 -71
  122. package/dist/machineApi.mjs.map +1 -1
  123. package/dist/main.cjs +2 -1
  124. package/dist/main.d.mts +2 -1
  125. package/dist/main.mjs +2 -1
  126. package/dist/mcpFacet.d.mts +3 -3
  127. package/dist/mcpProjection.cjs +13 -13
  128. package/dist/mcpProjection.d.mts +2 -2
  129. package/dist/mcpProjection.mjs +1 -2
  130. package/dist/mcpSchemaCost.cjs +4 -4
  131. package/dist/mcpSchemaCost.cjs.map +1 -1
  132. package/dist/mcpSchemaCost.d.mts +2 -2
  133. package/dist/mcpSchemaCost.mjs +4 -4
  134. package/dist/mcpSchemaCost.mjs.map +1 -1
  135. package/dist/mcpSession.cjs +7 -7
  136. package/dist/mcpSession.d.mts +2 -2
  137. package/dist/mcpSession.mjs +1 -2
  138. package/dist/mcpStatus.cjs +2 -2
  139. package/dist/mcpStatus.d.mts +2 -2
  140. package/dist/mcpStatus.mjs +1 -2
  141. package/dist/mcpToolResolver.cjs +3 -3
  142. package/dist/mcpToolResolver.d.mts +2 -2
  143. package/dist/mcpToolResolver.mjs +1 -2
  144. package/dist/mcpWidget.d.mts +2 -2
  145. package/dist/moduleResolution.cjs +43 -8
  146. package/dist/moduleResolution.cjs.map +1 -1
  147. package/dist/moduleResolution.d.mts +10 -1
  148. package/dist/moduleResolution.d.mts.map +1 -1
  149. package/dist/moduleResolution.mjs +40 -7
  150. package/dist/moduleResolution.mjs.map +1 -1
  151. package/dist/narration.cjs +3 -3
  152. package/dist/narration.d.mts +2 -2
  153. package/dist/narration.mjs +1 -2
  154. package/dist/native.cjs +9 -0
  155. package/dist/native.d.mts +4 -3
  156. package/dist/native.mjs +3 -2
  157. package/dist/nodePlatform.cjs +77 -0
  158. package/dist/nodePlatform.cjs.map +1 -0
  159. package/dist/nodePlatform.d.mts +17 -0
  160. package/dist/nodePlatform.d.mts.map +1 -0
  161. package/dist/nodePlatform.mjs +72 -0
  162. package/dist/nodePlatform.mjs.map +1 -0
  163. package/dist/notification.cjs +15 -15
  164. package/dist/notification.d.mts +2 -2
  165. package/dist/notification.mjs +1 -2
  166. package/dist/packageApi.cjs +11 -11
  167. package/dist/packageApi.d.mts +2 -2
  168. package/dist/packageApi.mjs +2 -2
  169. package/dist/packageApiServer.cjs +45 -27
  170. package/dist/packageApiServer.cjs.map +1 -1
  171. package/dist/packageApiServer.d.mts +36 -26
  172. package/dist/packageApiServer.d.mts.map +1 -1
  173. package/dist/packageApiServer.mjs +44 -26
  174. package/dist/packageApiServer.mjs.map +1 -1
  175. package/dist/piSettings.cjs +41 -20
  176. package/dist/piSettings.d.mts +4 -2
  177. package/dist/piSettings.mjs +4 -2
  178. package/dist/platform.cjs +62 -0
  179. package/dist/platform.d.mts +10 -0
  180. package/dist/platform.mjs +10 -0
  181. package/dist/pluginProtocol.cjs +7 -8
  182. package/dist/pluginProtocol.d.mts +2 -2
  183. package/dist/pluginProtocol.mjs +1 -2
  184. package/dist/poPackage.cjs +12 -0
  185. package/dist/poPackage.d.mts +3 -0
  186. package/dist/poPackage.mjs +3 -0
  187. package/dist/profileIdentity.cjs +1 -1
  188. package/dist/profileIdentity.d.mts +2 -2
  189. package/dist/profileIdentity.mjs +1 -2
  190. package/dist/protocol.cjs +3 -3
  191. package/dist/protocol.d.mts +2 -2
  192. package/dist/protocol.mjs +1 -2
  193. package/dist/readiness.cjs +6 -6
  194. package/dist/readiness.d.mts +2 -2
  195. package/dist/readiness.mjs +1 -2
  196. package/dist/remoteApi.cjs.map +1 -1
  197. package/dist/remoteApi.d.mts +2 -2
  198. package/dist/remoteApi.mjs.map +1 -1
  199. package/dist/remoteRuntime.cjs +42 -65
  200. package/dist/remoteRuntime.cjs.map +1 -1
  201. package/dist/remoteRuntime.d.mts +3 -2
  202. package/dist/remoteRuntime.d.mts.map +1 -1
  203. package/dist/remoteRuntime.mjs +41 -62
  204. package/dist/remoteRuntime.mjs.map +1 -1
  205. package/dist/runtimeConfig.cjs +4 -4
  206. package/dist/runtimeConfig.cjs.map +1 -1
  207. package/dist/runtimeConfig.d.mts +10 -9
  208. package/dist/runtimeConfig.d.mts.map +1 -1
  209. package/dist/runtimeConfig.mjs +4 -4
  210. package/dist/runtimeConfig.mjs.map +1 -1
  211. package/dist/runtimeContextApi.cjs +10 -3
  212. package/dist/runtimeContextApi.cjs.map +1 -1
  213. package/dist/runtimeContextApi.d.mts +3 -3
  214. package/dist/runtimeContextApi.d.mts.map +1 -1
  215. package/dist/runtimeContextApi.mjs +10 -3
  216. package/dist/runtimeContextApi.mjs.map +1 -1
  217. package/dist/runtimeCordisHost.cjs +46 -46
  218. package/dist/runtimeCordisHost.cjs.map +1 -1
  219. package/dist/runtimeCordisHost.d.mts +29 -28
  220. package/dist/runtimeCordisHost.d.mts.map +1 -1
  221. package/dist/runtimeCordisHost.mjs +42 -42
  222. package/dist/runtimeCordisHost.mjs.map +1 -1
  223. package/dist/runtimeIdentity.cjs +6 -9
  224. package/dist/runtimeIdentity.cjs.map +1 -1
  225. package/dist/runtimeIdentity.d.mts +5 -1
  226. package/dist/runtimeIdentity.d.mts.map +1 -1
  227. package/dist/runtimeIdentity.mjs +5 -8
  228. package/dist/runtimeIdentity.mjs.map +1 -1
  229. package/dist/runtimeJson.cjs +10 -45
  230. package/dist/runtimeJson.d.mts +3 -22
  231. package/dist/runtimeJson.mjs +3 -39
  232. package/dist/runtimeLogSinkTelemetry.cjs +19 -19
  233. package/dist/runtimeLogSinkTelemetry.cjs.map +1 -1
  234. package/dist/runtimeLogSinkTelemetry.d.mts +19 -19
  235. package/dist/runtimeLogSinkTelemetry.mjs +19 -19
  236. package/dist/runtimeLogSinkTelemetry.mjs.map +1 -1
  237. package/dist/runtimePackages.cjs +7 -2
  238. package/dist/runtimePackages.cjs.map +1 -1
  239. package/dist/runtimePackages.d.mts +4 -1
  240. package/dist/runtimePackages.d.mts.map +1 -1
  241. package/dist/runtimePackages.mjs +7 -2
  242. package/dist/runtimePackages.mjs.map +1 -1
  243. package/dist/runtimePiSettings.cjs +40 -263
  244. package/dist/runtimePiSettings.d.mts +3 -72
  245. package/dist/runtimePiSettings.mjs +3 -241
  246. package/dist/runtimeProtocol.cjs +19 -19
  247. package/dist/runtimeProtocol.cjs.map +1 -1
  248. package/dist/runtimeProtocol.d.mts +7 -7
  249. package/dist/runtimeProtocol.d.mts.map +1 -1
  250. package/dist/runtimeProtocol.mjs +17 -17
  251. package/dist/runtimeProtocol.mjs.map +1 -1
  252. package/dist/runtimeTransition.cjs +9 -9
  253. package/dist/runtimeTransition.cjs.map +1 -1
  254. package/dist/runtimeTransition.d.mts +10 -10
  255. package/dist/runtimeTransition.d.mts.map +1 -1
  256. package/dist/runtimeTransition.mjs +7 -7
  257. package/dist/runtimeTransition.mjs.map +1 -1
  258. package/dist/sandboxHarness.mjs +1 -2
  259. package/dist/server.cjs +3 -7
  260. package/dist/server.d.mts +6 -6
  261. package/dist/server.mjs +3 -4
  262. package/dist/serverPlugin.cjs +39 -0
  263. package/dist/serverPlugin.d.mts +12 -0
  264. package/dist/serverPlugin.mjs +11 -0
  265. package/dist/serverTelemetry.cjs +1 -1
  266. package/dist/serverTelemetry.cjs.map +1 -1
  267. package/dist/serverTelemetry.d.mts +2 -2
  268. package/dist/serverTelemetry.mjs +2 -2
  269. package/dist/serverTelemetry.mjs.map +1 -1
  270. package/dist/sessionFilesApi.cjs +41 -37
  271. package/dist/sessionFilesApi.cjs.map +1 -1
  272. package/dist/sessionFilesApi.d.mts +6 -3
  273. package/dist/sessionFilesApi.d.mts.map +1 -1
  274. package/dist/sessionFilesApi.mjs +41 -36
  275. package/dist/sessionFilesApi.mjs.map +1 -1
  276. package/dist/sessionProtocol.cjs +31 -6
  277. package/dist/sessionProtocol.d.mts +8 -3
  278. package/dist/sessionProtocol.mjs +8 -2
  279. package/dist/skills.cjs +5 -5
  280. package/dist/skills.d.mts +2 -2
  281. package/dist/skills.mjs +1 -2
  282. package/dist/sqliteSessionStorage.cjs +28 -50
  283. package/dist/sqliteSessionStorage.cjs.map +1 -1
  284. package/dist/sqliteSessionStorage.d.mts +13 -20
  285. package/dist/sqliteSessionStorage.d.mts.map +1 -1
  286. package/dist/sqliteSessionStorage.mjs +25 -48
  287. package/dist/sqliteSessionStorage.mjs.map +1 -1
  288. package/dist/src/constants/agentSettled.cjs +7 -0
  289. package/dist/src/constants/agentSettled.cjs.map +1 -0
  290. package/dist/src/constants/agentSettled.mjs +7 -0
  291. package/dist/src/constants/agentSettled.mjs.map +1 -0
  292. package/dist/src/constants/contextApi.cjs +3 -1
  293. package/dist/src/constants/contextApi.cjs.map +1 -1
  294. package/dist/src/constants/contextApi.d.mts +2 -1
  295. package/dist/src/constants/contextApi.d.mts.map +1 -1
  296. package/dist/src/constants/contextApi.mjs +3 -2
  297. package/dist/src/constants/contextApi.mjs.map +1 -1
  298. package/dist/src/constants/voiceTools.cjs +6 -6
  299. package/dist/src/constants/voiceTools.cjs.map +1 -1
  300. package/dist/src/constants/voiceTools.d.mts +3 -3
  301. package/dist/src/constants/voiceTools.mjs +4 -4
  302. package/dist/src/constants/voiceTools.mjs.map +1 -1
  303. package/dist/src/extensions/extensionFile.cjs +22 -5
  304. package/dist/src/extensions/extensionFile.cjs.map +1 -1
  305. package/dist/src/extensions/extensionFile.d.mts +17 -4
  306. package/dist/src/extensions/extensionFile.d.mts.map +1 -1
  307. package/dist/src/extensions/extensionFile.mjs +22 -6
  308. package/dist/src/extensions/extensionFile.mjs.map +1 -1
  309. package/dist/src/extensions/serverPlugin.cjs +231 -92
  310. package/dist/src/extensions/serverPlugin.cjs.map +1 -1
  311. package/dist/src/extensions/serverPlugin.d.mts +2 -2
  312. package/dist/src/extensions/serverPlugin.d.mts.map +1 -1
  313. package/dist/src/extensions/serverPlugin.mjs +232 -93
  314. package/dist/src/extensions/serverPlugin.mjs.map +1 -1
  315. package/dist/src/pi/piSessionRuntime.cjs +349 -142
  316. package/dist/src/pi/piSessionRuntime.cjs.map +1 -1
  317. package/dist/src/pi/piSessionRuntime.d.mts +18 -17
  318. package/dist/src/pi/piSessionRuntime.d.mts.map +1 -1
  319. package/dist/src/pi/piSessionRuntime.mjs +342 -135
  320. package/dist/src/pi/piSessionRuntime.mjs.map +1 -1
  321. package/dist/src/schemas/agentModel.cjs +2 -2
  322. package/dist/src/schemas/agentModel.cjs.map +1 -1
  323. package/dist/src/schemas/agentModel.d.mts +1 -1
  324. package/dist/src/schemas/agentModel.mjs +2 -2
  325. package/dist/src/schemas/agentModel.mjs.map +1 -1
  326. package/dist/src/schemas/apiContracts.d.mts +2 -2
  327. package/dist/src/schemas/apiContracts.d.mts.map +1 -1
  328. package/dist/src/schemas/askUser.cjs +4 -4
  329. package/dist/src/schemas/askUser.cjs.map +1 -1
  330. package/dist/src/schemas/askUser.d.mts +4 -4
  331. package/dist/src/schemas/askUser.d.mts.map +1 -1
  332. package/dist/src/schemas/askUser.mjs +3 -3
  333. package/dist/src/schemas/askUser.mjs.map +1 -1
  334. package/dist/src/schemas/backgroundWork.cjs +10 -10
  335. package/dist/src/schemas/backgroundWork.cjs.map +1 -1
  336. package/dist/src/schemas/backgroundWork.d.mts +9 -9
  337. package/dist/src/schemas/backgroundWork.d.mts.map +1 -1
  338. package/dist/src/schemas/backgroundWork.mjs +8 -8
  339. package/dist/src/schemas/backgroundWork.mjs.map +1 -1
  340. package/dist/src/schemas/childProcess.cjs +5 -5
  341. package/dist/src/schemas/childProcess.cjs.map +1 -1
  342. package/dist/src/schemas/childProcess.d.mts +2 -2
  343. package/dist/src/schemas/childProcess.mjs +5 -5
  344. package/dist/src/schemas/childProcess.mjs.map +1 -1
  345. package/dist/src/schemas/contextContributions.cjs +10 -10
  346. package/dist/src/schemas/contextContributions.cjs.map +1 -1
  347. package/dist/src/schemas/contextContributions.d.mts +16 -16
  348. package/dist/src/schemas/contextContributions.d.mts.map +1 -1
  349. package/dist/src/schemas/contextContributions.mjs +8 -8
  350. package/dist/src/schemas/contextContributions.mjs.map +1 -1
  351. package/dist/src/schemas/delegation.cjs +17 -17
  352. package/dist/src/schemas/delegation.cjs.map +1 -1
  353. package/dist/src/schemas/delegation.d.mts +16 -16
  354. package/dist/src/schemas/delegation.d.mts.map +1 -1
  355. package/dist/src/schemas/delegation.mjs +10 -10
  356. package/dist/src/schemas/delegation.mjs.map +1 -1
  357. package/dist/src/schemas/extensionFile.d.mts +23 -19
  358. package/dist/src/schemas/extensionFile.d.mts.map +1 -1
  359. package/dist/src/schemas/footer.cjs.map +1 -1
  360. package/dist/src/schemas/footer.d.mts +5 -5
  361. package/dist/src/schemas/footer.d.mts.map +1 -1
  362. package/dist/src/schemas/footer.mjs.map +1 -1
  363. package/dist/src/schemas/headless.cjs +37 -37
  364. package/dist/src/schemas/headless.cjs.map +1 -1
  365. package/dist/src/schemas/headless.d.mts +100 -101
  366. package/dist/src/schemas/headless.d.mts.map +1 -1
  367. package/dist/src/schemas/headless.mjs +24 -24
  368. package/dist/src/schemas/headless.mjs.map +1 -1
  369. package/dist/src/schemas/help.cjs +60 -60
  370. package/dist/src/schemas/help.cjs.map +1 -1
  371. package/dist/src/schemas/help.d.mts +43 -43
  372. package/dist/src/schemas/help.d.mts.map +1 -1
  373. package/dist/src/schemas/help.mjs +41 -41
  374. package/dist/src/schemas/help.mjs.map +1 -1
  375. package/dist/src/schemas/home.cjs +127 -0
  376. package/dist/src/schemas/home.cjs.map +1 -0
  377. package/dist/src/schemas/home.d.mts +63 -0
  378. package/dist/src/schemas/home.d.mts.map +1 -0
  379. package/dist/src/schemas/home.mjs +121 -0
  380. package/dist/src/schemas/home.mjs.map +1 -0
  381. package/dist/src/schemas/httpApiContracts.cjs +441 -0
  382. package/dist/src/schemas/httpApiContracts.cjs.map +1 -0
  383. package/dist/src/schemas/httpApiContracts.d.mts +78 -0
  384. package/dist/src/schemas/httpApiContracts.d.mts.map +1 -0
  385. package/dist/src/schemas/httpApiContracts.mjs +434 -0
  386. package/dist/src/schemas/httpApiContracts.mjs.map +1 -0
  387. package/dist/src/schemas/hubChannel.cjs +3 -0
  388. package/dist/src/schemas/hubChannel.cjs.map +1 -1
  389. package/dist/src/schemas/hubChannel.d.mts +84 -60
  390. package/dist/src/schemas/hubChannel.d.mts.map +1 -1
  391. package/dist/src/schemas/hubChannel.mjs +3 -1
  392. package/dist/src/schemas/hubChannel.mjs.map +1 -1
  393. package/dist/src/schemas/leader.cjs.map +1 -1
  394. package/dist/src/schemas/leader.d.mts +3 -3
  395. package/dist/src/schemas/leader.d.mts.map +1 -1
  396. package/dist/src/schemas/leader.mjs.map +1 -1
  397. package/dist/src/schemas/mcpBundle.d.mts +3 -3
  398. package/dist/src/schemas/mcpFacet.cjs.map +1 -1
  399. package/dist/src/schemas/mcpFacet.d.mts +22 -22
  400. package/dist/src/schemas/mcpFacet.d.mts.map +1 -1
  401. package/dist/src/schemas/mcpFacet.mjs.map +1 -1
  402. package/dist/src/schemas/mcpProjection.cjs +41 -41
  403. package/dist/src/schemas/mcpProjection.cjs.map +1 -1
  404. package/dist/src/schemas/mcpProjection.d.mts +31 -30
  405. package/dist/src/schemas/mcpProjection.d.mts.map +1 -1
  406. package/dist/src/schemas/mcpProjection.mjs +29 -29
  407. package/dist/src/schemas/mcpProjection.mjs.map +1 -1
  408. package/dist/src/schemas/mcpSession.cjs +23 -23
  409. package/dist/src/schemas/mcpSession.cjs.map +1 -1
  410. package/dist/src/schemas/mcpSession.d.mts +12 -12
  411. package/dist/src/schemas/mcpSession.d.mts.map +1 -1
  412. package/dist/src/schemas/mcpSession.mjs +18 -18
  413. package/dist/src/schemas/mcpSession.mjs.map +1 -1
  414. package/dist/src/schemas/mcpStatus.cjs +5 -5
  415. package/dist/src/schemas/mcpStatus.cjs.map +1 -1
  416. package/dist/src/schemas/mcpStatus.d.mts +4 -4
  417. package/dist/src/schemas/mcpStatus.d.mts.map +1 -1
  418. package/dist/src/schemas/mcpStatus.mjs +4 -4
  419. package/dist/src/schemas/mcpStatus.mjs.map +1 -1
  420. package/dist/src/schemas/mcpToolResolver.cjs +9 -9
  421. package/dist/src/schemas/mcpToolResolver.cjs.map +1 -1
  422. package/dist/src/schemas/mcpToolResolver.d.mts +7 -7
  423. package/dist/src/schemas/mcpToolResolver.d.mts.map +1 -1
  424. package/dist/src/schemas/mcpToolResolver.mjs +7 -7
  425. package/dist/src/schemas/mcpToolResolver.mjs.map +1 -1
  426. package/dist/src/schemas/narration.cjs +9 -9
  427. package/dist/src/schemas/narration.cjs.map +1 -1
  428. package/dist/src/schemas/narration.d.mts +5 -5
  429. package/dist/src/schemas/narration.d.mts.map +1 -1
  430. package/dist/src/schemas/narration.mjs +7 -7
  431. package/dist/src/schemas/narration.mjs.map +1 -1
  432. package/dist/src/schemas/notification.cjs +45 -45
  433. package/dist/src/schemas/notification.cjs.map +1 -1
  434. package/dist/src/schemas/notification.d.mts +22 -22
  435. package/dist/src/schemas/notification.d.mts.map +1 -1
  436. package/dist/src/schemas/notification.mjs +31 -31
  437. package/dist/src/schemas/notification.mjs.map +1 -1
  438. package/dist/src/schemas/packageApi.cjs +28 -28
  439. package/dist/src/schemas/packageApi.cjs.map +1 -1
  440. package/dist/src/schemas/packageApi.d.mts +91 -65
  441. package/dist/src/schemas/packageApi.d.mts.map +1 -1
  442. package/dist/src/schemas/packageApi.mjs +18 -18
  443. package/dist/src/schemas/packageApi.mjs.map +1 -1
  444. package/dist/src/schemas/platform.cjs +34 -0
  445. package/dist/src/schemas/platform.cjs.map +1 -0
  446. package/dist/src/schemas/platform.d.mts +75 -0
  447. package/dist/src/schemas/platform.d.mts.map +1 -0
  448. package/dist/src/schemas/platform.mjs +27 -0
  449. package/dist/src/schemas/platform.mjs.map +1 -0
  450. package/dist/src/schemas/pluginContributions.cjs.map +1 -1
  451. package/dist/src/schemas/pluginContributions.d.mts +12 -12
  452. package/dist/src/schemas/pluginContributions.d.mts.map +1 -1
  453. package/dist/src/schemas/pluginContributions.mjs.map +1 -1
  454. package/dist/src/schemas/pluginProtocol.cjs +24 -27
  455. package/dist/src/schemas/pluginProtocol.cjs.map +1 -1
  456. package/dist/src/schemas/pluginProtocol.d.mts +21 -21
  457. package/dist/src/schemas/pluginProtocol.d.mts.map +1 -1
  458. package/dist/src/schemas/pluginProtocol.mjs +18 -20
  459. package/dist/src/schemas/pluginProtocol.mjs.map +1 -1
  460. package/dist/src/schemas/profileIdentity.cjs +2 -2
  461. package/dist/src/schemas/profileIdentity.cjs.map +1 -1
  462. package/dist/src/schemas/profileIdentity.d.mts +1 -1
  463. package/dist/src/schemas/profileIdentity.mjs +2 -2
  464. package/dist/src/schemas/profileIdentity.mjs.map +1 -1
  465. package/dist/src/schemas/protocolChannelsContract.cjs +27 -0
  466. package/dist/src/schemas/protocolChannelsContract.cjs.map +1 -0
  467. package/dist/src/schemas/protocolChannelsContract.d.mts +37 -0
  468. package/dist/src/schemas/protocolChannelsContract.d.mts.map +1 -0
  469. package/dist/src/schemas/protocolChannelsContract.mjs +25 -0
  470. package/dist/src/schemas/protocolChannelsContract.mjs.map +1 -0
  471. package/dist/src/schemas/protocolContracts.cjs +168 -0
  472. package/dist/src/schemas/protocolContracts.cjs.map +1 -0
  473. package/dist/src/schemas/protocolContracts.d.mts +69 -0
  474. package/dist/src/schemas/protocolContracts.d.mts.map +1 -0
  475. package/dist/src/schemas/protocolContracts.mjs +164 -0
  476. package/dist/src/schemas/protocolContracts.mjs.map +1 -0
  477. package/dist/src/schemas/protocolHubContract.cjs +51 -0
  478. package/dist/src/schemas/protocolHubContract.cjs.map +1 -0
  479. package/dist/src/schemas/protocolHubContract.d.mts +218 -0
  480. package/dist/src/schemas/protocolHubContract.d.mts.map +1 -0
  481. package/dist/src/schemas/protocolHubContract.mjs +49 -0
  482. package/dist/src/schemas/protocolHubContract.mjs.map +1 -0
  483. package/dist/src/schemas/protocolSessionContract.cjs +22 -0
  484. package/dist/src/schemas/protocolSessionContract.cjs.map +1 -0
  485. package/dist/src/schemas/protocolSessionContract.d.mts +324 -0
  486. package/dist/src/schemas/protocolSessionContract.d.mts.map +1 -0
  487. package/dist/src/schemas/protocolSessionContract.mjs +22 -0
  488. package/dist/src/schemas/protocolSessionContract.mjs.map +1 -0
  489. package/dist/src/schemas/protocolThreadContract.cjs +21 -0
  490. package/dist/src/schemas/protocolThreadContract.cjs.map +1 -0
  491. package/dist/src/schemas/protocolThreadContract.d.mts +29 -0
  492. package/dist/src/schemas/protocolThreadContract.d.mts.map +1 -0
  493. package/dist/src/schemas/protocolThreadContract.mjs +20 -0
  494. package/dist/src/schemas/protocolThreadContract.mjs.map +1 -0
  495. package/dist/src/schemas/readiness.cjs +36 -36
  496. package/dist/src/schemas/readiness.cjs.map +1 -1
  497. package/dist/src/schemas/readiness.d.mts +37 -37
  498. package/dist/src/schemas/readiness.d.mts.map +1 -1
  499. package/dist/src/schemas/readiness.mjs +31 -31
  500. package/dist/src/schemas/readiness.mjs.map +1 -1
  501. package/dist/src/schemas/serverBundle.d.mts +5 -5
  502. package/dist/src/schemas/serverPlugin.cjs +103 -0
  503. package/dist/src/schemas/serverPlugin.cjs.map +1 -0
  504. package/dist/src/schemas/serverPlugin.d.mts +176 -0
  505. package/dist/src/schemas/serverPlugin.d.mts.map +1 -0
  506. package/dist/src/schemas/serverPlugin.mjs +95 -0
  507. package/dist/src/schemas/serverPlugin.mjs.map +1 -0
  508. package/dist/src/schemas/serverScope.cjs +37 -0
  509. package/dist/src/schemas/serverScope.cjs.map +1 -0
  510. package/dist/src/schemas/serverScope.d.mts +77 -0
  511. package/dist/src/schemas/serverScope.d.mts.map +1 -0
  512. package/dist/src/schemas/serverScope.mjs +33 -0
  513. package/dist/src/schemas/serverScope.mjs.map +1 -0
  514. package/dist/src/schemas/sessionApiContracts.cjs +320 -0
  515. package/dist/src/schemas/sessionApiContracts.cjs.map +1 -0
  516. package/dist/src/schemas/sessionApiContracts.mjs +318 -0
  517. package/dist/src/schemas/sessionApiContracts.mjs.map +1 -0
  518. package/dist/src/schemas/sessionProtocol.cjs +20 -13
  519. package/dist/src/schemas/sessionProtocol.cjs.map +1 -1
  520. package/dist/src/schemas/sessionProtocol.d.mts +37 -54
  521. package/dist/src/schemas/sessionProtocol.d.mts.map +1 -1
  522. package/dist/src/schemas/sessionProtocol.mjs +17 -8
  523. package/dist/src/schemas/sessionProtocol.mjs.map +1 -1
  524. package/dist/src/schemas/skills.cjs +16 -16
  525. package/dist/src/schemas/skills.cjs.map +1 -1
  526. package/dist/src/schemas/skills.d.mts +7 -7
  527. package/dist/src/schemas/skills.d.mts.map +1 -1
  528. package/dist/src/schemas/skills.mjs +12 -12
  529. package/dist/src/schemas/skills.mjs.map +1 -1
  530. package/dist/src/schemas/toolOverrides.cjs +9 -9
  531. package/dist/src/schemas/toolOverrides.cjs.map +1 -1
  532. package/dist/src/schemas/toolOverrides.d.mts +8 -8
  533. package/dist/src/schemas/toolOverrides.d.mts.map +1 -1
  534. package/dist/src/schemas/toolOverrides.mjs +7 -7
  535. package/dist/src/schemas/toolOverrides.mjs.map +1 -1
  536. package/dist/src/schemas/toolSurface.cjs +9 -9
  537. package/dist/src/schemas/toolSurface.cjs.map +1 -1
  538. package/dist/src/schemas/toolSurface.d.mts +13 -13
  539. package/dist/src/schemas/toolSurface.d.mts.map +1 -1
  540. package/dist/src/schemas/toolSurface.mjs +7 -7
  541. package/dist/src/schemas/toolSurface.mjs.map +1 -1
  542. package/dist/src/schemas/uiHub.cjs +9 -9
  543. package/dist/src/schemas/uiHub.cjs.map +1 -1
  544. package/dist/src/schemas/uiHub.d.mts +12 -12
  545. package/dist/src/schemas/uiHub.d.mts.map +1 -1
  546. package/dist/src/schemas/uiHub.mjs +7 -7
  547. package/dist/src/schemas/uiHub.mjs.map +1 -1
  548. package/dist/src/server/directHarnessRuntime.cjs +691 -775
  549. package/dist/src/server/directHarnessRuntime.cjs.map +1 -1
  550. package/dist/src/server/directHarnessRuntime.d.mts +5 -1
  551. package/dist/src/server/directHarnessRuntime.d.mts.map +1 -0
  552. package/dist/src/server/directHarnessRuntime.mjs +671 -754
  553. package/dist/src/server/directHarnessRuntime.mjs.map +1 -1
  554. package/dist/src/server/largeFrameLink.cjs +47 -0
  555. package/dist/src/server/largeFrameLink.cjs.map +1 -0
  556. package/dist/src/server/largeFrameLink.mjs +47 -0
  557. package/dist/src/server/largeFrameLink.mjs.map +1 -0
  558. package/dist/src/server/liveImport.cjs +1 -1
  559. package/dist/src/server/liveImport.cjs.map +1 -1
  560. package/dist/src/server/liveImport.d.mts +1 -1
  561. package/dist/src/server/liveImport.mjs +1 -1
  562. package/dist/src/server/liveImport.mjs.map +1 -1
  563. package/dist/src/server/mcpBundleLoader.cjs.map +1 -1
  564. package/dist/src/server/mcpBundleLoader.d.mts +6 -6
  565. package/dist/src/server/mcpBundleLoader.d.mts.map +1 -1
  566. package/dist/src/server/mcpBundleLoader.mjs.map +1 -1
  567. package/dist/src/server/serverPackages.cjs +60 -0
  568. package/dist/src/server/serverPackages.cjs.map +1 -0
  569. package/dist/src/server/serverPackages.d.mts +44 -0
  570. package/dist/src/server/serverPackages.d.mts.map +1 -0
  571. package/dist/src/server/serverPackages.mjs +59 -0
  572. package/dist/src/server/serverPackages.mjs.map +1 -0
  573. package/dist/src/server/serverScope.cjs +510 -0
  574. package/dist/src/server/serverScope.cjs.map +1 -0
  575. package/dist/src/server/serverScope.d.mts +123 -0
  576. package/dist/src/server/serverScope.d.mts.map +1 -0
  577. package/dist/src/server/serverScope.mjs +510 -0
  578. package/dist/src/server/serverScope.mjs.map +1 -0
  579. package/dist/src/server/sessionMcpHandler.cjs +3 -3
  580. package/dist/src/server/sessionMcpHandler.cjs.map +1 -1
  581. package/dist/src/server/sessionMcpHandler.mjs +4 -4
  582. package/dist/src/server/sessionMcpHandler.mjs.map +1 -1
  583. package/dist/src/server/sessionMcpRoutes.cjs +2 -1
  584. package/dist/src/server/sessionMcpRoutes.cjs.map +1 -1
  585. package/dist/src/server/sessionMcpRoutes.mjs +2 -1
  586. package/dist/src/server/sessionMcpRoutes.mjs.map +1 -1
  587. package/dist/src/server/threadJournals.cjs +38 -107
  588. package/dist/src/server/threadJournals.cjs.map +1 -1
  589. package/dist/src/server/threadJournals.mjs +38 -104
  590. package/dist/src/server/threadJournals.mjs.map +1 -1
  591. package/dist/src/services/apiSurfaceAssert/index.cjs +1 -1
  592. package/dist/src/services/apiSurfaceAssert/index.cjs.map +1 -1
  593. package/dist/src/services/apiSurfaceAssert/index.d.mts +6 -6
  594. package/dist/src/services/apiSurfaceAssert/index.mjs +1 -1
  595. package/dist/src/services/apiSurfaceAssert/index.mjs.map +1 -1
  596. package/dist/src/services/chatgptAuth/index.cjs +1 -220
  597. package/dist/src/services/chatgptAuth/index.cjs.map +1 -1
  598. package/dist/src/services/chatgptAuth/index.d.mts +0 -18
  599. package/dist/src/services/chatgptAuth/index.d.mts.map +1 -1
  600. package/dist/src/services/chatgptAuth/index.mjs +1 -217
  601. package/dist/src/services/chatgptAuth/index.mjs.map +1 -1
  602. package/dist/src/services/chatgptImages/index.cjs +1 -1
  603. package/dist/src/services/chatgptImages/index.cjs.map +1 -1
  604. package/dist/src/services/chatgptImages/index.mjs +1 -1
  605. package/dist/src/services/chatgptImages/index.mjs.map +1 -1
  606. package/dist/src/services/chatgptLogin/index.cjs +230 -0
  607. package/dist/src/services/chatgptLogin/index.cjs.map +1 -0
  608. package/dist/src/services/chatgptLogin/index.d.mts +21 -0
  609. package/dist/src/services/chatgptLogin/index.d.mts.map +1 -0
  610. package/dist/src/services/chatgptLogin/index.mjs +227 -0
  611. package/dist/src/services/chatgptLogin/index.mjs.map +1 -0
  612. package/dist/src/services/chatgptWebSearch/index.cjs +1 -1
  613. package/dist/src/services/chatgptWebSearch/index.cjs.map +1 -1
  614. package/dist/src/services/chatgptWebSearch/index.mjs +1 -1
  615. package/dist/src/services/chatgptWebSearch/index.mjs.map +1 -1
  616. package/dist/src/services/contextContributions/index.cjs +8 -8
  617. package/dist/src/services/contextContributions/index.cjs.map +1 -1
  618. package/dist/src/services/contextContributions/index.d.mts +3 -3
  619. package/dist/src/services/contextContributions/index.d.mts.map +1 -1
  620. package/dist/src/services/contextContributions/index.mjs +8 -8
  621. package/dist/src/services/contextContributions/index.mjs.map +1 -1
  622. package/dist/src/services/devProxyStore/devProxyRecords.cjs +59 -0
  623. package/dist/src/services/devProxyStore/devProxyRecords.cjs.map +1 -0
  624. package/dist/src/services/devProxyStore/devProxyRecords.mjs +56 -0
  625. package/dist/src/services/devProxyStore/devProxyRecords.mjs.map +1 -0
  626. package/dist/src/services/devProxyStore/index.cjs +7 -101
  627. package/dist/src/services/devProxyStore/index.cjs.map +1 -1
  628. package/dist/src/services/devProxyStore/index.mjs +7 -101
  629. package/dist/src/services/devProxyStore/index.mjs.map +1 -1
  630. package/dist/src/services/devProxyStore/sync.cjs +66 -0
  631. package/dist/src/services/devProxyStore/sync.cjs.map +1 -0
  632. package/dist/src/services/devProxyStore/sync.mjs +63 -0
  633. package/dist/src/services/devProxyStore/sync.mjs.map +1 -0
  634. package/dist/src/services/durableNavigation/docs.cjs +15 -0
  635. package/dist/src/services/durableNavigation/docs.cjs.map +1 -0
  636. package/dist/src/services/durableNavigation/docs.mjs +16 -0
  637. package/dist/src/services/durableNavigation/docs.mjs.map +1 -0
  638. package/dist/src/services/durableNavigation/index.cjs +3 -18
  639. package/dist/src/services/durableNavigation/index.cjs.map +1 -1
  640. package/dist/src/services/durableNavigation/index.mjs +2 -17
  641. package/dist/src/services/durableNavigation/index.mjs.map +1 -1
  642. package/dist/src/services/durableQueue/docs.cjs +12 -0
  643. package/dist/src/services/durableQueue/docs.cjs.map +1 -0
  644. package/dist/src/services/durableQueue/docs.mjs +13 -0
  645. package/dist/src/services/durableQueue/docs.mjs.map +1 -0
  646. package/dist/src/services/durableQueue/index.cjs +151 -0
  647. package/dist/src/services/durableQueue/index.cjs.map +1 -0
  648. package/dist/src/services/durableQueue/index.mjs +149 -0
  649. package/dist/src/services/durableQueue/index.mjs.map +1 -0
  650. package/dist/src/services/durableRequestReceipts/docs.cjs +11 -0
  651. package/dist/src/services/durableRequestReceipts/docs.cjs.map +1 -0
  652. package/dist/src/services/durableRequestReceipts/docs.mjs +12 -0
  653. package/dist/src/services/durableRequestReceipts/docs.mjs.map +1 -0
  654. package/dist/src/services/{requestReceipts → durableRequestReceipts}/index.cjs +10 -16
  655. package/dist/src/services/durableRequestReceipts/index.cjs.map +1 -0
  656. package/dist/src/services/durableRequestReceipts/index.d.mts +12 -0
  657. package/dist/src/services/durableRequestReceipts/index.d.mts.map +1 -0
  658. package/dist/src/services/{requestReceipts → durableRequestReceipts}/index.mjs +7 -13
  659. package/dist/src/services/durableRequestReceipts/index.mjs.map +1 -0
  660. package/dist/src/services/durableSession/docs.cjs +65 -0
  661. package/dist/src/services/durableSession/docs.cjs.map +1 -0
  662. package/dist/src/services/durableSession/docs.d.mts +17 -0
  663. package/dist/src/services/durableSession/docs.d.mts.map +1 -0
  664. package/dist/src/services/durableSession/docs.mjs +60 -0
  665. package/dist/src/services/durableSession/docs.mjs.map +1 -0
  666. package/dist/src/services/durableSession/index.cjs +21 -0
  667. package/dist/src/services/durableSession/index.cjs.map +1 -0
  668. package/dist/src/services/durableSession/index.d.mts +13 -0
  669. package/dist/src/services/durableSession/index.d.mts.map +1 -0
  670. package/dist/src/services/durableSession/index.mjs +20 -0
  671. package/dist/src/services/durableSession/index.mjs.map +1 -0
  672. package/dist/src/services/durableSubagents/docs.cjs +15 -0
  673. package/dist/src/services/durableSubagents/docs.cjs.map +1 -0
  674. package/dist/src/services/durableSubagents/docs.mjs +16 -0
  675. package/dist/src/services/durableSubagents/docs.mjs.map +1 -0
  676. package/dist/src/services/durableSubagents/extension.cjs +11 -0
  677. package/dist/src/services/durableSubagents/extension.cjs.map +1 -0
  678. package/dist/src/services/durableSubagents/extension.mjs +12 -0
  679. package/dist/src/services/durableSubagents/extension.mjs.map +1 -0
  680. package/dist/src/services/durableSubagents/index.cjs +95 -0
  681. package/dist/src/services/durableSubagents/index.cjs.map +1 -0
  682. package/dist/src/services/durableSubagents/index.mjs +90 -0
  683. package/dist/src/services/durableSubagents/index.mjs.map +1 -0
  684. package/dist/src/services/durableSubagents/tasks.cjs +25 -0
  685. package/dist/src/services/durableSubagents/tasks.cjs.map +1 -0
  686. package/dist/src/services/durableSubagents/tasks.mjs +26 -0
  687. package/dist/src/services/durableSubagents/tasks.mjs.map +1 -0
  688. package/dist/src/services/headlessClient/index.cjs +20 -13
  689. package/dist/src/services/headlessClient/index.cjs.map +1 -1
  690. package/dist/src/services/headlessClient/index.mjs +21 -14
  691. package/dist/src/services/headlessClient/index.mjs.map +1 -1
  692. package/dist/src/services/historyOwnership/type.d.mts +15 -0
  693. package/dist/src/services/historyOwnership/type.d.mts.map +1 -0
  694. package/dist/src/services/hubChannelHarness/index.cjs +2 -2
  695. package/dist/src/services/hubChannelHarness/index.cjs.map +1 -1
  696. package/dist/src/services/hubChannelHarness/index.d.mts +8 -8
  697. package/dist/src/services/hubChannelHarness/index.d.mts.map +1 -1
  698. package/dist/src/services/hubChannelHarness/index.mjs +2 -2
  699. package/dist/src/services/hubChannelHarness/index.mjs.map +1 -1
  700. package/dist/src/services/json/core.cjs +30 -0
  701. package/dist/src/services/json/core.cjs.map +1 -0
  702. package/dist/src/services/json/core.d.mts +21 -0
  703. package/dist/src/services/json/core.d.mts.map +1 -0
  704. package/dist/src/services/json/core.mjs +26 -0
  705. package/dist/src/services/json/core.mjs.map +1 -0
  706. package/dist/src/services/json/sync.cjs +48 -0
  707. package/dist/src/services/json/sync.cjs.map +1 -0
  708. package/dist/src/services/json/sync.d.mts +22 -0
  709. package/dist/src/services/json/sync.d.mts.map +1 -0
  710. package/dist/src/services/json/sync.mjs +43 -0
  711. package/dist/src/services/json/sync.mjs.map +1 -0
  712. package/dist/src/services/kernel/index.cjs +2 -2
  713. package/dist/src/services/kernel/index.cjs.map +1 -1
  714. package/dist/src/services/kernel/index.d.mts +3 -3
  715. package/dist/src/services/kernel/index.d.mts.map +1 -1
  716. package/dist/src/services/kernel/index.mjs +2 -2
  717. package/dist/src/services/kernel/index.mjs.map +1 -1
  718. package/dist/src/services/nativeChildTools/index.cjs +16 -0
  719. package/dist/src/services/nativeChildTools/index.cjs.map +1 -0
  720. package/dist/src/services/nativeChildTools/index.mjs +16 -0
  721. package/dist/src/services/nativeChildTools/index.mjs.map +1 -0
  722. package/dist/src/services/nodeHost/index.cjs +30 -0
  723. package/dist/src/services/nodeHost/index.cjs.map +1 -0
  724. package/dist/src/services/nodeHost/index.d.mts +16 -0
  725. package/dist/src/services/nodeHost/index.d.mts.map +1 -0
  726. package/dist/src/services/nodeHost/index.mjs +27 -0
  727. package/dist/src/services/nodeHost/index.mjs.map +1 -0
  728. package/dist/src/services/nodeModelDependencies/index.cjs +89 -0
  729. package/dist/src/services/nodeModelDependencies/index.cjs.map +1 -0
  730. package/dist/src/services/nodeModelDependencies/index.mjs +86 -0
  731. package/dist/src/services/nodeModelDependencies/index.mjs.map +1 -0
  732. package/dist/src/services/openSessionRegistry/index.cjs +6 -128
  733. package/dist/src/services/openSessionRegistry/index.cjs.map +1 -1
  734. package/dist/src/services/openSessionRegistry/index.d.mts +5 -36
  735. package/dist/src/services/openSessionRegistry/index.mjs +6 -128
  736. package/dist/src/services/openSessionRegistry/index.mjs.map +1 -1
  737. package/dist/src/services/openSessionRegistry/openSessionRecords.cjs +87 -0
  738. package/dist/src/services/openSessionRegistry/openSessionRecords.cjs.map +1 -0
  739. package/dist/src/services/openSessionRegistry/openSessionRecords.d.mts +30 -0
  740. package/dist/src/services/openSessionRegistry/openSessionRecords.d.mts.map +1 -0
  741. package/dist/src/services/openSessionRegistry/openSessionRecords.mjs +81 -0
  742. package/dist/src/services/openSessionRegistry/openSessionRecords.mjs.map +1 -0
  743. package/dist/src/services/openSessionRegistry/sync.cjs +71 -0
  744. package/dist/src/services/openSessionRegistry/sync.cjs.map +1 -0
  745. package/dist/src/services/openSessionRegistry/sync.d.mts +14 -0
  746. package/dist/src/services/openSessionRegistry/sync.d.mts.map +1 -0
  747. package/dist/src/services/openSessionRegistry/sync.mjs +68 -0
  748. package/dist/src/services/openSessionRegistry/sync.mjs.map +1 -0
  749. package/dist/src/services/packageApiHarness/index.cjs +1 -1
  750. package/dist/src/services/packageApiHarness/index.cjs.map +1 -1
  751. package/dist/src/services/packageApiHarness/index.d.mts +6 -6
  752. package/dist/src/services/packageApiHarness/index.d.mts.map +1 -1
  753. package/dist/src/services/packageApiHarness/index.mjs +2 -2
  754. package/dist/src/services/packageApiHarness/index.mjs.map +1 -1
  755. package/dist/src/services/piArgs/index.cjs +53 -0
  756. package/dist/src/services/piArgs/index.cjs.map +1 -0
  757. package/dist/src/services/piArgs/index.d.mts +6 -0
  758. package/dist/src/services/piArgs/index.d.mts.map +1 -0
  759. package/dist/src/services/piArgs/index.mjs +53 -0
  760. package/dist/src/services/piArgs/index.mjs.map +1 -0
  761. package/dist/src/services/piExtensionHost/index.cjs +47 -39
  762. package/dist/src/services/piExtensionHost/index.cjs.map +1 -1
  763. package/dist/src/services/piExtensionHost/index.d.mts +83 -0
  764. package/dist/src/services/piExtensionHost/index.d.mts.map +1 -0
  765. package/dist/src/services/piExtensionHost/index.mjs +47 -38
  766. package/dist/src/services/piExtensionHost/index.mjs.map +1 -1
  767. package/dist/src/services/piHelpTools/index.cjs +5 -5
  768. package/dist/src/services/piHelpTools/index.cjs.map +1 -1
  769. package/dist/src/services/piHelpTools/index.d.mts.map +1 -1
  770. package/dist/src/services/piHelpTools/index.mjs +7 -7
  771. package/dist/src/services/piHelpTools/index.mjs.map +1 -1
  772. package/dist/src/services/piMessages/index.cjs +106 -0
  773. package/dist/src/services/piMessages/index.cjs.map +1 -0
  774. package/dist/src/services/piMessages/index.mjs +105 -0
  775. package/dist/src/services/piMessages/index.mjs.map +1 -0
  776. package/dist/src/services/piSessionEntries/index.cjs +4 -4
  777. package/dist/src/services/piSessionEntries/index.cjs.map +1 -1
  778. package/dist/src/services/piSessionEntries/index.mjs +3 -3
  779. package/dist/src/services/piSessionEntries/index.mjs.map +1 -1
  780. package/dist/src/services/piSettings/core.cjs +308 -0
  781. package/dist/src/services/piSettings/core.cjs.map +1 -0
  782. package/dist/src/services/piSettings/core.d.mts +102 -0
  783. package/dist/src/services/piSettings/core.d.mts.map +1 -0
  784. package/dist/src/services/piSettings/core.mjs +276 -0
  785. package/dist/src/services/piSettings/core.mjs.map +1 -0
  786. package/dist/src/services/piSettings/sync.cjs +119 -0
  787. package/dist/src/services/piSettings/sync.cjs.map +1 -0
  788. package/dist/src/services/piSettings/sync.d.mts +44 -0
  789. package/dist/src/services/piSettings/sync.d.mts.map +1 -0
  790. package/dist/src/services/piSettings/sync.mjs +110 -0
  791. package/dist/src/services/piSettings/sync.mjs.map +1 -0
  792. package/dist/src/services/piSummary/index.cjs +7 -0
  793. package/dist/src/services/piSummary/index.cjs.map +1 -0
  794. package/dist/src/services/piSummary/index.mjs +7 -0
  795. package/dist/src/services/piSummary/index.mjs.map +1 -0
  796. package/dist/src/services/platformFiles/index.cjs +44 -0
  797. package/dist/src/services/platformFiles/index.cjs.map +1 -0
  798. package/dist/src/services/platformFiles/index.d.mts +16 -0
  799. package/dist/src/services/platformFiles/index.d.mts.map +1 -0
  800. package/dist/src/services/platformFiles/index.mjs +39 -0
  801. package/dist/src/services/platformFiles/index.mjs.map +1 -0
  802. package/dist/src/services/pluginLifecycle/index.cjs +19 -13
  803. package/dist/src/services/pluginLifecycle/index.cjs.map +1 -1
  804. package/dist/src/services/pluginLifecycle/index.d.mts +2 -0
  805. package/dist/src/services/pluginLifecycle/index.d.mts.map +1 -1
  806. package/dist/src/services/pluginLifecycle/index.mjs +19 -14
  807. package/dist/src/services/pluginLifecycle/index.mjs.map +1 -1
  808. package/dist/src/services/poPackage/core.cjs +73 -0
  809. package/dist/src/services/poPackage/core.cjs.map +1 -0
  810. package/dist/src/services/poPackage/core.d.mts +32 -0
  811. package/dist/src/services/poPackage/core.d.mts.map +1 -0
  812. package/dist/src/services/poPackage/core.mjs +66 -0
  813. package/dist/src/services/poPackage/core.mjs.map +1 -0
  814. package/dist/src/services/poPackage/sync.cjs +55 -0
  815. package/dist/src/services/poPackage/sync.cjs.map +1 -0
  816. package/dist/src/services/poPackage/sync.d.mts +21 -0
  817. package/dist/src/services/poPackage/sync.d.mts.map +1 -0
  818. package/dist/src/services/poPackage/sync.mjs +50 -0
  819. package/dist/src/services/poPackage/sync.mjs.map +1 -0
  820. package/dist/src/services/providerAuth/index.cjs +11 -7
  821. package/dist/src/services/providerAuth/index.cjs.map +1 -1
  822. package/dist/src/services/providerAuth/index.mjs +11 -7
  823. package/dist/src/services/providerAuth/index.mjs.map +1 -1
  824. package/dist/src/services/publicFileShares/index.cjs +1 -1
  825. package/dist/src/services/publicFileShares/index.cjs.map +1 -1
  826. package/dist/src/services/publicFileShares/index.d.mts +2 -2
  827. package/dist/src/services/publicFileShares/index.mjs +2 -2
  828. package/dist/src/services/publicFileShares/index.mjs.map +1 -1
  829. package/dist/src/services/remoteAccess/index.d.mts +1 -0
  830. package/dist/src/services/remoteAccess/index.d.mts.map +1 -1
  831. package/dist/src/services/remoteAccessStore/index.cjs +8 -190
  832. package/dist/src/services/remoteAccessStore/index.cjs.map +1 -1
  833. package/dist/src/services/remoteAccessStore/index.d.mts +2 -0
  834. package/dist/src/services/remoteAccessStore/index.mjs +7 -187
  835. package/dist/src/services/remoteAccessStore/index.mjs.map +1 -1
  836. package/dist/src/services/remoteAccessStore/remoteAccessRecords.cjs +98 -0
  837. package/dist/src/services/remoteAccessStore/remoteAccessRecords.cjs.map +1 -0
  838. package/dist/src/services/remoteAccessStore/remoteAccessRecords.mjs +88 -0
  839. package/dist/src/services/remoteAccessStore/remoteAccessRecords.mjs.map +1 -0
  840. package/dist/src/services/remoteAccessStore/sync.cjs +111 -0
  841. package/dist/src/services/remoteAccessStore/sync.cjs.map +1 -0
  842. package/dist/src/services/remoteAccessStore/sync.mjs +108 -0
  843. package/dist/src/services/remoteAccessStore/sync.mjs.map +1 -0
  844. package/dist/src/services/runtimeIdentity/sync.cjs +23 -0
  845. package/dist/src/services/runtimeIdentity/sync.cjs.map +1 -0
  846. package/dist/src/services/runtimeIdentity/sync.d.mts +9 -0
  847. package/dist/src/services/runtimeIdentity/sync.d.mts.map +1 -0
  848. package/dist/src/services/runtimeIdentity/sync.mjs +20 -0
  849. package/dist/src/services/runtimeIdentity/sync.mjs.map +1 -0
  850. package/dist/src/services/serialRunner/index.cjs +25 -0
  851. package/dist/src/services/serialRunner/index.cjs.map +1 -0
  852. package/dist/src/services/serialRunner/index.d.mts +10 -0
  853. package/dist/src/services/serialRunner/index.d.mts.map +1 -0
  854. package/dist/src/services/serialRunner/index.mjs +25 -0
  855. package/dist/src/services/serialRunner/index.mjs.map +1 -0
  856. package/dist/src/services/{serverFacet → serverHost}/index.cjs +5 -5
  857. package/dist/src/services/serverHost/index.cjs.map +1 -0
  858. package/dist/src/services/serverHost/index.d.mts +31 -0
  859. package/dist/src/services/serverHost/index.d.mts.map +1 -0
  860. package/dist/src/services/{serverFacet → serverHost}/index.mjs +5 -5
  861. package/dist/src/services/serverHost/index.mjs.map +1 -0
  862. package/dist/src/services/sessionAttachments/index.cjs +4 -3
  863. package/dist/src/services/sessionAttachments/index.cjs.map +1 -1
  864. package/dist/src/services/sessionAttachments/index.d.mts +1 -6
  865. package/dist/src/services/sessionAttachments/index.d.mts.map +1 -1
  866. package/dist/src/services/sessionAttachments/index.mjs +3 -2
  867. package/dist/src/services/sessionAttachments/index.mjs.map +1 -1
  868. package/dist/src/services/sessionAttachments/type.d.mts +9 -0
  869. package/dist/src/services/sessionAttachments/type.d.mts.map +1 -0
  870. package/dist/src/services/sessionFiles/index.cjs +96 -0
  871. package/dist/src/services/sessionFiles/index.cjs.map +1 -0
  872. package/dist/src/services/sessionFiles/index.d.mts +33 -0
  873. package/dist/src/services/sessionFiles/index.d.mts.map +1 -0
  874. package/dist/src/services/sessionFiles/index.mjs +89 -0
  875. package/dist/src/services/sessionFiles/index.mjs.map +1 -0
  876. package/dist/src/services/sessionFiles/sessionDirectory.cjs +66 -0
  877. package/dist/src/services/sessionFiles/sessionDirectory.cjs.map +1 -0
  878. package/dist/src/services/sessionFiles/sessionDirectory.mjs +62 -0
  879. package/dist/src/services/sessionFiles/sessionDirectory.mjs.map +1 -0
  880. package/dist/src/services/sessionGitStatus/index.cjs +31 -33
  881. package/dist/src/services/sessionGitStatus/index.cjs.map +1 -1
  882. package/dist/src/services/sessionGitStatus/index.mjs +31 -33
  883. package/dist/src/services/sessionGitStatus/index.mjs.map +1 -1
  884. package/dist/src/services/sessionPresentation/index.cjs +3 -27
  885. package/dist/src/services/sessionPresentation/index.cjs.map +1 -1
  886. package/dist/src/services/sessionPresentation/index.mjs +3 -27
  887. package/dist/src/services/sessionPresentation/index.mjs.map +1 -1
  888. package/dist/src/services/skillPrompt/index.cjs +11 -0
  889. package/dist/src/services/skillPrompt/index.cjs.map +1 -0
  890. package/dist/src/services/skillPrompt/index.mjs +11 -0
  891. package/dist/src/services/skillPrompt/index.mjs.map +1 -0
  892. package/dist/src/services/sqliteSessionHistory/index.cjs +44 -30
  893. package/dist/src/services/sqliteSessionHistory/index.cjs.map +1 -1
  894. package/dist/src/services/sqliteSessionHistory/index.d.mts +7 -4
  895. package/dist/src/services/sqliteSessionHistory/index.d.mts.map +1 -1
  896. package/dist/src/services/sqliteSessionHistory/index.mjs +43 -28
  897. package/dist/src/services/sqliteSessionHistory/index.mjs.map +1 -1
  898. package/dist/src/services/sqliteTranscriptReader/index.cjs +21 -45
  899. package/dist/src/services/sqliteTranscriptReader/index.cjs.map +1 -1
  900. package/dist/src/services/sqliteTranscriptReader/index.d.mts +3 -2
  901. package/dist/src/services/sqliteTranscriptReader/index.d.mts.map +1 -1
  902. package/dist/src/services/sqliteTranscriptReader/index.mjs +16 -38
  903. package/dist/src/services/sqliteTranscriptReader/index.mjs.map +1 -1
  904. package/dist/src/services/testMode/index.cjs +162 -0
  905. package/dist/src/services/testMode/index.cjs.map +1 -0
  906. package/dist/src/services/testMode/index.d.mts +17 -0
  907. package/dist/src/services/testMode/index.d.mts.map +1 -0
  908. package/dist/src/services/testMode/index.mjs +155 -0
  909. package/dist/src/services/testMode/index.mjs.map +1 -0
  910. package/dist/src/services/toolOverrides/index.cjs +6 -6
  911. package/dist/src/services/toolOverrides/index.cjs.map +1 -1
  912. package/dist/src/services/toolOverrides/index.d.mts +3 -3
  913. package/dist/src/services/toolOverrides/index.d.mts.map +1 -1
  914. package/dist/src/services/toolOverrides/index.mjs +6 -6
  915. package/dist/src/services/toolOverrides/index.mjs.map +1 -1
  916. package/dist/src/services/toolPrompt/index.d.mts +17 -0
  917. package/dist/src/services/toolPrompt/index.d.mts.map +1 -0
  918. package/dist/src/services/toolSurface/index.cjs +3 -3
  919. package/dist/src/services/toolSurface/index.cjs.map +1 -1
  920. package/dist/src/services/toolSurface/index.d.mts +3 -3
  921. package/dist/src/services/toolSurface/index.d.mts.map +1 -1
  922. package/dist/src/services/toolSurface/index.mjs +4 -4
  923. package/dist/src/services/toolSurface/index.mjs.map +1 -1
  924. package/dist/src/services/traceContext/index.cjs.map +1 -1
  925. package/dist/src/services/traceContext/index.mjs.map +1 -1
  926. package/dist/src/services/transcriptPages/index.cjs +159 -33
  927. package/dist/src/services/transcriptPages/index.cjs.map +1 -1
  928. package/dist/src/services/transcriptPages/index.mjs +158 -34
  929. package/dist/src/services/transcriptPages/index.mjs.map +1 -1
  930. package/dist/src/services/voiceToolsContract/index.cjs +7 -7
  931. package/dist/src/services/voiceToolsContract/index.cjs.map +1 -1
  932. package/dist/src/services/voiceToolsContract/index.d.mts +4 -4
  933. package/dist/src/services/voiceToolsContract/index.d.mts.map +1 -1
  934. package/dist/src/services/voiceToolsContract/index.mjs +7 -7
  935. package/dist/src/services/voiceToolsContract/index.mjs.map +1 -1
  936. package/dist/src/services/workspaceRegistry/index.cjs +9 -179
  937. package/dist/src/services/workspaceRegistry/index.cjs.map +1 -1
  938. package/dist/src/services/workspaceRegistry/index.d.mts +5 -47
  939. package/dist/src/services/workspaceRegistry/index.mjs +7 -176
  940. package/dist/src/services/workspaceRegistry/index.mjs.map +1 -1
  941. package/dist/src/services/workspaceRegistry/sync.cjs +148 -0
  942. package/dist/src/services/workspaceRegistry/sync.cjs.map +1 -0
  943. package/dist/src/services/workspaceRegistry/sync.d.mts +34 -0
  944. package/dist/src/services/workspaceRegistry/sync.d.mts.map +1 -0
  945. package/dist/src/services/workspaceRegistry/sync.mjs +140 -0
  946. package/dist/src/services/workspaceRegistry/sync.mjs.map +1 -0
  947. package/dist/src/services/workspaceRegistry/workspaceRecords.cjs +114 -0
  948. package/dist/src/services/workspaceRegistry/workspaceRecords.cjs.map +1 -0
  949. package/dist/src/services/workspaceRegistry/workspaceRecords.d.mts +31 -0
  950. package/dist/src/services/workspaceRegistry/workspaceRecords.d.mts.map +1 -0
  951. package/dist/src/services/workspaceRegistry/workspaceRecords.mjs +101 -0
  952. package/dist/src/services/workspaceRegistry/workspaceRecords.mjs.map +1 -0
  953. package/dist/src/systems/child/adapters/headlessChildSessionService.cjs +339 -202
  954. package/dist/src/systems/child/adapters/headlessChildSessionService.cjs.map +1 -1
  955. package/dist/src/systems/child/adapters/headlessChildSessionService.d.mts +16 -21
  956. package/dist/src/systems/child/adapters/headlessChildSessionService.d.mts.map +1 -1
  957. package/dist/src/systems/child/adapters/headlessChildSessionService.mjs +329 -191
  958. package/dist/src/systems/child/adapters/headlessChildSessionService.mjs.map +1 -1
  959. package/dist/src/systems/child/services/childSession/index.cjs +94 -20
  960. package/dist/src/systems/child/services/childSession/index.cjs.map +1 -1
  961. package/dist/src/systems/child/services/childSession/index.d.mts +12 -3
  962. package/dist/src/systems/child/services/childSession/index.d.mts.map +1 -1
  963. package/dist/src/systems/child/services/childSession/index.mjs +94 -20
  964. package/dist/src/systems/child/services/childSession/index.mjs.map +1 -1
  965. package/dist/src/systems/child/types/childSession.cjs +33 -13
  966. package/dist/src/systems/child/types/childSession.cjs.map +1 -1
  967. package/dist/src/systems/child/types/childSession.d.mts +143 -80
  968. package/dist/src/systems/child/types/childSession.d.mts.map +1 -1
  969. package/dist/src/systems/child/types/childSession.mjs +24 -9
  970. package/dist/src/systems/child/types/childSession.mjs.map +1 -1
  971. package/dist/src/systems/main/adapters/headlessHost.cjs +30 -27
  972. package/dist/src/systems/main/adapters/headlessHost.cjs.map +1 -1
  973. package/dist/src/systems/main/adapters/headlessHost.d.mts +22 -22
  974. package/dist/src/systems/main/adapters/headlessHost.d.mts.map +1 -1
  975. package/dist/src/systems/main/adapters/headlessHost.mjs +33 -30
  976. package/dist/src/systems/main/adapters/headlessHost.mjs.map +1 -1
  977. package/dist/src/systems/main/adapters/headlessSessionHost.cjs +248 -229
  978. package/dist/src/systems/main/adapters/headlessSessionHost.cjs.map +1 -1
  979. package/dist/src/systems/main/adapters/headlessSessionHost.d.mts +4 -5
  980. package/dist/src/systems/main/adapters/headlessSessionHost.d.mts.map +1 -1
  981. package/dist/src/systems/main/adapters/headlessSessionHost.mjs +239 -219
  982. package/dist/src/systems/main/adapters/headlessSessionHost.mjs.map +1 -1
  983. package/dist/src/systems/main/types/headlessHost.d.mts +16 -14
  984. package/dist/src/systems/main/types/headlessHost.d.mts.map +1 -1
  985. package/dist/src/testing/pi/testHost.cjs +2 -2
  986. package/dist/src/testing/pi/testHost.cjs.map +1 -1
  987. package/dist/src/testing/pi/testHost.d.mts +3 -2
  988. package/dist/src/testing/pi/testHost.mjs +3 -3
  989. package/dist/src/testing/pi/testHost.mjs.map +1 -1
  990. package/dist/src/types/config.d.mts +1 -1
  991. package/dist/src/types/config.d.mts.map +1 -1
  992. package/dist/src/types/kernel.d.mts +3 -3
  993. package/dist/src/types/server/directHarnessRuntime.d.mts +54 -25
  994. package/dist/src/types/server/directHarnessRuntime.d.mts.map +1 -1
  995. package/dist/src/types/server/sessionToolSurface.d.mts +9 -9
  996. package/dist/src/web/services/apiClient/index.d.mts +1 -0
  997. package/dist/src/web/services/apiPaths/index.cjs.map +1 -1
  998. package/dist/src/web/services/apiPaths/index.d.mts +1 -1
  999. package/dist/src/web/services/apiPaths/index.mjs.map +1 -1
  1000. package/dist/src/web/services/mcpWidget.cjs.map +1 -1
  1001. package/dist/src/web/services/mcpWidget.d.mts +2 -2
  1002. package/dist/src/web/services/mcpWidget.d.mts.map +1 -1
  1003. package/dist/src/web/services/mcpWidget.mjs.map +1 -1
  1004. package/dist/src/web/services/testing/templateRail.cjs +3 -0
  1005. package/dist/src/web/services/testing/templateRail.cjs.map +1 -1
  1006. package/dist/src/web/services/testing/templateRail.mjs +3 -0
  1007. package/dist/src/web/services/testing/templateRail.mjs.map +1 -1
  1008. package/dist/src/web/types/mcpWidget.d.mts +1 -1
  1009. package/dist/src/web/types/nativeTemplate.d.mts +1 -1
  1010. package/dist/src/web/types/nativeTemplate.d.mts.map +1 -1
  1011. package/dist/src/web/types/template.d.mts +8 -0
  1012. package/dist/src/web/types/template.d.mts.map +1 -1
  1013. package/dist/src/web/types/webPlugin.d.mts +17 -5
  1014. package/dist/src/web/types/webPlugin.d.mts.map +1 -1
  1015. package/dist/testMode.cjs +4 -0
  1016. package/dist/testMode.d.mts +2 -0
  1017. package/dist/testMode.mjs +1 -0
  1018. package/dist/testing.cjs +1 -1
  1019. package/dist/testing.d.mts +2 -2
  1020. package/dist/testing.mjs +2 -2
  1021. package/dist/toolInventory.cjs.map +1 -1
  1022. package/dist/toolInventory.mjs.map +1 -1
  1023. package/dist/toolNames.mjs +1 -2
  1024. package/dist/toolOverrides.cjs +4 -4
  1025. package/dist/toolOverrides.d.mts +3 -3
  1026. package/dist/toolOverrides.mjs +3 -3
  1027. package/dist/toolSurface.cjs +4 -4
  1028. package/dist/toolSurface.d.mts +3 -3
  1029. package/dist/toolSurface.mjs +3 -3
  1030. package/dist/transition.cjs +3 -3
  1031. package/dist/transition.d.cjs +3 -3
  1032. package/dist/transition.d.mts +2 -2
  1033. package/dist/transition.mjs +1 -2
  1034. package/dist/transitionClassifier.cjs.map +1 -1
  1035. package/dist/transitionClassifier.d.mts +2 -2
  1036. package/dist/transitionClassifier.d.mts.map +1 -1
  1037. package/dist/transitionClassifier.mjs.map +1 -1
  1038. package/dist/transitionCoordinator.cjs +3 -3
  1039. package/dist/transitionCoordinator.cjs.map +1 -1
  1040. package/dist/transitionCoordinator.d.mts +4 -4
  1041. package/dist/transitionCoordinator.d.mts.map +1 -1
  1042. package/dist/transitionCoordinator.mjs +3 -3
  1043. package/dist/transitionCoordinator.mjs.map +1 -1
  1044. package/dist/typesContextApi.d.mts +2 -1
  1045. package/dist/typesContextApi.d.mts.map +1 -1
  1046. package/dist/uiHub.cjs +3 -3
  1047. package/dist/uiHub.d.mts +2 -2
  1048. package/dist/uiHub.mjs +1 -2
  1049. package/dist/voiceTools.cjs +5 -5
  1050. package/dist/voiceTools.d.mts +3 -3
  1051. package/dist/voiceTools.mjs +3 -3
  1052. package/dist/web.cjs +8 -0
  1053. package/dist/web.d.mts +3 -2
  1054. package/dist/web.mjs +2 -1
  1055. package/dist/webCompositions.cjs.map +1 -1
  1056. package/dist/webCompositions.d.mts +7 -7
  1057. package/dist/webCompositions.d.mts.map +1 -1
  1058. package/dist/webCompositions.mjs.map +1 -1
  1059. package/licenses/Codex-Apache-2.0.txt +201 -0
  1060. package/package.json +58 -53
  1061. package/dist/doomPackage.cjs +0 -61
  1062. package/dist/doomPackage.cjs.map +0 -1
  1063. package/dist/doomPackage.d.mts +0 -17
  1064. package/dist/doomPackage.d.mts.map +0 -1
  1065. package/dist/doomPackage.mjs +0 -54
  1066. package/dist/doomPackage.mjs.map +0 -1
  1067. package/dist/jsonlSessionRepo.cjs +0 -44
  1068. package/dist/jsonlSessionRepo.cjs.map +0 -1
  1069. package/dist/jsonlSessionRepo.d.mts +0 -7
  1070. package/dist/jsonlSessionRepo.d.mts.map +0 -1
  1071. package/dist/jsonlSessionRepo.mjs +0 -42
  1072. package/dist/jsonlSessionRepo.mjs.map +0 -1
  1073. package/dist/runtimeJson.cjs.map +0 -1
  1074. package/dist/runtimeJson.d.mts.map +0 -1
  1075. package/dist/runtimeJson.mjs.map +0 -1
  1076. package/dist/runtimePiSettings.cjs.map +0 -1
  1077. package/dist/runtimePiSettings.d.mts.map +0 -1
  1078. package/dist/runtimePiSettings.mjs.map +0 -1
  1079. package/dist/serverFacet.cjs +0 -34
  1080. package/dist/serverFacet.d.mts +0 -10
  1081. package/dist/serverFacet.mjs +0 -9
  1082. package/dist/src/pi/piWebSocketListener.cjs +0 -115
  1083. package/dist/src/pi/piWebSocketListener.cjs.map +0 -1
  1084. package/dist/src/pi/piWebSocketListener.mjs +0 -115
  1085. package/dist/src/pi/piWebSocketListener.mjs.map +0 -1
  1086. package/dist/src/schemas/serverFacet.cjs +0 -111
  1087. package/dist/src/schemas/serverFacet.cjs.map +0 -1
  1088. package/dist/src/schemas/serverFacet.d.mts +0 -152
  1089. package/dist/src/schemas/serverFacet.d.mts.map +0 -1
  1090. package/dist/src/schemas/serverFacet.mjs +0 -101
  1091. package/dist/src/schemas/serverFacet.mjs.map +0 -1
  1092. package/dist/src/schemas/sessionUpdates.d.mts +0 -34
  1093. package/dist/src/schemas/sessionUpdates.d.mts.map +0 -1
  1094. package/dist/src/server/headlessProtocol.cjs +0 -382
  1095. package/dist/src/server/headlessProtocol.cjs.map +0 -1
  1096. package/dist/src/server/headlessProtocol.mjs +0 -382
  1097. package/dist/src/server/headlessProtocol.mjs.map +0 -1
  1098. package/dist/src/server/nativeChildTranscriptReader.cjs +0 -20
  1099. package/dist/src/server/nativeChildTranscriptReader.cjs.map +0 -1
  1100. package/dist/src/server/nativeChildTranscriptReader.mjs +0 -18
  1101. package/dist/src/server/nativeChildTranscriptReader.mjs.map +0 -1
  1102. package/dist/src/server/serverFacetLoader.cjs +0 -214
  1103. package/dist/src/server/serverFacetLoader.cjs.map +0 -1
  1104. package/dist/src/server/serverFacetLoader.d.mts +0 -72
  1105. package/dist/src/server/serverFacetLoader.d.mts.map +0 -1
  1106. package/dist/src/server/serverFacetLoader.mjs +0 -212
  1107. package/dist/src/server/serverFacetLoader.mjs.map +0 -1
  1108. package/dist/src/services/acpSessionUpdates/index.cjs +0 -129
  1109. package/dist/src/services/acpSessionUpdates/index.cjs.map +0 -1
  1110. package/dist/src/services/acpSessionUpdates/index.mjs +0 -129
  1111. package/dist/src/services/acpSessionUpdates/index.mjs.map +0 -1
  1112. package/dist/src/services/historyImport/index.cjs +0 -8
  1113. package/dist/src/services/historyImport/index.cjs.map +0 -1
  1114. package/dist/src/services/historyImport/index.d.mts +0 -68
  1115. package/dist/src/services/historyImport/index.d.mts.map +0 -1
  1116. package/dist/src/services/historyImport/index.mjs +0 -8
  1117. package/dist/src/services/historyImport/index.mjs.map +0 -1
  1118. package/dist/src/services/openSessionRegistry/index.d.mts.map +0 -1
  1119. package/dist/src/services/requestReceipts/index.cjs.map +0 -1
  1120. package/dist/src/services/requestReceipts/index.d.mts +0 -11
  1121. package/dist/src/services/requestReceipts/index.d.mts.map +0 -1
  1122. package/dist/src/services/requestReceipts/index.mjs.map +0 -1
  1123. package/dist/src/services/rpcTranscript/index.cjs +0 -633
  1124. package/dist/src/services/rpcTranscript/index.cjs.map +0 -1
  1125. package/dist/src/services/rpcTranscript/index.d.mts +0 -50
  1126. package/dist/src/services/rpcTranscript/index.d.mts.map +0 -1
  1127. package/dist/src/services/rpcTranscript/index.mjs +0 -632
  1128. package/dist/src/services/rpcTranscript/index.mjs.map +0 -1
  1129. package/dist/src/services/serverFacet/index.cjs.map +0 -1
  1130. package/dist/src/services/serverFacet/index.d.mts +0 -31
  1131. package/dist/src/services/serverFacet/index.d.mts.map +0 -1
  1132. package/dist/src/services/serverFacet/index.mjs.map +0 -1
  1133. package/dist/src/services/workspaceRegistry/index.d.mts.map +0 -1
  1134. package/dist/src/systems/child/adapters/nativeChildRuntimes.cjs +0 -28
  1135. package/dist/src/systems/child/adapters/nativeChildRuntimes.cjs.map +0 -1
  1136. package/dist/src/systems/child/adapters/nativeChildRuntimes.mjs +0 -25
  1137. package/dist/src/systems/child/adapters/nativeChildRuntimes.mjs.map +0 -1
  1138. package/dist/terminalPiChildSessionService.cjs +0 -324
  1139. package/dist/terminalPiChildSessionService.cjs.map +0 -1
  1140. package/dist/terminalPiChildSessionService.d.mts +0 -46
  1141. package/dist/terminalPiChildSessionService.d.mts.map +0 -1
  1142. package/dist/terminalPiChildSessionService.mjs +0 -318
  1143. package/dist/terminalPiChildSessionService.mjs.map +0 -1
  1144. package/dist/v3Export.cjs +0 -10
  1145. package/dist/v3Export.cjs.map +0 -1
  1146. package/dist/v3Export.d.mts +0 -35
  1147. package/dist/v3Export.d.mts.map +0 -1
  1148. package/dist/v3Export.mjs +0 -9
  1149. package/dist/v3Export.mjs.map +0 -1
@@ -0,0 +1,50 @@
1
+ import { PACKAGE_MANIFEST, PO_PACKAGE_NAME, parseManifestName } from "./core.mjs";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ //#region src/services/poPackage/sync.ts
5
+ /**
6
+ * The `name` field of the manifest in a directory, when it has a readable one.
7
+ *
8
+ * @deprecated Node-only sync shim; use manifestNameAsync. Removed in M2.
9
+ */
10
+ function manifestName(directory) {
11
+ let content;
12
+ try {
13
+ content = fs.readFileSync(path.join(directory, PACKAGE_MANIFEST), "utf8");
14
+ } catch {
15
+ return;
16
+ }
17
+ return parseManifestName(content);
18
+ }
19
+ /**
20
+ * Name of the nearest package a path belongs to, walking upward from it.
21
+ *
22
+ * @deprecated Node-only sync shim; use enclosingPackageNameAsync. Removed in M2.
23
+ */
24
+ function enclosingPackageName(target) {
25
+ let directory;
26
+ try {
27
+ directory = fs.statSync(target).isDirectory() ? target : path.dirname(target);
28
+ } catch {
29
+ return;
30
+ }
31
+ while (true) {
32
+ const name = manifestName(directory);
33
+ if (name !== void 0) return name;
34
+ const parent = path.dirname(directory);
35
+ if (parent === directory) return void 0;
36
+ directory = parent;
37
+ }
38
+ }
39
+ /**
40
+ * True when a resolved path lives inside an installed Po package.
41
+ *
42
+ * @deprecated Node-only sync shim; use isPoPackagePathAsync. Removed in M2.
43
+ */
44
+ function isPoPackagePath(target) {
45
+ return enclosingPackageName(target) === PO_PACKAGE_NAME;
46
+ }
47
+ //#endregion
48
+ export { enclosingPackageName, isPoPackagePath, manifestName };
49
+
50
+ //# sourceMappingURL=sync.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.mjs","names":[],"sources":["../../../../src/services/poPackage/sync.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { PO_PACKAGE_NAME, PACKAGE_MANIFEST, parseManifestName } from './core';\n\n/**\n * The `name` field of the manifest in a directory, when it has a readable one.\n *\n * @deprecated Node-only sync shim; use manifestNameAsync. Removed in M2.\n */\nexport function manifestName(directory: string): string | undefined {\n let content: string;\n try {\n content = fs.readFileSync(path.join(directory, PACKAGE_MANIFEST), 'utf8');\n } catch {\n // A directory with no readable manifest simply is not a package root.\n return undefined;\n }\n return parseManifestName(content);\n}\n\n/**\n * Name of the nearest package a path belongs to, walking upward from it.\n *\n * @deprecated Node-only sync shim; use enclosingPackageNameAsync. Removed in M2.\n */\nexport function enclosingPackageName(target: string): string | undefined {\n let directory: string;\n try {\n directory = fs.statSync(target).isDirectory() ? target : path.dirname(target);\n } catch {\n // Nothing at that path, so it names no package.\n return undefined;\n }\n\n while (true) {\n const name = manifestName(directory);\n if (name !== undefined) return name;\n const parent = path.dirname(directory);\n if (parent === directory) return undefined;\n directory = parent;\n }\n}\n\n/**\n * True when a resolved path lives inside an installed Po package.\n *\n * @deprecated Node-only sync shim; use isPoPackagePathAsync. Removed in M2.\n */\nexport function isPoPackagePath(target: string): boolean {\n return enclosingPackageName(target) === PO_PACKAGE_NAME;\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,aAAa,WAAuC;CAClE,IAAI;CACJ,IAAI;EACF,UAAU,GAAG,aAAa,KAAK,KAAK,WAAW,gBAAgB,GAAG,MAAM;CAC1E,QAAQ;EAEN;CACF;CACA,OAAO,kBAAkB,OAAO;AAClC;;;;;;AAOA,SAAgB,qBAAqB,QAAoC;CACvE,IAAI;CACJ,IAAI;EACF,YAAY,GAAG,SAAS,MAAM,CAAC,CAAC,YAAY,IAAI,SAAS,KAAK,QAAQ,MAAM;CAC9E,QAAQ;EAEN;CACF;CAEA,OAAO,MAAM;EACX,MAAM,OAAO,aAAa,SAAS;EACnC,IAAI,SAAS,KAAA,GAAW,OAAO;EAC/B,MAAM,SAAS,KAAK,QAAQ,SAAS;EACrC,IAAI,WAAW,WAAW,OAAO,KAAA;EACjC,YAAY;CACd;AACF;;;;;;AAOA,SAAgB,gBAAgB,QAAyB;CACvD,OAAO,qBAAqB,MAAM,MAAM;AAC1C"}
@@ -52,14 +52,18 @@ function createProviderAuth(options) {
52
52
  };
53
53
  const findProvider = (current, providerId) => current.getProviders().find((provider) => provider.id === providerId);
54
54
  const runningFor = (providerId) => [...flows.values()].find((flow) => flow.providerId === providerId && flow.snapshot().status === "running");
55
+ const refreshed = async () => {
56
+ const current = await runtime();
57
+ try {
58
+ await current.refresh({ allowNetwork: false });
59
+ } catch (error) {
60
+ notice(`provider auth refresh failed: ${describe(error)}`);
61
+ }
62
+ return current;
63
+ };
55
64
  return {
56
65
  async listProviders() {
57
- const current = await runtime();
58
- try {
59
- await current.refresh({ allowNetwork: false });
60
- } catch (error) {
61
- notice(`provider auth refresh failed: ${describe(error)}`);
62
- }
66
+ const current = await refreshed();
63
67
  return current.getProviders().map((provider) => summarize(current, provider)).sort((left, right) => left.name.localeCompare(right.name));
64
68
  },
65
69
  async startLogin(providerId, type, remote) {
@@ -138,7 +142,7 @@ function createProviderAuth(options) {
138
142
  return { ok: true };
139
143
  },
140
144
  async listModels() {
141
- const current = await runtime();
145
+ const current = await refreshed();
142
146
  const providers = new Map(current.getProviders().map((provider) => [provider.id, provider.name]));
143
147
  return current.getAvailableSnapshot().filter((model) => current.hasConfiguredAuth(model.provider)).map((model) => ({
144
148
  value: `${model.provider}/${model.id}`,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["createLoginFlow","crypto"],"sources":["../../../../src/services/providerAuth/index.ts"],"sourcesContent":["import crypto from 'node:crypto';\n\nimport type {\n AuthMethodType,\n AuthRuntime,\n AuthRuntimeProvider,\n LoginFlowSnapshot,\n ProviderAuthMethod,\n ProviderAuthSummary,\n} from '../../types/server/auth';\nimport { CHATGPT_AUTH_PROVIDER_ID } from '../chatgptAuth';\nimport { createLoginFlow, type LoginFlow } from '../loginFlow';\ninterface SettingsModel {\n value: string;\n label: string;\n group: string;\n}\n\n/** Matches the timeout Pi's own /logout gives the credential store. */\nconst LOGOUT_TIMEOUT_MS = 15_000;\n\nexport type StartLoginOutcome =\n | { ok: true; flow: LoginFlowSnapshot }\n | { ok: false; code: 'unknown_provider' | 'unsupported_method' | 'busy'; error: string };\n\nexport type LogoutOutcome = { ok: true } | { ok: false; code: 'unknown_provider' | 'runtime'; error: string };\n\nexport type AnswerOutcome = 'answered' | 'unknown_flow' | 'not_waiting';\n\n/** Provider credentials as the settings page sees them, backed by one Pi runtime. */\nexport interface ProviderAuth {\n /** Every provider Pi knows, with its current auth state; re-read from disk each call. */\n listProviders(): Promise<ProviderAuthSummary[]>;\n /**\n * Starts a login. `remote` means the browser driving it is on another\n * machine, which decides whether a redirect-free method is chosen for the\n * user; it comes from the accepted socket, never from the request body.\n */\n startLogin(providerId: string, type: AuthMethodType, remote?: boolean): Promise<StartLoginOutcome>;\n getLogin(flowId: string): LoginFlowSnapshot | undefined;\n answerLogin(flowId: string, promptId: string, value: string): AnswerOutcome;\n /** Cancels the flow and returns how it stands, or undefined for an unknown flow. */\n cancelLogin(flowId: string): LoginFlowSnapshot | undefined;\n logout(providerId: string): Promise<LogoutOutcome>;\n /**\n * Every model the machine can actually use, grouped by provider. Read from\n * the same runtime the providers page uses, so the settings model pickers\n * work with no session running.\n */\n listModels(): Promise<readonly SettingsModel[]>;\n /** Abandons every running flow; the hub is shutting down. */\n close(): void;\n}\n\nexport interface ProviderAuthOptions {\n runtime: () => Promise<AuthRuntime>;\n onNotice?: (message: string) => void;\n}\n\nfunction describe(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** The methods a page can start, in the order the TUI's selector lists them. */\nfunction methodsOf(provider: AuthRuntimeProvider): ProviderAuthMethod[] {\n const methods: ProviderAuthMethod[] = [];\n const { oauth, apiKey } = provider.auth;\n if (oauth) methods.push({ type: 'oauth', label: oauth.loginLabel ?? oauth.name });\n if (apiKey?.login) methods.push({ type: 'api_key', label: apiKey.name });\n return methods;\n}\n\n/** Mirrors the status the TUI's login selector shows beside each provider. */\nfunction summarize(runtime: AuthRuntime, provider: AuthRuntimeProvider): ProviderAuthSummary {\n const summary: ProviderAuthSummary = { id: provider.id, name: provider.name, methods: methodsOf(provider) };\n if (provider.id === CHATGPT_AUTH_PROVIDER_ID) summary.kind = 'po-feature';\n const status = runtime.getProviderAuthStatus(provider.id);\n if (status.configured) {\n summary.authenticated = {\n type: runtime.isUsingOAuth(provider.id) ? 'oauth' : 'api_key',\n source: status.label ?? status.source,\n };\n }\n return summary;\n}\n\nexport function createProviderAuth(options: ProviderAuthOptions): ProviderAuth {\n const notice = options.onNotice ?? ((): void => {});\n const load = options.runtime;\n const flows = new Map<string, LoginFlow>();\n let loading: Promise<AuthRuntime> | undefined;\n\n // A failed load is forgotten so the next request tries again rather than\n // pinning the page on a startup error.\n const runtime = (): Promise<AuthRuntime> => {\n loading ??= load().catch((error: unknown) => {\n loading = undefined;\n throw error;\n });\n return loading;\n };\n\n const findProvider = (current: AuthRuntime, providerId: string): AuthRuntimeProvider | undefined =>\n current.getProviders().find((provider) => provider.id === providerId);\n\n const runningFor = (providerId: string): LoginFlow | undefined =>\n [...flows.values()].find((flow) => flow.providerId === providerId && flow.snapshot().status === 'running');\n\n return {\n async listProviders() {\n const current = await runtime();\n // Another client may have stored a credential since the last look (a\n // TUI /login, a hand-edited auth.json); the stale snapshot still lists\n // on a failed refresh, which the notice explains.\n try {\n await current.refresh({ allowNetwork: false });\n } catch (error) {\n notice(`provider auth refresh failed: ${describe(error)}`);\n }\n return current\n .getProviders()\n .map((provider) => summarize(current, provider))\n .sort((left, right) => left.name.localeCompare(right.name));\n },\n\n async startLogin(providerId, type, remote) {\n const current = await runtime();\n const provider = findProvider(current, providerId);\n if (!provider) return { ok: false, code: 'unknown_provider', error: `Unknown provider: ${providerId}` };\n if (!methodsOf(provider).some((method) => method.type === type)) {\n return { ok: false, code: 'unsupported_method', error: `${provider.name} has no ${type} login.` };\n }\n if (runningFor(providerId)) {\n return { ok: false, code: 'busy', error: `A login for ${provider.name} is already in progress.` };\n }\n // Finished flows live until the next start: long enough for the page to\n // read how they ended, short enough that the map never grows.\n for (const [id, flow] of flows) if (flow.snapshot().status !== 'running') flows.delete(id);\n\n const flow = createLoginFlow({\n id: crypto.randomUUID(),\n providerId,\n providerName: provider.name,\n type,\n ...(remote === true ? { remote: true } : {}),\n });\n flows.set(flow.id, flow);\n current.login(providerId, type, flow.interaction).then(\n () => {\n flow.settle({ ok: true });\n notice(`signed in to ${provider.name} (${type})`);\n },\n (error: unknown) => {\n flow.settle({ ok: false, error: describe(error) });\n },\n );\n return { ok: true, flow: flow.snapshot() };\n },\n\n getLogin(flowId) {\n return flows.get(flowId)?.snapshot();\n },\n\n answerLogin(flowId, promptId, value) {\n const flow = flows.get(flowId);\n if (!flow) return 'unknown_flow';\n return flow.answer(promptId, value) ? 'answered' : 'not_waiting';\n },\n\n cancelLogin(flowId) {\n const flow = flows.get(flowId);\n if (!flow) return undefined;\n flow.cancel();\n return flow.snapshot();\n },\n\n async logout(providerId) {\n const current = await runtime();\n const provider = findProvider(current, providerId);\n if (!provider) return { ok: false, code: 'unknown_provider', error: `Unknown provider: ${providerId}` };\n try {\n await current.logout(providerId, { signal: AbortSignal.timeout(LOGOUT_TIMEOUT_MS) });\n } catch (error) {\n return { ok: false, code: 'runtime', error: describe(error) };\n }\n notice(`signed out of ${provider.name}`);\n return { ok: true };\n },\n\n async listModels() {\n const current = await runtime();\n const providers = new Map(current.getProviders().map((provider) => [provider.id, provider.name]));\n return current\n .getAvailableSnapshot()\n .filter((model) => current.hasConfiguredAuth(model.provider))\n .map((model) => ({\n value: `${model.provider}/${model.id}`,\n label: model.id,\n group: providers.get(model.provider) ?? model.provider,\n }));\n },\n\n close() {\n for (const flow of flows.values()) flow.cancel();\n flows.clear();\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["createLoginFlow","crypto"],"sources":["../../../../src/services/providerAuth/index.ts"],"sourcesContent":["import crypto from 'node:crypto';\n\nimport type {\n AuthMethodType,\n AuthRuntime,\n AuthRuntimeProvider,\n LoginFlowSnapshot,\n ProviderAuthMethod,\n ProviderAuthSummary,\n} from '../../types/server/auth';\nimport { CHATGPT_AUTH_PROVIDER_ID } from '../chatgptAuth';\nimport { createLoginFlow, type LoginFlow } from '../loginFlow';\ninterface SettingsModel {\n value: string;\n label: string;\n group: string;\n}\n\n/** Matches the timeout Pi's own /logout gives the credential store. */\nconst LOGOUT_TIMEOUT_MS = 15_000;\n\nexport type StartLoginOutcome =\n | { ok: true; flow: LoginFlowSnapshot }\n | { ok: false; code: 'unknown_provider' | 'unsupported_method' | 'busy'; error: string };\n\nexport type LogoutOutcome = { ok: true } | { ok: false; code: 'unknown_provider' | 'runtime'; error: string };\n\nexport type AnswerOutcome = 'answered' | 'unknown_flow' | 'not_waiting';\n\n/** Provider credentials as the settings page sees them, backed by one Pi runtime. */\nexport interface ProviderAuth {\n /** Every provider Pi knows, with its current auth state; re-read from disk each call. */\n listProviders(): Promise<ProviderAuthSummary[]>;\n /**\n * Starts a login. `remote` means the browser driving it is on another\n * machine, which decides whether a redirect-free method is chosen for the\n * user; it comes from the accepted socket, never from the request body.\n */\n startLogin(providerId: string, type: AuthMethodType, remote?: boolean): Promise<StartLoginOutcome>;\n getLogin(flowId: string): LoginFlowSnapshot | undefined;\n answerLogin(flowId: string, promptId: string, value: string): AnswerOutcome;\n /** Cancels the flow and returns how it stands, or undefined for an unknown flow. */\n cancelLogin(flowId: string): LoginFlowSnapshot | undefined;\n logout(providerId: string): Promise<LogoutOutcome>;\n /**\n * Every model the machine can actually use, grouped by provider. Read from\n * the same runtime the providers page uses, so the settings model pickers\n * work with no session running.\n */\n listModels(): Promise<readonly SettingsModel[]>;\n /** Abandons every running flow; the hub is shutting down. */\n close(): void;\n}\n\nexport interface ProviderAuthOptions {\n runtime: () => Promise<AuthRuntime>;\n onNotice?: (message: string) => void;\n}\n\nfunction describe(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** The methods a page can start, in the order the TUI's selector lists them. */\nfunction methodsOf(provider: AuthRuntimeProvider): ProviderAuthMethod[] {\n const methods: ProviderAuthMethod[] = [];\n const { oauth, apiKey } = provider.auth;\n if (oauth) methods.push({ type: 'oauth', label: oauth.loginLabel ?? oauth.name });\n if (apiKey?.login) methods.push({ type: 'api_key', label: apiKey.name });\n return methods;\n}\n\n/** Mirrors the status the TUI's login selector shows beside each provider. */\nfunction summarize(runtime: AuthRuntime, provider: AuthRuntimeProvider): ProviderAuthSummary {\n const summary: ProviderAuthSummary = { id: provider.id, name: provider.name, methods: methodsOf(provider) };\n if (provider.id === CHATGPT_AUTH_PROVIDER_ID) summary.kind = 'po-feature';\n const status = runtime.getProviderAuthStatus(provider.id);\n if (status.configured) {\n summary.authenticated = {\n type: runtime.isUsingOAuth(provider.id) ? 'oauth' : 'api_key',\n source: status.label ?? status.source,\n };\n }\n return summary;\n}\n\nexport function createProviderAuth(options: ProviderAuthOptions): ProviderAuth {\n const notice = options.onNotice ?? ((): void => {});\n const load = options.runtime;\n const flows = new Map<string, LoginFlow>();\n let loading: Promise<AuthRuntime> | undefined;\n\n // A failed load is forgotten so the next request tries again rather than\n // pinning the page on a startup error.\n const runtime = (): Promise<AuthRuntime> => {\n loading ??= load().catch((error: unknown) => {\n loading = undefined;\n throw error;\n });\n return loading;\n };\n\n const findProvider = (current: AuthRuntime, providerId: string): AuthRuntimeProvider | undefined =>\n current.getProviders().find((provider) => provider.id === providerId);\n\n const runningFor = (providerId: string): LoginFlow | undefined =>\n [...flows.values()].find((flow) => flow.providerId === providerId && flow.snapshot().status === 'running');\n\n // Another client may have stored a credential since the last look (a TUI\n // /login, a hand-edited auth.json), and a provider registered by a Pi\n // extension after the runtime was created is missing from the cached auth\n // state until a refresh. The stale snapshot still lists on a failed refresh,\n // which the notice explains.\n const refreshed = async (): Promise<AuthRuntime> => {\n const current = await runtime();\n try {\n await current.refresh({ allowNetwork: false });\n } catch (error) {\n notice(`provider auth refresh failed: ${describe(error)}`);\n }\n return current;\n };\n\n return {\n async listProviders() {\n const current = await refreshed();\n return current\n .getProviders()\n .map((provider) => summarize(current, provider))\n .sort((left, right) => left.name.localeCompare(right.name));\n },\n\n async startLogin(providerId, type, remote) {\n const current = await runtime();\n const provider = findProvider(current, providerId);\n if (!provider) return { ok: false, code: 'unknown_provider', error: `Unknown provider: ${providerId}` };\n if (!methodsOf(provider).some((method) => method.type === type)) {\n return { ok: false, code: 'unsupported_method', error: `${provider.name} has no ${type} login.` };\n }\n if (runningFor(providerId)) {\n return { ok: false, code: 'busy', error: `A login for ${provider.name} is already in progress.` };\n }\n // Finished flows live until the next start: long enough for the page to\n // read how they ended, short enough that the map never grows.\n for (const [id, flow] of flows) if (flow.snapshot().status !== 'running') flows.delete(id);\n\n const flow = createLoginFlow({\n id: crypto.randomUUID(),\n providerId,\n providerName: provider.name,\n type,\n ...(remote === true ? { remote: true } : {}),\n });\n flows.set(flow.id, flow);\n current.login(providerId, type, flow.interaction).then(\n () => {\n flow.settle({ ok: true });\n notice(`signed in to ${provider.name} (${type})`);\n },\n (error: unknown) => {\n flow.settle({ ok: false, error: describe(error) });\n },\n );\n return { ok: true, flow: flow.snapshot() };\n },\n\n getLogin(flowId) {\n return flows.get(flowId)?.snapshot();\n },\n\n answerLogin(flowId, promptId, value) {\n const flow = flows.get(flowId);\n if (!flow) return 'unknown_flow';\n return flow.answer(promptId, value) ? 'answered' : 'not_waiting';\n },\n\n cancelLogin(flowId) {\n const flow = flows.get(flowId);\n if (!flow) return undefined;\n flow.cancel();\n return flow.snapshot();\n },\n\n async logout(providerId) {\n const current = await runtime();\n const provider = findProvider(current, providerId);\n if (!provider) return { ok: false, code: 'unknown_provider', error: `Unknown provider: ${providerId}` };\n try {\n await current.logout(providerId, { signal: AbortSignal.timeout(LOGOUT_TIMEOUT_MS) });\n } catch (error) {\n return { ok: false, code: 'runtime', error: describe(error) };\n }\n notice(`signed out of ${provider.name}`);\n return { ok: true };\n },\n\n async listModels() {\n const current = await refreshed();\n const providers = new Map(current.getProviders().map((provider) => [provider.id, provider.name]));\n return current\n .getAvailableSnapshot()\n .filter((model) => current.hasConfiguredAuth(model.provider))\n .map((model) => ({\n value: `${model.provider}/${model.id}`,\n label: model.id,\n group: providers.get(model.provider) ?? model.provider,\n }));\n },\n\n close() {\n for (const flow of flows.values()) flow.cancel();\n flows.clear();\n },\n };\n}\n"],"mappings":"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"}
@@ -50,14 +50,18 @@ function createProviderAuth(options) {
50
50
  };
51
51
  const findProvider = (current, providerId) => current.getProviders().find((provider) => provider.id === providerId);
52
52
  const runningFor = (providerId) => [...flows.values()].find((flow) => flow.providerId === providerId && flow.snapshot().status === "running");
53
+ const refreshed = async () => {
54
+ const current = await runtime();
55
+ try {
56
+ await current.refresh({ allowNetwork: false });
57
+ } catch (error) {
58
+ notice(`provider auth refresh failed: ${describe(error)}`);
59
+ }
60
+ return current;
61
+ };
53
62
  return {
54
63
  async listProviders() {
55
- const current = await runtime();
56
- try {
57
- await current.refresh({ allowNetwork: false });
58
- } catch (error) {
59
- notice(`provider auth refresh failed: ${describe(error)}`);
60
- }
64
+ const current = await refreshed();
61
65
  return current.getProviders().map((provider) => summarize(current, provider)).sort((left, right) => left.name.localeCompare(right.name));
62
66
  },
63
67
  async startLogin(providerId, type, remote) {
@@ -136,7 +140,7 @@ function createProviderAuth(options) {
136
140
  return { ok: true };
137
141
  },
138
142
  async listModels() {
139
- const current = await runtime();
143
+ const current = await refreshed();
140
144
  const providers = new Map(current.getProviders().map((provider) => [provider.id, provider.name]));
141
145
  return current.getAvailableSnapshot().filter((model) => current.hasConfiguredAuth(model.provider)).map((model) => ({
142
146
  value: `${model.provider}/${model.id}`,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/providerAuth/index.ts"],"sourcesContent":["import crypto from 'node:crypto';\n\nimport type {\n AuthMethodType,\n AuthRuntime,\n AuthRuntimeProvider,\n LoginFlowSnapshot,\n ProviderAuthMethod,\n ProviderAuthSummary,\n} from '../../types/server/auth';\nimport { CHATGPT_AUTH_PROVIDER_ID } from '../chatgptAuth';\nimport { createLoginFlow, type LoginFlow } from '../loginFlow';\ninterface SettingsModel {\n value: string;\n label: string;\n group: string;\n}\n\n/** Matches the timeout Pi's own /logout gives the credential store. */\nconst LOGOUT_TIMEOUT_MS = 15_000;\n\nexport type StartLoginOutcome =\n | { ok: true; flow: LoginFlowSnapshot }\n | { ok: false; code: 'unknown_provider' | 'unsupported_method' | 'busy'; error: string };\n\nexport type LogoutOutcome = { ok: true } | { ok: false; code: 'unknown_provider' | 'runtime'; error: string };\n\nexport type AnswerOutcome = 'answered' | 'unknown_flow' | 'not_waiting';\n\n/** Provider credentials as the settings page sees them, backed by one Pi runtime. */\nexport interface ProviderAuth {\n /** Every provider Pi knows, with its current auth state; re-read from disk each call. */\n listProviders(): Promise<ProviderAuthSummary[]>;\n /**\n * Starts a login. `remote` means the browser driving it is on another\n * machine, which decides whether a redirect-free method is chosen for the\n * user; it comes from the accepted socket, never from the request body.\n */\n startLogin(providerId: string, type: AuthMethodType, remote?: boolean): Promise<StartLoginOutcome>;\n getLogin(flowId: string): LoginFlowSnapshot | undefined;\n answerLogin(flowId: string, promptId: string, value: string): AnswerOutcome;\n /** Cancels the flow and returns how it stands, or undefined for an unknown flow. */\n cancelLogin(flowId: string): LoginFlowSnapshot | undefined;\n logout(providerId: string): Promise<LogoutOutcome>;\n /**\n * Every model the machine can actually use, grouped by provider. Read from\n * the same runtime the providers page uses, so the settings model pickers\n * work with no session running.\n */\n listModels(): Promise<readonly SettingsModel[]>;\n /** Abandons every running flow; the hub is shutting down. */\n close(): void;\n}\n\nexport interface ProviderAuthOptions {\n runtime: () => Promise<AuthRuntime>;\n onNotice?: (message: string) => void;\n}\n\nfunction describe(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** The methods a page can start, in the order the TUI's selector lists them. */\nfunction methodsOf(provider: AuthRuntimeProvider): ProviderAuthMethod[] {\n const methods: ProviderAuthMethod[] = [];\n const { oauth, apiKey } = provider.auth;\n if (oauth) methods.push({ type: 'oauth', label: oauth.loginLabel ?? oauth.name });\n if (apiKey?.login) methods.push({ type: 'api_key', label: apiKey.name });\n return methods;\n}\n\n/** Mirrors the status the TUI's login selector shows beside each provider. */\nfunction summarize(runtime: AuthRuntime, provider: AuthRuntimeProvider): ProviderAuthSummary {\n const summary: ProviderAuthSummary = { id: provider.id, name: provider.name, methods: methodsOf(provider) };\n if (provider.id === CHATGPT_AUTH_PROVIDER_ID) summary.kind = 'po-feature';\n const status = runtime.getProviderAuthStatus(provider.id);\n if (status.configured) {\n summary.authenticated = {\n type: runtime.isUsingOAuth(provider.id) ? 'oauth' : 'api_key',\n source: status.label ?? status.source,\n };\n }\n return summary;\n}\n\nexport function createProviderAuth(options: ProviderAuthOptions): ProviderAuth {\n const notice = options.onNotice ?? ((): void => {});\n const load = options.runtime;\n const flows = new Map<string, LoginFlow>();\n let loading: Promise<AuthRuntime> | undefined;\n\n // A failed load is forgotten so the next request tries again rather than\n // pinning the page on a startup error.\n const runtime = (): Promise<AuthRuntime> => {\n loading ??= load().catch((error: unknown) => {\n loading = undefined;\n throw error;\n });\n return loading;\n };\n\n const findProvider = (current: AuthRuntime, providerId: string): AuthRuntimeProvider | undefined =>\n current.getProviders().find((provider) => provider.id === providerId);\n\n const runningFor = (providerId: string): LoginFlow | undefined =>\n [...flows.values()].find((flow) => flow.providerId === providerId && flow.snapshot().status === 'running');\n\n return {\n async listProviders() {\n const current = await runtime();\n // Another client may have stored a credential since the last look (a\n // TUI /login, a hand-edited auth.json); the stale snapshot still lists\n // on a failed refresh, which the notice explains.\n try {\n await current.refresh({ allowNetwork: false });\n } catch (error) {\n notice(`provider auth refresh failed: ${describe(error)}`);\n }\n return current\n .getProviders()\n .map((provider) => summarize(current, provider))\n .sort((left, right) => left.name.localeCompare(right.name));\n },\n\n async startLogin(providerId, type, remote) {\n const current = await runtime();\n const provider = findProvider(current, providerId);\n if (!provider) return { ok: false, code: 'unknown_provider', error: `Unknown provider: ${providerId}` };\n if (!methodsOf(provider).some((method) => method.type === type)) {\n return { ok: false, code: 'unsupported_method', error: `${provider.name} has no ${type} login.` };\n }\n if (runningFor(providerId)) {\n return { ok: false, code: 'busy', error: `A login for ${provider.name} is already in progress.` };\n }\n // Finished flows live until the next start: long enough for the page to\n // read how they ended, short enough that the map never grows.\n for (const [id, flow] of flows) if (flow.snapshot().status !== 'running') flows.delete(id);\n\n const flow = createLoginFlow({\n id: crypto.randomUUID(),\n providerId,\n providerName: provider.name,\n type,\n ...(remote === true ? { remote: true } : {}),\n });\n flows.set(flow.id, flow);\n current.login(providerId, type, flow.interaction).then(\n () => {\n flow.settle({ ok: true });\n notice(`signed in to ${provider.name} (${type})`);\n },\n (error: unknown) => {\n flow.settle({ ok: false, error: describe(error) });\n },\n );\n return { ok: true, flow: flow.snapshot() };\n },\n\n getLogin(flowId) {\n return flows.get(flowId)?.snapshot();\n },\n\n answerLogin(flowId, promptId, value) {\n const flow = flows.get(flowId);\n if (!flow) return 'unknown_flow';\n return flow.answer(promptId, value) ? 'answered' : 'not_waiting';\n },\n\n cancelLogin(flowId) {\n const flow = flows.get(flowId);\n if (!flow) return undefined;\n flow.cancel();\n return flow.snapshot();\n },\n\n async logout(providerId) {\n const current = await runtime();\n const provider = findProvider(current, providerId);\n if (!provider) return { ok: false, code: 'unknown_provider', error: `Unknown provider: ${providerId}` };\n try {\n await current.logout(providerId, { signal: AbortSignal.timeout(LOGOUT_TIMEOUT_MS) });\n } catch (error) {\n return { ok: false, code: 'runtime', error: describe(error) };\n }\n notice(`signed out of ${provider.name}`);\n return { ok: true };\n },\n\n async listModels() {\n const current = await runtime();\n const providers = new Map(current.getProviders().map((provider) => [provider.id, provider.name]));\n return current\n .getAvailableSnapshot()\n .filter((model) => current.hasConfiguredAuth(model.provider))\n .map((model) => ({\n value: `${model.provider}/${model.id}`,\n label: model.id,\n group: providers.get(model.provider) ?? model.provider,\n }));\n },\n\n close() {\n for (const flow of flows.values()) flow.cancel();\n flows.clear();\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/providerAuth/index.ts"],"sourcesContent":["import crypto from 'node:crypto';\n\nimport type {\n AuthMethodType,\n AuthRuntime,\n AuthRuntimeProvider,\n LoginFlowSnapshot,\n ProviderAuthMethod,\n ProviderAuthSummary,\n} from '../../types/server/auth';\nimport { CHATGPT_AUTH_PROVIDER_ID } from '../chatgptAuth';\nimport { createLoginFlow, type LoginFlow } from '../loginFlow';\ninterface SettingsModel {\n value: string;\n label: string;\n group: string;\n}\n\n/** Matches the timeout Pi's own /logout gives the credential store. */\nconst LOGOUT_TIMEOUT_MS = 15_000;\n\nexport type StartLoginOutcome =\n | { ok: true; flow: LoginFlowSnapshot }\n | { ok: false; code: 'unknown_provider' | 'unsupported_method' | 'busy'; error: string };\n\nexport type LogoutOutcome = { ok: true } | { ok: false; code: 'unknown_provider' | 'runtime'; error: string };\n\nexport type AnswerOutcome = 'answered' | 'unknown_flow' | 'not_waiting';\n\n/** Provider credentials as the settings page sees them, backed by one Pi runtime. */\nexport interface ProviderAuth {\n /** Every provider Pi knows, with its current auth state; re-read from disk each call. */\n listProviders(): Promise<ProviderAuthSummary[]>;\n /**\n * Starts a login. `remote` means the browser driving it is on another\n * machine, which decides whether a redirect-free method is chosen for the\n * user; it comes from the accepted socket, never from the request body.\n */\n startLogin(providerId: string, type: AuthMethodType, remote?: boolean): Promise<StartLoginOutcome>;\n getLogin(flowId: string): LoginFlowSnapshot | undefined;\n answerLogin(flowId: string, promptId: string, value: string): AnswerOutcome;\n /** Cancels the flow and returns how it stands, or undefined for an unknown flow. */\n cancelLogin(flowId: string): LoginFlowSnapshot | undefined;\n logout(providerId: string): Promise<LogoutOutcome>;\n /**\n * Every model the machine can actually use, grouped by provider. Read from\n * the same runtime the providers page uses, so the settings model pickers\n * work with no session running.\n */\n listModels(): Promise<readonly SettingsModel[]>;\n /** Abandons every running flow; the hub is shutting down. */\n close(): void;\n}\n\nexport interface ProviderAuthOptions {\n runtime: () => Promise<AuthRuntime>;\n onNotice?: (message: string) => void;\n}\n\nfunction describe(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** The methods a page can start, in the order the TUI's selector lists them. */\nfunction methodsOf(provider: AuthRuntimeProvider): ProviderAuthMethod[] {\n const methods: ProviderAuthMethod[] = [];\n const { oauth, apiKey } = provider.auth;\n if (oauth) methods.push({ type: 'oauth', label: oauth.loginLabel ?? oauth.name });\n if (apiKey?.login) methods.push({ type: 'api_key', label: apiKey.name });\n return methods;\n}\n\n/** Mirrors the status the TUI's login selector shows beside each provider. */\nfunction summarize(runtime: AuthRuntime, provider: AuthRuntimeProvider): ProviderAuthSummary {\n const summary: ProviderAuthSummary = { id: provider.id, name: provider.name, methods: methodsOf(provider) };\n if (provider.id === CHATGPT_AUTH_PROVIDER_ID) summary.kind = 'po-feature';\n const status = runtime.getProviderAuthStatus(provider.id);\n if (status.configured) {\n summary.authenticated = {\n type: runtime.isUsingOAuth(provider.id) ? 'oauth' : 'api_key',\n source: status.label ?? status.source,\n };\n }\n return summary;\n}\n\nexport function createProviderAuth(options: ProviderAuthOptions): ProviderAuth {\n const notice = options.onNotice ?? ((): void => {});\n const load = options.runtime;\n const flows = new Map<string, LoginFlow>();\n let loading: Promise<AuthRuntime> | undefined;\n\n // A failed load is forgotten so the next request tries again rather than\n // pinning the page on a startup error.\n const runtime = (): Promise<AuthRuntime> => {\n loading ??= load().catch((error: unknown) => {\n loading = undefined;\n throw error;\n });\n return loading;\n };\n\n const findProvider = (current: AuthRuntime, providerId: string): AuthRuntimeProvider | undefined =>\n current.getProviders().find((provider) => provider.id === providerId);\n\n const runningFor = (providerId: string): LoginFlow | undefined =>\n [...flows.values()].find((flow) => flow.providerId === providerId && flow.snapshot().status === 'running');\n\n // Another client may have stored a credential since the last look (a TUI\n // /login, a hand-edited auth.json), and a provider registered by a Pi\n // extension after the runtime was created is missing from the cached auth\n // state until a refresh. The stale snapshot still lists on a failed refresh,\n // which the notice explains.\n const refreshed = async (): Promise<AuthRuntime> => {\n const current = await runtime();\n try {\n await current.refresh({ allowNetwork: false });\n } catch (error) {\n notice(`provider auth refresh failed: ${describe(error)}`);\n }\n return current;\n };\n\n return {\n async listProviders() {\n const current = await refreshed();\n return current\n .getProviders()\n .map((provider) => summarize(current, provider))\n .sort((left, right) => left.name.localeCompare(right.name));\n },\n\n async startLogin(providerId, type, remote) {\n const current = await runtime();\n const provider = findProvider(current, providerId);\n if (!provider) return { ok: false, code: 'unknown_provider', error: `Unknown provider: ${providerId}` };\n if (!methodsOf(provider).some((method) => method.type === type)) {\n return { ok: false, code: 'unsupported_method', error: `${provider.name} has no ${type} login.` };\n }\n if (runningFor(providerId)) {\n return { ok: false, code: 'busy', error: `A login for ${provider.name} is already in progress.` };\n }\n // Finished flows live until the next start: long enough for the page to\n // read how they ended, short enough that the map never grows.\n for (const [id, flow] of flows) if (flow.snapshot().status !== 'running') flows.delete(id);\n\n const flow = createLoginFlow({\n id: crypto.randomUUID(),\n providerId,\n providerName: provider.name,\n type,\n ...(remote === true ? { remote: true } : {}),\n });\n flows.set(flow.id, flow);\n current.login(providerId, type, flow.interaction).then(\n () => {\n flow.settle({ ok: true });\n notice(`signed in to ${provider.name} (${type})`);\n },\n (error: unknown) => {\n flow.settle({ ok: false, error: describe(error) });\n },\n );\n return { ok: true, flow: flow.snapshot() };\n },\n\n getLogin(flowId) {\n return flows.get(flowId)?.snapshot();\n },\n\n answerLogin(flowId, promptId, value) {\n const flow = flows.get(flowId);\n if (!flow) return 'unknown_flow';\n return flow.answer(promptId, value) ? 'answered' : 'not_waiting';\n },\n\n cancelLogin(flowId) {\n const flow = flows.get(flowId);\n if (!flow) return undefined;\n flow.cancel();\n return flow.snapshot();\n },\n\n async logout(providerId) {\n const current = await runtime();\n const provider = findProvider(current, providerId);\n if (!provider) return { ok: false, code: 'unknown_provider', error: `Unknown provider: ${providerId}` };\n try {\n await current.logout(providerId, { signal: AbortSignal.timeout(LOGOUT_TIMEOUT_MS) });\n } catch (error) {\n return { ok: false, code: 'runtime', error: describe(error) };\n }\n notice(`signed out of ${provider.name}`);\n return { ok: true };\n },\n\n async listModels() {\n const current = await refreshed();\n const providers = new Map(current.getProviders().map((provider) => [provider.id, provider.name]));\n return current\n .getAvailableSnapshot()\n .filter((model) => current.hasConfiguredAuth(model.provider))\n .map((model) => ({\n value: `${model.provider}/${model.id}`,\n label: model.id,\n group: providers.get(model.provider) ?? model.provider,\n }));\n },\n\n close() {\n for (const flow of flows.values()) flow.cancel();\n flows.clear();\n },\n };\n}\n"],"mappings":"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"}
@@ -96,7 +96,7 @@ function createPublicFileShares(options) {
96
96
  async mint(request) {
97
97
  const origin = options.publicOrigin();
98
98
  const revision = options.publicOriginRevision();
99
- if (origin === void 0) throw new Error(require_packageApi.DOOM_SHARE_FILE_REMOTE_OFF_MESSAGE);
99
+ if (origin === void 0) throw new Error(require_packageApi.PO_SHARE_FILE_REMOTE_OFF_MESSAGE);
100
100
  const filePath = await resolveShareable(request, environment);
101
101
  const opened = await openPinned(filePath);
102
102
  if (opened === void 0) throw new Error(`"${request.path}" is not a regular file Po can share.`);
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["fs","createHash","path","sessionAttachmentRoot","DOOM_SHARE_FILE_REMOTE_OFF_MESSAGE","randomBytes","SESSION_FILE_CONTENT_TYPES","Readable"],"sources":["../../../../src/services/publicFileShares/index.ts"],"sourcesContent":["import { createHash, randomBytes } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\n\nimport {\n MAX_SESSION_FILE_BYTES,\n SESSION_FILE_CONTENT_TYPES,\n SESSION_FILE_DEFAULT_CONTENT_TYPE,\n} from '../../constants/sessionFiles';\nimport { DOOM_SHARE_FILE_REMOTE_OFF_MESSAGE, type DoomSharedFile } from '../../schemas/packageApi';\nimport { sessionAttachmentRoot } from '../sessionAttachments';\n\n/**\n * Short-lived public links to one session file, so a remote MCP server can fetch\n * what the model was asked to hand it.\n *\n * The link is the only credential, so only its hash is kept, and every way a\n * link can fail answers the same 404. A file is pinned by identity when the\n * link is minted and reopened when it is served: a path that now names another\n * file, or reaches it through a new symlink, is refused rather than followed.\n */\n\n/** Public tunnel path prefix; the token is the only segment after it. */\nexport const PUBLIC_FILE_SHARE_PREFIX = '/mcp-file/';\n\nconst TOKEN_BYTES = 32;\nconst TOKEN_PATTERN = /^[A-Za-z0-9_-]{43}$/u;\nconst SHARE_TTL_MS = 10 * 60 * 1000;\nconst SHARE_DOWNLOADS = 3;\nconst MAX_LIVE_SHARES_PER_SESSION = 16;\nconst OPEN_FLAGS = fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW;\n\nexport interface PublicFileShareRequest {\n sessionId: string;\n cwd: string;\n /** Relative to cwd, or absolute. */\n path: string;\n /** Who the file is for, for the host's notice. */\n label: string;\n}\n\nexport interface PublicFileShares {\n mint(request: PublicFileShareRequest): Promise<DoomSharedFile>;\n serve(token: string, method: string): Promise<Response>;\n}\n\nexport interface PublicFileSharesOptions {\n publicOrigin(): string | undefined;\n /** Bumped whenever the tunnel goes away; a link minted under another revision is dead. */\n publicOriginRevision(): number;\n /** Never receives a token or a link. */\n onNotice(message: string): void;\n /** Locates the attachment root; defaults to the process environment, as the upload route does. */\n environment?: Readonly<Record<string, string | undefined>>;\n}\n\ninterface Share {\n sessionId: string;\n filePath: string;\n fileName: string;\n dev: number;\n ino: number;\n size: number;\n mtimeMs: number;\n revision: number;\n expiresAt: number;\n downloadsLeft: number;\n revoked: boolean;\n}\n\nfunction tokenDigest(token: string): string {\n return createHash('sha256').update(token).digest('base64url');\n}\n\nfunction notFound(): Response {\n return Response.json({ error: 'Not found.' }, { status: 404 });\n}\n\n/** RFC 8187 value for `filename*`: encodeURIComponent leaves a few characters the grammar forbids. */\nfunction contentDispositionName(fileName: string): string {\n return encodeURIComponent(fileName).replace(\n /['()*]/gu,\n (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n}\n\n/** True when filePath sits strictly below the real root with no segment that starts with a dot. */\nasync function containedIn(root: string, filePath: string): Promise<boolean> {\n let realRoot: string;\n try {\n realRoot = await fs.promises.realpath(root);\n } catch {\n return false;\n }\n const relative = path.relative(realRoot, filePath);\n return (\n relative !== '' &&\n !path.isAbsolute(relative) &&\n relative.split(path.sep).every((segment) => !segment.startsWith('.'))\n );\n}\n\n/** The real path of a shareable file: inside the session cwd or its attachment root, never through a dot segment. */\nasync function resolveShareable(\n request: PublicFileShareRequest,\n environment: Readonly<Record<string, string | undefined>>,\n): Promise<string> {\n const refused = new Error(`\"${request.path}\" is not a file in this session's working directory or attachments.`);\n if (\n request.path === '' ||\n request.path.includes('\\0') ||\n request.path.split(/[\\\\/]/u).some((segment) => segment === '.' || segment === '..')\n )\n throw refused;\n let filePath: string;\n try {\n filePath = await fs.promises.realpath(path.resolve(request.cwd, request.path));\n } catch {\n throw refused;\n }\n const roots = [request.cwd];\n try {\n roots.push(sessionAttachmentRoot(request.sessionId, environment));\n } catch {\n // An id that cannot hold attachments only has its working directory.\n }\n for (const root of roots) if (await containedIn(root, filePath)) return filePath;\n throw refused;\n}\n\n/**\n * Opens a regular file without following a final symlink, then proves the handle is\n * still the file at that real path: a parent swapped for a symlink changes the real\n * path, and a replaced file changes the identity. Resolves undefined, with nothing\n * left open, when either check fails.\n */\nasync function openPinned(filePath: string): Promise<{ handle: fs.promises.FileHandle; stat: fs.Stats } | undefined> {\n let handle: fs.promises.FileHandle;\n try {\n handle = await fs.promises.open(filePath, OPEN_FLAGS);\n } catch {\n return undefined;\n }\n try {\n const stat = await handle.stat();\n const named = await fs.promises.lstat(filePath);\n if (\n stat.isFile() &&\n named.dev === stat.dev &&\n named.ino === stat.ino &&\n (await fs.promises.realpath(filePath)) === filePath\n )\n return { handle, stat };\n } catch {\n // Treated like a mismatch below.\n }\n await handle.close();\n return undefined;\n}\n\nexport function createPublicFileShares(options: PublicFileSharesOptions): PublicFileShares {\n const environment = options.environment ?? process.env;\n const shares = new Map<string, Share>();\n\n const authorized = (share: Share): boolean =>\n !share.revoked &&\n Date.now() < share.expiresAt &&\n share.revision === options.publicOriginRevision() &&\n options.publicOrigin() !== undefined;\n const live = (share: Share): boolean => authorized(share) && share.downloadsLeft > 0;\n\n return {\n async mint(request) {\n const origin = options.publicOrigin();\n const revision = options.publicOriginRevision();\n if (origin === undefined) throw new Error(DOOM_SHARE_FILE_REMOTE_OFF_MESSAGE);\n const filePath = await resolveShareable(request, environment);\n const opened = await openPinned(filePath);\n if (opened === undefined) throw new Error(`\"${request.path}\" is not a regular file Po can share.`);\n const { stat } = opened;\n await opened.handle.close();\n if (stat.size > MAX_SESSION_FILE_BYTES)\n throw new Error(`\"${request.path}\" is larger than the 25 MB file sharing limit.`);\n for (const [key, share] of shares) if (!live(share)) shares.delete(key);\n if (\n [...shares.values()].filter((share) => share.sessionId === request.sessionId).length >=\n MAX_LIVE_SHARES_PER_SESSION\n )\n throw new Error(\n `This session already shares ${String(MAX_LIVE_SHARES_PER_SESSION)} files. Retry after a tool call finishes.`,\n );\n const token = randomBytes(TOKEN_BYTES).toString('base64url');\n const key = tokenDigest(token);\n const fileName = path.basename(filePath);\n const share: Share = {\n sessionId: request.sessionId,\n filePath,\n fileName,\n dev: stat.dev,\n ino: stat.ino,\n size: stat.size,\n mtimeMs: stat.mtimeMs,\n revision,\n expiresAt: Date.now() + SHARE_TTL_MS,\n downloadsLeft: SHARE_DOWNLOADS,\n revoked: false,\n };\n shares.set(key, share);\n options.onNotice(`file share: published \"${fileName}\" for ${request.label} on the remote-access tunnel.`);\n return {\n url: `${origin}${PUBLIC_FILE_SHARE_PREFIX}${token}`,\n fileName,\n mimeType: SESSION_FILE_CONTENT_TYPES[path.extname(fileName).toLowerCase()] ?? SESSION_FILE_DEFAULT_CONTENT_TYPE,\n size: stat.size,\n expiresAt: share.expiresAt,\n maxDownloads: SHARE_DOWNLOADS,\n revoke: () => {\n share.revoked = true;\n shares.delete(key);\n },\n };\n },\n\n async serve(token, method) {\n if ((method !== 'GET' && method !== 'HEAD') || !TOKEN_PATTERN.test(token)) return notFound();\n const key = tokenDigest(token);\n const share = shares.get(key);\n if (share === undefined) return notFound();\n if (!live(share)) {\n shares.delete(key);\n return notFound();\n }\n // Counted before the first await, so concurrent downloads cannot outrun the limit.\n if (method === 'GET') {\n share.downloadsLeft -= 1;\n if (share.downloadsLeft === 0) shares.delete(key);\n }\n const opened = await openPinned(share.filePath);\n if (\n opened === undefined ||\n opened.stat.dev !== share.dev ||\n opened.stat.ino !== share.ino ||\n opened.stat.size !== share.size ||\n opened.stat.mtimeMs !== share.mtimeMs\n ) {\n await opened?.handle.close();\n shares.delete(key);\n options.onNotice(`file share: refused \"${share.fileName}\" because the file changed after it was shared.`);\n return notFound();\n }\n // Opening a file yields to revocation and tunnel changes. The download already\n // reserved its allowance, so this check must not reject the final permitted GET.\n if (!authorized(share)) {\n await opened.handle.close();\n shares.delete(key);\n return notFound();\n }\n const headers = {\n 'content-type': 'application/octet-stream',\n 'content-length': String(share.size),\n 'content-disposition': `attachment; filename*=UTF-8''${contentDispositionName(share.fileName)}`,\n 'x-content-type-options': 'nosniff',\n 'content-security-policy': \"sandbox; default-src 'none'\",\n 'cross-origin-resource-policy': 'same-origin',\n 'cache-control': 'no-store, private',\n 'referrer-policy': 'no-referrer',\n 'accept-ranges': 'none',\n 'x-robots-tag': 'noindex',\n };\n if (method === 'HEAD' || share.size === 0) {\n await opened.handle.close();\n return new Response(method === 'HEAD' ? null : new Uint8Array(), { headers });\n }\n // The stream closes the handle when it ends, fails, or is cancelled. Bounded to the\n // pinned size, so bytes appended after the identity check are never sent.\n const body = Readable.toWeb(opened.handle.createReadStream({ start: 0, end: share.size - 1 }));\n return new Response(body as ReadableStream<Uint8Array>, { headers });\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["fs","createHash","path","sessionAttachmentRoot","PO_SHARE_FILE_REMOTE_OFF_MESSAGE","randomBytes","SESSION_FILE_CONTENT_TYPES","Readable"],"sources":["../../../../src/services/publicFileShares/index.ts"],"sourcesContent":["import { createHash, randomBytes } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\n\nimport {\n MAX_SESSION_FILE_BYTES,\n SESSION_FILE_CONTENT_TYPES,\n SESSION_FILE_DEFAULT_CONTENT_TYPE,\n} from '../../constants/sessionFiles';\nimport { PO_SHARE_FILE_REMOTE_OFF_MESSAGE, type PoSharedFile } from '../../schemas/packageApi';\nimport { sessionAttachmentRoot } from '../sessionAttachments';\n\n/**\n * Short-lived public links to one session file, so a remote MCP server can fetch\n * what the model was asked to hand it.\n *\n * The link is the only credential, so only its hash is kept, and every way a\n * link can fail answers the same 404. A file is pinned by identity when the\n * link is minted and reopened when it is served: a path that now names another\n * file, or reaches it through a new symlink, is refused rather than followed.\n */\n\n/** Public tunnel path prefix; the token is the only segment after it. */\nexport const PUBLIC_FILE_SHARE_PREFIX = '/mcp-file/';\n\nconst TOKEN_BYTES = 32;\nconst TOKEN_PATTERN = /^[A-Za-z0-9_-]{43}$/u;\nconst SHARE_TTL_MS = 10 * 60 * 1000;\nconst SHARE_DOWNLOADS = 3;\nconst MAX_LIVE_SHARES_PER_SESSION = 16;\nconst OPEN_FLAGS = fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW;\n\nexport interface PublicFileShareRequest {\n sessionId: string;\n cwd: string;\n /** Relative to cwd, or absolute. */\n path: string;\n /** Who the file is for, for the host's notice. */\n label: string;\n}\n\nexport interface PublicFileShares {\n mint(request: PublicFileShareRequest): Promise<PoSharedFile>;\n serve(token: string, method: string): Promise<Response>;\n}\n\nexport interface PublicFileSharesOptions {\n publicOrigin(): string | undefined;\n /** Bumped whenever the tunnel goes away; a link minted under another revision is dead. */\n publicOriginRevision(): number;\n /** Never receives a token or a link. */\n onNotice(message: string): void;\n /** Locates the attachment root; defaults to the process environment, as the upload route does. */\n environment?: Readonly<Record<string, string | undefined>>;\n}\n\ninterface Share {\n sessionId: string;\n filePath: string;\n fileName: string;\n dev: number;\n ino: number;\n size: number;\n mtimeMs: number;\n revision: number;\n expiresAt: number;\n downloadsLeft: number;\n revoked: boolean;\n}\n\nfunction tokenDigest(token: string): string {\n return createHash('sha256').update(token).digest('base64url');\n}\n\nfunction notFound(): Response {\n return Response.json({ error: 'Not found.' }, { status: 404 });\n}\n\n/** RFC 8187 value for `filename*`: encodeURIComponent leaves a few characters the grammar forbids. */\nfunction contentDispositionName(fileName: string): string {\n return encodeURIComponent(fileName).replace(\n /['()*]/gu,\n (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n}\n\n/** True when filePath sits strictly below the real root with no segment that starts with a dot. */\nasync function containedIn(root: string, filePath: string): Promise<boolean> {\n let realRoot: string;\n try {\n realRoot = await fs.promises.realpath(root);\n } catch {\n return false;\n }\n const relative = path.relative(realRoot, filePath);\n return (\n relative !== '' &&\n !path.isAbsolute(relative) &&\n relative.split(path.sep).every((segment) => !segment.startsWith('.'))\n );\n}\n\n/** The real path of a shareable file: inside the session cwd or its attachment root, never through a dot segment. */\nasync function resolveShareable(\n request: PublicFileShareRequest,\n environment: Readonly<Record<string, string | undefined>>,\n): Promise<string> {\n const refused = new Error(`\"${request.path}\" is not a file in this session's working directory or attachments.`);\n if (\n request.path === '' ||\n request.path.includes('\\0') ||\n request.path.split(/[\\\\/]/u).some((segment) => segment === '.' || segment === '..')\n )\n throw refused;\n let filePath: string;\n try {\n filePath = await fs.promises.realpath(path.resolve(request.cwd, request.path));\n } catch {\n throw refused;\n }\n const roots = [request.cwd];\n try {\n roots.push(sessionAttachmentRoot(request.sessionId, environment));\n } catch {\n // An id that cannot hold attachments only has its working directory.\n }\n for (const root of roots) if (await containedIn(root, filePath)) return filePath;\n throw refused;\n}\n\n/**\n * Opens a regular file without following a final symlink, then proves the handle is\n * still the file at that real path: a parent swapped for a symlink changes the real\n * path, and a replaced file changes the identity. Resolves undefined, with nothing\n * left open, when either check fails.\n */\nasync function openPinned(filePath: string): Promise<{ handle: fs.promises.FileHandle; stat: fs.Stats } | undefined> {\n let handle: fs.promises.FileHandle;\n try {\n handle = await fs.promises.open(filePath, OPEN_FLAGS);\n } catch {\n return undefined;\n }\n try {\n const stat = await handle.stat();\n const named = await fs.promises.lstat(filePath);\n if (\n stat.isFile() &&\n named.dev === stat.dev &&\n named.ino === stat.ino &&\n (await fs.promises.realpath(filePath)) === filePath\n )\n return { handle, stat };\n } catch {\n // Treated like a mismatch below.\n }\n await handle.close();\n return undefined;\n}\n\nexport function createPublicFileShares(options: PublicFileSharesOptions): PublicFileShares {\n const environment = options.environment ?? process.env;\n const shares = new Map<string, Share>();\n\n const authorized = (share: Share): boolean =>\n !share.revoked &&\n Date.now() < share.expiresAt &&\n share.revision === options.publicOriginRevision() &&\n options.publicOrigin() !== undefined;\n const live = (share: Share): boolean => authorized(share) && share.downloadsLeft > 0;\n\n return {\n async mint(request) {\n const origin = options.publicOrigin();\n const revision = options.publicOriginRevision();\n if (origin === undefined) throw new Error(PO_SHARE_FILE_REMOTE_OFF_MESSAGE);\n const filePath = await resolveShareable(request, environment);\n const opened = await openPinned(filePath);\n if (opened === undefined) throw new Error(`\"${request.path}\" is not a regular file Po can share.`);\n const { stat } = opened;\n await opened.handle.close();\n if (stat.size > MAX_SESSION_FILE_BYTES)\n throw new Error(`\"${request.path}\" is larger than the 25 MB file sharing limit.`);\n for (const [key, share] of shares) if (!live(share)) shares.delete(key);\n if (\n [...shares.values()].filter((share) => share.sessionId === request.sessionId).length >=\n MAX_LIVE_SHARES_PER_SESSION\n )\n throw new Error(\n `This session already shares ${String(MAX_LIVE_SHARES_PER_SESSION)} files. Retry after a tool call finishes.`,\n );\n const token = randomBytes(TOKEN_BYTES).toString('base64url');\n const key = tokenDigest(token);\n const fileName = path.basename(filePath);\n const share: Share = {\n sessionId: request.sessionId,\n filePath,\n fileName,\n dev: stat.dev,\n ino: stat.ino,\n size: stat.size,\n mtimeMs: stat.mtimeMs,\n revision,\n expiresAt: Date.now() + SHARE_TTL_MS,\n downloadsLeft: SHARE_DOWNLOADS,\n revoked: false,\n };\n shares.set(key, share);\n options.onNotice(`file share: published \"${fileName}\" for ${request.label} on the remote-access tunnel.`);\n return {\n url: `${origin}${PUBLIC_FILE_SHARE_PREFIX}${token}`,\n fileName,\n mimeType: SESSION_FILE_CONTENT_TYPES[path.extname(fileName).toLowerCase()] ?? SESSION_FILE_DEFAULT_CONTENT_TYPE,\n size: stat.size,\n expiresAt: share.expiresAt,\n maxDownloads: SHARE_DOWNLOADS,\n revoke: () => {\n share.revoked = true;\n shares.delete(key);\n },\n };\n },\n\n async serve(token, method) {\n if ((method !== 'GET' && method !== 'HEAD') || !TOKEN_PATTERN.test(token)) return notFound();\n const key = tokenDigest(token);\n const share = shares.get(key);\n if (share === undefined) return notFound();\n if (!live(share)) {\n shares.delete(key);\n return notFound();\n }\n // Counted before the first await, so concurrent downloads cannot outrun the limit.\n if (method === 'GET') {\n share.downloadsLeft -= 1;\n if (share.downloadsLeft === 0) shares.delete(key);\n }\n const opened = await openPinned(share.filePath);\n if (\n opened === undefined ||\n opened.stat.dev !== share.dev ||\n opened.stat.ino !== share.ino ||\n opened.stat.size !== share.size ||\n opened.stat.mtimeMs !== share.mtimeMs\n ) {\n await opened?.handle.close();\n shares.delete(key);\n options.onNotice(`file share: refused \"${share.fileName}\" because the file changed after it was shared.`);\n return notFound();\n }\n // Opening a file yields to revocation and tunnel changes. The download already\n // reserved its allowance, so this check must not reject the final permitted GET.\n if (!authorized(share)) {\n await opened.handle.close();\n shares.delete(key);\n return notFound();\n }\n const headers = {\n 'content-type': 'application/octet-stream',\n 'content-length': String(share.size),\n 'content-disposition': `attachment; filename*=UTF-8''${contentDispositionName(share.fileName)}`,\n 'x-content-type-options': 'nosniff',\n 'content-security-policy': \"sandbox; default-src 'none'\",\n 'cross-origin-resource-policy': 'same-origin',\n 'cache-control': 'no-store, private',\n 'referrer-policy': 'no-referrer',\n 'accept-ranges': 'none',\n 'x-robots-tag': 'noindex',\n };\n if (method === 'HEAD' || share.size === 0) {\n await opened.handle.close();\n return new Response(method === 'HEAD' ? null : new Uint8Array(), { headers });\n }\n // The stream closes the handle when it ends, fails, or is cancelled. Bounded to the\n // pinned size, so bytes appended after the identity check are never sent.\n const body = Readable.toWeb(opened.handle.createReadStream({ start: 0, end: share.size - 1 }));\n return new Response(body as ReadableStream<Uint8Array>, { headers });\n },\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { DoomSharedFile } from "../../schemas/packageApi.mjs";
1
+ import { PoSharedFile } from "../../schemas/packageApi.mjs";
2
2
  //#region src/services/publicFileShares/index.d.ts
3
3
  export interface PublicFileShareRequest {
4
4
  sessionId: string;
@@ -9,7 +9,7 @@ export interface PublicFileShareRequest {
9
9
  label: string;
10
10
  }
11
11
  export interface PublicFileShares {
12
- mint(request: PublicFileShareRequest): Promise<DoomSharedFile>;
12
+ mint(request: PublicFileShareRequest): Promise<PoSharedFile>;
13
13
  serve(token: string, method: string): Promise<Response>;
14
14
  }
15
15
  //#endregion
@@ -1,4 +1,4 @@
1
- import { DOOM_SHARE_FILE_REMOTE_OFF_MESSAGE } from "../../schemas/packageApi.mjs";
1
+ import { PO_SHARE_FILE_REMOTE_OFF_MESSAGE } from "../../schemas/packageApi.mjs";
2
2
  import { SESSION_FILE_CONTENT_TYPES } from "../../constants/sessionFiles.mjs";
3
3
  import { sessionAttachmentRoot } from "../sessionAttachments/index.mjs";
4
4
  import { createHash, randomBytes } from "node:crypto";
@@ -93,7 +93,7 @@ function createPublicFileShares(options) {
93
93
  async mint(request) {
94
94
  const origin = options.publicOrigin();
95
95
  const revision = options.publicOriginRevision();
96
- if (origin === void 0) throw new Error(DOOM_SHARE_FILE_REMOTE_OFF_MESSAGE);
96
+ if (origin === void 0) throw new Error(PO_SHARE_FILE_REMOTE_OFF_MESSAGE);
97
97
  const filePath = await resolveShareable(request, environment);
98
98
  const opened = await openPinned(filePath);
99
99
  if (opened === void 0) throw new Error(`"${request.path}" is not a regular file Po can share.`);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/publicFileShares/index.ts"],"sourcesContent":["import { createHash, randomBytes } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\n\nimport {\n MAX_SESSION_FILE_BYTES,\n SESSION_FILE_CONTENT_TYPES,\n SESSION_FILE_DEFAULT_CONTENT_TYPE,\n} from '../../constants/sessionFiles';\nimport { DOOM_SHARE_FILE_REMOTE_OFF_MESSAGE, type DoomSharedFile } from '../../schemas/packageApi';\nimport { sessionAttachmentRoot } from '../sessionAttachments';\n\n/**\n * Short-lived public links to one session file, so a remote MCP server can fetch\n * what the model was asked to hand it.\n *\n * The link is the only credential, so only its hash is kept, and every way a\n * link can fail answers the same 404. A file is pinned by identity when the\n * link is minted and reopened when it is served: a path that now names another\n * file, or reaches it through a new symlink, is refused rather than followed.\n */\n\n/** Public tunnel path prefix; the token is the only segment after it. */\nexport const PUBLIC_FILE_SHARE_PREFIX = '/mcp-file/';\n\nconst TOKEN_BYTES = 32;\nconst TOKEN_PATTERN = /^[A-Za-z0-9_-]{43}$/u;\nconst SHARE_TTL_MS = 10 * 60 * 1000;\nconst SHARE_DOWNLOADS = 3;\nconst MAX_LIVE_SHARES_PER_SESSION = 16;\nconst OPEN_FLAGS = fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW;\n\nexport interface PublicFileShareRequest {\n sessionId: string;\n cwd: string;\n /** Relative to cwd, or absolute. */\n path: string;\n /** Who the file is for, for the host's notice. */\n label: string;\n}\n\nexport interface PublicFileShares {\n mint(request: PublicFileShareRequest): Promise<DoomSharedFile>;\n serve(token: string, method: string): Promise<Response>;\n}\n\nexport interface PublicFileSharesOptions {\n publicOrigin(): string | undefined;\n /** Bumped whenever the tunnel goes away; a link minted under another revision is dead. */\n publicOriginRevision(): number;\n /** Never receives a token or a link. */\n onNotice(message: string): void;\n /** Locates the attachment root; defaults to the process environment, as the upload route does. */\n environment?: Readonly<Record<string, string | undefined>>;\n}\n\ninterface Share {\n sessionId: string;\n filePath: string;\n fileName: string;\n dev: number;\n ino: number;\n size: number;\n mtimeMs: number;\n revision: number;\n expiresAt: number;\n downloadsLeft: number;\n revoked: boolean;\n}\n\nfunction tokenDigest(token: string): string {\n return createHash('sha256').update(token).digest('base64url');\n}\n\nfunction notFound(): Response {\n return Response.json({ error: 'Not found.' }, { status: 404 });\n}\n\n/** RFC 8187 value for `filename*`: encodeURIComponent leaves a few characters the grammar forbids. */\nfunction contentDispositionName(fileName: string): string {\n return encodeURIComponent(fileName).replace(\n /['()*]/gu,\n (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n}\n\n/** True when filePath sits strictly below the real root with no segment that starts with a dot. */\nasync function containedIn(root: string, filePath: string): Promise<boolean> {\n let realRoot: string;\n try {\n realRoot = await fs.promises.realpath(root);\n } catch {\n return false;\n }\n const relative = path.relative(realRoot, filePath);\n return (\n relative !== '' &&\n !path.isAbsolute(relative) &&\n relative.split(path.sep).every((segment) => !segment.startsWith('.'))\n );\n}\n\n/** The real path of a shareable file: inside the session cwd or its attachment root, never through a dot segment. */\nasync function resolveShareable(\n request: PublicFileShareRequest,\n environment: Readonly<Record<string, string | undefined>>,\n): Promise<string> {\n const refused = new Error(`\"${request.path}\" is not a file in this session's working directory or attachments.`);\n if (\n request.path === '' ||\n request.path.includes('\\0') ||\n request.path.split(/[\\\\/]/u).some((segment) => segment === '.' || segment === '..')\n )\n throw refused;\n let filePath: string;\n try {\n filePath = await fs.promises.realpath(path.resolve(request.cwd, request.path));\n } catch {\n throw refused;\n }\n const roots = [request.cwd];\n try {\n roots.push(sessionAttachmentRoot(request.sessionId, environment));\n } catch {\n // An id that cannot hold attachments only has its working directory.\n }\n for (const root of roots) if (await containedIn(root, filePath)) return filePath;\n throw refused;\n}\n\n/**\n * Opens a regular file without following a final symlink, then proves the handle is\n * still the file at that real path: a parent swapped for a symlink changes the real\n * path, and a replaced file changes the identity. Resolves undefined, with nothing\n * left open, when either check fails.\n */\nasync function openPinned(filePath: string): Promise<{ handle: fs.promises.FileHandle; stat: fs.Stats } | undefined> {\n let handle: fs.promises.FileHandle;\n try {\n handle = await fs.promises.open(filePath, OPEN_FLAGS);\n } catch {\n return undefined;\n }\n try {\n const stat = await handle.stat();\n const named = await fs.promises.lstat(filePath);\n if (\n stat.isFile() &&\n named.dev === stat.dev &&\n named.ino === stat.ino &&\n (await fs.promises.realpath(filePath)) === filePath\n )\n return { handle, stat };\n } catch {\n // Treated like a mismatch below.\n }\n await handle.close();\n return undefined;\n}\n\nexport function createPublicFileShares(options: PublicFileSharesOptions): PublicFileShares {\n const environment = options.environment ?? process.env;\n const shares = new Map<string, Share>();\n\n const authorized = (share: Share): boolean =>\n !share.revoked &&\n Date.now() < share.expiresAt &&\n share.revision === options.publicOriginRevision() &&\n options.publicOrigin() !== undefined;\n const live = (share: Share): boolean => authorized(share) && share.downloadsLeft > 0;\n\n return {\n async mint(request) {\n const origin = options.publicOrigin();\n const revision = options.publicOriginRevision();\n if (origin === undefined) throw new Error(DOOM_SHARE_FILE_REMOTE_OFF_MESSAGE);\n const filePath = await resolveShareable(request, environment);\n const opened = await openPinned(filePath);\n if (opened === undefined) throw new Error(`\"${request.path}\" is not a regular file Po can share.`);\n const { stat } = opened;\n await opened.handle.close();\n if (stat.size > MAX_SESSION_FILE_BYTES)\n throw new Error(`\"${request.path}\" is larger than the 25 MB file sharing limit.`);\n for (const [key, share] of shares) if (!live(share)) shares.delete(key);\n if (\n [...shares.values()].filter((share) => share.sessionId === request.sessionId).length >=\n MAX_LIVE_SHARES_PER_SESSION\n )\n throw new Error(\n `This session already shares ${String(MAX_LIVE_SHARES_PER_SESSION)} files. Retry after a tool call finishes.`,\n );\n const token = randomBytes(TOKEN_BYTES).toString('base64url');\n const key = tokenDigest(token);\n const fileName = path.basename(filePath);\n const share: Share = {\n sessionId: request.sessionId,\n filePath,\n fileName,\n dev: stat.dev,\n ino: stat.ino,\n size: stat.size,\n mtimeMs: stat.mtimeMs,\n revision,\n expiresAt: Date.now() + SHARE_TTL_MS,\n downloadsLeft: SHARE_DOWNLOADS,\n revoked: false,\n };\n shares.set(key, share);\n options.onNotice(`file share: published \"${fileName}\" for ${request.label} on the remote-access tunnel.`);\n return {\n url: `${origin}${PUBLIC_FILE_SHARE_PREFIX}${token}`,\n fileName,\n mimeType: SESSION_FILE_CONTENT_TYPES[path.extname(fileName).toLowerCase()] ?? SESSION_FILE_DEFAULT_CONTENT_TYPE,\n size: stat.size,\n expiresAt: share.expiresAt,\n maxDownloads: SHARE_DOWNLOADS,\n revoke: () => {\n share.revoked = true;\n shares.delete(key);\n },\n };\n },\n\n async serve(token, method) {\n if ((method !== 'GET' && method !== 'HEAD') || !TOKEN_PATTERN.test(token)) return notFound();\n const key = tokenDigest(token);\n const share = shares.get(key);\n if (share === undefined) return notFound();\n if (!live(share)) {\n shares.delete(key);\n return notFound();\n }\n // Counted before the first await, so concurrent downloads cannot outrun the limit.\n if (method === 'GET') {\n share.downloadsLeft -= 1;\n if (share.downloadsLeft === 0) shares.delete(key);\n }\n const opened = await openPinned(share.filePath);\n if (\n opened === undefined ||\n opened.stat.dev !== share.dev ||\n opened.stat.ino !== share.ino ||\n opened.stat.size !== share.size ||\n opened.stat.mtimeMs !== share.mtimeMs\n ) {\n await opened?.handle.close();\n shares.delete(key);\n options.onNotice(`file share: refused \"${share.fileName}\" because the file changed after it was shared.`);\n return notFound();\n }\n // Opening a file yields to revocation and tunnel changes. The download already\n // reserved its allowance, so this check must not reject the final permitted GET.\n if (!authorized(share)) {\n await opened.handle.close();\n shares.delete(key);\n return notFound();\n }\n const headers = {\n 'content-type': 'application/octet-stream',\n 'content-length': String(share.size),\n 'content-disposition': `attachment; filename*=UTF-8''${contentDispositionName(share.fileName)}`,\n 'x-content-type-options': 'nosniff',\n 'content-security-policy': \"sandbox; default-src 'none'\",\n 'cross-origin-resource-policy': 'same-origin',\n 'cache-control': 'no-store, private',\n 'referrer-policy': 'no-referrer',\n 'accept-ranges': 'none',\n 'x-robots-tag': 'noindex',\n };\n if (method === 'HEAD' || share.size === 0) {\n await opened.handle.close();\n return new Response(method === 'HEAD' ? null : new Uint8Array(), { headers });\n }\n // The stream closes the handle when it ends, fails, or is cancelled. Bounded to the\n // pinned size, so bytes appended after the identity check are never sent.\n const body = Readable.toWeb(opened.handle.createReadStream({ start: 0, end: share.size - 1 }));\n return new Response(body as ReadableStream<Uint8Array>, { headers });\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/publicFileShares/index.ts"],"sourcesContent":["import { createHash, randomBytes } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\n\nimport {\n MAX_SESSION_FILE_BYTES,\n SESSION_FILE_CONTENT_TYPES,\n SESSION_FILE_DEFAULT_CONTENT_TYPE,\n} from '../../constants/sessionFiles';\nimport { PO_SHARE_FILE_REMOTE_OFF_MESSAGE, type PoSharedFile } from '../../schemas/packageApi';\nimport { sessionAttachmentRoot } from '../sessionAttachments';\n\n/**\n * Short-lived public links to one session file, so a remote MCP server can fetch\n * what the model was asked to hand it.\n *\n * The link is the only credential, so only its hash is kept, and every way a\n * link can fail answers the same 404. A file is pinned by identity when the\n * link is minted and reopened when it is served: a path that now names another\n * file, or reaches it through a new symlink, is refused rather than followed.\n */\n\n/** Public tunnel path prefix; the token is the only segment after it. */\nexport const PUBLIC_FILE_SHARE_PREFIX = '/mcp-file/';\n\nconst TOKEN_BYTES = 32;\nconst TOKEN_PATTERN = /^[A-Za-z0-9_-]{43}$/u;\nconst SHARE_TTL_MS = 10 * 60 * 1000;\nconst SHARE_DOWNLOADS = 3;\nconst MAX_LIVE_SHARES_PER_SESSION = 16;\nconst OPEN_FLAGS = fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW;\n\nexport interface PublicFileShareRequest {\n sessionId: string;\n cwd: string;\n /** Relative to cwd, or absolute. */\n path: string;\n /** Who the file is for, for the host's notice. */\n label: string;\n}\n\nexport interface PublicFileShares {\n mint(request: PublicFileShareRequest): Promise<PoSharedFile>;\n serve(token: string, method: string): Promise<Response>;\n}\n\nexport interface PublicFileSharesOptions {\n publicOrigin(): string | undefined;\n /** Bumped whenever the tunnel goes away; a link minted under another revision is dead. */\n publicOriginRevision(): number;\n /** Never receives a token or a link. */\n onNotice(message: string): void;\n /** Locates the attachment root; defaults to the process environment, as the upload route does. */\n environment?: Readonly<Record<string, string | undefined>>;\n}\n\ninterface Share {\n sessionId: string;\n filePath: string;\n fileName: string;\n dev: number;\n ino: number;\n size: number;\n mtimeMs: number;\n revision: number;\n expiresAt: number;\n downloadsLeft: number;\n revoked: boolean;\n}\n\nfunction tokenDigest(token: string): string {\n return createHash('sha256').update(token).digest('base64url');\n}\n\nfunction notFound(): Response {\n return Response.json({ error: 'Not found.' }, { status: 404 });\n}\n\n/** RFC 8187 value for `filename*`: encodeURIComponent leaves a few characters the grammar forbids. */\nfunction contentDispositionName(fileName: string): string {\n return encodeURIComponent(fileName).replace(\n /['()*]/gu,\n (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n}\n\n/** True when filePath sits strictly below the real root with no segment that starts with a dot. */\nasync function containedIn(root: string, filePath: string): Promise<boolean> {\n let realRoot: string;\n try {\n realRoot = await fs.promises.realpath(root);\n } catch {\n return false;\n }\n const relative = path.relative(realRoot, filePath);\n return (\n relative !== '' &&\n !path.isAbsolute(relative) &&\n relative.split(path.sep).every((segment) => !segment.startsWith('.'))\n );\n}\n\n/** The real path of a shareable file: inside the session cwd or its attachment root, never through a dot segment. */\nasync function resolveShareable(\n request: PublicFileShareRequest,\n environment: Readonly<Record<string, string | undefined>>,\n): Promise<string> {\n const refused = new Error(`\"${request.path}\" is not a file in this session's working directory or attachments.`);\n if (\n request.path === '' ||\n request.path.includes('\\0') ||\n request.path.split(/[\\\\/]/u).some((segment) => segment === '.' || segment === '..')\n )\n throw refused;\n let filePath: string;\n try {\n filePath = await fs.promises.realpath(path.resolve(request.cwd, request.path));\n } catch {\n throw refused;\n }\n const roots = [request.cwd];\n try {\n roots.push(sessionAttachmentRoot(request.sessionId, environment));\n } catch {\n // An id that cannot hold attachments only has its working directory.\n }\n for (const root of roots) if (await containedIn(root, filePath)) return filePath;\n throw refused;\n}\n\n/**\n * Opens a regular file without following a final symlink, then proves the handle is\n * still the file at that real path: a parent swapped for a symlink changes the real\n * path, and a replaced file changes the identity. Resolves undefined, with nothing\n * left open, when either check fails.\n */\nasync function openPinned(filePath: string): Promise<{ handle: fs.promises.FileHandle; stat: fs.Stats } | undefined> {\n let handle: fs.promises.FileHandle;\n try {\n handle = await fs.promises.open(filePath, OPEN_FLAGS);\n } catch {\n return undefined;\n }\n try {\n const stat = await handle.stat();\n const named = await fs.promises.lstat(filePath);\n if (\n stat.isFile() &&\n named.dev === stat.dev &&\n named.ino === stat.ino &&\n (await fs.promises.realpath(filePath)) === filePath\n )\n return { handle, stat };\n } catch {\n // Treated like a mismatch below.\n }\n await handle.close();\n return undefined;\n}\n\nexport function createPublicFileShares(options: PublicFileSharesOptions): PublicFileShares {\n const environment = options.environment ?? process.env;\n const shares = new Map<string, Share>();\n\n const authorized = (share: Share): boolean =>\n !share.revoked &&\n Date.now() < share.expiresAt &&\n share.revision === options.publicOriginRevision() &&\n options.publicOrigin() !== undefined;\n const live = (share: Share): boolean => authorized(share) && share.downloadsLeft > 0;\n\n return {\n async mint(request) {\n const origin = options.publicOrigin();\n const revision = options.publicOriginRevision();\n if (origin === undefined) throw new Error(PO_SHARE_FILE_REMOTE_OFF_MESSAGE);\n const filePath = await resolveShareable(request, environment);\n const opened = await openPinned(filePath);\n if (opened === undefined) throw new Error(`\"${request.path}\" is not a regular file Po can share.`);\n const { stat } = opened;\n await opened.handle.close();\n if (stat.size > MAX_SESSION_FILE_BYTES)\n throw new Error(`\"${request.path}\" is larger than the 25 MB file sharing limit.`);\n for (const [key, share] of shares) if (!live(share)) shares.delete(key);\n if (\n [...shares.values()].filter((share) => share.sessionId === request.sessionId).length >=\n MAX_LIVE_SHARES_PER_SESSION\n )\n throw new Error(\n `This session already shares ${String(MAX_LIVE_SHARES_PER_SESSION)} files. Retry after a tool call finishes.`,\n );\n const token = randomBytes(TOKEN_BYTES).toString('base64url');\n const key = tokenDigest(token);\n const fileName = path.basename(filePath);\n const share: Share = {\n sessionId: request.sessionId,\n filePath,\n fileName,\n dev: stat.dev,\n ino: stat.ino,\n size: stat.size,\n mtimeMs: stat.mtimeMs,\n revision,\n expiresAt: Date.now() + SHARE_TTL_MS,\n downloadsLeft: SHARE_DOWNLOADS,\n revoked: false,\n };\n shares.set(key, share);\n options.onNotice(`file share: published \"${fileName}\" for ${request.label} on the remote-access tunnel.`);\n return {\n url: `${origin}${PUBLIC_FILE_SHARE_PREFIX}${token}`,\n fileName,\n mimeType: SESSION_FILE_CONTENT_TYPES[path.extname(fileName).toLowerCase()] ?? SESSION_FILE_DEFAULT_CONTENT_TYPE,\n size: stat.size,\n expiresAt: share.expiresAt,\n maxDownloads: SHARE_DOWNLOADS,\n revoke: () => {\n share.revoked = true;\n shares.delete(key);\n },\n };\n },\n\n async serve(token, method) {\n if ((method !== 'GET' && method !== 'HEAD') || !TOKEN_PATTERN.test(token)) return notFound();\n const key = tokenDigest(token);\n const share = shares.get(key);\n if (share === undefined) return notFound();\n if (!live(share)) {\n shares.delete(key);\n return notFound();\n }\n // Counted before the first await, so concurrent downloads cannot outrun the limit.\n if (method === 'GET') {\n share.downloadsLeft -= 1;\n if (share.downloadsLeft === 0) shares.delete(key);\n }\n const opened = await openPinned(share.filePath);\n if (\n opened === undefined ||\n opened.stat.dev !== share.dev ||\n opened.stat.ino !== share.ino ||\n opened.stat.size !== share.size ||\n opened.stat.mtimeMs !== share.mtimeMs\n ) {\n await opened?.handle.close();\n shares.delete(key);\n options.onNotice(`file share: refused \"${share.fileName}\" because the file changed after it was shared.`);\n return notFound();\n }\n // Opening a file yields to revocation and tunnel changes. The download already\n // reserved its allowance, so this check must not reject the final permitted GET.\n if (!authorized(share)) {\n await opened.handle.close();\n shares.delete(key);\n return notFound();\n }\n const headers = {\n 'content-type': 'application/octet-stream',\n 'content-length': String(share.size),\n 'content-disposition': `attachment; filename*=UTF-8''${contentDispositionName(share.fileName)}`,\n 'x-content-type-options': 'nosniff',\n 'content-security-policy': \"sandbox; default-src 'none'\",\n 'cross-origin-resource-policy': 'same-origin',\n 'cache-control': 'no-store, private',\n 'referrer-policy': 'no-referrer',\n 'accept-ranges': 'none',\n 'x-robots-tag': 'noindex',\n };\n if (method === 'HEAD' || share.size === 0) {\n await opened.handle.close();\n return new Response(method === 'HEAD' ? null : new Uint8Array(), { headers });\n }\n // The stream closes the handle when it ends, fails, or is cancelled. Bounded to the\n // pinned size, so bytes appended after the identity check are never sent.\n const body = Readable.toWeb(opened.handle.createReadStream({ start: 0, end: share.size - 1 }));\n return new Response(body as ReadableStream<Uint8Array>, { headers });\n },\n };\n}\n"],"mappings":"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"}
@@ -2,6 +2,7 @@ import { BundlePairingTrust, DeviceTrustKind, PairingStatus, RemoteAccessSetting
2
2
  import { EnrolledDevice } from "../deviceAuth/index.mjs";
3
3
  import { PairingFlow } from "../pairingFlow/index.mjs";
4
4
  import { StepUpAction, StoredCredential } from "../webauthnPolicy/index.mjs";
5
+ import "../remoteAccessStore/index.mjs";
5
6
  import { OriginPolicy } from "../remoteGuardPolicy/index.mjs";
6
7
  import { PasskeySupport, WebAuthn } from "../webauthn/index.mjs";
7
8
  import { SealedChannel } from "@agimon-ai/po-web-security/node";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../../../src/services/remoteAccess/index.ts"],"mappings":";;;;;;;;iBA+FiB;EACf,MAAM,uBAAuB,2BAA2B;EACxD,YAAY;EACZ,eAAe,OAAO,QAAQ,wBAAwB;EACtD;;EAEA;;EAEA;EACA,gBAAgB;EAChB,UAAU;IAAU;;IAAe;IAAW;;;EAE9C;;EAEA;EACA,WAAW;;EAEX;IACO;IAAc;IAAoB;IAAiB;MAAsB;EAEhF,eAAe;EACf,MAAM;IACJ;IACA;IACA;IACA;MACE,WAAW;EACf,cAAc,oBAAoB;EAClC,QAAQ,oBAAoB,WAAW;EACvC,KAAK,oBAAoB,WAAW;;EAEpC,OAAO,qBAAqB;IAAmB;;EAC/C,UAAU;;EAEV,mBAAmB;;EAEnB,kBAAkB,gBAAgB;IAAmB;;EACrD;IACE,eAAe;IACf,qBAAqB;IACrB,mBAAmB;IACnB,oBAAoB;IACpB,qBAAqB;IACrB,sBAAsB;IACtB,aAAa;IACb,cAAc;IACd,SAAS;;;EAGX,sBACE,yBACA;IACG;IAAU;;IAA8B;IAAW;;;EAExD,gBAAgB;IACd;IACA;;IAEI;IAAU;IAAqB;IAAmB;IAAuB;;IACzE;IAAW;;;EAEjB,iBAAiB,iBAAiB;IAAmB;;EACrD,kBACE,yBACA,QAAQ;IACL;IAAoB;IAAmB;;EAC5C,mBAAmB,yBAAyB,QAAQ,cAAc,qBAAqB;;EAEvF,oBAAoB;EACpB,UAAU,mBAAmB;;;;;EAK7B,eAAe,QAAQ,cAAc;;EAErC;;EAEA,YAAY,kBAAkB,OAAO,oBAAoB;EACzD,WAAW,kBAAkB,OAAO,qBAAqB;EACzD,aAAa;EACb,kBAAkB;;EAElB,YAAY,kBAAkB,QAAQ,cAAc;EACpD,SAAS"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../../../src/services/remoteAccess/index.ts"],"mappings":";;;;;;;;;iBA+FiB;EACf,MAAM,uBAAuB,2BAA2B;EACxD,YAAY;EACZ,eAAe,OAAO,QAAQ,wBAAwB;EACtD;;EAEA;;EAEA;EACA,gBAAgB;EAChB,UAAU;IAAU;;IAAe;IAAW;;;EAE9C;;EAEA;EACA,WAAW;;EAEX;IACO;IAAc;IAAoB;IAAiB;MAAsB;EAEhF,eAAe;EACf,MAAM;IACJ;IACA;IACA;IACA;MACE,WAAW;EACf,cAAc,oBAAoB;EAClC,QAAQ,oBAAoB,WAAW;EACvC,KAAK,oBAAoB,WAAW;;EAEpC,OAAO,qBAAqB;IAAmB;;EAC/C,UAAU;;EAEV,mBAAmB;;EAEnB,kBAAkB,gBAAgB;IAAmB;;EACrD;IACE,eAAe;IACf,qBAAqB;IACrB,mBAAmB;IACnB,oBAAoB;IACpB,qBAAqB;IACrB,sBAAsB;IACtB,aAAa;IACb,cAAc;IACd,SAAS;;;EAGX,sBACE,yBACA;IACG;IAAU;;IAA8B;IAAW;;;EAExD,gBAAgB;IACd;IACA;;IAEI;IAAU;IAAqB;IAAmB;IAAuB;;IACzE;IAAW;;;EAEjB,iBAAiB,iBAAiB;IAAmB;;EACrD,kBACE,yBACA,QAAQ;IACL;IAAoB;IAAmB;;EAC5C,mBAAmB,yBAAyB,QAAQ,cAAc,qBAAqB;;EAEvF,oBAAoB;EACpB,UAAU,mBAAmB;;;;;EAK7B,eAAe,QAAQ,cAAc;;EAErC;;EAEA,YAAY,kBAAkB,OAAO,oBAAoB;EACzD,WAAW,kBAAkB,OAAO,qBAAqB;EACzD,aAAa;EACb,kBAAkB;;EAElB,YAAY,kBAAkB,QAAQ,cAAc;EACpD,SAAS"}