@itphx/synth-core 0.2.0 → 0.4.4

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 (670) hide show
  1. package/definitions/protected-paths.json +36 -0
  2. package/definitions/shell-policy.json +36 -0
  3. package/dist/auth/local.d.ts +14 -0
  4. package/dist/auth/local.d.ts.map +1 -1
  5. package/dist/auth/local.js +63 -11
  6. package/dist/auth/local.js.map +1 -1
  7. package/dist/auth/local.test.js +59 -0
  8. package/dist/auth/local.test.js.map +1 -1
  9. package/dist/definitions/protected-paths.json +36 -0
  10. package/dist/definitions/shell-policy.json +36 -0
  11. package/dist/engine/agents/definitions/admin.json +3 -1
  12. package/dist/engine/agents/definitions/analyst.json +3 -1
  13. package/dist/engine/agents/definitions/assistant.json +2 -2
  14. package/dist/engine/agents/definitions/auditor.json +4 -1
  15. package/dist/engine/agents/definitions/developer.json +4 -1
  16. package/dist/engine/agents/definitions/devops.json +4 -1
  17. package/dist/engine/agents/definitions/explore.json +3 -3
  18. package/dist/engine/agents/definitions/general.json +2 -2
  19. package/dist/engine/agents/definitions/pm.json +5 -1
  20. package/dist/engine/agents/definitions/qa.json +4 -1
  21. package/dist/engine/agents/definitions/title.json +2 -2
  22. package/dist/engine/agents/index.d.ts +4 -0
  23. package/dist/engine/agents/index.d.ts.map +1 -1
  24. package/dist/engine/agents/index.js +9 -3
  25. package/dist/engine/agents/index.js.map +1 -1
  26. package/dist/engine/agents/mode.d.ts +5 -3
  27. package/dist/engine/agents/mode.d.ts.map +1 -1
  28. package/dist/engine/agents/mode.js +6 -6
  29. package/dist/engine/agents/mode.js.map +1 -1
  30. package/dist/engine/agents/mode.test.js +9 -3
  31. package/dist/engine/agents/mode.test.js.map +1 -1
  32. package/dist/engine/agents/normalize.d.ts +9 -0
  33. package/dist/engine/agents/normalize.d.ts.map +1 -0
  34. package/dist/engine/agents/normalize.js +22 -0
  35. package/dist/engine/agents/normalize.js.map +1 -0
  36. package/dist/engine/agents/normalize.test.d.ts +2 -0
  37. package/dist/engine/agents/normalize.test.d.ts.map +1 -0
  38. package/dist/engine/agents/normalize.test.js +37 -0
  39. package/dist/engine/agents/normalize.test.js.map +1 -0
  40. package/dist/engine/agents/registry.d.ts +2 -1
  41. package/dist/engine/agents/registry.d.ts.map +1 -1
  42. package/dist/engine/agents/registry.js +7 -6
  43. package/dist/engine/agents/registry.js.map +1 -1
  44. package/dist/engine/agents/registry.test.js +24 -0
  45. package/dist/engine/agents/registry.test.js.map +1 -1
  46. package/dist/engine/context/config.d.ts +43 -6
  47. package/dist/engine/context/config.d.ts.map +1 -1
  48. package/dist/engine/context/config.js +123 -26
  49. package/dist/engine/context/config.js.map +1 -1
  50. package/dist/engine/context/config.security.test.d.ts +2 -0
  51. package/dist/engine/context/config.security.test.d.ts.map +1 -0
  52. package/dist/engine/context/config.security.test.js +82 -0
  53. package/dist/engine/context/config.security.test.js.map +1 -0
  54. package/dist/engine/context/config.test.js +199 -10
  55. package/dist/engine/context/config.test.js.map +1 -1
  56. package/dist/engine/context/optimizer.d.ts +20 -1
  57. package/dist/engine/context/optimizer.d.ts.map +1 -1
  58. package/dist/engine/context/optimizer.js +63 -29
  59. package/dist/engine/context/optimizer.js.map +1 -1
  60. package/dist/engine/context/optimizer.test.js +156 -0
  61. package/dist/engine/context/optimizer.test.js.map +1 -1
  62. package/dist/engine/gateway/gateway-provider.d.ts +4 -0
  63. package/dist/engine/gateway/gateway-provider.d.ts.map +1 -1
  64. package/dist/engine/gateway/gateway-provider.js +7 -2
  65. package/dist/engine/gateway/gateway-provider.js.map +1 -1
  66. package/dist/engine/gateway/gateway-provider.test.js +3 -3
  67. package/dist/engine/gateway/gateway-provider.test.js.map +1 -1
  68. package/dist/engine/gateway/input-guard.d.ts.map +1 -1
  69. package/dist/engine/gateway/input-guard.js +2 -1
  70. package/dist/engine/gateway/input-guard.js.map +1 -1
  71. package/dist/engine/gateway/secret-detector.d.ts.map +1 -1
  72. package/dist/engine/gateway/secret-detector.js +2 -3
  73. package/dist/engine/gateway/secret-detector.js.map +1 -1
  74. package/dist/engine/gateway/secret-detector.test.js +4 -4
  75. package/dist/engine/gateway/secret-detector.test.js.map +1 -1
  76. package/dist/engine/llm-error.d.ts +23 -0
  77. package/dist/engine/llm-error.d.ts.map +1 -0
  78. package/dist/engine/llm-error.js +86 -0
  79. package/dist/engine/llm-error.js.map +1 -0
  80. package/dist/engine/llm-error.test.d.ts +2 -0
  81. package/dist/engine/llm-error.test.d.ts.map +1 -0
  82. package/dist/engine/llm-error.test.js +101 -0
  83. package/dist/engine/llm-error.test.js.map +1 -0
  84. package/dist/engine/orchestrator-deny-abort.test.d.ts +2 -0
  85. package/dist/engine/orchestrator-deny-abort.test.d.ts.map +1 -0
  86. package/dist/engine/orchestrator-deny-abort.test.js +414 -0
  87. package/dist/engine/orchestrator-deny-abort.test.js.map +1 -0
  88. package/dist/engine/orchestrator-error.test.d.ts +2 -0
  89. package/dist/engine/orchestrator-error.test.d.ts.map +1 -0
  90. package/dist/engine/orchestrator-error.test.js +136 -0
  91. package/dist/engine/orchestrator-error.test.js.map +1 -0
  92. package/dist/engine/orchestrator.d.ts +123 -10
  93. package/dist/engine/orchestrator.d.ts.map +1 -1
  94. package/dist/engine/orchestrator.js +791 -181
  95. package/dist/engine/orchestrator.js.map +1 -1
  96. package/dist/engine/orchestrator.test.js +723 -0
  97. package/dist/engine/orchestrator.test.js.map +1 -1
  98. package/dist/engine/permission/approval.d.ts.map +1 -1
  99. package/dist/engine/permission/approval.js +29 -10
  100. package/dist/engine/permission/approval.js.map +1 -1
  101. package/dist/engine/permission/approval.test.js +57 -0
  102. package/dist/engine/permission/approval.test.js.map +1 -1
  103. package/dist/engine/permission/evaluator.d.ts +13 -0
  104. package/dist/engine/permission/evaluator.d.ts.map +1 -1
  105. package/dist/engine/permission/evaluator.js +121 -22
  106. package/dist/engine/permission/evaluator.js.map +1 -1
  107. package/dist/engine/permission/evaluator.test.js +188 -4
  108. package/dist/engine/permission/evaluator.test.js.map +1 -1
  109. package/dist/engine/permission/groups.d.ts.map +1 -1
  110. package/dist/engine/permission/groups.js +19 -1
  111. package/dist/engine/permission/groups.js.map +1 -1
  112. package/dist/engine/permission/integration.test.js +165 -4
  113. package/dist/engine/permission/integration.test.js.map +1 -1
  114. package/dist/engine/plan.integration.test.js +142 -33
  115. package/dist/engine/plan.integration.test.js.map +1 -1
  116. package/dist/engine/router/micro/tasks/classify-intent.d.ts.map +1 -1
  117. package/dist/engine/router/micro/tasks/classify-intent.js +24 -18
  118. package/dist/engine/router/micro/tasks/classify-intent.js.map +1 -1
  119. package/dist/engine/router/micro/tasks/classify-intent.test.js +4 -4
  120. package/dist/engine/router/micro/tasks/classify-intent.test.js.map +1 -1
  121. package/dist/engine/router/micro/tasks/enum-decision.d.ts.map +1 -1
  122. package/dist/engine/router/micro/tasks/enum-decision.js +14 -8
  123. package/dist/engine/router/micro/tasks/enum-decision.js.map +1 -1
  124. package/dist/engine/router/micro/tasks/enum-decision.test.js +2 -2
  125. package/dist/engine/router/micro/tasks/enum-decision.test.js.map +1 -1
  126. package/dist/engine/router/micro/tasks/small-talk.d.ts.map +1 -1
  127. package/dist/engine/router/micro/tasks/small-talk.js +20 -17
  128. package/dist/engine/router/micro/tasks/small-talk.js.map +1 -1
  129. package/dist/engine/router/micro/types.d.ts +2 -0
  130. package/dist/engine/router/micro/types.d.ts.map +1 -1
  131. package/dist/engine/router/provider-pool.d.ts +2 -2
  132. package/dist/engine/router/provider-pool.d.ts.map +1 -1
  133. package/dist/engine/router/provider-pool.js +5 -3
  134. package/dist/engine/router/provider-pool.js.map +1 -1
  135. package/dist/engine/router/quality-checker.d.ts.map +1 -1
  136. package/dist/engine/router/quality-checker.js +15 -14
  137. package/dist/engine/router/quality-checker.js.map +1 -1
  138. package/dist/engine/router/router.d.ts +2 -2
  139. package/dist/engine/router/router.d.ts.map +1 -1
  140. package/dist/engine/router/router.js +8 -5
  141. package/dist/engine/router/router.js.map +1 -1
  142. package/dist/engine/router/utils.d.ts +2 -2
  143. package/dist/engine/router/utils.d.ts.map +1 -1
  144. package/dist/engine/router/utils.js +2 -1
  145. package/dist/engine/router/utils.js.map +1 -1
  146. package/dist/engine/security/index.d.ts +6 -0
  147. package/dist/engine/security/index.d.ts.map +1 -1
  148. package/dist/engine/security/index.js +3 -0
  149. package/dist/engine/security/index.js.map +1 -1
  150. package/dist/engine/security/integration.test.js +11 -11
  151. package/dist/engine/security/integration.test.js.map +1 -1
  152. package/dist/engine/security/prompt-injection.d.ts +1 -1
  153. package/dist/engine/security/prompt-injection.d.ts.map +1 -1
  154. package/dist/engine/security/prompt-injection.js +2 -1
  155. package/dist/engine/security/prompt-injection.js.map +1 -1
  156. package/dist/engine/security/prompt-injection.test.js +1 -1
  157. package/dist/engine/security/prompt-injection.test.js.map +1 -1
  158. package/dist/engine/security/protected-paths-store.d.ts +56 -0
  159. package/dist/engine/security/protected-paths-store.d.ts.map +1 -0
  160. package/dist/engine/security/protected-paths-store.js +239 -0
  161. package/dist/engine/security/protected-paths-store.js.map +1 -0
  162. package/dist/engine/security/protected-paths.d.ts +54 -0
  163. package/dist/engine/security/protected-paths.d.ts.map +1 -0
  164. package/dist/engine/security/protected-paths.js +193 -0
  165. package/dist/engine/security/protected-paths.js.map +1 -0
  166. package/dist/engine/security/protected-paths.test.d.ts +2 -0
  167. package/dist/engine/security/protected-paths.test.d.ts.map +1 -0
  168. package/dist/engine/security/protected-paths.test.js +166 -0
  169. package/dist/engine/security/protected-paths.test.js.map +1 -0
  170. package/dist/engine/security/shell-guard.d.ts +117 -0
  171. package/dist/engine/security/shell-guard.d.ts.map +1 -0
  172. package/dist/engine/security/shell-guard.js +578 -0
  173. package/dist/engine/security/shell-guard.js.map +1 -0
  174. package/dist/engine/security/shell-guard.test.d.ts +2 -0
  175. package/dist/engine/security/shell-guard.test.d.ts.map +1 -0
  176. package/dist/engine/security/shell-guard.test.js +378 -0
  177. package/dist/engine/security/shell-guard.test.js.map +1 -0
  178. package/dist/engine/system-messages.d.ts +237 -0
  179. package/dist/engine/system-messages.d.ts.map +1 -0
  180. package/dist/engine/system-messages.js +276 -0
  181. package/dist/engine/system-messages.js.map +1 -0
  182. package/dist/engine/system-messages.test.d.ts +2 -0
  183. package/dist/engine/system-messages.test.d.ts.map +1 -0
  184. package/dist/engine/system-messages.test.js +81 -0
  185. package/dist/engine/system-messages.test.js.map +1 -0
  186. package/dist/engine/tools/abort.d.ts +21 -0
  187. package/dist/engine/tools/abort.d.ts.map +1 -0
  188. package/dist/engine/tools/abort.js +44 -0
  189. package/dist/engine/tools/abort.js.map +1 -0
  190. package/dist/engine/tools/classify-conversation.d.ts.map +1 -1
  191. package/dist/engine/tools/classify-conversation.js +7 -2
  192. package/dist/engine/tools/classify-conversation.js.map +1 -1
  193. package/dist/engine/tools/fs-read.d.ts.map +1 -1
  194. package/dist/engine/tools/fs-read.js +17 -6
  195. package/dist/engine/tools/fs-read.js.map +1 -1
  196. package/dist/engine/tools/fs-read.test.js +43 -0
  197. package/dist/engine/tools/fs-read.test.js.map +1 -1
  198. package/dist/engine/tools/fs-write.d.ts.map +1 -1
  199. package/dist/engine/tools/fs-write.js +47 -17
  200. package/dist/engine/tools/fs-write.js.map +1 -1
  201. package/dist/engine/tools/git.d.ts +2 -1
  202. package/dist/engine/tools/git.d.ts.map +1 -1
  203. package/dist/engine/tools/git.js +85 -17
  204. package/dist/engine/tools/git.js.map +1 -1
  205. package/dist/engine/tools/git.test.js +39 -0
  206. package/dist/engine/tools/git.test.js.map +1 -1
  207. package/dist/engine/tools/index.d.ts.map +1 -1
  208. package/dist/engine/tools/index.js +16 -2
  209. package/dist/engine/tools/index.js.map +1 -1
  210. package/dist/engine/tools/json-schema.js +38 -0
  211. package/dist/engine/tools/json-schema.js.map +1 -1
  212. package/dist/engine/tools/json-schema.test.d.ts +2 -0
  213. package/dist/engine/tools/json-schema.test.d.ts.map +1 -0
  214. package/dist/engine/tools/json-schema.test.js +40 -0
  215. package/dist/engine/tools/json-schema.test.js.map +1 -0
  216. package/dist/engine/tools/path-utils.d.ts.map +1 -1
  217. package/dist/engine/tools/path-utils.js +24 -0
  218. package/dist/engine/tools/path-utils.js.map +1 -1
  219. package/dist/engine/tools/path-utils.test.js +15 -0
  220. package/dist/engine/tools/path-utils.test.js.map +1 -1
  221. package/dist/engine/tools/plan.d.ts +11 -3
  222. package/dist/engine/tools/plan.d.ts.map +1 -1
  223. package/dist/engine/tools/plan.js +326 -95
  224. package/dist/engine/tools/plan.js.map +1 -1
  225. package/dist/engine/tools/plan.test.js +161 -47
  226. package/dist/engine/tools/plan.test.js.map +1 -1
  227. package/dist/engine/tools/project-context.d.ts.map +1 -1
  228. package/dist/engine/tools/project-context.js +54 -42
  229. package/dist/engine/tools/project-context.js.map +1 -1
  230. package/dist/engine/tools/project-context.test.js +37 -22
  231. package/dist/engine/tools/project-context.test.js.map +1 -1
  232. package/dist/engine/tools/project-manage.d.ts +24 -0
  233. package/dist/engine/tools/project-manage.d.ts.map +1 -0
  234. package/dist/engine/tools/project-manage.js +311 -0
  235. package/dist/engine/tools/project-manage.js.map +1 -0
  236. package/dist/engine/tools/project-manage.test.d.ts +2 -0
  237. package/dist/engine/tools/project-manage.test.d.ts.map +1 -0
  238. package/dist/engine/tools/project-manage.test.js +196 -0
  239. package/dist/engine/tools/project-manage.test.js.map +1 -0
  240. package/dist/engine/tools/read-reference.d.ts.map +1 -1
  241. package/dist/engine/tools/read-reference.js +10 -5
  242. package/dist/engine/tools/read-reference.js.map +1 -1
  243. package/dist/engine/tools/read-reference.test.js +5 -2
  244. package/dist/engine/tools/read-reference.test.js.map +1 -1
  245. package/dist/engine/tools/search.d.ts.map +1 -1
  246. package/dist/engine/tools/search.js +16 -6
  247. package/dist/engine/tools/search.js.map +1 -1
  248. package/dist/engine/tools/shell.d.ts.map +1 -1
  249. package/dist/engine/tools/shell.js +17 -4
  250. package/dist/engine/tools/shell.js.map +1 -1
  251. package/dist/engine/tools/shell.test.js +63 -1
  252. package/dist/engine/tools/shell.test.js.map +1 -1
  253. package/dist/engine/tools/task-resume.d.ts +93 -0
  254. package/dist/engine/tools/task-resume.d.ts.map +1 -0
  255. package/dist/engine/tools/task-resume.js +269 -0
  256. package/dist/engine/tools/task-resume.js.map +1 -0
  257. package/dist/engine/tools/task-resume.test.d.ts +2 -0
  258. package/dist/engine/tools/task-resume.test.d.ts.map +1 -0
  259. package/dist/engine/tools/task-resume.test.js +423 -0
  260. package/dist/engine/tools/task-resume.test.js.map +1 -0
  261. package/dist/engine/tools/task.d.ts +81 -2
  262. package/dist/engine/tools/task.d.ts.map +1 -1
  263. package/dist/engine/tools/task.js +898 -471
  264. package/dist/engine/tools/task.js.map +1 -1
  265. package/dist/engine/tools/task.test.js +371 -3
  266. package/dist/engine/tools/task.test.js.map +1 -1
  267. package/dist/engine/tools/todo.d.ts +27 -1
  268. package/dist/engine/tools/todo.d.ts.map +1 -1
  269. package/dist/engine/tools/todo.js +320 -14
  270. package/dist/engine/tools/todo.js.map +1 -1
  271. package/dist/engine/tools/todo.test.js +150 -48
  272. package/dist/engine/tools/todo.test.js.map +1 -1
  273. package/dist/engine/tools/web.d.ts.map +1 -1
  274. package/dist/engine/tools/web.js +65 -18
  275. package/dist/engine/tools/web.js.map +1 -1
  276. package/dist/engine/tools/web.test.js +94 -2
  277. package/dist/engine/tools/web.test.js.map +1 -1
  278. package/dist/events/bus.d.ts +7 -0
  279. package/dist/events/bus.d.ts.map +1 -1
  280. package/dist/events/bus.js +26 -3
  281. package/dist/events/bus.js.map +1 -1
  282. package/dist/events/bus.test.js +46 -0
  283. package/dist/events/bus.test.js.map +1 -1
  284. package/dist/index.d.ts +11 -3
  285. package/dist/index.d.ts.map +1 -1
  286. package/dist/index.js +7 -3
  287. package/dist/index.js.map +1 -1
  288. package/dist/logger.d.ts.map +1 -1
  289. package/dist/logger.js +0 -1
  290. package/dist/logger.js.map +1 -1
  291. package/dist/main.js +250 -10
  292. package/dist/main.js.map +1 -1
  293. package/dist/prompts/roles/ADMIN.en.md +12 -11
  294. package/dist/prompts/roles/ADMIN.ru.md +12 -11
  295. package/dist/prompts/roles/ANALYST.en.md +12 -11
  296. package/dist/prompts/roles/ANALYST.ru.md +12 -11
  297. package/dist/prompts/roles/ASSISTANT.en.md +12 -11
  298. package/dist/prompts/roles/ASSISTANT.ru.md +12 -11
  299. package/dist/prompts/roles/AUDITOR.en.md +12 -11
  300. package/dist/prompts/roles/AUDITOR.ru.md +12 -11
  301. package/dist/prompts/roles/DEVELOPER.en.md +12 -11
  302. package/dist/prompts/roles/DEVELOPER.ru.md +12 -11
  303. package/dist/prompts/roles/DEVOPS.en.md +12 -11
  304. package/dist/prompts/roles/DEVOPS.ru.md +12 -11
  305. package/dist/prompts/roles/PM.en.md +12 -11
  306. package/dist/prompts/roles/PM.ru.md +12 -11
  307. package/dist/prompts/roles/QA.en.md +12 -11
  308. package/dist/prompts/roles/QA.ru.md +12 -11
  309. package/dist/prompts/roles/TITLE.en.md +30 -0
  310. package/dist/prompts/roles/TITLE.ru.md +3 -11
  311. package/dist/prompts/security/ask-protected-path.en.md +1 -0
  312. package/dist/prompts/security/ask-protected-path.ru.md +1 -0
  313. package/dist/prompts/security/deny-command.en.md +1 -0
  314. package/dist/prompts/security/deny-command.ru.md +1 -0
  315. package/dist/prompts/security/deny-protected-dir.en.md +1 -0
  316. package/dist/prompts/security/deny-protected-dir.ru.md +1 -0
  317. package/dist/prompts/security/deny-protected-path.en.md +1 -0
  318. package/dist/prompts/security/deny-protected-path.ru.md +1 -0
  319. package/dist/prompts/subagents/explore.en.md +23 -0
  320. package/dist/prompts/subagents/general.en.md +19 -0
  321. package/dist/prompts/system/MODE_ACT.en.md +20 -0
  322. package/{prompts/modes/act.md → dist/prompts/system/MODE_ACT.ru.md} +2 -0
  323. package/dist/prompts/system/MODE_PLAN.en.md +22 -0
  324. package/dist/prompts/{modes/plan.md → system/MODE_PLAN.ru.md} +4 -3
  325. package/dist/prompts/system/MODE_YOLO.en.md +22 -0
  326. package/{prompts/modes/yolo.md → dist/prompts/system/MODE_YOLO.ru.md} +2 -0
  327. package/dist/prompts/system/PLAN_GUIDE.en.md +36 -0
  328. package/dist/prompts/system/PLAN_GUIDE.ru.md +33 -0
  329. package/dist/prompts/system/PLAN_MODE_AUTO.en.md +11 -0
  330. package/dist/prompts/system/PLAN_MODE_AUTO.ru.md +12 -0
  331. package/dist/prompts/system/PLAN_MODE_STRICT_APPROVED.en.md +8 -0
  332. package/dist/prompts/system/PLAN_MODE_STRICT_APPROVED.ru.md +8 -0
  333. package/dist/prompts/system/PLAN_MODE_STRICT_NOT_APPROVED.en.md +7 -0
  334. package/dist/prompts/system/PLAN_MODE_STRICT_NOT_APPROVED.ru.md +7 -0
  335. package/dist/providers/anthropic.d.ts.map +1 -1
  336. package/dist/providers/anthropic.js +28 -2
  337. package/dist/providers/anthropic.js.map +1 -1
  338. package/dist/providers/base.d.ts +20 -1
  339. package/dist/providers/base.d.ts.map +1 -1
  340. package/dist/providers/base.js +17 -0
  341. package/dist/providers/base.js.map +1 -1
  342. package/dist/providers/exceptions.d.ts.map +1 -1
  343. package/dist/providers/exceptions.js +3 -2
  344. package/dist/providers/exceptions.js.map +1 -1
  345. package/dist/providers/index.d.ts +1 -0
  346. package/dist/providers/index.d.ts.map +1 -1
  347. package/dist/providers/index.js +4 -0
  348. package/dist/providers/index.js.map +1 -1
  349. package/dist/providers/ollama.d.ts +23 -0
  350. package/dist/providers/ollama.d.ts.map +1 -1
  351. package/dist/providers/ollama.js +128 -12
  352. package/dist/providers/ollama.js.map +1 -1
  353. package/dist/providers/ollama.test.d.ts +2 -0
  354. package/dist/providers/ollama.test.d.ts.map +1 -0
  355. package/dist/providers/ollama.test.js +129 -0
  356. package/dist/providers/ollama.test.js.map +1 -0
  357. package/dist/providers/openai.d.ts.map +1 -1
  358. package/dist/providers/openai.js +82 -9
  359. package/dist/providers/openai.js.map +1 -1
  360. package/dist/providers/openai.test.d.ts +2 -0
  361. package/dist/providers/openai.test.d.ts.map +1 -0
  362. package/dist/providers/openai.test.js +84 -0
  363. package/dist/providers/openai.test.js.map +1 -0
  364. package/dist/providers/remote.d.ts +60 -0
  365. package/dist/providers/remote.d.ts.map +1 -0
  366. package/dist/providers/remote.js +394 -0
  367. package/dist/providers/remote.js.map +1 -0
  368. package/dist/providers/remote.test.d.ts +2 -0
  369. package/dist/providers/remote.test.d.ts.map +1 -0
  370. package/dist/providers/remote.test.js +258 -0
  371. package/dist/providers/remote.test.js.map +1 -0
  372. package/dist/providers/stream-error.test.d.ts +2 -0
  373. package/dist/providers/stream-error.test.d.ts.map +1 -0
  374. package/dist/providers/stream-error.test.js +63 -0
  375. package/dist/providers/stream-error.test.js.map +1 -0
  376. package/dist/providers/timeout.test.d.ts +2 -0
  377. package/dist/providers/timeout.test.d.ts.map +1 -0
  378. package/dist/providers/timeout.test.js +129 -0
  379. package/dist/providers/timeout.test.js.map +1 -0
  380. package/dist/queue/processor.d.ts +22 -0
  381. package/dist/queue/processor.d.ts.map +1 -1
  382. package/dist/queue/processor.js +150 -25
  383. package/dist/queue/processor.js.map +1 -1
  384. package/dist/queue/processor.test.d.ts +2 -0
  385. package/dist/queue/processor.test.d.ts.map +1 -0
  386. package/dist/queue/processor.test.js +211 -0
  387. package/dist/queue/processor.test.js.map +1 -0
  388. package/dist/remote/aggregate.d.ts +43 -0
  389. package/dist/remote/aggregate.d.ts.map +1 -0
  390. package/dist/remote/aggregate.js +84 -0
  391. package/dist/remote/aggregate.js.map +1 -0
  392. package/dist/remote/aggregate.test.d.ts +2 -0
  393. package/dist/remote/aggregate.test.d.ts.map +1 -0
  394. package/dist/remote/aggregate.test.js +120 -0
  395. package/dist/remote/aggregate.test.js.map +1 -0
  396. package/dist/remote/client.d.ts +142 -0
  397. package/dist/remote/client.d.ts.map +1 -0
  398. package/dist/remote/client.js +290 -0
  399. package/dist/remote/client.js.map +1 -0
  400. package/dist/remote/client.test.d.ts +2 -0
  401. package/dist/remote/client.test.d.ts.map +1 -0
  402. package/dist/remote/client.test.js +176 -0
  403. package/dist/remote/client.test.js.map +1 -0
  404. package/dist/remote/connection.d.ts +66 -0
  405. package/dist/remote/connection.d.ts.map +1 -0
  406. package/dist/remote/connection.js +298 -0
  407. package/dist/remote/connection.js.map +1 -0
  408. package/dist/remote/connection.test.d.ts +2 -0
  409. package/dist/remote/connection.test.d.ts.map +1 -0
  410. package/dist/remote/connection.test.js +323 -0
  411. package/dist/remote/connection.test.js.map +1 -0
  412. package/dist/remote/credentials.d.ts +13 -0
  413. package/dist/remote/credentials.d.ts.map +1 -0
  414. package/dist/remote/credentials.js +81 -0
  415. package/dist/remote/credentials.js.map +1 -0
  416. package/dist/remote/credentials.test.d.ts +2 -0
  417. package/dist/remote/credentials.test.d.ts.map +1 -0
  418. package/dist/remote/credentials.test.js +69 -0
  419. package/dist/remote/credentials.test.js.map +1 -0
  420. package/dist/remote/device-flow.d.ts +72 -0
  421. package/dist/remote/device-flow.d.ts.map +1 -0
  422. package/dist/remote/device-flow.js +229 -0
  423. package/dist/remote/device-flow.js.map +1 -0
  424. package/dist/remote/device-flow.test.d.ts +2 -0
  425. package/dist/remote/device-flow.test.d.ts.map +1 -0
  426. package/dist/remote/device-flow.test.js +103 -0
  427. package/dist/remote/device-flow.test.js.map +1 -0
  428. package/dist/remote/event-bridge.d.ts +46 -0
  429. package/dist/remote/event-bridge.d.ts.map +1 -0
  430. package/dist/remote/event-bridge.js +218 -0
  431. package/dist/remote/event-bridge.js.map +1 -0
  432. package/dist/remote/event-bridge.test.d.ts +2 -0
  433. package/dist/remote/event-bridge.test.d.ts.map +1 -0
  434. package/dist/remote/event-bridge.test.js +240 -0
  435. package/dist/remote/event-bridge.test.js.map +1 -0
  436. package/dist/remote/index.d.ts +19 -0
  437. package/dist/remote/index.d.ts.map +1 -0
  438. package/dist/remote/index.js +11 -0
  439. package/dist/remote/index.js.map +1 -0
  440. package/dist/remote/session.d.ts +72 -0
  441. package/dist/remote/session.d.ts.map +1 -0
  442. package/dist/remote/session.js +248 -0
  443. package/dist/remote/session.js.map +1 -0
  444. package/dist/remote/session.test.d.ts +2 -0
  445. package/dist/remote/session.test.d.ts.map +1 -0
  446. package/dist/remote/session.test.js +482 -0
  447. package/dist/remote/session.test.js.map +1 -0
  448. package/dist/remote/transfer.d.ts +75 -0
  449. package/dist/remote/transfer.d.ts.map +1 -0
  450. package/dist/remote/transfer.js +491 -0
  451. package/dist/remote/transfer.js.map +1 -0
  452. package/dist/remote/transfer.test.d.ts +2 -0
  453. package/dist/remote/transfer.test.d.ts.map +1 -0
  454. package/dist/remote/transfer.test.js +416 -0
  455. package/dist/remote/transfer.test.js.map +1 -0
  456. package/dist/remote/types.d.ts +28 -0
  457. package/dist/remote/types.d.ts.map +1 -0
  458. package/dist/remote/types.js +10 -0
  459. package/dist/remote/types.js.map +1 -0
  460. package/dist/server/app.d.ts +62 -1
  461. package/dist/server/app.d.ts.map +1 -1
  462. package/dist/server/app.js +393 -27
  463. package/dist/server/app.js.map +1 -1
  464. package/dist/server/app.proxy.test.d.ts +2 -0
  465. package/dist/server/app.proxy.test.d.ts.map +1 -0
  466. package/dist/server/app.proxy.test.js +193 -0
  467. package/dist/server/app.proxy.test.js.map +1 -0
  468. package/dist/server/app.remote.test.d.ts +2 -0
  469. package/dist/server/app.remote.test.d.ts.map +1 -0
  470. package/dist/server/app.remote.test.js +674 -0
  471. package/dist/server/app.remote.test.js.map +1 -0
  472. package/dist/server/chat.d.ts.map +1 -1
  473. package/dist/server/chat.js +18 -2
  474. package/dist/server/chat.js.map +1 -1
  475. package/dist/server/proxy.d.ts +14 -0
  476. package/dist/server/proxy.d.ts.map +1 -0
  477. package/dist/server/proxy.js +93 -0
  478. package/dist/server/proxy.js.map +1 -0
  479. package/dist/server/routes/agents.d.ts.map +1 -1
  480. package/dist/server/routes/agents.js +39 -23
  481. package/dist/server/routes/agents.js.map +1 -1
  482. package/dist/server/routes/auth.d.ts +26 -2
  483. package/dist/server/routes/auth.d.ts.map +1 -1
  484. package/dist/server/routes/auth.js +269 -36
  485. package/dist/server/routes/auth.js.map +1 -1
  486. package/dist/server/routes/auth.test.d.ts +2 -0
  487. package/dist/server/routes/auth.test.d.ts.map +1 -0
  488. package/dist/server/routes/auth.test.js +466 -0
  489. package/dist/server/routes/auth.test.js.map +1 -0
  490. package/dist/server/routes/fs.d.ts +2 -1
  491. package/dist/server/routes/fs.d.ts.map +1 -1
  492. package/dist/server/routes/fs.js +340 -7
  493. package/dist/server/routes/fs.js.map +1 -1
  494. package/dist/server/routes/hybrid.d.ts +32 -0
  495. package/dist/server/routes/hybrid.d.ts.map +1 -0
  496. package/dist/server/routes/hybrid.js +21 -0
  497. package/dist/server/routes/hybrid.js.map +1 -0
  498. package/dist/server/routes/hybrid.test.d.ts +2 -0
  499. package/dist/server/routes/hybrid.test.d.ts.map +1 -0
  500. package/dist/server/routes/hybrid.test.js +454 -0
  501. package/dist/server/routes/hybrid.test.js.map +1 -0
  502. package/dist/server/routes/messages.d.ts +2 -1
  503. package/dist/server/routes/messages.d.ts.map +1 -1
  504. package/dist/server/routes/messages.js +104 -1
  505. package/dist/server/routes/messages.js.map +1 -1
  506. package/dist/server/routes/models.cache.test.d.ts +2 -0
  507. package/dist/server/routes/models.cache.test.d.ts.map +1 -0
  508. package/dist/server/routes/models.cache.test.js +59 -0
  509. package/dist/server/routes/models.cache.test.js.map +1 -0
  510. package/dist/server/routes/models.d.ts +9 -1
  511. package/dist/server/routes/models.d.ts.map +1 -1
  512. package/dist/server/routes/models.js +38 -3
  513. package/dist/server/routes/models.js.map +1 -1
  514. package/dist/server/routes/models.remote.test.d.ts +2 -0
  515. package/dist/server/routes/models.remote.test.d.ts.map +1 -0
  516. package/dist/server/routes/models.remote.test.js +101 -0
  517. package/dist/server/routes/models.remote.test.js.map +1 -0
  518. package/dist/server/routes/project-transfer.d.ts +16 -0
  519. package/dist/server/routes/project-transfer.d.ts.map +1 -0
  520. package/dist/server/routes/project-transfer.js +141 -0
  521. package/dist/server/routes/project-transfer.js.map +1 -0
  522. package/dist/server/routes/project-transfer.test.d.ts +2 -0
  523. package/dist/server/routes/project-transfer.test.d.ts.map +1 -0
  524. package/dist/server/routes/project-transfer.test.js +199 -0
  525. package/dist/server/routes/project-transfer.test.js.map +1 -0
  526. package/dist/server/routes/projects.d.ts +2 -1
  527. package/dist/server/routes/projects.d.ts.map +1 -1
  528. package/dist/server/routes/projects.js +101 -5
  529. package/dist/server/routes/projects.js.map +1 -1
  530. package/dist/server/routes/providers.d.ts +1 -1
  531. package/dist/server/routes/providers.d.ts.map +1 -1
  532. package/dist/server/routes/providers.js +3 -1
  533. package/dist/server/routes/providers.js.map +1 -1
  534. package/dist/server/routes/providers.test.d.ts +2 -0
  535. package/dist/server/routes/providers.test.d.ts.map +1 -0
  536. package/dist/server/routes/providers.test.js +58 -0
  537. package/dist/server/routes/providers.test.js.map +1 -0
  538. package/dist/server/routes/queue.d.ts +2 -1
  539. package/dist/server/routes/queue.d.ts.map +1 -1
  540. package/dist/server/routes/queue.js +180 -18
  541. package/dist/server/routes/queue.js.map +1 -1
  542. package/dist/server/routes/sessions.d.ts +9 -1
  543. package/dist/server/routes/sessions.d.ts.map +1 -1
  544. package/dist/server/routes/sessions.js +269 -18
  545. package/dist/server/routes/sessions.js.map +1 -1
  546. package/dist/server/routes/sessions.test.js +102 -2
  547. package/dist/server/routes/sessions.test.js.map +1 -1
  548. package/dist/server/routes/settings.d.ts +6 -1
  549. package/dist/server/routes/settings.d.ts.map +1 -1
  550. package/dist/server/routes/settings.js +138 -0
  551. package/dist/server/routes/settings.js.map +1 -1
  552. package/dist/server/routes/settings.test.js +65 -1
  553. package/dist/server/routes/settings.test.js.map +1 -1
  554. package/dist/server/serialize.d.ts +11 -3
  555. package/dist/server/serialize.d.ts.map +1 -1
  556. package/dist/server/serialize.js +11 -3
  557. package/dist/server/serialize.js.map +1 -1
  558. package/dist/sessions/auto-title.d.ts +1 -1
  559. package/dist/sessions/auto-title.d.ts.map +1 -1
  560. package/dist/sessions/auto-title.js +24 -13
  561. package/dist/sessions/auto-title.js.map +1 -1
  562. package/dist/sessions/manager.d.ts +1 -2
  563. package/dist/sessions/manager.d.ts.map +1 -1
  564. package/dist/sessions/manager.js +11 -36
  565. package/dist/sessions/manager.js.map +1 -1
  566. package/dist/sessions/manager.test.js +2 -10
  567. package/dist/sessions/manager.test.js.map +1 -1
  568. package/dist/storage/file-store.d.ts.map +1 -1
  569. package/dist/storage/file-store.js +2 -6
  570. package/dist/storage/file-store.js.map +1 -1
  571. package/dist/storage/file-store.test.js +1 -6
  572. package/dist/storage/file-store.test.js.map +1 -1
  573. package/dist/storage/project-store.d.ts.map +1 -1
  574. package/dist/storage/project-store.js +12 -0
  575. package/dist/storage/project-store.js.map +1 -1
  576. package/dist/storage/runtime-settings.d.ts +25 -1
  577. package/dist/storage/runtime-settings.d.ts.map +1 -1
  578. package/dist/storage/runtime-settings.js +31 -0
  579. package/dist/storage/runtime-settings.js.map +1 -1
  580. package/package.json +10 -5
  581. package/prompts/roles/TITLE.en.md +30 -0
  582. package/prompts/security/ask-protected-path.en.md +1 -0
  583. package/prompts/security/ask-protected-path.ru.md +1 -0
  584. package/prompts/security/deny-command.en.md +1 -0
  585. package/prompts/security/deny-command.ru.md +1 -0
  586. package/prompts/security/deny-protected-dir.en.md +1 -0
  587. package/prompts/security/deny-protected-dir.ru.md +1 -0
  588. package/prompts/security/deny-protected-path.en.md +1 -0
  589. package/prompts/security/deny-protected-path.ru.md +1 -0
  590. package/prompts/subagents/explore.en.md +23 -0
  591. package/prompts/subagents/general.en.md +19 -0
  592. package/prompts/system/MODE_ACT.en.md +20 -0
  593. package/{dist/prompts/modes/act.md → prompts/system/MODE_ACT.ru.md} +2 -0
  594. package/prompts/system/MODE_PLAN.en.md +22 -0
  595. package/{dist/prompts/prompts/modes/plan.md → prompts/system/MODE_PLAN.ru.md} +4 -3
  596. package/prompts/system/MODE_YOLO.en.md +22 -0
  597. package/{dist/prompts/prompts/modes/yolo.md → prompts/system/MODE_YOLO.ru.md} +2 -0
  598. package/prompts/system/PLAN_GUIDE.en.md +36 -0
  599. package/prompts/system/PLAN_GUIDE.ru.md +33 -0
  600. package/prompts/system/PLAN_MODE_AUTO.en.md +11 -0
  601. package/prompts/system/PLAN_MODE_AUTO.ru.md +12 -0
  602. package/prompts/system/PLAN_MODE_STRICT_APPROVED.en.md +8 -0
  603. package/prompts/system/PLAN_MODE_STRICT_APPROVED.ru.md +8 -0
  604. package/prompts/system/PLAN_MODE_STRICT_NOT_APPROVED.en.md +7 -0
  605. package/prompts/system/PLAN_MODE_STRICT_NOT_APPROVED.ru.md +7 -0
  606. package/dist/dictionaries/dictionaries/coding.en.yaml +0 -20
  607. package/dist/dictionaries/dictionaries/coding.ru.yaml +0 -22
  608. package/dist/dictionaries/dictionaries/coding.tools.yaml +0 -12
  609. package/dist/dictionaries/dictionaries/enum.en.yaml +0 -54
  610. package/dist/dictionaries/dictionaries/enum.ru.yaml +0 -67
  611. package/dist/dictionaries/dictionaries/injection.en.yaml +0 -51
  612. package/dist/dictionaries/dictionaries/injection.ru.yaml +0 -51
  613. package/dist/dictionaries/dictionaries/intents.en.yaml +0 -68
  614. package/dist/dictionaries/dictionaries/intents.ru.yaml +0 -78
  615. package/dist/dictionaries/dictionaries/research.en.yaml +0 -17
  616. package/dist/dictionaries/dictionaries/research.ru.yaml +0 -17
  617. package/dist/dictionaries/dictionaries/small-talk.en.yaml +0 -67
  618. package/dist/dictionaries/dictionaries/small-talk.ru.yaml +0 -81
  619. package/dist/prompts/modes/yolo.md +0 -20
  620. package/dist/prompts/prompts/modes/act.md +0 -18
  621. package/dist/prompts/prompts/roles/ADMIN.en.md +0 -33
  622. package/dist/prompts/prompts/roles/ADMIN.ru.md +0 -33
  623. package/dist/prompts/prompts/roles/ANALYST.en.md +0 -33
  624. package/dist/prompts/prompts/roles/ANALYST.ru.md +0 -33
  625. package/dist/prompts/prompts/roles/ASSISTANT.en.md +0 -38
  626. package/dist/prompts/prompts/roles/ASSISTANT.ru.md +0 -38
  627. package/dist/prompts/prompts/roles/AUDITOR.en.md +0 -33
  628. package/dist/prompts/prompts/roles/AUDITOR.ru.md +0 -33
  629. package/dist/prompts/prompts/roles/DEVELOPER.en.md +0 -42
  630. package/dist/prompts/prompts/roles/DEVELOPER.ru.md +0 -42
  631. package/dist/prompts/prompts/roles/DEVOPS.en.md +0 -35
  632. package/dist/prompts/prompts/roles/DEVOPS.ru.md +0 -35
  633. package/dist/prompts/prompts/roles/PM.en.md +0 -33
  634. package/dist/prompts/prompts/roles/PM.ru.md +0 -33
  635. package/dist/prompts/prompts/roles/QA.en.md +0 -33
  636. package/dist/prompts/prompts/roles/QA.ru.md +0 -33
  637. package/dist/prompts/prompts/roles/TITLE.ru.md +0 -30
  638. package/dist/prompts/prompts/subagents/explore.ru.md +0 -23
  639. package/dist/prompts/prompts/subagents/general.ru.md +0 -19
  640. package/dist/prompts/prompts/system/COMPRESSED_DIALOG.en.md +0 -5
  641. package/dist/prompts/prompts/system/COMPRESSED_DIALOG.ru.md +0 -5
  642. package/dist/prompts/prompts/system/INTERVIEW.en.md +0 -18
  643. package/dist/prompts/prompts/system/INTERVIEW.ru.md +0 -18
  644. package/dist/prompts/prompts/system/PARTICIPANTS_NOTICE.en.md +0 -7
  645. package/dist/prompts/prompts/system/PARTICIPANTS_NOTICE.ru.md +0 -7
  646. package/dist/prompts/prompts/system/ROLES_DESCRIPTION.en.md +0 -16
  647. package/dist/prompts/prompts/system/ROLES_DESCRIPTION.ru.md +0 -16
  648. package/dist/prompts/prompts/system/ROUTING.en.md +0 -13
  649. package/dist/prompts/prompts/system/ROUTING.md +0 -6
  650. package/dist/prompts/prompts/system/ROUTING.ru.md +0 -13
  651. package/dist/prompts/prompts/system/RULES.en.md +0 -10
  652. package/dist/prompts/prompts/system/RULES.md +0 -10
  653. package/dist/prompts/prompts/system/RULES.ru.md +0 -10
  654. package/dist/prompts/prompts/system/STICKY_NOTES.en.md +0 -6
  655. package/dist/prompts/prompts/system/STICKY_NOTES.ru.md +0 -6
  656. package/dist/prompts/prompts/system/SUMMARIZER.en.md +0 -54
  657. package/dist/prompts/prompts/system/SUMMARIZER.ru.md +0 -54
  658. package/dist/prompts/prompts/system/USER_CONTEXT.en.md +0 -5
  659. package/dist/prompts/prompts/system/USER_CONTEXT.ru.md +0 -5
  660. package/dist/prompts/system/ROUTING.md +0 -6
  661. package/dist/prompts/system/RULES.md +0 -10
  662. package/dist/server/routes/i18n.d.ts +0 -3
  663. package/dist/server/routes/i18n.d.ts.map +0 -1
  664. package/dist/server/routes/i18n.js +0 -83
  665. package/dist/server/routes/i18n.js.map +0 -1
  666. package/prompts/modes/plan.md +0 -20
  667. package/prompts/system/ROUTING.md +0 -6
  668. package/prompts/system/RULES.md +0 -10
  669. /package/dist/prompts/{prompts/system → system}/GATEWAY.en.md +0 -0
  670. /package/dist/prompts/{prompts/system → system}/GATEWAY.ru.md +0 -0
@@ -7,26 +7,40 @@ import { join, extname } from 'node:path';
7
7
  import { Hono } from 'hono';
8
8
  import { cors } from 'hono/cors';
9
9
  import { logger } from 'hono/logger';
10
- import { FileStore, SessionManager, EventBus, QueueProcessorManager, ContextConfig, ContextBuilder, ContextOptimizer, ChatOrchestrator, enqueueUserMessage, createToolRegistry, createAgentRegistry, McpManager, SecretPatternStore, } from '../index.js';
10
+ import { FileStore, SessionManager, EventBus, QueueProcessorManager, ContextConfig, ContextBuilder, ContextOptimizer, ChatOrchestrator, enqueueUserMessage, createToolRegistry, createAgentRegistry, McpManager, SecretPatternStore, ProtectedPathsStore, } from '../index.js';
11
11
  import { nowISO, ensureDataDir, MessageRole, generateStreamId, makeTextPart } from '@itphx/synth-shared';
12
12
  import { createLocalAuth } from '../auth/local.js';
13
+ import { RemoteConnection } from '../remote/connection.js';
14
+ import { RemoteError } from '../remote/types.js';
15
+ import { RemoteEventBridge } from '../remote/event-bridge.js';
16
+ import { isRemoteRef, toLocalId } from '../remote/aggregate.js';
17
+ import { setRemoteTokenProvider, removeRemoteTokenProvider } from '../providers/remote.js';
13
18
  import { JsonStore } from '../storage/json-store.js';
14
19
  import { ProjectStore } from '../storage/project-store.js';
15
- import { RuntimeSettingsStore, mergeLlmGatewayConfig } from '../storage/runtime-settings.js';
20
+ import { RuntimeSettingsStore, mergeLlmGatewayConfig, mergeSecurityConfig } from '../storage/runtime-settings.js';
16
21
  import { createHealthRoutes } from './routes/health.js';
22
+ import { createHybridRoutes } from './routes/hybrid.js';
17
23
  import { createAuthRoutes } from './routes/auth.js';
18
24
  import { createSessionRoutes } from './routes/sessions.js';
19
25
  import { createProjectRoutes } from './routes/projects.js';
26
+ import { createProjectTransferRoutes } from './routes/project-transfer.js';
20
27
  import { createProviderRoutes } from './routes/providers.js';
21
28
  import { createModelRoutes } from './routes/models.js';
22
29
  import { createAgentRoutes } from './routes/agents.js';
23
30
  import { createFsRoutes } from './routes/fs.js';
24
31
  import { createQueueRoutes } from './routes/queue.js';
25
- import { createI18nRoutes } from './routes/i18n.js';
26
32
  import { createUpdateRoutes } from './routes/updates.js';
27
33
  import { createMessageRoutes } from './routes/messages.js';
28
34
  import { createSettingsRoutes } from './routes/settings.js';
29
35
  import { createMcpRoutes } from './routes/mcp.js';
36
+ import { createRemoteProxyMiddleware } from './proxy.js';
37
+ /**
38
+ * @deprecated Гибрид переведён на runtime-подключение через RemoteConnection
39
+ * (поле defaultBackendUrl + методы connect* на возвращаемом app-хэндле).
40
+ * Статические remoteClient/remoteProvider/remoteGetToken/remoteEventBridge/
41
+ * remoteBlockLocalProviders удалены — при необходимости подключите приложение
42
+ * через connectRemoteWithApiKey/connectRemoteFromSaved.
43
+ */
30
44
  const MIME_TYPES = {
31
45
  '.html': 'text/html',
32
46
  '.js': 'application/javascript',
@@ -133,6 +147,26 @@ async function syncProvidersFromEnv(providerStore, modelStore) {
133
147
  console.log(` [env] провайдер: ${name} (${provider.type})${provider.baseUrl ? ` → ${provider.baseUrl}` : ''}`);
134
148
  }
135
149
  }
150
+ /**
151
+ * Инъекция одного remote-зеркала в кэши (гибрид: зеркалирование серверных
152
+ * провайдеров). Добавляет провайдера в providerCache и его модели в modelCache —
153
+ * только in-memory, в JsonStore не пишется. Регистрирует поставщика токена для
154
+ * RemoteProvider, создаваемых через ProviderFactory. Возвращает имя
155
+ * remote-провайдера (для политики blockLocalProviders) или undefined.
156
+ */
157
+ export function injectRemoteProvider(providerCache, modelCache, remoteProvider) {
158
+ if (!remoteProvider)
159
+ return undefined;
160
+ const rp = remoteProvider.provider;
161
+ providerCache.set(rp.name, { ...rp, enabled: rp.enabled ?? true });
162
+ if (remoteProvider.getToken) {
163
+ setRemoteTokenProvider(rp.name, remoteProvider.getToken);
164
+ }
165
+ for (const m of remoteProvider.models ?? []) {
166
+ modelCache.set(m.id, m);
167
+ }
168
+ return rp.name;
169
+ }
136
170
  export async function createStandaloneApp(config) {
137
171
  const app = new Hono();
138
172
  const auth = createLocalAuth({ apiKey: config.apiKey });
@@ -141,16 +175,214 @@ export async function createStandaloneApp(config) {
141
175
  origin: (_origin) => _origin || '*',
142
176
  credentials: true,
143
177
  }));
178
+ // Runtime-подключение к удалённому backend (гибрид). Connection создаётся
179
+ // всегда: без defaultBackendUrl/credentials он остаётся disconnected, а
180
+ // пользователь логинится в UI (POST /auth/login) в рантайме.
181
+ const connection = new RemoteConnection({
182
+ credentialsPath: config.remoteCredentialsPath ?? config.remoteAuth?.credentialsPath,
183
+ timeoutMs: config.remoteTimeoutMs,
184
+ defaultIssuer: config.remoteAuth?.issuer,
185
+ defaultClientId: config.remoteAuth?.clientId,
186
+ });
187
+ // Текущее активное remote-состояние: зеркала провайдеров/модели/мост задаются
188
+ // в applyConnected() (после успешного connect*) и сбрасываются в disconnectRemote().
189
+ // Зеркал несколько — по одному на каждого включённого серверного провайдера.
190
+ let activeRemoteProviderNames = new Set();
191
+ let activeRemoteModels = [];
192
+ let activeBridge;
193
+ /** Политика «все LLM — через сервер»: активна только при подключении И remoteLlm !== 'local'. */
194
+ let blockLocalProviders = false;
195
+ // Снапшоты локальных записей providerCache/modelCache, перекрытых зеркалами, —
196
+ // для восстановления в disconnectRemote (иначе локальные провайдеры/модели с теми
197
+ // же именами, что и серверные, исчезли бы из in-memory кэшей до рестарта).
198
+ const providerMirrorSnapshot = new Map();
199
+ const modelMirrorSnapshot = new Map();
200
+ // ── Состояние гибрида (для hybrid/status, без auth) ──
201
+ function getHybridState() {
202
+ const serverConfigured = !!config.defaultBackendUrl;
203
+ return {
204
+ enabled: serverConfigured || connection.connected,
205
+ connected: connection.connected,
206
+ backendUrl: connection.backendUrl,
207
+ user: connection.user,
208
+ serverConfigured,
209
+ // Вход на сервер возможен: адрес известен (--connect/env/конфиг), есть
210
+ // OIDC issuer (--oidc-issuer/--oidc-client-id как fallback дискавери)
211
+ // или уже есть runtime-подключение.
212
+ serverLoginAvailable: serverConfigured || !!config.remoteAuth?.issuer || connection.connected,
213
+ };
214
+ }
215
+ /**
216
+ * Откат зеркал: восстановить перекрытые локальные записи из снапшотов и
217
+ * дерегистрировать токены. Вызывается перед новым подключением (reconnect)
218
+ * и в disconnectRemote.
219
+ */
220
+ function restoreRemoteMirrors() {
221
+ for (const name of activeRemoteProviderNames) {
222
+ removeRemoteTokenProvider(name);
223
+ }
224
+ for (const [name, prev] of providerMirrorSnapshot) {
225
+ if (prev)
226
+ providerCache.set(name, prev);
227
+ else
228
+ providerCache.delete(name);
229
+ }
230
+ for (const [id, prev] of modelMirrorSnapshot) {
231
+ if (prev)
232
+ modelCache.set(id, prev);
233
+ else
234
+ modelCache.delete(id);
235
+ }
236
+ providerMirrorSnapshot.clear();
237
+ modelMirrorSnapshot.clear();
238
+ activeRemoteProviderNames.clear();
239
+ activeRemoteModels = [];
240
+ blockLocalProviders = false;
241
+ }
242
+ // ── Подключение: применить состояние после успешного connect* ──
243
+ async function applyConnected(user) {
244
+ const client = connection.client;
245
+ const backendUrl = connection.backendUrl;
246
+ if (!client || !backendUrl) {
247
+ throw new RemoteError('Удалённый backend не подключён', 'AUTH');
248
+ }
249
+ // Reconnect без disconnect: сначала откатываем предыдущие зеркала.
250
+ restoreRemoteMirrors();
251
+ // Зеркалирование (Задача 1): вместо одного синтетического synth-remote берём
252
+ // с сервера полный список провайдеров и моделей. Каждый включённый серверный
253
+ // провайдер зеркалится в providerCache под НАСТОЯЩИМ именем (itphx, ollama, …)
254
+ // как type:'remote' → локальная сессия резолвит имя через providerLoader и
255
+ // RemoteProvider уходит на сервер с явным provider в теле LLM Proxy.
256
+ // Инъекция строго in-memory: в providers/*.json и models/* не пишется.
257
+ const [rawProviders, rawModels] = await Promise.all([
258
+ client.listProviders({ timeoutMs: 5000 }).catch(() => []),
259
+ client.listModels({ timeoutMs: 5000 }).catch(() => []),
260
+ ]);
261
+ blockLocalProviders = (config.remoteLlm ?? 'server') !== 'local';
262
+ // В remote.llm:local зеркала не должны перекрывать локальных провайдеров —
263
+ // их имена берём из локального store (провайдеры из env тоже сохранены туда).
264
+ const localProviderNames = new Set((await providerStore.list()).map((p) => p.name));
265
+ const models = (rawModels ?? [])
266
+ .map((m) => ({
267
+ id: m.id,
268
+ name: m.name,
269
+ // Провайдер сохраняем как на сервере (без переписывания на synth-remote).
270
+ provider: m.provider,
271
+ description: m.description,
272
+ enabled: m.enabled !== false,
273
+ isDefault: m.isDefault === true || undefined,
274
+ contextWindow: m.contextWindow && m.contextWindow > 0 ? m.contextWindow : undefined,
275
+ contextSource: m.contextSource,
276
+ maxOutputTokens: m.maxOutputTokens,
277
+ inputPrice: m.inputPrice,
278
+ outputPrice: m.outputPrice,
279
+ cacheReadPrice: m.cacheReadPrice,
280
+ cacheWritePrice: m.cacheWritePrice,
281
+ }))
282
+ .filter((m) => m.id && m.provider);
283
+ // Имена провайдеров, которые реально зеркалим: включённые и не служебные
284
+ // (__*), а в remote.llm:local — ещё и не совпадающие с локальными.
285
+ const mirrorNames = new Set();
286
+ for (const sp of rawProviders ?? []) {
287
+ if (!sp.name || sp.name.startsWith('__'))
288
+ continue;
289
+ if (sp.enabled === false)
290
+ continue;
291
+ if (!blockLocalProviders && localProviderNames.has(sp.name))
292
+ continue;
293
+ mirrorNames.add(sp.name);
294
+ }
295
+ // Модели зеркалим только тех провайдеров, что реально зеркалим: модель
296
+ // провайдера без зеркала не резолвится оркестратором (provider_not_found).
297
+ const modelsToMirror = models.filter((m) => mirrorNames.has(m.provider));
298
+ // Снапшот перекрываемых записей до инъекции.
299
+ for (const name of mirrorNames) {
300
+ providerMirrorSnapshot.set(name, providerCache.get(name) ?? null);
301
+ }
302
+ for (const m of modelsToMirror) {
303
+ if (!modelMirrorSnapshot.has(m.id)) {
304
+ modelMirrorSnapshot.set(m.id, modelCache.get(m.id) ?? null);
305
+ }
306
+ }
307
+ // Инъекция зеркал: провайдер → кэш, модели этого провайдера → modelCache,
308
+ // токен → реестр RemoteProvider (имя зеркала = серверное имя).
309
+ const getToken = connection.getToken;
310
+ for (const name of mirrorNames) {
311
+ const providerInfo = (rawProviders ?? []).find((p) => p.name === name);
312
+ const spec = {
313
+ provider: {
314
+ name,
315
+ type: 'remote',
316
+ baseUrl: backendUrl,
317
+ apiKey: '',
318
+ defaultModel: providerInfo.model || undefined,
319
+ enabled: true,
320
+ },
321
+ models: modelsToMirror.filter((m) => m.provider === name),
322
+ getToken: getToken ?? (async () => null),
323
+ };
324
+ injectRemoteProvider(providerCache, modelCache, spec);
325
+ }
326
+ activeRemoteProviderNames = mirrorNames;
327
+ activeRemoteModels = modelsToMirror;
328
+ // Мост событий backend → локальный EventBus: останавливаем старый (если был)
329
+ // и запускаем новый для текущего клиента.
330
+ activeBridge?.stop();
331
+ if (getToken) {
332
+ activeBridge = new RemoteEventBridge({ client, getToken, eventBus, backendUrl });
333
+ activeBridge.start();
334
+ }
335
+ return user;
336
+ }
337
+ // ── Отключение: полный сброс runtime-состояния ──
338
+ async function disconnectRemote() {
339
+ activeBridge?.stop();
340
+ activeBridge = undefined;
341
+ restoreRemoteMirrors();
342
+ connection.disconnect();
343
+ }
344
+ // ── Публичные обёртки connect* + applyConnected ──
345
+ async function connectRemote(serverUrl, username, password) {
346
+ const user = await connection.connectByPassword(serverUrl, username, password);
347
+ return applyConnected(user);
348
+ }
349
+ async function connectRemoteFromSaved(backendUrl) {
350
+ const user = await connection.connectFromSaved(backendUrl);
351
+ if (!user)
352
+ return null;
353
+ return applyConnected(user);
354
+ }
355
+ async function connectRemoteWithApiKey(serverUrl, apiKey) {
356
+ const user = await connection.connectWithApiKey(serverUrl, apiKey);
357
+ return applyConnected(user);
358
+ }
144
359
  // Health — без auth
145
360
  const healthRoutes = createHealthRoutes();
146
361
  app.route('/', healthRoutes);
362
+ // Hybrid status — без auth (как health): UI опрашивает статус подключения
363
+ // к удалённому backend до аутентификации.
364
+ const hybridRoutes = createHybridRoutes(getHybridState);
365
+ app.route('/', hybridRoutes);
147
366
  // Auth routes — без auth (только spa-login проверяет ключ сам)
148
- app.route('/auth', createAuthRoutes(auth));
149
- // i18n — без auth
150
- app.route('/api/v2/i18n', createI18nRoutes());
367
+ app.route('/auth', createAuthRoutes(auth, {
368
+ connection,
369
+ connectRemote,
370
+ connectRemoteFromSaved,
371
+ connectRemoteWithApiKey,
372
+ disconnectRemote,
373
+ defaultBackendUrl: config.defaultBackendUrl,
374
+ issuerAvailable: !!config.remoteAuth?.issuer,
375
+ }));
151
376
  // Всё остальное требует аутентификации
152
377
  app.use('/api/*', auth.requireAuth);
153
378
  app.use('/ws/*', auth.requireAuth);
379
+ // Гибрид (Batch 2, T5): серверные/админ-эндпоинты (которых нет у standalone
380
+ // или источник истины — сервер) проксируются на удалённый backend.
381
+ // Стоит ПОСЛЕ requireAuth и ДО локальных роутов — в гибриде перехватывает
382
+ // /api/v2/{audit,users,admin,logs,gateway,context,llm,providers,models}.
383
+ // Middleware регистрируется ВСЕГДА; без runtime-подключения getClient() даёт
384
+ // null → next() (запрос обрабатывают локальные роуты).
385
+ app.use('/api/*', createRemoteProxyMiddleware(() => connection.client, () => connection.getToken?.() ?? Promise.resolve(null)));
154
386
  const dataDir = config.dataDir;
155
387
  await ensureDataDir(dataDir);
156
388
  // Runtime-настройки (AD-005): workspace из {dataDir}/settings.json приоритетнее config/env
@@ -161,8 +393,13 @@ export async function createStandaloneApp(config) {
161
393
  // AD-036: runtime-настройка LLM Gateway (тумблер из UI) приоритетнее config.yaml
162
394
  const runtimeGateway = await settingsStore.getLlmGatewaySettings();
163
395
  const gatewayConfig = mergeLlmGatewayConfig(config.gatewayConfig, runtimeGateway);
396
+ // Защищённые пути: runtime-настройка protectedPaths.enabled (тумблер из UI) приоритетнее config.yaml
397
+ const runtimeSecurity = await settingsStore.getSecuritySettings();
398
+ const effectiveSecurityConfig = mergeSecurityConfig(config.securityConfig, runtimeSecurity);
164
399
  // AD-036: хранилище кастомных regex-паттернов детекции секретов (override ?? дефолт)
165
400
  const patternStore = new SecretPatternStore({ dataDir });
401
+ // Защищённые пути: store override-политики (add/remove) + миграция legacy shell-policy
402
+ const protectedPathsStore = new ProtectedPathsStore({ dataDir });
166
403
  const fileStore = new FileStore({ dataDir });
167
404
  const sessionManager = new SessionManager(fileStore, {
168
405
  mcpSettingsProvider: () => settingsStore.getMcpSettings(),
@@ -185,9 +422,6 @@ export async function createStandaloneApp(config) {
185
422
  projectDataDir: `${dataDir}/projects`,
186
423
  defaultLanguage: 'ru',
187
424
  });
188
- const providerLoader = (name) => {
189
- return providerCache.get(name) ?? null;
190
- };
191
425
  const providerCache = new Map();
192
426
  (await providerStore.list()).forEach((p) => {
193
427
  providerCache.set(p.name, p);
@@ -196,13 +430,32 @@ export async function createStandaloneApp(config) {
196
430
  (await modelStore.list()).forEach((m) => {
197
431
  modelCache.set(m.id, m);
198
432
  });
433
+ // Гибрид: remote-провайдер/модели инъектируются в кэши в applyConnected()
434
+ // (после успешного runtime-подключения), а не при создании приложения.
435
+ // Загрузчик провайдеров для движка: при политике remoteLlm=server разрешены
436
+ // ТОЛЬКО зеркала серверных провайдеров (blockLocalProviders ставится в
437
+ // applyConnected); при remote.llm=local локальные провайдеры остаются доступны.
438
+ const providerLoader = (name) => {
439
+ if (blockLocalProviders && activeRemoteProviderNames.size > 0 && !activeRemoteProviderNames.has(name))
440
+ return null;
441
+ return providerCache.get(name) ?? null;
442
+ };
443
+ // Загрузчик сохранённого контекстного окна модели (ModelConfig.contextWindow)
444
+ const modelWindowLoader = (modelName) => {
445
+ for (const m of modelCache.values()) {
446
+ if (m.name === modelName || m.id === modelName) {
447
+ return m.contextWindow && m.contextWindow > 0 ? m.contextWindow : 0;
448
+ }
449
+ }
450
+ return 0;
451
+ };
199
452
  const summarizationConfig = {
200
453
  provider: '',
201
454
  model: '',
202
455
  temperature: 0.3,
203
456
  promptFile: 'SUMMARIZER',
204
457
  };
205
- const contextOptimizer = new ContextOptimizer(contextConfig, providerLoader, summarizationConfig);
458
+ const contextOptimizer = new ContextOptimizer(contextConfig, providerLoader, summarizationConfig, modelWindowLoader);
206
459
  queueManager.setContextOptimizer(contextOptimizer);
207
460
  const modelPriceLoader = (modelName) => {
208
461
  for (const m of modelCache.values()) {
@@ -223,6 +476,7 @@ export async function createStandaloneApp(config) {
223
476
  sessionManager,
224
477
  eventBus,
225
478
  contextBuilder,
479
+ contextConfig,
226
480
  providerLoader,
227
481
  contextOptimizer,
228
482
  modelPriceLoader,
@@ -234,7 +488,7 @@ export async function createStandaloneApp(config) {
234
488
  workspacesRoot: config.workspacesRoot ?? join(dataDir, 'workspaces'),
235
489
  permissionConfig: config.permissionConfig,
236
490
  defaultPlanMode: config.defaultPlanMode,
237
- securityConfig: config.securityConfig,
491
+ securityConfig: effectiveSecurityConfig,
238
492
  gatewayConfig,
239
493
  gatewayPatternStore: patternStore,
240
494
  mcpManager,
@@ -243,23 +497,39 @@ export async function createStandaloneApp(config) {
243
497
  // API-заглушки для UI
244
498
  app.get('/api/config/themes', (c) => c.json({ themes: [] }));
245
499
  // Sessions
246
- app.route('/api/v2/sessions', createSessionRoutes(auth, sessionManager, eventBus, queueManager, processMessage, orchestrator, contextOptimizer));
500
+ app.route('/api/v2/sessions', createSessionRoutes(auth, sessionManager, eventBus, queueManager, processMessage, orchestrator, contextOptimizer, projectStore, () => connection.client));
247
501
  // Projects
248
- app.route('/api/v2/projects', createProjectRoutes(auth, projectStore));
502
+ app.route('/api/v2/projects', createProjectRoutes(auth, projectStore, () => connection.client));
503
+ // Перенос проектов между мирами (гибрид, UI publish/fork): те же пути, что у
504
+ // project-роутов (:id/publish, :id/fork-local — без конфликта с :id). Работает
505
+ // in-process через remote/transfer.ts, требует runtime-подключения к backend.
506
+ app.route('/api/v2/projects', createProjectTransferRoutes(auth, projectStore, sessionManager, config.workspacesRoot ?? join(dataDir, 'workspaces'), defaultWorkingDir, () => connection.client));
249
507
  // Providers
250
- app.route('/api/v2/providers', createProviderRoutes(auth, providerStore, true));
251
- // Models
252
- app.route('/api/v2/models', createModelRoutes(auth, modelStore, providerStore));
508
+ app.route('/api/v2/providers', createProviderRoutes(auth, providerStore, providerCache, true));
509
+ // Models: remote-модели/провайдер читаются на каждый запрос (runtime-подключение).
510
+ app.route('/api/v2/models', createModelRoutes(auth, modelStore, providerStore, modelCache, {
511
+ extraModels: () => [...activeRemoteModels],
512
+ extraProviders: () => {
513
+ const out = [];
514
+ for (const name of activeRemoteProviderNames) {
515
+ const p = providerCache.get(name);
516
+ if (p)
517
+ out.push(p);
518
+ }
519
+ return out;
520
+ },
521
+ onlyRemoteModels: () => blockLocalProviders && activeRemoteProviderNames.size > 0,
522
+ }));
253
523
  // Agents
254
524
  app.route('/api/v2/agents', createAgentRoutes(auth, agentStore, agentRegistry));
255
525
  // FS
256
- app.route('/api/v2/fs', createFsRoutes(auth, config.workspacesRoot));
526
+ app.route('/api/v2/fs', createFsRoutes(auth, config.workspacesRoot, () => connection.client));
257
527
  // Queue
258
- app.route('/api/v2/queue', createQueueRoutes(auth, sessionManager, queueManager, eventBus, processMessage));
528
+ app.route('/api/v2/queue', createQueueRoutes(auth, sessionManager, queueManager, eventBus, processMessage, () => connection.client));
259
529
  // Updates
260
530
  app.route('/api/v2/updates', createUpdateRoutes(auth, dataDir));
261
531
  // Messages (batch operations)
262
- app.route('/api/v2/messages', createMessageRoutes(auth, sessionManager));
532
+ app.route('/api/v2/messages', createMessageRoutes(auth, sessionManager, () => connection.client));
263
533
  // Settings (runtime-настройки для UI, раздел «Проекты»)
264
534
  app.route('/api/v2/settings', createSettingsRoutes(auth, {
265
535
  settingsStore,
@@ -269,6 +539,16 @@ export async function createStandaloneApp(config) {
269
539
  const merged = mergeLlmGatewayConfig(config.gatewayConfig, runtime);
270
540
  orchestrator.setGatewayConfig(merged);
271
541
  },
542
+ // Live-применение тумблера защищённых путей + таймаута подтверждения из UI —
543
+ // без рестарта сервера.
544
+ onSecurityChange: async (runtime) => {
545
+ const merged = mergeSecurityConfig(config.securityConfig, runtime);
546
+ orchestrator.setSecurityConfig(merged);
547
+ if (merged?.askTimeoutMs !== undefined) {
548
+ orchestrator.setDefaultPermissionTimeout(merged.askTimeoutMs);
549
+ }
550
+ },
551
+ protectedPathsStore,
272
552
  }));
273
553
  // MCP (probe подключения к серверу)
274
554
  app.route('/api/v2/mcp', createMcpRoutes(auth, { mcpManager }));
@@ -278,7 +558,6 @@ export async function createStandaloneApp(config) {
278
558
  return new Response(new ReadableStream({
279
559
  async start(controller) {
280
560
  const encoder = new TextEncoder();
281
- const allSessions = await sessionManager.listSessions({ userId: 'local' });
282
561
  const unsubs = [];
283
562
  const handler = (event) => {
284
563
  try {
@@ -289,8 +568,16 @@ export async function createStandaloneApp(config) {
289
568
  // disconnected
290
569
  }
291
570
  };
292
- for (const s of allSessions) {
293
- unsubs.push(eventBus.subscribe(s.id, handler));
571
+ if (connection.connected) {
572
+ // Гибрид: события удалённых сессий (remote:<id>) публикует мост,
573
+ // локальных — оркестратор. Только subscribeAll — без дублей.
574
+ unsubs.push(eventBus.subscribeAll(handler));
575
+ }
576
+ else {
577
+ const allSessions = await sessionManager.listSessions({ userId: 'local' });
578
+ for (const s of allSessions) {
579
+ unsubs.push(eventBus.subscribe(s.id, handler));
580
+ }
294
581
  }
295
582
  const keepalive = setInterval(() => {
296
583
  try {
@@ -402,6 +689,11 @@ export async function createStandaloneApp(config) {
402
689
  }
403
690
  const headers = Object.fromEntries(response.headers.entries());
404
691
  res.writeHead(response.status, headers);
692
+ // SSE/долгоживущие стримы: при chunked-кодировании Node не сбрасывает
693
+ // заголовки в сокет до первого write()/end(). Для пустого начала стрима
694
+ // (SSE до первого события/keepalive) клиент иначе не получит заголовки
695
+ // вовсе — сбрасываем head принудительно.
696
+ res.flushHeaders();
405
697
  if (response.body) {
406
698
  const reader = response.body.getReader();
407
699
  const pump = async () => {
@@ -433,14 +725,28 @@ export async function createStandaloneApp(config) {
433
725
  const token = typeof authHeader === 'string' && authHeader.startsWith('Bearer ')
434
726
  ? authHeader.slice(7)
435
727
  : null;
436
- if (token !== config.apiKey) {
728
+ // Аутентификация: либо валидный Bearer API-ключ (CLI/API-клиенты), либо
729
+ // cookie-сессия v2 (server-identity/local) — браузер не может ставить
730
+ // Authorization-заголовок на WebSocket, поэтому UI полагается на cookie.
731
+ let authorized = token === config.apiKey;
732
+ if (!authorized) {
733
+ const cookieContext = {
734
+ req: {
735
+ header: (name) => {
736
+ const v = request.headers[name.toLowerCase()];
737
+ return Array.isArray(v) ? v[0] : v;
738
+ },
739
+ },
740
+ };
741
+ authorized = auth.getCurrentUser(cookieContext) !== null;
742
+ }
743
+ if (!authorized) {
437
744
  socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
438
745
  socket.destroy();
439
746
  return;
440
747
  }
441
748
  wss.handleUpgrade(request, socket, head, async (ws) => {
442
749
  const clientId = `ws-events-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
443
- const allSessions = await sessionManager.listSessions({ userId: 'local' });
444
750
  const unsubs = [];
445
751
  const handler = (event) => {
446
752
  try {
@@ -450,8 +756,16 @@ export async function createStandaloneApp(config) {
450
756
  }
451
757
  catch { /* ignore */ }
452
758
  };
453
- for (const s of allSessions) {
454
- unsubs.push(eventBus.subscribe(s.id, handler));
759
+ if (connection.connected) {
760
+ // Гибрид: события удалённых сессий (remote:<id>) публикует мост —
761
+ // подписываемся на все события (без дублей для локальных).
762
+ unsubs.push(eventBus.subscribeAll(handler));
763
+ }
764
+ else {
765
+ const allSessions = await sessionManager.listSessions({ userId: 'local' });
766
+ for (const s of allSessions) {
767
+ unsubs.push(eventBus.subscribe(s.id, handler));
768
+ }
455
769
  }
456
770
  ws.send(JSON.stringify({
457
771
  type: 'connected',
@@ -476,6 +790,39 @@ export async function createStandaloneApp(config) {
476
790
  timestamp: nowISO(),
477
791
  }));
478
792
  (async () => {
793
+ // Гибрид: remote-сессия (`remote:<id>`) — промпт уходит на удалённый
794
+ // backend (raw Response, тело не читаем), события возвращаются через
795
+ // RemoteEventBridge. Локальный оркестратор не запускается.
796
+ if (isRemoteRef(sid)) {
797
+ const remote = connection.client;
798
+ if (!remote) {
799
+ ws.send(JSON.stringify({
800
+ type: 'error',
801
+ session_id: sid,
802
+ data: { error: 'Удалённый сервер не подключён' },
803
+ timestamp: nowISO(),
804
+ }));
805
+ return;
806
+ }
807
+ try {
808
+ await remote.promptSession(toLocalId(sid), {
809
+ content: msg.content.trim(),
810
+ messageId: streamId,
811
+ ...(msg.agent_role ? { agent: msg.agent_role } : {}),
812
+ ...(msg.provider ? { provider: msg.provider } : {}),
813
+ ...(msg.model ? { model: msg.model } : {}),
814
+ });
815
+ }
816
+ catch (err) {
817
+ ws.send(JSON.stringify({
818
+ type: 'error',
819
+ session_id: sid,
820
+ data: { error: err instanceof Error ? err.message : String(err) },
821
+ timestamp: nowISO(),
822
+ }));
823
+ }
824
+ return;
825
+ }
479
826
  const session = await sessionManager.getSession(sid);
480
827
  if (!session) {
481
828
  ws.send(JSON.stringify({
@@ -568,6 +915,25 @@ export async function createStandaloneApp(config) {
568
915
  if (config.uiDistPath && existsSync(config.uiDistPath)) {
569
916
  console.log(` ui: serving from ${config.uiDistPath}`);
570
917
  }
571
- return { app, server, wss, port };
918
+ if (config.defaultBackendUrl) {
919
+ console.log(` remote: гибридный режим (сервер ${config.defaultBackendUrl}) — подключение в рантайме`);
920
+ }
921
+ return {
922
+ app,
923
+ server,
924
+ wss,
925
+ port,
926
+ connection,
927
+ connectRemote,
928
+ connectRemoteFromSaved,
929
+ connectRemoteWithApiKey,
930
+ disconnectRemote,
931
+ getHybridStatus: getHybridState,
932
+ eventBus,
933
+ // Текущий мост событий (создаётся/обновляется в applyConnected) — для stop() при shutdown.
934
+ get remoteEventBridge() {
935
+ return activeBridge;
936
+ },
937
+ };
572
938
  }
573
939
  //# sourceMappingURL=app.js.map