pybao-cli 1.5.51 → 1.5.52

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 (217) hide show
  1. package/dist/REPL-CDBGUX7H.js +53 -0
  2. package/dist/{acp-OGXPDTPB.js → acp-KC4VUW7Q.js} +47 -47
  3. package/dist/{agentsValidate-7USQLEWU.js → agentsValidate-YGJMW4T4.js} +9 -9
  4. package/dist/{ask-KTRDNR5F.js → ask-YHWMV475.js} +46 -46
  5. package/dist/{autoUpdater-YTVTFZKD.js → autoUpdater-76RMCNA7.js} +4 -4
  6. package/dist/{blockParser-QPLEX5NJ.js → blockParser-RZPICWAA.js} +2 -2
  7. package/dist/{chunk-D2MHLZDN.js → chunk-2EQA5NLL.js} +1 -1
  8. package/dist/{chunk-A2QSQWOQ.js → chunk-33EYH7S3.js} +5 -5
  9. package/dist/{chunk-I6GA6HKT.js → chunk-3I35GELX.js} +5 -5
  10. package/dist/{chunk-OLQLK3UC.js → chunk-4MAX5UNY.js} +1 -1
  11. package/dist/{chunk-CXWYHX64.js → chunk-4UQCXDKA.js} +4 -4
  12. package/dist/{chunk-WZDDUIIK.js → chunk-6QSG5OON.js} +5 -5
  13. package/dist/{chunk-TKU3UJXS.js → chunk-AZF3LTDE.js} +3 -3
  14. package/dist/{chunk-726GW5OD.js → chunk-CBDJJ2WQ.js} +2 -2
  15. package/dist/{chunk-56FKUXNO.js → chunk-DPE2QUR4.js} +4 -4
  16. package/dist/{chunk-UMOI4SIG.js → chunk-DYLRL3GG.js} +1 -1
  17. package/dist/{chunk-F4AXICO7.js → chunk-EXNV3ROJ.js} +1 -1
  18. package/dist/{chunk-QHRHQ4TE.js → chunk-FNMZKMUC.js} +2 -2
  19. package/dist/{chunk-RDDHG7KT.js → chunk-HSOB4XJ2.js} +1 -1
  20. package/dist/{chunk-PWHPXHNR.js → chunk-I42N2MZA.js} +3 -3
  21. package/dist/{chunk-5C3V4WBH.js → chunk-JGECWVPT.js} +1160 -65
  22. package/dist/{chunk-LG4DZXZE.js → chunk-KPZ4UMNV.js} +1 -1
  23. package/dist/{chunk-FTPQJIPL.js → chunk-KQBUAEA5.js} +4 -4
  24. package/dist/{chunk-UIKYSSZX.js → chunk-L2JZIHLB.js} +6 -6
  25. package/dist/{chunk-X6MCOKYP.js → chunk-NQJAXQZX.js} +3 -3
  26. package/dist/{chunk-PGRCNKEQ.js → chunk-O6CVVWZV.js} +1 -1
  27. package/dist/{chunk-HM2PO36Q.js → chunk-OEHXDSEI.js} +4 -4
  28. package/dist/{chunk-GZOD5652.js → chunk-PA5FTBIQ.js} +2 -2
  29. package/dist/{chunk-YEUUN3PW.js → chunk-QEPBMPEE.js} +1 -1
  30. package/dist/{chunk-5AGDLQAW.js → chunk-QQ27ECXF.js} +1 -1
  31. package/dist/{chunk-NXWVCWZU.js → chunk-QYVB7FJ4.js} +1 -1
  32. package/dist/{chunk-EEOIMMFC.js → chunk-R64GVTIZ.js} +3 -3
  33. package/dist/{chunk-276WD5RN.js → chunk-RETS7G2B.js} +6 -6
  34. package/dist/{chunk-TGGCRPZR.js → chunk-SZS6SEDB.js} +1 -1
  35. package/dist/{chunk-GUNRUYLP.js → chunk-UCNZU6OO.js} +2 -2
  36. package/dist/{chunk-TZGJRTAC.js → chunk-UG7ZFONK.js} +4 -4
  37. package/dist/{chunk-XTFXKDRC.js → chunk-VFFYWI27.js} +4 -4
  38. package/dist/{chunk-OMELVAJD.js → chunk-YQ6JLMLS.js} +1 -1
  39. package/dist/{chunk-ESKGSE6G.js → chunk-ZFLQSIXD.js} +3 -3
  40. package/dist/{chunk-CLYWO4WT.js → chunk-ZWTGVUTI.js} +3 -3
  41. package/dist/{cli-KFO36PW7.js → cli-JMJIGYNF.js} +120 -120
  42. package/dist/commands-N4RLEJU6.js +57 -0
  43. package/dist/{config-UGXKX5W7.js → config-6AW7SYEB.js} +6 -6
  44. package/dist/{context-TDXVLXJZ.js → context-VGBWHZ57.js} +9 -9
  45. package/dist/{conversationPersistence-ATHSGPCA.js → conversationPersistence-AAJPHPUT.js} +4 -4
  46. package/dist/{conversationTracker-IGKMS7I2.js → conversationTracker-MVX6VQG2.js} +5 -5
  47. package/dist/{costTracker-DJVFVAVZ.js → costTracker-KBXHS4NS.js} +2 -2
  48. package/dist/{customCommands-5MIZHJIB.js → customCommands-PJI43HDH.js} +6 -6
  49. package/dist/{env-3KNLQRPA.js → env-JEHV2OD5.js} +3 -3
  50. package/dist/{file-DFXDFI6W.js → file-G3IOPSJE.js} +5 -5
  51. package/dist/index.js +4 -4
  52. package/dist/{llm-MRDYTVAB.js → llm-CVILTZMI.js} +50 -50
  53. package/dist/{llmLazy-2O7VC463.js → llmLazy-TS22QBZC.js} +2 -2
  54. package/dist/{loader-FZWD5WHH.js → loader-DA33SOZU.js} +7 -7
  55. package/dist/{lsp-2TM75CW4.js → lsp-M5NJ7YC7.js} +9 -9
  56. package/dist/{lspAnchor-XGTUMZDM.js → lspAnchor-LUE27QI2.js} +10 -10
  57. package/dist/{mcp-FITQROXI.js → mcp-3R7KNW6M.js} +10 -10
  58. package/dist/{mentionProcessor-L5WCXBIE.js → mentionProcessor-KM7DJSIF.js} +8 -8
  59. package/dist/{messages-4S23AYLZ.js → messages-EUS4CRVP.js} +3 -3
  60. package/dist/{model-ECABFXED.js → model-3GE72U3P.js} +7 -7
  61. package/dist/{openai-AAHVW6AQ.js → openai-3TL5XAIV.js} +8 -8
  62. package/dist/{outputStyles-2QWBQSS4.js → outputStyles-7FC4BJZX.js} +7 -7
  63. package/dist/{pluginRuntime-TDH3JKLN.js → pluginRuntime-IWKORZEI.js} +8 -8
  64. package/dist/{pluginValidation-FBGQ4JDV.js → pluginValidation-DC2PWTS3.js} +8 -8
  65. package/dist/prompts-X5RHKH65.js +59 -0
  66. package/dist/{pybAgentSessionId-EPCAMQ25.js → pybAgentSessionId-3LL4RMFU.js} +2 -2
  67. package/dist/{pybAgentSessionLoad-WEEMBEOX.js → pybAgentSessionLoad-DCESKISD.js} +6 -6
  68. package/dist/{pybAgentSessionResume-FXJA5YEY.js → pybAgentSessionResume-CIJIMHTT.js} +8 -8
  69. package/dist/{pybAgentStreamJson-EQPO52B6.js → pybAgentStreamJson-K7E4VEFE.js} +2 -2
  70. package/dist/{pybAgentStreamJsonSession-I3QVTPS4.js → pybAgentStreamJsonSession-SZMCWTVW.js} +4 -4
  71. package/dist/{pybAgentStructuredStdio-ROCSOGNT.js → pybAgentStructuredStdio-T6JJLJVC.js} +3 -3
  72. package/dist/{pybHooks-QVFTX2NF.js → pybHooks-CYAJNZ6G.js} +7 -7
  73. package/dist/query-7PFFQCW2.js +57 -0
  74. package/dist/{registry-R642XWSX.js → registry-HF5Y4WZS.js} +6 -6
  75. package/dist/{replSessionBridge-EBXNFUAD.js → replSessionBridge-4XEXXNRH.js} +3 -3
  76. package/dist/{responsesStreaming-NPGJLPV3.js → responsesStreaming-RZW2QVJU.js} +3 -3
  77. package/dist/{ripgrep-ZCE3BIKN.js → ripgrep-W5ULQHU4.js} +4 -4
  78. package/dist/{skillMarketplace-O2RFNXT4.js → skillMarketplace-WKOGEWIO.js} +4 -4
  79. package/dist/{smart-edit-AWHJDSU6.js → smart-edit-EQBEMPKQ.js} +2 -2
  80. package/dist/{state-GMP5BAO3.js → state-GWKESQ7O.js} +3 -3
  81. package/dist/theme-VRKM2HNU.js +14 -0
  82. package/dist/{toolPermissionContext-BSFV23IL.js → toolPermissionContext-TAUII5GX.js} +2 -2
  83. package/dist/{toolPermissionSettings-SLI774QB.js → toolPermissionSettings-Z2I77LVO.js} +9 -9
  84. package/dist/tools-VM7IZKXZ.js +57 -0
  85. package/dist/{userInput-73ASWIUB.js → userInput-Q2HIIFPM.js} +49 -49
  86. package/dist/{uuid-CVHEFGW4.js → uuid-EJN2AIBK.js} +2 -2
  87. package/package.json +3 -3
  88. package/dist/REPL-VQEZ7GBU.js +0 -53
  89. package/dist/REPL-VQEZ7GBU.js.map +0 -7
  90. package/dist/acp-OGXPDTPB.js.map +0 -7
  91. package/dist/agentsValidate-7USQLEWU.js.map +0 -7
  92. package/dist/ask-KTRDNR5F.js.map +0 -7
  93. package/dist/autoUpdater-YTVTFZKD.js.map +0 -7
  94. package/dist/blockParser-QPLEX5NJ.js.map +0 -7
  95. package/dist/chunk-276WD5RN.js.map +0 -7
  96. package/dist/chunk-2RXKUCFS.js.map +0 -7
  97. package/dist/chunk-3DFBSQIT.js.map +0 -7
  98. package/dist/chunk-56FKUXNO.js.map +0 -7
  99. package/dist/chunk-5AGDLQAW.js.map +0 -7
  100. package/dist/chunk-5C3V4WBH.js.map +0 -7
  101. package/dist/chunk-5JHD6MUL.js.map +0 -7
  102. package/dist/chunk-5P7HBXTD.js.map +0 -7
  103. package/dist/chunk-726GW5OD.js.map +0 -7
  104. package/dist/chunk-A2QSQWOQ.js.map +0 -7
  105. package/dist/chunk-A3BVXXA3.js.map +0 -7
  106. package/dist/chunk-B6IMQJZM.js.map +0 -7
  107. package/dist/chunk-BJSWTHRM.js.map +0 -7
  108. package/dist/chunk-BKCAVW2G.js.map +0 -7
  109. package/dist/chunk-CLYWO4WT.js.map +0 -7
  110. package/dist/chunk-CXWYHX64.js.map +0 -7
  111. package/dist/chunk-CZZKRPE2.js.map +0 -7
  112. package/dist/chunk-D2MHLZDN.js.map +0 -7
  113. package/dist/chunk-EEOIMMFC.js.map +0 -7
  114. package/dist/chunk-ESKGSE6G.js.map +0 -7
  115. package/dist/chunk-F4AXICO7.js.map +0 -7
  116. package/dist/chunk-FTPQJIPL.js.map +0 -7
  117. package/dist/chunk-GUNRUYLP.js.map +0 -7
  118. package/dist/chunk-GZOD5652.js.map +0 -7
  119. package/dist/chunk-HM2PO36Q.js.map +0 -7
  120. package/dist/chunk-I3J4JYES.js.map +0 -7
  121. package/dist/chunk-I6GA6HKT.js.map +0 -7
  122. package/dist/chunk-KFEHHKZ2.js.map +0 -7
  123. package/dist/chunk-LG4DZXZE.js.map +0 -7
  124. package/dist/chunk-MWPFU2KU.js.map +0 -7
  125. package/dist/chunk-NXWVCWZU.js.map +0 -7
  126. package/dist/chunk-OLQLK3UC.js.map +0 -7
  127. package/dist/chunk-OMELVAJD.js.map +0 -7
  128. package/dist/chunk-OUXHGDLH.js.map +0 -7
  129. package/dist/chunk-PGRCNKEQ.js.map +0 -7
  130. package/dist/chunk-PWHPXHNR.js.map +0 -7
  131. package/dist/chunk-QHRHQ4TE.js.map +0 -7
  132. package/dist/chunk-QWIBSCDN.js.map +0 -7
  133. package/dist/chunk-RDDHG7KT.js.map +0 -7
  134. package/dist/chunk-RQVLBMP7.js.map +0 -7
  135. package/dist/chunk-TFHFYID3.js.map +0 -7
  136. package/dist/chunk-TGGCRPZR.js.map +0 -7
  137. package/dist/chunk-TKU3UJXS.js.map +0 -7
  138. package/dist/chunk-TZGJRTAC.js.map +0 -7
  139. package/dist/chunk-UIKYSSZX.js.map +0 -7
  140. package/dist/chunk-UMOI4SIG.js.map +0 -7
  141. package/dist/chunk-UNNVICVU.js.map +0 -7
  142. package/dist/chunk-UZ34JEUK.js.map +0 -7
  143. package/dist/chunk-WZDDUIIK.js.map +0 -7
  144. package/dist/chunk-X6MCOKYP.js.map +0 -7
  145. package/dist/chunk-XKYHFZEC.js.map +0 -7
  146. package/dist/chunk-XTFXKDRC.js.map +0 -7
  147. package/dist/chunk-YEUUN3PW.js.map +0 -7
  148. package/dist/cli-KFO36PW7.js.map +0 -7
  149. package/dist/commands-DKTG7VIQ.js +0 -57
  150. package/dist/commands-DKTG7VIQ.js.map +0 -7
  151. package/dist/config-UGXKX5W7.js.map +0 -7
  152. package/dist/context-TDXVLXJZ.js.map +0 -7
  153. package/dist/conversationPersistence-ATHSGPCA.js.map +0 -7
  154. package/dist/conversationTracker-IGKMS7I2.js.map +0 -7
  155. package/dist/costTracker-DJVFVAVZ.js.map +0 -7
  156. package/dist/customCommands-5MIZHJIB.js.map +0 -7
  157. package/dist/env-3KNLQRPA.js.map +0 -7
  158. package/dist/file-DFXDFI6W.js.map +0 -7
  159. package/dist/index.js.map +0 -7
  160. package/dist/llm-MRDYTVAB.js.map +0 -7
  161. package/dist/llmLazy-2O7VC463.js.map +0 -7
  162. package/dist/loader-FZWD5WHH.js.map +0 -7
  163. package/dist/lsp-2TM75CW4.js.map +0 -7
  164. package/dist/lspAnchor-XGTUMZDM.js.map +0 -7
  165. package/dist/mcp-FITQROXI.js.map +0 -7
  166. package/dist/mentionProcessor-L5WCXBIE.js.map +0 -7
  167. package/dist/messages-4S23AYLZ.js.map +0 -7
  168. package/dist/model-ECABFXED.js.map +0 -7
  169. package/dist/openai-AAHVW6AQ.js.map +0 -7
  170. package/dist/outputStyles-2QWBQSS4.js.map +0 -7
  171. package/dist/pluginRuntime-TDH3JKLN.js.map +0 -7
  172. package/dist/pluginValidation-FBGQ4JDV.js.map +0 -7
  173. package/dist/prompts-PLA42YDC.js +0 -59
  174. package/dist/prompts-PLA42YDC.js.map +0 -7
  175. package/dist/pybAgentSessionId-EPCAMQ25.js.map +0 -7
  176. package/dist/pybAgentSessionLoad-WEEMBEOX.js.map +0 -7
  177. package/dist/pybAgentSessionResume-FXJA5YEY.js.map +0 -7
  178. package/dist/pybAgentStreamJson-EQPO52B6.js.map +0 -7
  179. package/dist/pybAgentStreamJsonSession-I3QVTPS4.js.map +0 -7
  180. package/dist/pybAgentStructuredStdio-ROCSOGNT.js.map +0 -7
  181. package/dist/pybHooks-QVFTX2NF.js.map +0 -7
  182. package/dist/query-GEX7UFS4.js +0 -57
  183. package/dist/query-GEX7UFS4.js.map +0 -7
  184. package/dist/registry-R642XWSX.js.map +0 -7
  185. package/dist/replSessionBridge-EBXNFUAD.js.map +0 -7
  186. package/dist/responsesStreaming-NPGJLPV3.js.map +0 -7
  187. package/dist/ripgrep-ZCE3BIKN.js.map +0 -7
  188. package/dist/skillMarketplace-O2RFNXT4.js.map +0 -7
  189. package/dist/smart-edit-AWHJDSU6.js.map +0 -7
  190. package/dist/state-GMP5BAO3.js.map +0 -7
  191. package/dist/theme-BXH5IJVI.js +0 -14
  192. package/dist/theme-BXH5IJVI.js.map +0 -7
  193. package/dist/toolPermissionContext-BSFV23IL.js.map +0 -7
  194. package/dist/toolPermissionSettings-SLI774QB.js.map +0 -7
  195. package/dist/tools-GEQDCFN6.js +0 -57
  196. package/dist/tools-GEQDCFN6.js.map +0 -7
  197. package/dist/userInput-73ASWIUB.js.map +0 -7
  198. package/dist/uuid-CVHEFGW4.js.map +0 -7
  199. /package/dist/{chunk-UZ34JEUK.js → chunk-7HEKZ73X.js} +0 -0
  200. /package/dist/{chunk-5JHD6MUL.js → chunk-ADD7XJ5F.js} +0 -0
  201. /package/dist/{chunk-B6IMQJZM.js → chunk-DRSLDSBY.js} +0 -0
  202. /package/dist/{chunk-KFEHHKZ2.js → chunk-F3JSDBR6.js} +0 -0
  203. /package/dist/{chunk-QWIBSCDN.js → chunk-GEEDQS2I.js} +0 -0
  204. /package/dist/{chunk-2RXKUCFS.js → chunk-ISMRCABJ.js} +0 -0
  205. /package/dist/{chunk-MWPFU2KU.js → chunk-JVKJ7J5H.js} +0 -0
  206. /package/dist/{chunk-BJSWTHRM.js → chunk-KNUG3M6O.js} +0 -0
  207. /package/dist/{chunk-UNNVICVU.js → chunk-LG65MFKB.js} +0 -0
  208. /package/dist/{chunk-CZZKRPE2.js → chunk-MGN3VYPN.js} +0 -0
  209. /package/dist/{chunk-A3BVXXA3.js → chunk-OQEZC7X2.js} +0 -0
  210. /package/dist/{chunk-I3J4JYES.js → chunk-OYT6EI36.js} +0 -0
  211. /package/dist/{chunk-RQVLBMP7.js → chunk-PDH2QHLY.js} +0 -0
  212. /package/dist/{chunk-5P7HBXTD.js → chunk-QAMAR4LW.js} +0 -0
  213. /package/dist/{chunk-TFHFYID3.js → chunk-TNCBVAVV.js} +0 -0
  214. /package/dist/{chunk-XKYHFZEC.js → chunk-U6BMHOQT.js} +0 -0
  215. /package/dist/{chunk-OUXHGDLH.js → chunk-VEHLCRJN.js} +0 -0
  216. /package/dist/{chunk-3DFBSQIT.js → chunk-XZG5WCDK.js} +0 -0
  217. /package/dist/{chunk-BKCAVW2G.js → chunk-ZY2PESP4.js} +0 -0
@@ -2,17 +2,17 @@ import { createRequire as __pybCreateRequire } from "node:module";
2
2
  const require = __pybCreateRequire(import.meta.url);
3
3
  import {
4
4
  loadPybAgentSessionMessages
5
- } from "./chunk-YEUUN3PW.js";
5
+ } from "./chunk-QEPBMPEE.js";
6
6
  import {
7
7
  appendSessionCustomTitleRecord,
8
8
  appendSessionJsonlFromMessage,
9
9
  appendSessionTagRecord,
10
10
  listPybAgentSessions
11
- } from "./chunk-I6GA6HKT.js";
11
+ } from "./chunk-3I35GELX.js";
12
12
  import {
13
13
  formatValidationResult,
14
14
  validatePluginOrMarketplacePath
15
- } from "./chunk-EEOIMMFC.js";
15
+ } from "./chunk-R64GVTIZ.js";
16
16
  import {
17
17
  ConversationTracker,
18
18
  appendFinishState,
@@ -20,13 +20,13 @@ import {
20
20
  getConversationTrackerForContext,
21
21
  isFinishComplete,
22
22
  mapFinishReason
23
- } from "./chunk-D2MHLZDN.js";
23
+ } from "./chunk-2EQA5NLL.js";
24
24
  import {
25
25
  FileSystemConversationPersistence
26
- } from "./chunk-NXWVCWZU.js";
26
+ } from "./chunk-QYVB7FJ4.js";
27
27
  import {
28
28
  beginReplSessionScope
29
- } from "./chunk-F4AXICO7.js";
29
+ } from "./chunk-EXNV3ROJ.js";
30
30
  import {
31
31
  drainHookSystemPromptAdditions,
32
32
  getHookTranscriptPath,
@@ -38,7 +38,7 @@ import {
38
38
  runStopHooks,
39
39
  runUserPromptSubmitHooks,
40
40
  updateHookTranscriptForMessages
41
- } from "./chunk-WZDDUIIK.js";
41
+ } from "./chunk-6QSG5OON.js";
42
42
  import {
43
43
  DEFAULT_OUTPUT_STYLE,
44
44
  getAvailableOutputStyles,
@@ -47,20 +47,20 @@ import {
47
47
  getOutputStyleSystemPromptAdditions,
48
48
  resolveOutputStyleName,
49
49
  setCurrentOutputStyle
50
- } from "./chunk-TZGJRTAC.js";
50
+ } from "./chunk-UG7ZFONK.js";
51
51
  import {
52
52
  fetchCustomModels,
53
53
  getModelFeatures
54
- } from "./chunk-CLYWO4WT.js";
54
+ } from "./chunk-ZWTGVUTI.js";
55
55
  import {
56
56
  getCurrentSessionId,
57
57
  getSessionState
58
- } from "./chunk-XKYHFZEC.js";
58
+ } from "./chunk-U6BMHOQT.js";
59
59
  import {
60
60
  queryLLM,
61
61
  queryQuick,
62
62
  verifyApiKey
63
- } from "./chunk-CXWYHX64.js";
63
+ } from "./chunk-4UQCXDKA.js";
64
64
  import {
65
65
  DEFAULT_TIMEOUT_MS,
66
66
  DESCRIPTION,
@@ -92,7 +92,7 @@ import {
92
92
  listMCPServers,
93
93
  loadMergedSettings,
94
94
  normalizeSandboxRuntimeConfigFromSettings
95
- } from "./chunk-A2QSQWOQ.js";
95
+ } from "./chunk-33EYH7S3.js";
96
96
  import {
97
97
  addMarketplace,
98
98
  disableSkillPlugin,
@@ -105,29 +105,29 @@ import {
105
105
  refreshMarketplaceAsync,
106
106
  removeMarketplace,
107
107
  uninstallSkillPlugin
108
- } from "./chunk-OLQLK3UC.js";
108
+ } from "./chunk-4MAX5UNY.js";
109
109
  import {
110
110
  loadToolPermissionContextFromDisk,
111
111
  persistToolPermissionUpdateToDisk
112
- } from "./chunk-HM2PO36Q.js";
112
+ } from "./chunk-OEHXDSEI.js";
113
113
  import {
114
114
  applyToolPermissionContextUpdate,
115
115
  applyToolPermissionContextUpdates,
116
116
  createDefaultToolPermissionContext
117
- } from "./chunk-UNNVICVU.js";
117
+ } from "./chunk-LG65MFKB.js";
118
118
  import {
119
119
  emitReminderEvent,
120
120
  generateSystemReminders,
121
121
  resetReminderSession,
122
122
  systemReminderService
123
- } from "./chunk-GZOD5652.js";
123
+ } from "./chunk-PA5FTBIQ.js";
124
124
  import {
125
125
  clearAgentCache,
126
126
  getActiveAgents,
127
127
  getAgentByType,
128
128
  getAllAgents,
129
129
  getAvailableAgentTypes
130
- } from "./chunk-56FKUXNO.js";
130
+ } from "./chunk-DPE2QUR4.js";
131
131
  import {
132
132
  API_ERROR_MESSAGE_PREFIX,
133
133
  CANCEL_MESSAGE,
@@ -162,16 +162,16 @@ import {
162
162
  reorderMessages,
163
163
  resetAutoCompactTelemetry,
164
164
  stripSystemMessages
165
- } from "./chunk-GUNRUYLP.js";
165
+ } from "./chunk-UCNZU6OO.js";
166
166
  import {
167
167
  getRequestStatus,
168
168
  setRequestStatus,
169
169
  subscribeRequestStatus
170
- } from "./chunk-3DFBSQIT.js";
170
+ } from "./chunk-XZG5WCDK.js";
171
171
  import {
172
172
  getPybAgentSessionId,
173
173
  setPybAgentSessionId
174
- } from "./chunk-B6IMQJZM.js";
174
+ } from "./chunk-DRSLDSBY.js";
175
175
  import {
176
176
  formatDuration,
177
177
  formatNumber,
@@ -180,7 +180,7 @@ import {
180
180
  getTotalCost,
181
181
  getTotalDuration,
182
182
  wrapText
183
- } from "./chunk-OUXHGDLH.js";
183
+ } from "./chunk-VEHLCRJN.js";
184
184
  import {
185
185
  addLineNumbers,
186
186
  detectFileEncoding,
@@ -194,13 +194,13 @@ import {
194
194
  normalizeFilePath,
195
195
  readTextContent,
196
196
  writeTextContent
197
- } from "./chunk-QHRHQ4TE.js";
197
+ } from "./chunk-FNMZKMUC.js";
198
198
  import {
199
199
  parseBlockEdits
200
- } from "./chunk-QWIBSCDN.js";
200
+ } from "./chunk-GEEDQS2I.js";
201
201
  import {
202
202
  toLspToolFallbackEvent
203
- } from "./chunk-2RXKUCFS.js";
203
+ } from "./chunk-ISMRCABJ.js";
204
204
  import {
205
205
  LspAPI,
206
206
  LspFacade,
@@ -208,31 +208,31 @@ import {
208
208
  formatDiagnosticsPretty,
209
209
  initParser,
210
210
  loadLanguage
211
- } from "./chunk-UIKYSSZX.js";
211
+ } from "./chunk-L2JZIHLB.js";
212
212
  import {
213
213
  emitTelemetryEvent,
214
214
  registerTelemetryListener
215
- } from "./chunk-TFHFYID3.js";
215
+ } from "./chunk-TNCBVAVV.js";
216
216
  import {
217
217
  getSettingsFileCandidates,
218
218
  loadSettingsWithLegacyFallback,
219
219
  readSettingsFile
220
- } from "./chunk-UMOI4SIG.js";
220
+ } from "./chunk-DYLRL3GG.js";
221
221
  import {
222
222
  getCustomCommandDirectories,
223
223
  hasCustomCommands,
224
224
  loadCustomCommands,
225
225
  reloadCustomCommands
226
- } from "./chunk-PWHPXHNR.js";
226
+ } from "./chunk-I42N2MZA.js";
227
227
  import {
228
228
  getSessionPlugins
229
- } from "./chunk-BJSWTHRM.js";
229
+ } from "./chunk-KNUG3M6O.js";
230
230
  import {
231
231
  ModelManager,
232
232
  buildModelProfileKey,
233
233
  getModelManager,
234
234
  isDefaultSlowAndCapableModel
235
- } from "./chunk-TKU3UJXS.js";
235
+ } from "./chunk-AZF3LTDE.js";
236
236
  import {
237
237
  getCodeStyle,
238
238
  getContext,
@@ -240,16 +240,16 @@ import {
240
240
  getIsGit,
241
241
  getProjectDocs,
242
242
  getProjectStructureStatisticsBlock
243
- } from "./chunk-276WD5RN.js";
243
+ } from "./chunk-RETS7G2B.js";
244
244
  import {
245
245
  getRipgrepPath,
246
246
  getRipgrepPolicyMode,
247
247
  resolveRipgrepPolicy,
248
248
  ripGrep
249
- } from "./chunk-RDDHG7KT.js";
249
+ } from "./chunk-HSOB4XJ2.js";
250
250
  import {
251
251
  getTheme
252
- } from "./chunk-TGGCRPZR.js";
252
+ } from "./chunk-SZS6SEDB.js";
253
253
  import {
254
254
  DEFAULT_GLOBAL_CONFIG,
255
255
  enableConfigs,
@@ -262,16 +262,16 @@ import {
262
262
  saveGlobalConfig,
263
263
  setAllPointersToModel,
264
264
  setModelPointer
265
- } from "./chunk-FTPQJIPL.js";
265
+ } from "./chunk-KQBUAEA5.js";
266
266
  import {
267
267
  AbortError
268
- } from "./chunk-RQVLBMP7.js";
268
+ } from "./chunk-PDH2QHLY.js";
269
269
  import {
270
270
  debug,
271
271
  getCurrentRequest,
272
272
  logUserFriendly,
273
273
  markPhase
274
- } from "./chunk-PGRCNKEQ.js";
274
+ } from "./chunk-O6CVVWZV.js";
275
275
  import {
276
276
  ASCII_LOGO,
277
277
  BunShell,
@@ -315,13 +315,13 @@ import {
315
315
  setCwd,
316
316
  shouldApplyToolOutputTruncation,
317
317
  truncateToolOutput
318
- } from "./chunk-LG4DZXZE.js";
318
+ } from "./chunk-KPZ4UMNV.js";
319
319
  import {
320
320
  MACRO
321
- } from "./chunk-X6MCOKYP.js";
321
+ } from "./chunk-NQJAXQZX.js";
322
322
  import {
323
323
  __export
324
- } from "./chunk-I3J4JYES.js";
324
+ } from "./chunk-OYT6EI36.js";
325
325
 
326
326
  // src/tools/system/BashTool/BashTool.tsx
327
327
  import { statSync as statSync16 } from "fs";
@@ -499,7 +499,7 @@ var getCommandSubcommandPrefix = memoize(
499
499
  var getCommandPrefix = memoize(
500
500
  async (command4, abortSignal) => {
501
501
  const { systemPrompt, userPrompt } = buildBashCommandPrefixDetectionPrompt(command4);
502
- const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryQuick: queryQuick2 } = await import("./llm-MRDYTVAB.js");
502
+ const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryQuick: queryQuick2 } = await import("./llm-CVILTZMI.js");
503
503
  const response = await queryQuick2({
504
504
  systemPrompt,
505
505
  userPrompt,
@@ -4301,7 +4301,7 @@ function formatParseError(error) {
4301
4301
  return error instanceof Error ? error.message : String(error);
4302
4302
  }
4303
4303
  async function defaultGateQuery(args) {
4304
- const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryLLM: queryLLM2 } = await import("./llm-MRDYTVAB.js");
4304
+ const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryLLM: queryLLM2 } = await import("./llm-CVILTZMI.js");
4305
4305
  const queryLLMFn = args.queryLLMOverride ?? queryLLM2;
4306
4306
  const messages = [
4307
4307
  {
@@ -6793,14 +6793,14 @@ var FileEditTool = {
6793
6793
  }
6794
6794
  let editOperations = [];
6795
6795
  if (edits) {
6796
- const { parseBlockEdits: parseBlockEdits2 } = await import("./blockParser-QPLEX5NJ.js");
6796
+ const { parseBlockEdits: parseBlockEdits2 } = await import("./blockParser-RZPICWAA.js");
6797
6797
  editOperations = parseBlockEdits2(edits);
6798
6798
  }
6799
6799
  let currentFileContent = fileExistsBun(fullFilePath) ? normalizeLineEndings(await readFileBun(fullFilePath) ?? "") : "";
6800
6800
  const originalFileContent = currentFileContent;
6801
6801
  let totalPatch = [];
6802
- const { SmartEdit } = await import("./smart-edit-AWHJDSU6.js");
6803
- const { findLspAnchor } = await import("./lspAnchor-XGTUMZDM.js");
6802
+ const { SmartEdit } = await import("./smart-edit-EQBEMPKQ.js");
6803
+ const { findLspAnchor } = await import("./lspAnchor-LUE27QI2.js");
6804
6804
  for (const op of editOperations) {
6805
6805
  const normalizedSearch = normalizeLineEndings(op.search);
6806
6806
  const normalizedReplace = normalizeLineEndings(op.replace);
@@ -12408,7 +12408,7 @@ async function createAndStoreApiKey(accessToken) {
12408
12408
  }
12409
12409
  saveGlobalConfig(config2);
12410
12410
  try {
12411
- const { resetAnthropicClient } = await import("./llm-MRDYTVAB.js");
12411
+ const { resetAnthropicClient } = await import("./llm-CVILTZMI.js");
12412
12412
  resetAnthropicClient();
12413
12413
  } catch {
12414
12414
  }
@@ -16832,7 +16832,7 @@ async function refreshPluginRuntimeFromInstalls() {
16832
16832
  const existingRoots = getSessionPlugins().map((p) => p.rootDir);
16833
16833
  const dirs = Array.from(/* @__PURE__ */ new Set([...existingRoots, ...installedRoots]));
16834
16834
  if (dirs.length === 0) return [];
16835
- const { configureSessionPlugins } = await import("./pluginRuntime-TDH3JKLN.js");
16835
+ const { configureSessionPlugins } = await import("./pluginRuntime-IWKORZEI.js");
16836
16836
  const { errors } = await configureSessionPlugins({ pluginDirs: dirs });
16837
16837
  return errors;
16838
16838
  }
@@ -17507,7 +17507,7 @@ async function call(onDone, context) {
17507
17507
  ModelConfig,
17508
17508
  {
17509
17509
  onClose: () => {
17510
- import("./model-ECABFXED.js").then(({ reloadModelManager: reloadModelManager2 }) => {
17510
+ import("./model-3GE72U3P.js").then(({ reloadModelManager: reloadModelManager2 }) => {
17511
17511
  reloadModelManager2();
17512
17512
  triggerModelConfigChange();
17513
17513
  onDone();
@@ -18276,7 +18276,7 @@ var rename = {
18276
18276
  var rename_default = rename;
18277
18277
 
18278
18278
  // src/server/index.ts
18279
- import { Hono as Hono6 } from "hono";
18279
+ import { Hono as Hono10 } from "hono";
18280
18280
  import { cors } from "hono/cors";
18281
18281
  import { logger } from "hono/logger";
18282
18282
  import { streamSSE as streamSSE2 } from "hono/streaming";
@@ -26997,7 +26997,7 @@ async function analyzeOutputWithLsp(output, exitCode) {
26997
26997
  if (exitCode !== 0 || errorCount > 0 || warningCount > 0) {
26998
26998
  try {
26999
26999
  const { isAbsolute: isAbsolute11, resolve: resolve16 } = await import("path");
27000
- const { getSessionRoot: getSessionRoot2 } = await import("./state-GMP5BAO3.js");
27000
+ const { getSessionRoot: getSessionRoot2 } = await import("./state-GWKESQ7O.js");
27001
27001
  const lines = output.split("\n");
27002
27002
  const uniqueFiles = /* @__PURE__ */ new Set();
27003
27003
  const lspSuggestions = [];
@@ -27399,7 +27399,7 @@ var DeleteTool = {
27399
27399
  }
27400
27400
  if (!force) {
27401
27401
  try {
27402
- const { LspFacade: LspFacade2 } = await import("./lsp-2TM75CW4.js");
27402
+ const { LspFacade: LspFacade2 } = await import("./lsp-M5NJ7YC7.js");
27403
27403
  const referenceDetail = await LspFacade2.checkFileReferences(fullPath);
27404
27404
  if (referenceDetail) {
27405
27405
  failedItems.push(
@@ -31033,6 +31033,20 @@ var getReadOnlyTools = memoize4(async () => {
31033
31033
  return tools.filter((_, index) => isEnabled5[index]);
31034
31034
  });
31035
31035
 
31036
+ // src/server/bus/eventIdGenerator.ts
31037
+ var EventIdGenerator = class {
31038
+ sequenceMap = /* @__PURE__ */ new Map();
31039
+ nextId(sessionId) {
31040
+ const next = (this.sequenceMap.get(sessionId) ?? 0) + 1;
31041
+ this.sequenceMap.set(sessionId, next);
31042
+ return `sess-${sessionId}-seq-${String(next).padStart(6, "0")}`;
31043
+ }
31044
+ };
31045
+ function parseSessionIdFromEventId(eventId) {
31046
+ const match = eventId.match(/^sess-(.+)-seq-(\d+)$/);
31047
+ return match?.[1] ?? null;
31048
+ }
31049
+
31036
31050
  // src/server/bus/index.ts
31037
31051
  var BusEvent;
31038
31052
  ((BusEvent2) => {
@@ -31053,9 +31067,12 @@ var Bus;
31053
31067
  const state = {
31054
31068
  subscriptions: /* @__PURE__ */ new Map()
31055
31069
  };
31070
+ const eventIdGenerator = new EventIdGenerator();
31056
31071
  async function publish(def, properties) {
31072
+ const sessionId = typeof properties.sessionId === "string" ? properties.sessionId : void 0;
31057
31073
  const payload = {
31058
31074
  type: def.type,
31075
+ ...sessionId ? { id: eventIdGenerator.nextId(sessionId) } : {},
31059
31076
  properties
31060
31077
  };
31061
31078
  const pending = [];
@@ -31904,6 +31921,971 @@ function createMCPRoutes() {
31904
31921
  return router;
31905
31922
  }
31906
31923
 
31924
+ // src/server/routes/providers.ts
31925
+ import * as crypto2 from "crypto";
31926
+ import { Hono as Hono6 } from "hono";
31927
+
31928
+ // src/server/modelPool/providerCatalog.ts
31929
+ function normalizeText(input) {
31930
+ return String(input ?? "").trim();
31931
+ }
31932
+ function normalizeProviderID(input) {
31933
+ return normalizeText(input).toLowerCase();
31934
+ }
31935
+ function rankSources(priority) {
31936
+ const rank = /* @__PURE__ */ new Map();
31937
+ priority.forEach((source, index) => {
31938
+ rank.set(source, index);
31939
+ });
31940
+ return rank;
31941
+ }
31942
+ function composeProviderCatalog(sources, priority = ["env", "auth", "plugin", "config"]) {
31943
+ const ranks = rankSources(priority);
31944
+ const fallbackRank = priority.length + 1;
31945
+ const sortedSources = [...sources].sort((a, b) => {
31946
+ const aRank = ranks.get(a.sourceType) ?? fallbackRank;
31947
+ const bRank = ranks.get(b.sourceType) ?? fallbackRank;
31948
+ return aRank - bRank;
31949
+ });
31950
+ const providerMap = /* @__PURE__ */ new Map();
31951
+ for (const source of sortedSources) {
31952
+ for (const provider of source.providers) {
31953
+ const providerID = normalizeProviderID(provider?.providerID);
31954
+ if (!providerID) continue;
31955
+ const displayName = normalizeText(provider?.displayName) || providerID;
31956
+ const connected2 = provider?.connected === true;
31957
+ const existing = providerMap.get(providerID);
31958
+ if (!existing) {
31959
+ providerMap.set(providerID, {
31960
+ providerID,
31961
+ displayName,
31962
+ connected: connected2
31963
+ });
31964
+ continue;
31965
+ }
31966
+ if (!existing.connected && connected2) {
31967
+ existing.connected = true;
31968
+ }
31969
+ }
31970
+ }
31971
+ const all = [...providerMap.values()].sort(
31972
+ (a, b) => a.providerID.localeCompare(b.providerID)
31973
+ );
31974
+ const connected = all.filter((item) => item.connected).map((item) => item.providerID);
31975
+ let defaultModel = null;
31976
+ for (const source of sortedSources) {
31977
+ if (source.defaultModel) {
31978
+ defaultModel = source.defaultModel;
31979
+ break;
31980
+ }
31981
+ }
31982
+ return {
31983
+ all,
31984
+ default: defaultModel,
31985
+ connected
31986
+ };
31987
+ }
31988
+ function buildProviderSourceFromProfiles(sourceType, profiles, defaultModel) {
31989
+ const providerMap = /* @__PURE__ */ new Map();
31990
+ for (const profile of profiles) {
31991
+ if (profile?.isActive !== true) continue;
31992
+ const providerID = normalizeProviderID(profile?.provider);
31993
+ if (!providerID) continue;
31994
+ const existing = providerMap.get(providerID);
31995
+ const connected = normalizeText(profile?.apiKey).length > 0;
31996
+ const displayName = normalizeText(profile?.provider) || providerID;
31997
+ if (!existing) {
31998
+ providerMap.set(providerID, {
31999
+ providerID,
32000
+ displayName,
32001
+ connected
32002
+ });
32003
+ continue;
32004
+ }
32005
+ if (!existing.connected && connected) {
32006
+ existing.connected = true;
32007
+ }
32008
+ }
32009
+ return {
32010
+ sourceType,
32011
+ providers: [...providerMap.values()].sort(
32012
+ (a, b) => a.providerID.localeCompare(b.providerID)
32013
+ ),
32014
+ defaultModel
32015
+ };
32016
+ }
32017
+
32018
+ // src/server/modelPool/authKernel.ts
32019
+ function parseTtlMs(input) {
32020
+ const parsed = Number(input);
32021
+ if (!Number.isFinite(parsed) || parsed <= 0) {
32022
+ return 5 * 60 * 1e3;
32023
+ }
32024
+ return Math.floor(parsed);
32025
+ }
32026
+ var AuthKernel = class {
32027
+ ttlMs;
32028
+ pendingByProvider = /* @__PURE__ */ new Map();
32029
+ consumedStatesByProvider = /* @__PURE__ */ new Map();
32030
+ constructor(ttlMs = parseTtlMs(process.env.PYB_OAUTH_PENDING_TTL_MS)) {
32031
+ this.ttlMs = ttlMs;
32032
+ }
32033
+ setOAuthPendingTtlMs(ttlMs) {
32034
+ if (!Number.isFinite(ttlMs) || ttlMs <= 0) {
32035
+ throw new Error("ttlMs must be a positive number");
32036
+ }
32037
+ this.ttlMs = Math.floor(ttlMs);
32038
+ }
32039
+ beginOAuthSession(providerID, state, codeVerifier) {
32040
+ const now = Date.now();
32041
+ this.pruneConsumedStates(providerID, now);
32042
+ this.pendingByProvider.set(providerID, {
32043
+ state,
32044
+ codeVerifier,
32045
+ createdAt: now
32046
+ });
32047
+ }
32048
+ consumeOAuthSession(providerID, state) {
32049
+ const now = Date.now();
32050
+ this.pruneConsumedStates(providerID, now);
32051
+ const consumed = this.consumedStatesByProvider.get(providerID);
32052
+ if (consumed?.has(state)) {
32053
+ return { success: false, errorCode: "OAUTH_STATE_REPLAYED" };
32054
+ }
32055
+ const pending = this.pendingByProvider.get(providerID);
32056
+ if (!pending || pending.state !== state) {
32057
+ return { success: false, errorCode: "OAUTH_STATE_MISMATCH" };
32058
+ }
32059
+ if (now - pending.createdAt > this.ttlMs) {
32060
+ this.pendingByProvider.delete(providerID);
32061
+ return { success: false, errorCode: "OAUTH_STATE_EXPIRED" };
32062
+ }
32063
+ this.pendingByProvider.delete(providerID);
32064
+ let nextConsumed = this.consumedStatesByProvider.get(providerID);
32065
+ if (!nextConsumed) {
32066
+ nextConsumed = /* @__PURE__ */ new Map();
32067
+ this.consumedStatesByProvider.set(providerID, nextConsumed);
32068
+ }
32069
+ nextConsumed.set(state, now);
32070
+ return {
32071
+ success: true,
32072
+ codeVerifier: pending.codeVerifier
32073
+ };
32074
+ }
32075
+ pruneConsumedStates(providerID, now) {
32076
+ const consumed = this.consumedStatesByProvider.get(providerID);
32077
+ if (!consumed) return;
32078
+ for (const [state, consumedAt] of consumed.entries()) {
32079
+ if (now - consumedAt > this.ttlMs) {
32080
+ consumed.delete(state);
32081
+ }
32082
+ }
32083
+ if (consumed.size === 0) {
32084
+ this.consumedStatesByProvider.delete(providerID);
32085
+ }
32086
+ }
32087
+ };
32088
+
32089
+ // src/server/routes/providers.ts
32090
+ var authKernel = new AuthKernel();
32091
+ function normalizeText2(input) {
32092
+ return String(input ?? "").trim();
32093
+ }
32094
+ function normalizeProviderID2(input) {
32095
+ return normalizeText2(input).toLowerCase();
32096
+ }
32097
+ function getActiveProfiles(config2) {
32098
+ const profiles = Array.isArray(config2?.modelProfiles) ? config2.modelProfiles : [];
32099
+ return profiles.filter((profile) => profile?.isActive === true);
32100
+ }
32101
+ function hasProvider(config2, providerID) {
32102
+ const profiles = Array.isArray(config2?.modelProfiles) ? config2.modelProfiles : [];
32103
+ return profiles.some((profile) => normalizeProviderID2(profile?.provider) === providerID);
32104
+ }
32105
+ function setProviderApiKey(providerID, apiKey) {
32106
+ const config2 = getGlobalConfig();
32107
+ const profiles = Array.isArray(config2?.modelProfiles) ? config2.modelProfiles : [];
32108
+ let updated = false;
32109
+ const nextProfiles = profiles.map((profile) => {
32110
+ if (normalizeProviderID2(profile?.provider) !== providerID) return profile;
32111
+ updated = true;
32112
+ return {
32113
+ ...profile,
32114
+ apiKey
32115
+ };
32116
+ });
32117
+ if (!updated) return false;
32118
+ saveGlobalConfig({
32119
+ ...config2,
32120
+ modelProfiles: nextProfiles
32121
+ });
32122
+ return true;
32123
+ }
32124
+ function setProviderAuthValue(providerIDRaw, apiKeyRaw) {
32125
+ const providerID = normalizeProviderID2(providerIDRaw);
32126
+ const apiKey = normalizeText2(apiKeyRaw);
32127
+ if (!providerID) {
32128
+ return {
32129
+ success: false,
32130
+ code: "INVALID_PROVIDER_ID",
32131
+ message: "providerID is required"
32132
+ };
32133
+ }
32134
+ if (!apiKey) {
32135
+ return {
32136
+ success: false,
32137
+ code: "INVALID_AUTH_INPUT",
32138
+ message: "apiKey is required"
32139
+ };
32140
+ }
32141
+ const config2 = getGlobalConfig();
32142
+ if (!hasProvider(config2, providerID)) {
32143
+ return {
32144
+ success: false,
32145
+ code: "PROVIDER_NOT_FOUND",
32146
+ message: `Provider '${providerID}' not found`
32147
+ };
32148
+ }
32149
+ const updated = setProviderApiKey(providerID, apiKey);
32150
+ if (!updated) {
32151
+ return {
32152
+ success: false,
32153
+ code: "PROVIDER_AUTH_UPDATE_FAILED",
32154
+ message: "Failed to update provider auth"
32155
+ };
32156
+ }
32157
+ return { success: true };
32158
+ }
32159
+ function removeProviderAuthValue(providerIDRaw) {
32160
+ const providerID = normalizeProviderID2(providerIDRaw);
32161
+ if (!providerID) {
32162
+ return {
32163
+ success: false,
32164
+ code: "INVALID_PROVIDER_ID",
32165
+ message: "providerID is required"
32166
+ };
32167
+ }
32168
+ const config2 = getGlobalConfig();
32169
+ if (!hasProvider(config2, providerID)) {
32170
+ return {
32171
+ success: false,
32172
+ code: "PROVIDER_NOT_FOUND",
32173
+ message: `Provider '${providerID}' not found`
32174
+ };
32175
+ }
32176
+ const updated = setProviderApiKey(providerID, "");
32177
+ if (!updated) {
32178
+ return {
32179
+ success: false,
32180
+ code: "PROVIDER_AUTH_REMOVE_FAILED",
32181
+ message: "Failed to remove provider auth"
32182
+ };
32183
+ }
32184
+ return { success: true };
32185
+ }
32186
+ function buildCodeVerifier() {
32187
+ return crypto2.randomBytes(32).toString("base64url");
32188
+ }
32189
+ function buildCodeChallenge(verifier) {
32190
+ return crypto2.createHash("sha256").update(verifier).digest("base64url");
32191
+ }
32192
+ function resolveDefaultModelRef(config2, activeProfiles) {
32193
+ const pointer = normalizeText2(config2?.modelPointers?.main);
32194
+ if (!pointer) return null;
32195
+ const normalizedPointer = pointer.toLowerCase();
32196
+ const profile = activeProfiles.find((item) => {
32197
+ const providerID = normalizeProviderID2(item?.provider);
32198
+ const modelID = normalizeText2(item?.modelName);
32199
+ const profileName = normalizeText2(item?.name);
32200
+ const providerQualifiedModel = `${providerID}:${modelID}`.toLowerCase();
32201
+ const providerQualifiedName = `${providerID}:${profileName}`.toLowerCase();
32202
+ return modelID === pointer || profileName === pointer || providerQualifiedModel === normalizedPointer || providerQualifiedName === normalizedPointer;
32203
+ });
32204
+ if (!profile) return null;
32205
+ return {
32206
+ providerID: normalizeProviderID2(profile.provider),
32207
+ modelID: normalizeText2(profile.modelName),
32208
+ displayName: normalizeText2(profile.name) || normalizeText2(profile.modelName),
32209
+ capabilities: []
32210
+ };
32211
+ }
32212
+ function createProviderListPayload(config2) {
32213
+ const activeProfiles = getActiveProfiles(config2);
32214
+ const defaultModel = resolveDefaultModelRef(config2, activeProfiles);
32215
+ const configSource = buildProviderSourceFromProfiles(
32216
+ "config",
32217
+ activeProfiles,
32218
+ defaultModel
32219
+ );
32220
+ return composeProviderCatalog([configSource], ["env", "auth", "plugin", "config"]);
32221
+ }
32222
+ function createProviderAuthMethods(providers2) {
32223
+ return providers2.map((provider) => ({
32224
+ providerID: provider.providerID,
32225
+ type: "api",
32226
+ label: "API Key",
32227
+ scopes: []
32228
+ }));
32229
+ }
32230
+ function createProvidersRoutes() {
32231
+ const router = new Hono6();
32232
+ router.get("/", (c) => {
32233
+ const config2 = getGlobalConfig();
32234
+ const data = createProviderListPayload(config2);
32235
+ return c.json({
32236
+ success: true,
32237
+ data
32238
+ });
32239
+ });
32240
+ router.get("/auth", (c) => {
32241
+ const config2 = getGlobalConfig();
32242
+ const data = createProviderListPayload(config2);
32243
+ return c.json({
32244
+ success: true,
32245
+ data: createProviderAuthMethods(data.all)
32246
+ });
32247
+ });
32248
+ router.post("/:providerID/oauth/authorize", async (c) => {
32249
+ const providerID = normalizeProviderID2(c.req.param("providerID"));
32250
+ const config2 = getGlobalConfig();
32251
+ if (!hasProvider(config2, providerID)) {
32252
+ return c.json(
32253
+ {
32254
+ success: false,
32255
+ error: {
32256
+ code: "PROVIDER_NOT_FOUND",
32257
+ message: `Provider '${providerID}' not found`,
32258
+ recoverable: true
32259
+ }
32260
+ },
32261
+ 404
32262
+ );
32263
+ }
32264
+ const body = await c.req.json().catch(() => ({}));
32265
+ const redirectUri = normalizeText2(body?.redirectUri) || `http://localhost:4096/v1/providers/${providerID}/oauth/callback`;
32266
+ const scope = normalizeText2(body?.scope) || "default";
32267
+ const state = crypto2.randomBytes(24).toString("base64url");
32268
+ const codeVerifier = buildCodeVerifier();
32269
+ const codeChallenge = buildCodeChallenge(codeVerifier);
32270
+ authKernel.beginOAuthSession(providerID, state, codeVerifier);
32271
+ const authorizationUrl = new URL(
32272
+ `https://auth.${providerID || "provider"}.example.com/oauth/authorize`
32273
+ );
32274
+ authorizationUrl.searchParams.set("response_type", "code");
32275
+ authorizationUrl.searchParams.set("client_id", "pyb-cli");
32276
+ authorizationUrl.searchParams.set("redirect_uri", redirectUri);
32277
+ authorizationUrl.searchParams.set("scope", scope);
32278
+ authorizationUrl.searchParams.set("state", state);
32279
+ authorizationUrl.searchParams.set("code_challenge", codeChallenge);
32280
+ authorizationUrl.searchParams.set("code_challenge_method", "S256");
32281
+ return c.json({
32282
+ success: true,
32283
+ data: {
32284
+ providerID,
32285
+ authorizationUrl: authorizationUrl.toString(),
32286
+ state,
32287
+ codeChallengeMethod: "S256"
32288
+ }
32289
+ });
32290
+ });
32291
+ router.post("/:providerID/oauth/callback", async (c) => {
32292
+ const providerID = normalizeProviderID2(c.req.param("providerID"));
32293
+ const config2 = getGlobalConfig();
32294
+ if (!hasProvider(config2, providerID)) {
32295
+ return c.json(
32296
+ {
32297
+ success: false,
32298
+ error: {
32299
+ code: "PROVIDER_NOT_FOUND",
32300
+ message: `Provider '${providerID}' not found`,
32301
+ recoverable: true
32302
+ }
32303
+ },
32304
+ 404
32305
+ );
32306
+ }
32307
+ const body = await c.req.json().catch(() => ({}));
32308
+ const state = normalizeText2(body?.state);
32309
+ const code = normalizeText2(body?.code);
32310
+ if (!state || !code) {
32311
+ return c.json(
32312
+ {
32313
+ success: false,
32314
+ error: {
32315
+ code: "INVALID_OAUTH_CALLBACK",
32316
+ message: "code and state are required",
32317
+ recoverable: true
32318
+ }
32319
+ },
32320
+ 400
32321
+ );
32322
+ }
32323
+ const consumed = authKernel.consumeOAuthSession(providerID, state);
32324
+ if (consumed.success === false) {
32325
+ const errorCode = consumed.errorCode;
32326
+ const errorMap = {
32327
+ OAUTH_STATE_MISMATCH: "Invalid oauth state",
32328
+ OAUTH_STATE_EXPIRED: "OAuth state expired",
32329
+ OAUTH_STATE_REPLAYED: "OAuth state already consumed"
32330
+ };
32331
+ return c.json(
32332
+ {
32333
+ success: false,
32334
+ error: {
32335
+ code: errorCode,
32336
+ message: errorMap[errorCode],
32337
+ recoverable: true
32338
+ }
32339
+ },
32340
+ 400
32341
+ );
32342
+ }
32343
+ const synthesizedApiKey = crypto2.createHash("sha256").update(`${providerID}:${code}:${consumed.codeVerifier}:${state}`).digest("hex").slice(0, 40);
32344
+ const result = setProviderAuthValue(providerID, `oauth_${synthesizedApiKey}`);
32345
+ if (!result.success) {
32346
+ return c.json(
32347
+ {
32348
+ success: false,
32349
+ error: {
32350
+ code: result.code ?? "PROVIDER_AUTH_UPDATE_FAILED",
32351
+ message: result.message ?? "Failed to update provider auth",
32352
+ recoverable: true
32353
+ }
32354
+ },
32355
+ 400
32356
+ );
32357
+ }
32358
+ return c.json({
32359
+ success: true,
32360
+ data: {
32361
+ providerID,
32362
+ connected: true,
32363
+ method: "oauth"
32364
+ }
32365
+ });
32366
+ });
32367
+ return router;
32368
+ }
32369
+
32370
+ // src/server/routes/auth.ts
32371
+ import { Hono as Hono7 } from "hono";
32372
+ function isNotFound(code) {
32373
+ return code === "PROVIDER_NOT_FOUND";
32374
+ }
32375
+ function createAuthRoutes() {
32376
+ const router = new Hono7();
32377
+ router.put("/:providerID", async (c) => {
32378
+ const providerID = c.req.param("providerID");
32379
+ const body = await c.req.json().catch(() => ({}));
32380
+ const result = setProviderAuthValue(providerID, body?.apiKey);
32381
+ if (!result.success) {
32382
+ return c.json(
32383
+ {
32384
+ success: false,
32385
+ error: {
32386
+ code: result.code ?? "PROVIDER_AUTH_UPDATE_FAILED",
32387
+ message: result.message ?? "Failed to update provider auth",
32388
+ recoverable: true
32389
+ }
32390
+ },
32391
+ isNotFound(result.code) ? 404 : 400
32392
+ );
32393
+ }
32394
+ return c.json({
32395
+ success: true,
32396
+ data: {
32397
+ providerID: providerID.toLowerCase(),
32398
+ connected: true,
32399
+ method: "api"
32400
+ }
32401
+ });
32402
+ });
32403
+ router.delete("/:providerID", (c) => {
32404
+ const providerID = c.req.param("providerID");
32405
+ const result = removeProviderAuthValue(providerID);
32406
+ if (!result.success) {
32407
+ return c.json(
32408
+ {
32409
+ success: false,
32410
+ error: {
32411
+ code: result.code ?? "PROVIDER_AUTH_REMOVE_FAILED",
32412
+ message: result.message ?? "Failed to remove provider auth",
32413
+ recoverable: true
32414
+ }
32415
+ },
32416
+ isNotFound(result.code) ? 404 : 400
32417
+ );
32418
+ }
32419
+ return c.json({
32420
+ success: true,
32421
+ data: {
32422
+ providerID: providerID.toLowerCase(),
32423
+ removed: true
32424
+ }
32425
+ });
32426
+ });
32427
+ return router;
32428
+ }
32429
+
32430
+ // src/server/routes/model.ts
32431
+ import { Hono as Hono8 } from "hono";
32432
+
32433
+ // src/server/modelPool/modelCatalog.ts
32434
+ function normalizeText3(input) {
32435
+ return String(input ?? "").trim();
32436
+ }
32437
+ function normalizeProviderID3(input) {
32438
+ return normalizeText3(input).toLowerCase();
32439
+ }
32440
+ function isActiveProfile(profile) {
32441
+ return profile?.isActive === true;
32442
+ }
32443
+ function resolveModelSelection(profiles, providerID, modelID) {
32444
+ const providerProfiles = profiles.filter(
32445
+ (profile) => normalizeProviderID3(profile?.provider) === providerID
32446
+ );
32447
+ if (providerProfiles.length === 0) {
32448
+ return {
32449
+ success: false,
32450
+ errorCode: "PROVIDER_NOT_FOUND",
32451
+ message: `Provider '${providerID}' not found`,
32452
+ status: 404
32453
+ };
32454
+ }
32455
+ const matchingProfiles = providerProfiles.filter(
32456
+ (profile) => normalizeText3(profile?.modelName) === modelID
32457
+ );
32458
+ if (matchingProfiles.length === 0) {
32459
+ return {
32460
+ success: false,
32461
+ errorCode: "MODEL_NOT_FOUND",
32462
+ message: `Model '${modelID}' not found under provider '${providerID}'`,
32463
+ status: 404
32464
+ };
32465
+ }
32466
+ const enabledProfile = matchingProfiles.find(isActiveProfile);
32467
+ if (!enabledProfile) {
32468
+ return {
32469
+ success: false,
32470
+ errorCode: "MODEL_DISABLED",
32471
+ message: `Model '${modelID}' is disabled under provider '${providerID}'`,
32472
+ status: 409
32473
+ };
32474
+ }
32475
+ return {
32476
+ success: true,
32477
+ current: {
32478
+ providerID,
32479
+ modelID,
32480
+ displayName: normalizeText3(enabledProfile?.name) || modelID,
32481
+ capabilities: []
32482
+ }
32483
+ };
32484
+ }
32485
+
32486
+ // src/server/modelPool/policyEngine.ts
32487
+ function normalizeText4(input) {
32488
+ return String(input ?? "").trim();
32489
+ }
32490
+ function normalizeProviderID4(input) {
32491
+ return normalizeText4(input).toLowerCase();
32492
+ }
32493
+ function readBlockedModelRules() {
32494
+ const raw = process.env.PYB_POLICY_BLOCKED_MODELS ?? "";
32495
+ const entries = raw.split(",").map((item) => item.trim().toLowerCase()).filter(Boolean);
32496
+ return new Set(entries);
32497
+ }
32498
+ function evaluateDefaultModelPolicy(input) {
32499
+ const providerID = normalizeProviderID4(input.providerID);
32500
+ const modelID = normalizeText4(input.modelID).toLowerCase();
32501
+ const blocked = readBlockedModelRules();
32502
+ const exactKey = `${providerID}:${modelID}`;
32503
+ const wildcardProviderKey = `${providerID}:*`;
32504
+ const wildcardGlobalKey = `*:${modelID}`;
32505
+ const fullWildcardKey = "*:*";
32506
+ if (blocked.has(exactKey) || blocked.has(wildcardProviderKey) || blocked.has(wildcardGlobalKey) || blocked.has(fullWildcardKey)) {
32507
+ return {
32508
+ allowed: false,
32509
+ errorCode: "POLICY_REJECTED",
32510
+ message: `Policy rejected model '${modelID}' under provider '${providerID}'`,
32511
+ status: 403
32512
+ };
32513
+ }
32514
+ return { allowed: true };
32515
+ }
32516
+
32517
+ // src/server/routes/model.ts
32518
+ function normalizeText5(input) {
32519
+ return String(input ?? "").trim();
32520
+ }
32521
+ function normalizeProviderID5(input) {
32522
+ return normalizeText5(input).toLowerCase();
32523
+ }
32524
+ function isSupportedScope(input) {
32525
+ return input === "global" || input === "workspace";
32526
+ }
32527
+ function resolveScope(input) {
32528
+ const scope = normalizeText5(input).toLowerCase();
32529
+ if (!scope) return "global";
32530
+ if (isSupportedScope(scope)) return scope;
32531
+ throw new Error("INVALID_SCOPE");
32532
+ }
32533
+ function createModelRoutes() {
32534
+ const router = new Hono8();
32535
+ router.put("/default", async (c) => {
32536
+ const body = await c.req.json().catch(() => ({}));
32537
+ const providerID = normalizeProviderID5(body?.providerID);
32538
+ const modelID = normalizeText5(body?.modelID);
32539
+ if (!providerID || !modelID) {
32540
+ return c.json(
32541
+ {
32542
+ success: false,
32543
+ error: {
32544
+ code: "INVALID_MODEL_REF",
32545
+ message: "providerID and modelID are required",
32546
+ recoverable: true
32547
+ }
32548
+ },
32549
+ 400
32550
+ );
32551
+ }
32552
+ let requestedScope;
32553
+ try {
32554
+ requestedScope = resolveScope(body?.scope);
32555
+ } catch {
32556
+ return c.json(
32557
+ {
32558
+ success: false,
32559
+ error: {
32560
+ code: "INVALID_SCOPE",
32561
+ message: "scope must be global or workspace",
32562
+ recoverable: true
32563
+ }
32564
+ },
32565
+ 400
32566
+ );
32567
+ }
32568
+ const globalConfig = getGlobalConfig();
32569
+ const profiles = Array.isArray(globalConfig.modelProfiles) ? globalConfig.modelProfiles : [];
32570
+ const selection = resolveModelSelection(profiles, providerID, modelID);
32571
+ if (selection.success === false) {
32572
+ return c.json(
32573
+ {
32574
+ success: false,
32575
+ error: {
32576
+ code: selection.errorCode,
32577
+ message: selection.message,
32578
+ recoverable: true
32579
+ }
32580
+ },
32581
+ selection.status
32582
+ );
32583
+ }
32584
+ const policy = evaluateDefaultModelPolicy({
32585
+ providerID,
32586
+ modelID,
32587
+ scope: requestedScope
32588
+ });
32589
+ if (policy.allowed === false) {
32590
+ return c.json(
32591
+ {
32592
+ success: false,
32593
+ error: {
32594
+ code: policy.errorCode,
32595
+ message: policy.message,
32596
+ recoverable: true
32597
+ }
32598
+ },
32599
+ policy.status
32600
+ );
32601
+ }
32602
+ const appliedScope = "global";
32603
+ const fallbackReason = requestedScope === "workspace" ? "workspace_scope_not_supported" : null;
32604
+ const currentPointers = globalConfig.modelPointers ?? {};
32605
+ const nextPointers = {
32606
+ ...currentPointers,
32607
+ main: modelID,
32608
+ task: currentPointers.task ?? modelID,
32609
+ compact: currentPointers.compact ?? modelID,
32610
+ quick: currentPointers.quick ?? modelID
32611
+ };
32612
+ saveGlobalConfig({
32613
+ ...globalConfig,
32614
+ modelPointers: nextPointers
32615
+ });
32616
+ return c.json({
32617
+ success: true,
32618
+ data: {
32619
+ scope: appliedScope,
32620
+ requestedScope,
32621
+ applied: true,
32622
+ fallbackReason,
32623
+ current: selection.current
32624
+ }
32625
+ });
32626
+ });
32627
+ return router;
32628
+ }
32629
+
32630
+ // src/server/routes/modelPools.ts
32631
+ import { Hono as Hono9 } from "hono";
32632
+
32633
+ // src/server/modelPool/sourceResolver.ts
32634
+ function normalize2(input) {
32635
+ return input.trim();
32636
+ }
32637
+ function normalizeID(input) {
32638
+ return normalize2(input).toLowerCase();
32639
+ }
32640
+ function parseGitHubRepo(spec) {
32641
+ const ssh = spec.match(/^git@github\.com:([^/]+\/[^/]+?)(?:\.git)?$/i);
32642
+ if (ssh?.[1]) return normalizeID(ssh[1]);
32643
+ const https = spec.match(/^https?:\/\/github\.com\/([^/]+\/[^/]+?)(?:\.git)?(?:#.*)?$/i);
32644
+ if (https?.[1]) return normalizeID(https[1]);
32645
+ return null;
32646
+ }
32647
+ function extractLocalPluginID(spec) {
32648
+ try {
32649
+ const url2 = new URL(spec);
32650
+ const path6 = decodeURIComponent(url2.pathname);
32651
+ const segments = path6.split("/").filter(Boolean);
32652
+ const tail = segments[segments.length - 1] ?? "local-plugin";
32653
+ return normalizeID(tail.replace(/\.(tgz|tar\.gz|zip)$/i, ""));
32654
+ } catch {
32655
+ return "local-plugin";
32656
+ }
32657
+ }
32658
+ function parseMarketplaceSpec(spec) {
32659
+ const trimmed = normalize2(spec);
32660
+ const parts = trimmed.split("@");
32661
+ if (parts.length !== 2) return null;
32662
+ if (trimmed.startsWith("@")) return null;
32663
+ const plugin2 = normalize2(parts[0] ?? "");
32664
+ const marketplace = normalize2(parts[1] ?? "");
32665
+ if (!plugin2 || !marketplace) return null;
32666
+ if (marketplace.includes("/")) return null;
32667
+ return {
32668
+ pluginID: normalizeID(plugin2),
32669
+ marketplace: normalizeID(marketplace)
32670
+ };
32671
+ }
32672
+ function stripNpmVersion(spec) {
32673
+ const trimmed = normalize2(spec);
32674
+ if (!trimmed) throw new Error("pluginSpec is required");
32675
+ if (trimmed.startsWith("@")) {
32676
+ const slash = trimmed.indexOf("/");
32677
+ const lastAt = trimmed.lastIndexOf("@");
32678
+ if (slash > 0 && lastAt > slash) {
32679
+ return normalizeID(trimmed.slice(0, lastAt));
32680
+ }
32681
+ return normalizeID(trimmed);
32682
+ }
32683
+ const at = trimmed.lastIndexOf("@");
32684
+ if (at > 0) {
32685
+ return normalizeID(trimmed.slice(0, at));
32686
+ }
32687
+ return normalizeID(trimmed);
32688
+ }
32689
+ function resolvePluginSourceRecord(pluginSpecRaw) {
32690
+ const pluginSpec = normalize2(pluginSpecRaw);
32691
+ if (!pluginSpec) throw new Error("pluginSpec is required");
32692
+ if (pluginSpec.startsWith("file://")) {
32693
+ const pluginID2 = extractLocalPluginID(pluginSpec);
32694
+ return {
32695
+ pluginSpec,
32696
+ pluginID: pluginID2,
32697
+ sourceID: `local:${pluginSpec}`,
32698
+ sourceType: "local"
32699
+ };
32700
+ }
32701
+ const githubRepo = parseGitHubRepo(pluginSpec);
32702
+ if (githubRepo) {
32703
+ return {
32704
+ pluginSpec,
32705
+ pluginID: githubRepo,
32706
+ sourceID: `github:${githubRepo}`,
32707
+ sourceType: "github"
32708
+ };
32709
+ }
32710
+ const marketplace = parseMarketplaceSpec(pluginSpec);
32711
+ if (marketplace) {
32712
+ return {
32713
+ pluginSpec,
32714
+ pluginID: marketplace.pluginID,
32715
+ sourceID: `marketplace:${marketplace.marketplace}`,
32716
+ sourceType: "marketplace"
32717
+ };
32718
+ }
32719
+ const pluginID = stripNpmVersion(pluginSpec);
32720
+ return {
32721
+ pluginSpec,
32722
+ pluginID,
32723
+ sourceID: "npm:registry",
32724
+ sourceType: "npm"
32725
+ };
32726
+ }
32727
+ function dedupeSourceRecordsByPluginID(records, sourcePriority = ["marketplace", "github", "npm", "local"]) {
32728
+ const priority = /* @__PURE__ */ new Map();
32729
+ sourcePriority.forEach((source, index) => {
32730
+ priority.set(source, index);
32731
+ });
32732
+ const fallbackRank = sourcePriority.length + 1;
32733
+ const deduped = /* @__PURE__ */ new Map();
32734
+ for (const record of records) {
32735
+ const key = normalizeID(record.pluginID);
32736
+ const current = deduped.get(key);
32737
+ if (!current) {
32738
+ deduped.set(key, { ...record, pluginID: key });
32739
+ continue;
32740
+ }
32741
+ const currentRank = priority.get(current.sourceType) ?? fallbackRank;
32742
+ const nextRank = priority.get(record.sourceType) ?? fallbackRank;
32743
+ if (nextRank < currentRank) {
32744
+ deduped.set(key, { ...record, pluginID: key });
32745
+ }
32746
+ }
32747
+ return Array.from(deduped.values());
32748
+ }
32749
+ var ModelPoolRegistry = class {
32750
+ pools = /* @__PURE__ */ new Map();
32751
+ register(definition) {
32752
+ const modelPoolID = normalizeID(definition.modelPoolID);
32753
+ if (!modelPoolID) throw new Error("modelPoolID is required");
32754
+ if (this.pools.has(modelPoolID)) {
32755
+ throw new Error(`model pool already exists: ${modelPoolID}`);
32756
+ }
32757
+ this.pools.set(modelPoolID, {
32758
+ definition: {
32759
+ modelPoolID,
32760
+ pluginSpecs: definition.pluginSpecs.map(normalize2).filter(Boolean),
32761
+ metadata: definition.metadata ?? {}
32762
+ },
32763
+ state: "registered"
32764
+ });
32765
+ }
32766
+ activate(modelPoolIDRaw) {
32767
+ const modelPoolID = normalizeID(modelPoolIDRaw);
32768
+ const record = this.pools.get(modelPoolID);
32769
+ if (!record) throw new Error(`model pool not found: ${modelPoolID}`);
32770
+ record.state = "active";
32771
+ }
32772
+ deactivate(modelPoolIDRaw) {
32773
+ const modelPoolID = normalizeID(modelPoolIDRaw);
32774
+ const record = this.pools.get(modelPoolID);
32775
+ if (!record) throw new Error(`model pool not found: ${modelPoolID}`);
32776
+ record.state = "inactive";
32777
+ }
32778
+ getStatus() {
32779
+ const pools = Array.from(this.pools.values()).map((record) => {
32780
+ const resolved = record.definition.pluginSpecs.map(resolvePluginSourceRecord);
32781
+ const deduped = dedupeSourceRecordsByPluginID(resolved);
32782
+ return {
32783
+ modelPoolID: record.definition.modelPoolID,
32784
+ state: record.state,
32785
+ pluginCount: deduped.length,
32786
+ sourceRecords: deduped,
32787
+ metadata: record.definition.metadata ?? {}
32788
+ };
32789
+ });
32790
+ const active2 = pools.filter((item) => item.state === "active").length;
32791
+ return {
32792
+ total: pools.length,
32793
+ active: active2,
32794
+ pools
32795
+ };
32796
+ }
32797
+ };
32798
+
32799
+ // src/server/routes/modelPools.ts
32800
+ function normalizeProviderID6(input) {
32801
+ return String(input ?? "").trim().toLowerCase();
32802
+ }
32803
+ function buildPluginSpecsFromProfiles(profiles) {
32804
+ const specs = /* @__PURE__ */ new Set();
32805
+ for (const profile of profiles) {
32806
+ if (profile?.isActive !== true) continue;
32807
+ const providerID = normalizeProviderID6(profile?.provider);
32808
+ if (!providerID) continue;
32809
+ specs.add(`${providerID}@config`);
32810
+ }
32811
+ return [...specs];
32812
+ }
32813
+ function createModelPoolRoutes() {
32814
+ const router = new Hono9();
32815
+ router.get("/status", async (c) => {
32816
+ const globalConfig = getGlobalConfig();
32817
+ const profiles = Array.isArray(globalConfig.modelProfiles) ? globalConfig.modelProfiles : [];
32818
+ const pluginSpecs = buildPluginSpecsFromProfiles(profiles);
32819
+ const registry = new ModelPoolRegistry();
32820
+ const modelPoolID = "default";
32821
+ registry.register({
32822
+ modelPoolID,
32823
+ pluginSpecs,
32824
+ metadata: {
32825
+ source: "config"
32826
+ }
32827
+ });
32828
+ registry.activate(modelPoolID);
32829
+ return c.json({
32830
+ success: true,
32831
+ data: registry.getStatus()
32832
+ });
32833
+ });
32834
+ return router;
32835
+ }
32836
+
32837
+ // src/server/events/eventBuffer.ts
32838
+ var SessionEventRingBuffer = class {
32839
+ buffers = /* @__PURE__ */ new Map();
32840
+ touchedAt = /* @__PURE__ */ new Map();
32841
+ maxSize;
32842
+ ttlMs;
32843
+ constructor(maxSize = 100, ttlMs = 15 * 60 * 1e3) {
32844
+ this.maxSize = maxSize;
32845
+ this.ttlMs = ttlMs;
32846
+ }
32847
+ push(sessionId, event) {
32848
+ this.pruneExpired(Date.now());
32849
+ const buffer = this.buffers.get(sessionId) ?? [];
32850
+ buffer.push(event);
32851
+ if (buffer.length > this.maxSize) {
32852
+ buffer.shift();
32853
+ }
32854
+ this.buffers.set(sessionId, buffer);
32855
+ this.touchedAt.set(sessionId, Date.now());
32856
+ }
32857
+ replayAfter(sessionId, lastEventId) {
32858
+ const buffer = this.buffers.get(sessionId);
32859
+ if (!buffer || buffer.length === 0) {
32860
+ return { kind: "gap", reason: "last_event_not_found" };
32861
+ }
32862
+ const index = buffer.findIndex((item) => item.id === lastEventId);
32863
+ if (index === -1) {
32864
+ return { kind: "gap", reason: "buffer_evicted" };
32865
+ }
32866
+ return { kind: "ok", events: buffer.slice(index + 1) };
32867
+ }
32868
+ clear(sessionId) {
32869
+ this.buffers.delete(sessionId);
32870
+ this.touchedAt.delete(sessionId);
32871
+ }
32872
+ getStats(sessionId) {
32873
+ const buffer = this.buffers.get(sessionId) ?? [];
32874
+ return {
32875
+ count: buffer.length,
32876
+ oldestId: buffer[0]?.id,
32877
+ newestId: buffer[buffer.length - 1]?.id
32878
+ };
32879
+ }
32880
+ pruneExpired(now) {
32881
+ for (const [sessionId, touchedAt] of this.touchedAt.entries()) {
32882
+ if (now - touchedAt > this.ttlMs) {
32883
+ this.clear(sessionId);
32884
+ }
32885
+ }
32886
+ }
32887
+ };
32888
+
31907
32889
  // src/server/version.ts
31908
32890
  import { readFileSync as readFileSync14 } from "fs";
31909
32891
  import { resolve as resolve12 } from "path";
@@ -31921,17 +32903,66 @@ function resolveServerVersion() {
31921
32903
  var SERVER_VERSION = resolveServerVersion();
31922
32904
 
31923
32905
  // src/server/index.ts
32906
+ var DEFAULT_HEARTBEAT_INTERVAL_MS = 5e3;
32907
+ var MIN_HEARTBEAT_INTERVAL_MS = 3e3;
32908
+ var MAX_HEARTBEAT_INTERVAL_MS = 5e3;
31924
32909
  function toPublicSSEEvent(event) {
31925
32910
  const sessionId = typeof event.properties.sessionId === "string" ? event.properties.sessionId : void 0;
31926
32911
  return {
31927
32912
  type: event.type,
32913
+ ...typeof event.id === "string" ? { id: event.id } : {},
31928
32914
  timestamp: Date.now(),
31929
32915
  ...sessionId ? { sessionId } : {},
31930
32916
  data: event.properties
31931
32917
  };
31932
32918
  }
32919
+ function resolveIdleTimeoutSeconds(value) {
32920
+ if (value === void 0 || value === "0") return 0;
32921
+ const ms = Number(value);
32922
+ if (!Number.isFinite(ms) || ms < 0) return 0;
32923
+ return ms >= 6e4 ? Math.floor(ms / 1e3) : 0;
32924
+ }
32925
+ function resolveHeartbeatIntervalMs(value) {
32926
+ if (value === void 0) return DEFAULT_HEARTBEAT_INTERVAL_MS;
32927
+ const ms = Number(value);
32928
+ if (!Number.isFinite(ms) || ms < MIN_HEARTBEAT_INTERVAL_MS || ms > MAX_HEARTBEAT_INTERVAL_MS) {
32929
+ return DEFAULT_HEARTBEAT_INTERVAL_MS;
32930
+ }
32931
+ return ms;
32932
+ }
32933
+ function resolveIdleTimeoutSecondsFromOptions(input) {
32934
+ const override = input.idleTimeoutMs;
32935
+ if (override !== void 0) {
32936
+ return resolveIdleTimeoutSeconds(String(override));
32937
+ }
32938
+ return resolveIdleTimeoutSeconds(input.env.PYB_SSE_IDLE_TIMEOUT_MS);
32939
+ }
32940
+ function resolveHeartbeatIntervalMsFromOptions(input) {
32941
+ const override = input.heartbeatIntervalMs;
32942
+ if (override !== void 0) {
32943
+ return resolveHeartbeatIntervalMs(String(override));
32944
+ }
32945
+ return resolveHeartbeatIntervalMs(input.env.PYB_SSE_HEARTBEAT_INTERVAL_MS);
32946
+ }
32947
+ function resolveSSEServerRuntimeConfig(env2 = process.env, options = {}) {
32948
+ return {
32949
+ idleTimeoutSeconds: resolveIdleTimeoutSecondsFromOptions({
32950
+ env: env2,
32951
+ idleTimeoutMs: options.idleTimeoutMs
32952
+ }),
32953
+ heartbeatIntervalMs: resolveHeartbeatIntervalMsFromOptions({
32954
+ env: env2,
32955
+ heartbeatIntervalMs: options.heartbeatIntervalMs
32956
+ })
32957
+ };
32958
+ }
31933
32959
  function createServer2(options = {}) {
31934
- const app = new Hono6();
32960
+ const app = new Hono10();
32961
+ const sseRuntimeConfig = resolveSSEServerRuntimeConfig(process.env, {
32962
+ heartbeatIntervalMs: options.heartbeatIntervalMs,
32963
+ idleTimeoutMs: options.idleTimeoutMs
32964
+ });
32965
+ const eventBuffer = new SessionEventRingBuffer();
31935
32966
  app.use("*", cors());
31936
32967
  app.use("*", logger());
31937
32968
  app.get("/v1/health", (c) => {
@@ -31951,9 +32982,15 @@ function createServer2(options = {}) {
31951
32982
  app.route("/v1/permissions", createPermissionRoutes());
31952
32983
  app.route("/v1/config", createConfigRoutes());
31953
32984
  app.route("/v1/mcp", createMCPRoutes());
32985
+ app.route("/v1/providers", createProvidersRoutes());
32986
+ app.route("/v1/auth", createAuthRoutes());
32987
+ app.route("/v1/models", createModelRoutes());
32988
+ app.route("/v1/model-pools", createModelPoolRoutes());
31954
32989
  app.get("/v1/events", (c) => {
31955
32990
  c.header("X-Accel-Buffering", "no");
31956
32991
  c.header("X-Content-Type-Options", "nosniff");
32992
+ const requestedLastEventId = c.req.query("lastEventId") ?? c.req.header("Last-Event-ID");
32993
+ const replaySessionId = typeof requestedLastEventId === "string" ? parseSessionIdFromEventId(requestedLastEventId) : null;
31957
32994
  return streamSSE2(c, async (stream) => {
31958
32995
  await stream.writeSSE({
31959
32996
  event: "server.connected",
@@ -31967,22 +33004,75 @@ function createServer2(options = {}) {
31967
33004
  }
31968
33005
  })
31969
33006
  });
33007
+ if (requestedLastEventId && replaySessionId) {
33008
+ const replayResult = eventBuffer.replayAfter(replaySessionId, requestedLastEventId);
33009
+ if (replayResult.kind === "ok") {
33010
+ for (const replayEvent of replayResult.events) {
33011
+ await stream.writeSSE({
33012
+ event: replayEvent.type,
33013
+ data: JSON.stringify(replayEvent.data)
33014
+ });
33015
+ }
33016
+ } else {
33017
+ await stream.writeSSE({
33018
+ event: "sse.replay_gap",
33019
+ data: JSON.stringify({
33020
+ type: "sse.replay_gap",
33021
+ timestamp: Date.now(),
33022
+ data: {
33023
+ lastEventId: requestedLastEventId,
33024
+ reason: replayResult.reason
33025
+ }
33026
+ })
33027
+ });
33028
+ }
33029
+ await stream.writeSSE({
33030
+ event: "sse.replay",
33031
+ data: JSON.stringify({
33032
+ type: "sse.replay",
33033
+ timestamp: Date.now(),
33034
+ data: {
33035
+ replayCount: replayResult.kind === "ok" ? replayResult.events.length : 0,
33036
+ replayGapCount: replayResult.kind === "gap" ? 1 : 0,
33037
+ lastEventId: requestedLastEventId,
33038
+ firstReplayId: replayResult.kind === "ok" ? replayResult.events[0]?.id ?? null : null,
33039
+ lastReplayId: replayResult.kind === "ok" ? replayResult.events[replayResult.events.length - 1]?.id ?? null : null
33040
+ }
33041
+ })
33042
+ });
33043
+ }
31970
33044
  const unsubscribe = Bus.subscribeAll(async (event) => {
33045
+ const publicEvent = toPublicSSEEvent(event);
33046
+ if (typeof publicEvent.sessionId === "string" && typeof publicEvent.id === "string") {
33047
+ eventBuffer.push(publicEvent.sessionId, {
33048
+ id: publicEvent.id,
33049
+ type: event.type,
33050
+ timestamp: publicEvent.timestamp,
33051
+ data: publicEvent
33052
+ });
33053
+ }
33054
+ if (event.type === "session.deleted" && typeof publicEvent.sessionId === "string") {
33055
+ eventBuffer.clear(publicEvent.sessionId);
33056
+ }
31971
33057
  await stream.writeSSE({
31972
33058
  event: event.type,
31973
- data: JSON.stringify(toPublicSSEEvent(event))
33059
+ data: JSON.stringify(publicEvent)
31974
33060
  });
31975
33061
  });
31976
33062
  const heartbeatInterval = setInterval(async () => {
31977
- await stream.writeSSE({
31978
- event: "server.heartbeat",
31979
- data: JSON.stringify({
31980
- type: "server.heartbeat",
31981
- timestamp: Date.now(),
31982
- data: { timestamp: Date.now() }
31983
- })
31984
- });
31985
- }, 1e4);
33063
+ try {
33064
+ await stream.writeSSE({
33065
+ event: "server.heartbeat",
33066
+ data: JSON.stringify({
33067
+ type: "server.heartbeat",
33068
+ timestamp: Date.now(),
33069
+ data: { timestamp: Date.now() }
33070
+ })
33071
+ });
33072
+ } catch (error) {
33073
+ console.error("[pyb-sse-heartbeat] write failed", error);
33074
+ }
33075
+ }, sseRuntimeConfig.heartbeatIntervalMs);
31986
33076
  await new Promise((resolve16) => {
31987
33077
  stream.onAbort(() => {
31988
33078
  clearInterval(heartbeatInterval);
@@ -31998,13 +33088,18 @@ async function startServer(options = {}) {
31998
33088
  const port = options.port ?? 4096;
31999
33089
  const host = options.host ?? "localhost";
32000
33090
  const app = createServer2(options);
33091
+ const sseRuntimeConfig = resolveSSEServerRuntimeConfig(process.env, {
33092
+ heartbeatIntervalMs: options.heartbeatIntervalMs,
33093
+ idleTimeoutMs: options.idleTimeoutMs
33094
+ });
32001
33095
  if (typeof Bun === "undefined" || typeof Bun.serve !== "function") {
32002
33096
  throw new Error("Bun runtime is required to start the web server");
32003
33097
  }
32004
33098
  const server = Bun.serve({
32005
33099
  fetch: app.fetch,
32006
33100
  hostname: host,
32007
- port
33101
+ port,
33102
+ idleTimeout: sseRuntimeConfig.idleTimeoutSeconds
32008
33103
  });
32009
33104
  console.log(`PYB-CLI Web Server starting on http://${host}:${port}`);
32010
33105
  return {
@@ -38309,7 +39404,7 @@ function useStatusLine() {
38309
39404
  // src/ui/components/PromptInput.tsx
38310
39405
  async function interpretHashCommand(input) {
38311
39406
  try {
38312
- const { queryQuick: queryQuick2 } = await import("./llm-MRDYTVAB.js");
39407
+ const { queryQuick: queryQuick2 } = await import("./llm-CVILTZMI.js");
38313
39408
  const systemPrompt = [
38314
39409
  "You're helping the user structure notes that will be added to their PYB.md file.",
38315
39410
  "Format the user's input into a well-structured note that will be useful for later reference.",
@@ -38622,7 +39717,7 @@ function PromptInput({
38622
39717
  if (messages2.length) {
38623
39718
  if (mode === "bash") {
38624
39719
  onQuery(messages2, newAbortController).then(async () => {
38625
- const { getCwd: getCwd2 } = await import("./state-GMP5BAO3.js");
39720
+ const { getCwd: getCwd2 } = await import("./state-GWKESQ7O.js");
38626
39721
  setCurrentPwd(getCwd2());
38627
39722
  });
38628
39723
  } else {
@@ -40252,7 +41347,7 @@ import { homedir as homedir8 } from "os";
40252
41347
  // src/commands/agents/generation.ts
40253
41348
  import { randomUUID as randomUUID9 } from "crypto";
40254
41349
  async function generateAgentWithClaude(prompt) {
40255
- const { queryModel } = await import("./llm-MRDYTVAB.js");
41350
+ const { queryModel } = await import("./llm-CVILTZMI.js");
40256
41351
  const systemPrompt = `You are an expert at creating AI agent configurations. Based on the user's description, generate a specialized agent configuration.
40257
41352
 
40258
41353
  Return your response as a JSON object with exactly these fields: