@ai-setting/roy-agent-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. package/dist/index.js +99145 -0
  2. package/package.json +114 -0
  3. package/src/config/config-component.test.ts +627 -0
  4. package/src/config/config-component.ts +906 -0
  5. package/src/config/config-parser.test.ts +319 -0
  6. package/src/config/config-parser.ts +203 -0
  7. package/src/config/decentralized-config.test.ts +740 -0
  8. package/src/config/env-key.ts +210 -0
  9. package/src/config/env-source.test.ts +252 -0
  10. package/src/config/env-source.ts +301 -0
  11. package/src/config/file-source.test.ts +357 -0
  12. package/src/config/file-source.ts +421 -0
  13. package/src/config/index.ts +24 -0
  14. package/src/config/protocol-resolver.test.ts +217 -0
  15. package/src/config/protocol-resolver.ts +228 -0
  16. package/src/env/agent/agent-component.abort.test.ts +511 -0
  17. package/src/env/agent/agent-component.record-session.test.ts +349 -0
  18. package/src/env/agent/agent-component.test.ts +1389 -0
  19. package/src/env/agent/agent-component.tool-error.test.ts +327 -0
  20. package/src/env/agent/agent-component.ts +1711 -0
  21. package/src/env/agent/agent-config-registration.test.ts +226 -0
  22. package/src/env/agent/agent-config-registration.ts +46 -0
  23. package/src/env/agent/agent-reminder-plugin.integration.test.ts +243 -0
  24. package/src/env/agent/index.ts +10 -0
  25. package/src/env/agent/summary-agent.parse-hint.test.ts +360 -0
  26. package/src/env/agent/summary-agent.ts +508 -0
  27. package/src/env/agent/types.ts +536 -0
  28. package/src/env/commands/commands-component.test.ts +364 -0
  29. package/src/env/commands/commands-component.ts +604 -0
  30. package/src/env/commands/commands-config-registration.test.ts +198 -0
  31. package/src/env/commands/commands-config-registration.ts +38 -0
  32. package/src/env/commands/index.ts +21 -0
  33. package/src/env/commands/parser.test.ts +203 -0
  34. package/src/env/commands/parser.ts +115 -0
  35. package/src/env/commands/types.ts +184 -0
  36. package/src/env/commands-prompt-integration.test.ts +243 -0
  37. package/src/env/component-env.test.ts +119 -0
  38. package/src/env/component.ts +335 -0
  39. package/src/env/constants.test.ts +72 -0
  40. package/src/env/constants.ts +123 -0
  41. package/src/env/debug/debug-component.test.ts +114 -0
  42. package/src/env/debug/debug-component.ts +547 -0
  43. package/src/env/debug/formatters/index.ts +9 -0
  44. package/src/env/debug/formatters/repl-formatter.test.ts +139 -0
  45. package/src/env/debug/formatters/repl-formatter.ts +358 -0
  46. package/src/env/debug/formatters/trace-formatter.test.ts +119 -0
  47. package/src/env/debug/formatters/trace-formatter.ts +191 -0
  48. package/src/env/debug/formatters/tree-formatter.test.ts +107 -0
  49. package/src/env/debug/formatters/tree-formatter.ts +325 -0
  50. package/src/env/debug/index.ts +38 -0
  51. package/src/env/debug/parser/regex-parser.test.ts +201 -0
  52. package/src/env/debug/parser/regex-parser.ts +196 -0
  53. package/src/env/debug/parser/span-builder.test.ts +241 -0
  54. package/src/env/debug/parser/span-builder.ts +386 -0
  55. package/src/env/debug/reader/log-reader.test.ts +170 -0
  56. package/src/env/debug/reader/log-reader.ts +186 -0
  57. package/src/env/debug/reader/span-db-reader.test.ts +118 -0
  58. package/src/env/debug/reader/span-db-reader.ts +201 -0
  59. package/src/env/debug/types.test.ts +187 -0
  60. package/src/env/debug/types.ts +171 -0
  61. package/src/env/environment-init.test.ts +183 -0
  62. package/src/env/environment-lifecycle.test.ts +516 -0
  63. package/src/env/environment-service.test.ts +332 -0
  64. package/src/env/environment.handle-query.test.ts +96 -0
  65. package/src/env/environment.test.ts +232 -0
  66. package/src/env/environment.ts +708 -0
  67. package/src/env/errors.test.ts +165 -0
  68. package/src/env/errors.ts +157 -0
  69. package/src/env/event-source/event-source-agent-handler.test.ts +193 -0
  70. package/src/env/event-source/event-source-agent-handler.ts +111 -0
  71. package/src/env/event-source/event-source-component.process-cleanup.test.ts +236 -0
  72. package/src/env/event-source/event-source-component.stop.test.ts +346 -0
  73. package/src/env/event-source/event-source-component.test.ts +1207 -0
  74. package/src/env/event-source/event-source-component.ts +1379 -0
  75. package/src/env/event-source/event-source-config-registration.test.ts +242 -0
  76. package/src/env/event-source/event-source-config-registration.ts +37 -0
  77. package/src/env/event-source/event-source-integration.test.ts +320 -0
  78. package/src/env/event-source/event-source-platform.test.ts +630 -0
  79. package/src/env/event-source/types.ts +298 -0
  80. package/src/env/hook/global-hook-manager.ts +162 -0
  81. package/src/env/hook/hook-manager.test.ts +374 -0
  82. package/src/env/hook/hook-manager.ts +309 -0
  83. package/src/env/hook/index.ts +38 -0
  84. package/src/env/hook/types.ts +138 -0
  85. package/src/env/index.ts +144 -0
  86. package/src/env/interface.ts +203 -0
  87. package/src/env/llm/hooks.test.ts +293 -0
  88. package/src/env/llm/hooks.ts +316 -0
  89. package/src/env/llm/index.ts +61 -0
  90. package/src/env/llm/invoke-threshold-check.test.ts +88 -0
  91. package/src/env/llm/invoke-timeout.test.ts +54 -0
  92. package/src/env/llm/invoke.test.ts +71 -0
  93. package/src/env/llm/invoke.ts +1039 -0
  94. package/src/env/llm/llm-config.test.ts +523 -0
  95. package/src/env/llm/llm.test.ts +233 -0
  96. package/src/env/llm/llm.ts +568 -0
  97. package/src/env/llm/provider.test.ts +182 -0
  98. package/src/env/llm/provider.ts +108 -0
  99. package/src/env/llm/transform.test.ts +251 -0
  100. package/src/env/llm/transform.ts +286 -0
  101. package/src/env/llm/types.test.ts +580 -0
  102. package/src/env/llm/types.ts +424 -0
  103. package/src/env/log-trace/decorator-otel.test.ts +182 -0
  104. package/src/env/log-trace/decorator.ts +230 -0
  105. package/src/env/log-trace/index.ts +79 -0
  106. package/src/env/log-trace/log-trace-component.test.ts +242 -0
  107. package/src/env/log-trace/log-trace-component.ts +497 -0
  108. package/src/env/log-trace/log-trace-config-registration.test.ts +348 -0
  109. package/src/env/log-trace/log-trace-config-registration.ts +45 -0
  110. package/src/env/log-trace/logger.test.ts +149 -0
  111. package/src/env/log-trace/logger.ts +522 -0
  112. package/src/env/log-trace/opentelemetry/cli-propagation.test.ts +147 -0
  113. package/src/env/log-trace/opentelemetry/cli-propagation.ts +194 -0
  114. package/src/env/log-trace/opentelemetry/integration.test.ts +668 -0
  115. package/src/env/log-trace/opentelemetry/mod.ts +25 -0
  116. package/src/env/log-trace/opentelemetry/propagation-env.test.ts +181 -0
  117. package/src/env/log-trace/opentelemetry/propagation-env.ts +136 -0
  118. package/src/env/log-trace/opentelemetry/propagation.test.ts +259 -0
  119. package/src/env/log-trace/opentelemetry/propagation.ts +215 -0
  120. package/src/env/log-trace/opentelemetry/tracer-provider-context.test.ts +166 -0
  121. package/src/env/log-trace/opentelemetry/tracer-provider.test.ts +379 -0
  122. package/src/env/log-trace/opentelemetry/tracer-provider.ts +612 -0
  123. package/src/env/log-trace/span-storage.test.ts +145 -0
  124. package/src/env/log-trace/span-storage.ts +230 -0
  125. package/src/env/log-trace/trace-context.test.ts +187 -0
  126. package/src/env/log-trace/trace-context.ts +162 -0
  127. package/src/env/log-trace/types.test.ts +63 -0
  128. package/src/env/log-trace/types.ts +172 -0
  129. package/src/env/mcp/README.md +244 -0
  130. package/src/env/mcp/__integration__/mcp-component.integration.test.ts +373 -0
  131. package/src/env/mcp/config.test.ts +74 -0
  132. package/src/env/mcp/config.ts +116 -0
  133. package/src/env/mcp/index.ts +41 -0
  134. package/src/env/mcp/loader.test.ts +161 -0
  135. package/src/env/mcp/loader.ts +209 -0
  136. package/src/env/mcp/mcp-component.test.ts +111 -0
  137. package/src/env/mcp/mcp-component.ts +358 -0
  138. package/src/env/mcp/mcp-config-registration.test.ts +304 -0
  139. package/src/env/mcp/mcp-config-registration.ts +50 -0
  140. package/src/env/mcp/scanner.test.ts +170 -0
  141. package/src/env/mcp/scanner.ts +246 -0
  142. package/src/env/mcp/tool/adapter.test.ts +520 -0
  143. package/src/env/mcp/tool/adapter.ts +521 -0
  144. package/src/env/mcp/tool/index.ts +5 -0
  145. package/src/env/mcp/types.test.ts +171 -0
  146. package/src/env/mcp/types.ts +79 -0
  147. package/src/env/memory/README.md +177 -0
  148. package/src/env/memory/built-in/index.ts +59 -0
  149. package/src/env/memory/built-in/recall-memory.ts +103 -0
  150. package/src/env/memory/built-in/record-memory.ts +148 -0
  151. package/src/env/memory/index.ts +20 -0
  152. package/src/env/memory/memory-component.test.ts +239 -0
  153. package/src/env/memory/memory-component.ts +503 -0
  154. package/src/env/memory/memory-config-registration.test.ts +67 -0
  155. package/src/env/memory/memory-config-registration.ts +48 -0
  156. package/src/env/memory/memory-config.ts +45 -0
  157. package/src/env/memory/memory-file.test.ts +268 -0
  158. package/src/env/memory/plugin/index.ts +48 -0
  159. package/src/env/memory/plugin/memory-agent.test.ts +249 -0
  160. package/src/env/memory/plugin/memory-agent.ts +365 -0
  161. package/src/env/memory/plugin/memory-manager.ts +198 -0
  162. package/src/env/memory/plugin/memory-plugin-agent.test.ts +145 -0
  163. package/src/env/memory/plugin/memory-plugin.ts +210 -0
  164. package/src/env/memory/plugin/plugin-simplified.test.ts +51 -0
  165. package/src/env/memory/plugin/recall-memory.test.ts +106 -0
  166. package/src/env/memory/plugin/recall-memory.ts +53 -0
  167. package/src/env/memory/plugin/types.ts +101 -0
  168. package/src/env/memory/tools/memory-agent-tools.ts +228 -0
  169. package/src/env/memory/types.ts +85 -0
  170. package/src/env/paths.ts +118 -0
  171. package/src/env/prompt/index.ts +18 -0
  172. package/src/env/prompt/memory-prompts.test.ts +91 -0
  173. package/src/env/prompt/prompt-component.test.ts +491 -0
  174. package/src/env/prompt/prompt-component.ts +619 -0
  175. package/src/env/prompt/prompt-config-registration.test.ts +213 -0
  176. package/src/env/prompt/prompt-config-registration.ts +39 -0
  177. package/src/env/prompt/prompts-index.ts +504 -0
  178. package/src/env/prompt/renderer.ts +67 -0
  179. package/src/env/prompt/types.ts +136 -0
  180. package/src/env/session/hooks.ts +18 -0
  181. package/src/env/session/index.ts +37 -0
  182. package/src/env/session/search-query-parser.test.ts +425 -0
  183. package/src/env/session/search-query-parser.ts +171 -0
  184. package/src/env/session/session-checkpoint.test.ts +523 -0
  185. package/src/env/session/session-component.extract-recent-messages.test.ts +209 -0
  186. package/src/env/session/session-component.test.ts +132 -0
  187. package/src/env/session/session-component.ts +1249 -0
  188. package/src/env/session/session-config-registration.test.ts +138 -0
  189. package/src/env/session/session-config-registration.ts +52 -0
  190. package/src/env/session/session-message-converter.test.ts +763 -0
  191. package/src/env/session/session-message-converter.ts +415 -0
  192. package/src/env/session/session-message-e2e.test.ts +448 -0
  193. package/src/env/session/session-search.test.ts +391 -0
  194. package/src/env/session/session-store.test.ts +362 -0
  195. package/src/env/session/session-store.ts +141 -0
  196. package/src/env/session/storage/index.ts +6 -0
  197. package/src/env/session/storage/memory.ts +502 -0
  198. package/src/env/session/storage/sqlite.ts +794 -0
  199. package/src/env/session/types.ts +742 -0
  200. package/src/env/skill/config.ts +39 -0
  201. package/src/env/skill/index.ts +6 -0
  202. package/src/env/skill/parser.test.ts +116 -0
  203. package/src/env/skill/parser.ts +77 -0
  204. package/src/env/skill/scanner.test.ts +211 -0
  205. package/src/env/skill/scanner.ts +119 -0
  206. package/src/env/skill/skill-component.test.ts +234 -0
  207. package/src/env/skill/skill-component.ts +352 -0
  208. package/src/env/skill/skill-config-registration.test.ts +60 -0
  209. package/src/env/skill/skill-config-registration.ts +43 -0
  210. package/src/env/skill/tool/index.ts +1 -0
  211. package/src/env/skill/tool/skill-tool.test.ts +100 -0
  212. package/src/env/skill/tool/skill-tool.ts +72 -0
  213. package/src/env/skill/types.ts +64 -0
  214. package/src/env/task/delegate/delegate-tool.test.ts +498 -0
  215. package/src/env/task/delegate/delegate-tool.ts +1014 -0
  216. package/src/env/task/delegate/index.ts +18 -0
  217. package/src/env/task/delegate/stop-tool.test.ts +140 -0
  218. package/src/env/task/delegate/stop-tool.ts +119 -0
  219. package/src/env/task/delegate/task-events.test.ts +178 -0
  220. package/src/env/task/delegate/task-events.ts +143 -0
  221. package/src/env/task/hooks/contexts.test.ts +92 -0
  222. package/src/env/task/hooks/contexts.ts +192 -0
  223. package/src/env/task/hooks/index.ts +23 -0
  224. package/src/env/task/hooks/task-hook-points.test.ts +32 -0
  225. package/src/env/task/hooks/task-hook-points.ts +54 -0
  226. package/src/env/task/index.ts +7 -0
  227. package/src/env/task/plugins/index.ts +13 -0
  228. package/src/env/task/plugins/task-plugin.test.ts +74 -0
  229. package/src/env/task/plugins/task-plugin.ts +89 -0
  230. package/src/env/task/plugins/task-tag-plugin.test.ts +377 -0
  231. package/src/env/task/plugins/task-tag-plugin.ts +319 -0
  232. package/src/env/task/plugins/task-workflow-extractor.integration.test.ts +226 -0
  233. package/src/env/task/plugins/workflow-extractor-agent.test.ts +107 -0
  234. package/src/env/task/plugins/workflow-extractor-agent.ts +225 -0
  235. package/src/env/task/storage/index.ts +6 -0
  236. package/src/env/task/storage/sqlite-task-store.test.ts +283 -0
  237. package/src/env/task/storage/sqlite-task-store.ts +903 -0
  238. package/src/env/task/storage/task-search.test.ts +291 -0
  239. package/src/env/task/tag-service.test.ts +198 -0
  240. package/src/env/task/tag-service.ts +264 -0
  241. package/src/env/task/task-component.test.ts +193 -0
  242. package/src/env/task/task-component.ts +658 -0
  243. package/src/env/task/task-config-registration.test.ts +57 -0
  244. package/src/env/task/task-config-registration.ts +37 -0
  245. package/src/env/task/task-types.test.ts +137 -0
  246. package/src/env/task/tools/complete-tool.ts +44 -0
  247. package/src/env/task/tools/create-tool.ts +49 -0
  248. package/src/env/task/tools/delete-tool.ts +43 -0
  249. package/src/env/task/tools/get-tool.ts +59 -0
  250. package/src/env/task/tools/index.ts +10 -0
  251. package/src/env/task/tools/list-tool.ts +40 -0
  252. package/src/env/task/tools/operation/create-tool.ts +48 -0
  253. package/src/env/task/tools/operation/delete-tool.ts +43 -0
  254. package/src/env/task/tools/operation/get-tool.ts +43 -0
  255. package/src/env/task/tools/operation/index.ts +9 -0
  256. package/src/env/task/tools/operation/list-tool.ts +40 -0
  257. package/src/env/task/tools/operation/operation-tools.test.ts +274 -0
  258. package/src/env/task/tools/operation/operation-types.ts +75 -0
  259. package/src/env/task/tools/operation/update-tool.ts +47 -0
  260. package/src/env/task/tools/task-tools.test.ts +203 -0
  261. package/src/env/task/tools/task-types.test.ts +75 -0
  262. package/src/env/task/tools/task-types.ts +68 -0
  263. package/src/env/task/tools/update-tool.ts +70 -0
  264. package/src/env/task/types.ts +160 -0
  265. package/src/env/tool/built-in/bash.ts +201 -0
  266. package/src/env/tool/built-in/echo.ts +29 -0
  267. package/src/env/tool/built-in/edit-file.test.ts +136 -0
  268. package/src/env/tool/built-in/edit-file.ts +92 -0
  269. package/src/env/tool/built-in/glob.test.ts +94 -0
  270. package/src/env/tool/built-in/glob.ts +65 -0
  271. package/src/env/tool/built-in/grep.test.ts +122 -0
  272. package/src/env/tool/built-in/grep.ts +108 -0
  273. package/src/env/tool/built-in/index.ts +44 -0
  274. package/src/env/tool/built-in/read-file.test.ts +84 -0
  275. package/src/env/tool/built-in/read-file.ts +75 -0
  276. package/src/env/tool/built-in/write-file.test.ts +119 -0
  277. package/src/env/tool/built-in/write-file.ts +68 -0
  278. package/src/env/tool/index.ts +24 -0
  279. package/src/env/tool/registry.test.ts +257 -0
  280. package/src/env/tool/registry.ts +167 -0
  281. package/src/env/tool/tool-component.test.ts +559 -0
  282. package/src/env/tool/tool-component.ts +563 -0
  283. package/src/env/tool/tool-config-registration.test.ts +249 -0
  284. package/src/env/tool/tool-config-registration.ts +46 -0
  285. package/src/env/tool/types.ts +267 -0
  286. package/src/env/tool/validator.test.ts +143 -0
  287. package/src/env/tool/validator.ts +44 -0
  288. package/src/env/types.ts +180 -0
  289. package/src/env/workflow/ask-user-tool-registration.test.ts +216 -0
  290. package/src/env/workflow/complex-workflow.integration.test.ts +1900 -0
  291. package/src/env/workflow/decorators/decorator-node.ts +229 -0
  292. package/src/env/workflow/decorators/decorator.test.ts +196 -0
  293. package/src/env/workflow/decorators/edge.ts +82 -0
  294. package/src/env/workflow/decorators/index.ts +31 -0
  295. package/src/env/workflow/decorators/node-as.ts +98 -0
  296. package/src/env/workflow/decorators/workflow.ts +54 -0
  297. package/src/env/workflow/engine/dag-manager.test.ts +570 -0
  298. package/src/env/workflow/engine/dag-manager.ts +594 -0
  299. package/src/env/workflow/engine/engine.ts +1422 -0
  300. package/src/env/workflow/engine/event-bus.test.ts +359 -0
  301. package/src/env/workflow/engine/event-bus.ts +156 -0
  302. package/src/env/workflow/engine/executor-agent-session.test.ts +84 -0
  303. package/src/env/workflow/engine/executor.test.ts +619 -0
  304. package/src/env/workflow/engine/executor.ts +593 -0
  305. package/src/env/workflow/engine/index.ts +24 -0
  306. package/src/env/workflow/engine/node-registry.test.ts +560 -0
  307. package/src/env/workflow/engine/node-registry.ts +289 -0
  308. package/src/env/workflow/engine/resume-removed.test.ts +22 -0
  309. package/src/env/workflow/engine/scheduler.test.ts +715 -0
  310. package/src/env/workflow/engine/scheduler.ts +318 -0
  311. package/src/env/workflow/engine/workflow-engine.test.ts +815 -0
  312. package/src/env/workflow/extractor/workflow-converter.ts +306 -0
  313. package/src/env/workflow/fixtures.ts +380 -0
  314. package/src/env/workflow/index.ts +38 -0
  315. package/src/env/workflow/integration/run-resume-unified.test.ts +186 -0
  316. package/src/env/workflow/integration/service-integration.test.ts +267 -0
  317. package/src/env/workflow/metadata/keys.ts +12 -0
  318. package/src/env/workflow/nodes/agent-component-adapter.test.ts +318 -0
  319. package/src/env/workflow/nodes/agent-component-adapter.ts +448 -0
  320. package/src/env/workflow/nodes/agent-node.test.ts +371 -0
  321. package/src/env/workflow/nodes/agent-node.ts +598 -0
  322. package/src/env/workflow/nodes/ask-user-node.ts +113 -0
  323. package/src/env/workflow/nodes/condition-node.ts +200 -0
  324. package/src/env/workflow/nodes/index.ts +9 -0
  325. package/src/env/workflow/nodes/merge-node.ts +141 -0
  326. package/src/env/workflow/nodes/skill-node.test.ts +253 -0
  327. package/src/env/workflow/nodes/skill-node.ts +393 -0
  328. package/src/env/workflow/nodes/tool-node.test.ts +251 -0
  329. package/src/env/workflow/nodes/tool-node.ts +493 -0
  330. package/src/env/workflow/nodes/workflow-llm-history.test.ts +455 -0
  331. package/src/env/workflow/nodes/workflow-node.test.ts +315 -0
  332. package/src/env/workflow/nodes/workflow-node.ts +311 -0
  333. package/src/env/workflow/service/index.ts +27 -0
  334. package/src/env/workflow/service/registry.test.ts +133 -0
  335. package/src/env/workflow/service/registry.ts +71 -0
  336. package/src/env/workflow/service/workflow-service.test.ts +310 -0
  337. package/src/env/workflow/service/workflow-service.ts +393 -0
  338. package/src/env/workflow/storage/index.ts +28 -0
  339. package/src/env/workflow/storage/mock-repositories.ts +385 -0
  340. package/src/env/workflow/storage/sqlite.test.ts +179 -0
  341. package/src/env/workflow/storage/sqlite.ts +163 -0
  342. package/src/env/workflow/storage/workflow-repo.test.ts +780 -0
  343. package/src/env/workflow/storage/workflow-repo.ts +342 -0
  344. package/src/env/workflow/tools/ask-user-tool.ts +82 -0
  345. package/src/env/workflow/tools/index.ts +26 -0
  346. package/src/env/workflow/tools/run-workflow.test.ts +352 -0
  347. package/src/env/workflow/tools/run-workflow.ts +214 -0
  348. package/src/env/workflow/types/context.ts +18 -0
  349. package/src/env/workflow/types/decorators-types.ts +198 -0
  350. package/src/env/workflow/types/event.test.ts +515 -0
  351. package/src/env/workflow/types/event.ts +193 -0
  352. package/src/env/workflow/types/index.ts +49 -0
  353. package/src/env/workflow/types/run.test.ts +437 -0
  354. package/src/env/workflow/types/run.ts +173 -0
  355. package/src/env/workflow/types/workflow-hil.ts +114 -0
  356. package/src/env/workflow/types/workflow-message.test.ts +138 -0
  357. package/src/env/workflow/types/workflow-message.ts +196 -0
  358. package/src/env/workflow/types/workflow-session.test.ts +95 -0
  359. package/src/env/workflow/types/workflow-session.ts +59 -0
  360. package/src/env/workflow/types/workflow.test.ts +495 -0
  361. package/src/env/workflow/types/workflow.ts +195 -0
  362. package/src/env/workflow/types_compat.ts +51 -0
  363. package/src/env/workflow/utils/create-workflow.ts +47 -0
  364. package/src/env/workflow/utils/execution-state.ts +245 -0
  365. package/src/env/workflow/utils/index.ts +18 -0
  366. package/src/env/workflow/utils/node-registry-helper.ts +58 -0
  367. package/src/env/workflow/utils/recovery-validator.test.ts +460 -0
  368. package/src/env/workflow/utils/recovery-validator.ts +377 -0
  369. package/src/env/workflow/utils/session-parser.test.ts +111 -0
  370. package/src/env/workflow/utils/session-parser.ts +94 -0
  371. package/src/env/workflow/utils/session-recovery.test.ts +334 -0
  372. package/src/env/workflow/utils/session-recovery.ts +188 -0
  373. package/src/env/workflow/utils/template-resolver.test.ts +258 -0
  374. package/src/env/workflow/utils/template-resolver.ts +436 -0
  375. package/src/env/workflow/utils/validation-rules.ts +149 -0
  376. package/src/env/workflow/workflow-component.ts +544 -0
  377. package/src/index.ts +422 -0
  378. package/src/utils/id.ts +21 -0
@@ -0,0 +1,374 @@
1
+ import { describe, test, expect, beforeEach } from "bun:test";
2
+ import { HookManager, type Hook, type HookContext } from "./hook-manager";
3
+ import { createHook } from "./types";
4
+
5
+ // 测试用的上下文类型
6
+ interface TestData {
7
+ value: number;
8
+ }
9
+
10
+ // 创建测试 Hook 的辅助函数
11
+ function makeHook(
12
+ name: string,
13
+ execute: (ctx: HookContext<TestData>) => void | Promise<void>,
14
+ priority?: number
15
+ ): Hook<TestData> {
16
+ return createHook({ name, priority }, execute);
17
+ }
18
+
19
+ describe("HookManager", () => {
20
+ let manager: HookManager<TestData>;
21
+
22
+ beforeEach(() => {
23
+ manager = new HookManager<TestData>();
24
+ });
25
+
26
+ // ========================================================================
27
+ // 基础功能测试
28
+ // ========================================================================
29
+
30
+ describe("register", () => {
31
+ test("should register a hook to a hook point", () => {
32
+ const hook = makeHook("test-hook", async () => {});
33
+
34
+ manager.register("test.point", hook);
35
+
36
+ expect(manager.count("test.point")).toBe(1);
37
+ });
38
+
39
+ test("should register multiple hooks to the same hook point", () => {
40
+ const hook1 = makeHook("hook-1", async () => {});
41
+ const hook2 = makeHook("hook-2", async () => {});
42
+
43
+ manager.register("test.point", hook1);
44
+ manager.register("test.point", hook2);
45
+
46
+ expect(manager.count("test.point")).toBe(2);
47
+ });
48
+
49
+ test("should register hooks to different hook points", () => {
50
+ const hook1 = makeHook("hook-1", async () => {});
51
+ const hook2 = makeHook("hook-2", async () => {});
52
+
53
+ manager.register("point.1", hook1);
54
+ manager.register("point.2", hook2);
55
+
56
+ expect(manager.count("point.1")).toBe(1);
57
+ expect(manager.count("point.2")).toBe(1);
58
+ });
59
+ });
60
+
61
+ describe("registerMany", () => {
62
+ test("should register multiple hooks at once", () => {
63
+ const hooks = [
64
+ makeHook("hook-1", async () => {}),
65
+ makeHook("hook-2", async () => {}),
66
+ ];
67
+
68
+ manager.registerMany("test.point", hooks);
69
+
70
+ expect(manager.count("test.point")).toBe(2);
71
+ });
72
+
73
+ test("should register empty array", () => {
74
+ manager.registerMany("test.point", []);
75
+ expect(manager.count("test.point")).toBe(0);
76
+ });
77
+ });
78
+
79
+ describe("unregister", () => {
80
+ test("should unregister a hook by name", () => {
81
+ const hook1 = makeHook("hook-1", async () => {});
82
+ const hook2 = makeHook("hook-2", async () => {});
83
+
84
+ manager.register("test.point", hook1);
85
+ manager.register("test.point", hook2);
86
+
87
+ const result = manager.unregister("test.point", "hook-1");
88
+
89
+ expect(result).toBe(true);
90
+ expect(manager.count("test.point")).toBe(1);
91
+ });
92
+
93
+ test("should return false if hook not found", () => {
94
+ const result = manager.unregister("nonexistent", "hook");
95
+ expect(result).toBe(false);
96
+ });
97
+ });
98
+
99
+ describe("unregisterAll", () => {
100
+ test("should unregister all hooks at a hook point", () => {
101
+ manager.register("test.point", makeHook("hook-1", async () => {}));
102
+ manager.register("test.point", makeHook("hook-2", async () => {}));
103
+
104
+ manager.unregisterAll("test.point");
105
+
106
+ expect(manager.count("test.point")).toBe(0);
107
+ });
108
+ });
109
+
110
+ describe("count", () => {
111
+ test("should return 0 for non-existent hook point", () => {
112
+ expect(manager.count("nonexistent")).toBe(0);
113
+ });
114
+ });
115
+
116
+ describe("clear", () => {
117
+ test("should clear all hooks", () => {
118
+ manager.register("point.1", makeHook("hook-1", async () => {}));
119
+ manager.register("point.2", makeHook("hook-2", async () => {}));
120
+
121
+ manager.clear();
122
+
123
+ expect(manager.count("point.1")).toBe(0);
124
+ expect(manager.count("point.2")).toBe(0);
125
+ });
126
+ });
127
+
128
+ describe("getHookPoints", () => {
129
+ test("should return all registered hook points", () => {
130
+ manager.register("point.1", makeHook("hook-1", async () => {}));
131
+ manager.register("point.2", makeHook("hook-2", async () => {}));
132
+ manager.register("point.3", makeHook("hook-3", async () => {}));
133
+
134
+ const points = manager.getHookPoints();
135
+
136
+ expect(points).toContain("point.1");
137
+ expect(points).toContain("point.2");
138
+ expect(points).toContain("point.3");
139
+ });
140
+
141
+ test("should return empty array when no hooks registered", () => {
142
+ expect(manager.getHookPoints()).toEqual([]);
143
+ });
144
+ });
145
+
146
+ // ========================================================================
147
+ // 执行测试
148
+ // ========================================================================
149
+
150
+ describe("execute", () => {
151
+ test("should execute all hooks at a hook point", async () => {
152
+ const executionOrder: string[] = [];
153
+
154
+ manager.register("test.point", makeHook("hook-1", async () => {
155
+ executionOrder.push("hook-1");
156
+ }));
157
+ manager.register("test.point", makeHook("hook-2", async () => {
158
+ executionOrder.push("hook-2");
159
+ }));
160
+
161
+ await manager.execute("test.point", { value: 42 }, { meta: "test" });
162
+
163
+ expect(executionOrder).toEqual(["hook-1", "hook-2"]);
164
+ });
165
+
166
+ test("should pass correct context to hooks", async () => {
167
+ let receivedCtx: HookContext<TestData> | null = null;
168
+
169
+ manager.register("test.point", makeHook("test-hook", async (ctx) => {
170
+ receivedCtx = ctx;
171
+ }));
172
+
173
+ const testData = { value: 123 };
174
+ const testMeta = { source: "unit-test" };
175
+
176
+ await manager.execute("test.point", testData, testMeta);
177
+
178
+ expect(receivedCtx).not.toBeNull();
179
+ expect(receivedCtx!.data).toEqual(testData);
180
+ expect(receivedCtx!.metadata).toEqual(testMeta);
181
+ expect(receivedCtx!.phase).toBe("before");
182
+ expect(receivedCtx!.hookPoint).toBe("test.point");
183
+ });
184
+
185
+ test("should do nothing for non-existent hook point", async () => {
186
+ const hook = makeHook("should-not-run", async () => {
187
+ throw new Error("This hook should not run");
188
+ });
189
+
190
+ // 不注册,直接执行
191
+ await manager.execute("nonexistent", { value: 0 });
192
+
193
+ // 没有错误即为通过
194
+ expect(true).toBe(true);
195
+ });
196
+ });
197
+
198
+ describe("executeAndCollect", () => {
199
+ test("should collect return values from hooks", async () => {
200
+ manager.register("test.point", makeHook("hook-1", async () => "result-1"));
201
+ manager.register("test.point", makeHook("hook-2", async () => "result-2"));
202
+
203
+ const results = await manager.executeAndCollect<string>("test.point", { value: 0 });
204
+
205
+ expect(results).toEqual(["result-1", "result-2"]);
206
+ });
207
+
208
+ test("should return empty array for non-existent hook point", async () => {
209
+ const results = await manager.executeAndCollect<string>("nonexistent", { value: 0 });
210
+ expect(results).toEqual([]);
211
+ });
212
+ });
213
+
214
+ // ========================================================================
215
+ // 优先级测试
216
+ // ========================================================================
217
+
218
+ describe("hook priority", () => {
219
+ test("should execute hooks in priority order (lower priority first)", async () => {
220
+ const executionOrder: string[] = [];
221
+
222
+ manager.register("test.point", makeHook("low-priority", async () => {
223
+ executionOrder.push("low-priority");
224
+ }, 100));
225
+
226
+ manager.register("test.point", makeHook("high-priority", async () => {
227
+ executionOrder.push("high-priority");
228
+ }, 1));
229
+
230
+ manager.register("test.point", makeHook("medium-priority", async () => {
231
+ executionOrder.push("medium-priority");
232
+ }, 50));
233
+
234
+ await manager.execute("test.point", { value: 0 });
235
+
236
+ expect(executionOrder).toEqual([
237
+ "high-priority",
238
+ "medium-priority",
239
+ "low-priority"
240
+ ]);
241
+ });
242
+
243
+ test("should maintain registration order for same priority", async () => {
244
+ const executionOrder: string[] = [];
245
+
246
+ manager.register("test.point", makeHook("first", async () => {
247
+ executionOrder.push("first");
248
+ }, 0));
249
+
250
+ manager.register("test.point", makeHook("second", async () => {
251
+ executionOrder.push("second");
252
+ }, 0));
253
+
254
+ await manager.execute("test.point", { value: 0 });
255
+
256
+ expect(executionOrder).toEqual(["first", "second"]);
257
+ });
258
+
259
+ test("should use default priority 0 when not specified", async () => {
260
+ const executionOrder: string[] = [];
261
+
262
+ manager.register("test.point", makeHook("with-priority", async () => {
263
+ executionOrder.push("with-priority");
264
+ }, 10));
265
+
266
+ manager.register("test.point", makeHook("no-priority", async () => {
267
+ executionOrder.push("no-priority");
268
+ }));
269
+
270
+ await manager.execute("test.point", { value: 0 });
271
+
272
+ expect(executionOrder).toEqual(["no-priority", "with-priority"]);
273
+ });
274
+ });
275
+
276
+ // ========================================================================
277
+ // 错误隔离测试
278
+ // ========================================================================
279
+
280
+ describe("error isolation", () => {
281
+ test("should not throw if a hook throws", async () => {
282
+ manager.register("test.point", makeHook("failing-hook", async () => {
283
+ throw new Error("Hook failed");
284
+ }));
285
+
286
+ manager.register("test.point", makeHook("good-hook", async () => {}));
287
+
288
+ // 应该不抛出错误 - 直接调用而不是用 expect
289
+ let threw = false;
290
+ try {
291
+ await manager.execute("test.point", { value: 0 });
292
+ } catch {
293
+ threw = true;
294
+ }
295
+ expect(threw).toBe(false);
296
+ });
297
+
298
+ test("should continue executing other hooks if one fails", async () => {
299
+ const executionOrder: string[] = [];
300
+
301
+ manager.register("test.point", makeHook("hook-1", async () => {
302
+ executionOrder.push("hook-1");
303
+ }));
304
+
305
+ manager.register("test.point", makeHook("failing-hook", async () => {
306
+ throw new Error("Hook failed");
307
+ }));
308
+
309
+ manager.register("test.point", makeHook("hook-2", async () => {
310
+ executionOrder.push("hook-2");
311
+ }));
312
+
313
+ await manager.execute("test.point", { value: 0 });
314
+
315
+ expect(executionOrder).toEqual(["hook-1", "hook-2"]);
316
+ });
317
+
318
+ test("should handle async hooks throwing", async () => {
319
+ const executionOrder: string[] = [];
320
+
321
+ manager.register("test.point", makeHook("hook-1", async () => {
322
+ executionOrder.push("hook-1");
323
+ }));
324
+
325
+ manager.register("test.point", makeHook("async-failing", async () => {
326
+ await Promise.resolve();
327
+ throw new Error("Async hook failed");
328
+ }));
329
+
330
+ manager.register("test.point", makeHook("hook-2", async () => {
331
+ executionOrder.push("hook-2");
332
+ }));
333
+
334
+ await manager.execute("test.point", { value: 0 });
335
+
336
+ expect(executionOrder).toEqual(["hook-1", "hook-2"]);
337
+ });
338
+ });
339
+
340
+ // ========================================================================
341
+ // 生命周期测试
342
+ // ========================================================================
343
+
344
+ describe("hook lifecycle", () => {
345
+ test("should pass component info to hooks", async () => {
346
+ let receivedCtx: HookContext<TestData> | null = null;
347
+ const customManager = new HookManager<TestData>({
348
+ componentName: "TestComponent",
349
+ componentVersion: "2.0.0"
350
+ });
351
+
352
+ customManager.register("test.point", makeHook("test-hook", async (ctx) => {
353
+ receivedCtx = ctx;
354
+ }));
355
+
356
+ await customManager.execute("test.point", { value: 0 });
357
+
358
+ expect(receivedCtx!.component.name).toBe("TestComponent");
359
+ expect(receivedCtx!.component.version).toBe("2.0.0");
360
+ });
361
+
362
+ test("should pass correct hookPoint to hooks", async () => {
363
+ let receivedHookPoint: string | null = null;
364
+
365
+ manager.register("my.hook.point", makeHook("test-hook", async (ctx) => {
366
+ receivedHookPoint = ctx.hookPoint;
367
+ }));
368
+
369
+ await manager.execute("my.hook.point", { value: 0 });
370
+
371
+ expect(receivedHookPoint).toBe("my.hook.point");
372
+ });
373
+ });
374
+ });
@@ -0,0 +1,309 @@
1
+ /**
2
+ * @fileoverview Hook Manager - 统一管理 Component 的 Hook
3
+ *
4
+ * 提供:
5
+ * - Hook 注册和管理
6
+ * - 按优先级排序执行
7
+ * - 错误隔离
8
+ * - 动态添加/移除
9
+ * - 干预机制(executeWithIntervention)
10
+ */
11
+
12
+ import type { Hook, HookContext, HookPhase, HookResult } from "./types";
13
+
14
+ /**
15
+ * HookManager 配置
16
+ */
17
+ export interface HookManagerOptions {
18
+ /** 组件名称(用于上下文) */
19
+ componentName?: string;
20
+ /** 组件版本(用于上下文) */
21
+ componentVersion?: string;
22
+ /** 默认优先级 */
23
+ defaultPriority?: number;
24
+ }
25
+
26
+ /**
27
+ * HookManager
28
+ *
29
+ * 统一管理 Component 的 Hook
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const manager = new HookManager<MyContext>();
34
+ *
35
+ * // 注册 Hook
36
+ * manager.register("before-action", {
37
+ * name: "my-hook",
38
+ * priority: 10,
39
+ * execute: async (ctx) => { /* ... *\/ }
40
+ * });
41
+ *
42
+ * // 执行 Hooks
43
+ * await manager.execute("before-action", data);
44
+ * ```
45
+ */
46
+ export class HookManager<T = unknown> {
47
+ private _hooks: Map<string, Hook<T>[]> = new Map();
48
+ private componentName: string;
49
+ private componentVersion: string;
50
+ private defaultPriority: number;
51
+
52
+ constructor(options: HookManagerOptions = {}) {
53
+ this.componentName = options.componentName ?? "unknown";
54
+ this.componentVersion = options.componentVersion ?? "0.0.0";
55
+ this.defaultPriority = options.defaultPriority ?? 0;
56
+ }
57
+
58
+ /**
59
+ * 注册 Hook 到指定 hook 点
60
+ */
61
+ register(hookPoint: string, hook: Hook<T>): void {
62
+ const hooks = this.getOrCreateHooks(hookPoint);
63
+ hooks.push(hook);
64
+ }
65
+
66
+ /**
67
+ * 注册多个 Hook
68
+ */
69
+ registerMany(hookPoint: string, hooks: Hook<T>[]): void {
70
+ const hookList = this.getOrCreateHooks(hookPoint);
71
+ hookList.push(...hooks);
72
+ }
73
+
74
+ /**
75
+ * 按名称取消注册 Hook
76
+ * @returns 是否成功取消注册
77
+ */
78
+ unregister(hookPoint: string, name: string): boolean {
79
+ const hooks = this._hooks.get(hookPoint);
80
+ if (!hooks) return false;
81
+
82
+ const index = hooks.findIndex((h) => h.name === name);
83
+ if (index === -1) return false;
84
+
85
+ hooks.splice(index, 1);
86
+ return true;
87
+ }
88
+
89
+ /**
90
+ * 取消注册所有指定 hook 点的 Hook
91
+ */
92
+ unregisterAll(hookPoint: string): void {
93
+ this._hooks.delete(hookPoint);
94
+ }
95
+
96
+ /**
97
+ * 执行指定 hook 点的所有 Hook
98
+ */
99
+ async execute(
100
+ hookPoint: string,
101
+ data: T,
102
+ metadata: Record<string, unknown> = {}
103
+ ): Promise<void> {
104
+ const hooks = this._hooks.get(hookPoint);
105
+ if (!hooks || hooks.length === 0) return;
106
+
107
+ const sortedHooks = this.sortHooks(hooks);
108
+ const ctx = this.createContext(hookPoint, data, metadata, "before");
109
+
110
+ for (const hook of sortedHooks) {
111
+ await this.safeExecute(hook, ctx);
112
+ }
113
+ }
114
+
115
+ /**
116
+ * 执行指定 hook 点的所有 Hook 并收集返回值
117
+ */
118
+ async executeAndCollect<R>(
119
+ hookPoint: string,
120
+ data: T,
121
+ metadata: Record<string, unknown> = {}
122
+ ): Promise<R[]> {
123
+ const hooks = this._hooks.get(hookPoint);
124
+ if (!hooks || hooks.length === 0) return [];
125
+
126
+ const sortedHooks = this.sortHooks(hooks);
127
+ const ctx = this.createContext(hookPoint, data, metadata, "before");
128
+ const results: R[] = [];
129
+
130
+ for (const hook of sortedHooks) {
131
+ const result = await this.safeExecuteAndReturn(hook, ctx);
132
+ if (result !== undefined) {
133
+ results.push(result as R);
134
+ }
135
+ }
136
+
137
+ return results;
138
+ }
139
+
140
+ /**
141
+ * 获取指定 hook 点的 Hook 数量
142
+ */
143
+ count(hookPoint: string): number {
144
+ return this._hooks.get(hookPoint)?.length ?? 0;
145
+ }
146
+
147
+ /**
148
+ * 清空所有 Hook
149
+ */
150
+ clear(): void {
151
+ this._hooks.clear();
152
+ }
153
+
154
+ /**
155
+ * 获取所有已注册的 hook 点
156
+ */
157
+ getHookPoints(): string[] {
158
+ return Array.from(this._hooks.keys());
159
+ }
160
+
161
+ /**
162
+ * 检查 hook 点是否有任何 Hook
163
+ */
164
+ hasHooks(hookPoint: string): boolean {
165
+ return this.count(hookPoint) > 0;
166
+ }
167
+
168
+ /**
169
+ * 设置组件信息
170
+ */
171
+ setComponentInfo(name: string, version: string): void {
172
+ this.componentName = name;
173
+ this.componentVersion = version;
174
+ }
175
+
176
+ /**
177
+ * 获取所有注册的 hooks(只读副本)
178
+ */
179
+ get hooks(): ReadonlyMap<string, Hook<T>[]> {
180
+ return this._hooks;
181
+ }
182
+
183
+ // ========================================================================
184
+ // 干预机制
185
+ // ========================================================================
186
+
187
+ /**
188
+ * 执行 Hook 并支持干预机制
189
+ *
190
+ * 如果任何一个 Hook 返回 { stop: true },执行会停止
191
+ * Hook 可以通过返回 HookResult 来执行干预动作
192
+ *
193
+ * @param hookPoint Hook 点
194
+ * @param data 数据
195
+ * @param metadata 元数据
196
+ * @returns 执行结果
197
+ */
198
+ async executeWithIntervention(
199
+ hookPoint: string,
200
+ data: T,
201
+ metadata: Record<string, unknown> = {}
202
+ ): Promise<HookResult> {
203
+ const hooks = this._hooks.get(hookPoint);
204
+ if (!hooks || hooks.length === 0) {
205
+ return { stopped: false, results: [] };
206
+ }
207
+
208
+ const sortedHooks = this.sortHooks(hooks);
209
+ const ctx = this.createContext(hookPoint, data, metadata, "before");
210
+ const results: unknown[] = [];
211
+ let stopped = false;
212
+ let action: HookResult["action"];
213
+
214
+ for (const hook of sortedHooks) {
215
+ if (stopped) break;
216
+
217
+ const result = await this.safeExecuteAndReturn(hook, ctx);
218
+ results.push(result);
219
+
220
+ // 检查是否需要干预
221
+ if (result && typeof result === "object" && "stopped" in result) {
222
+ const hookResult = result as HookResult;
223
+ if (hookResult.stopped) {
224
+ stopped = true;
225
+ action = hookResult.action;
226
+ }
227
+ }
228
+ }
229
+
230
+ return { stopped, action, results };
231
+ }
232
+
233
+ // ========================================================================
234
+ // 私有方法
235
+ // ========================================================================
236
+
237
+ /**
238
+ * 获取或创建 hook 列表
239
+ */
240
+ private getOrCreateHooks(hookPoint: string): Hook<T>[] {
241
+ let hooks = this._hooks.get(hookPoint);
242
+ if (!hooks) {
243
+ hooks = [];
244
+ this._hooks.set(hookPoint, hooks);
245
+ }
246
+ return hooks;
247
+ }
248
+
249
+ /**
250
+ * 按优先级排序 Hook
251
+ *
252
+ * 优先级相同时保持原顺序(稳定排序)
253
+ */
254
+ private sortHooks(hooks: Hook<T>[]): Hook<T>[] {
255
+ return [...hooks].sort((a, b) => {
256
+ const priorityA = a.priority ?? this.defaultPriority;
257
+ const priorityB = b.priority ?? this.defaultPriority;
258
+ return priorityA - priorityB;
259
+ });
260
+ }
261
+
262
+ /**
263
+ * 创建 Hook 上下文
264
+ */
265
+ private createContext(
266
+ hookPoint: string,
267
+ data: T,
268
+ metadata: Record<string, unknown>,
269
+ phase: HookPhase
270
+ ): HookContext<T> {
271
+ return {
272
+ component: {
273
+ name: this.componentName,
274
+ version: this.componentVersion,
275
+ },
276
+ data,
277
+ metadata,
278
+ phase,
279
+ hookPoint,
280
+ };
281
+ }
282
+
283
+ /**
284
+ * 安全执行 Hook(错误隔离)
285
+ */
286
+ private async safeExecute(hook: Hook<T>, ctx: HookContext<T>): Promise<void> {
287
+ try {
288
+ await hook.execute(ctx);
289
+ } catch (error) {
290
+ // 记录错误但不中断执行
291
+ console.error(`Hook "${hook.name}" failed:`, error);
292
+ }
293
+ }
294
+
295
+ /**
296
+ * 安全执行 Hook 并返回结果
297
+ */
298
+ private async safeExecuteAndReturn<R>(
299
+ hook: Hook<T>,
300
+ ctx: HookContext<T>
301
+ ): Promise<R | undefined> {
302
+ try {
303
+ return await (hook.execute(ctx) as Promise<R>);
304
+ } catch (error) {
305
+ console.error(`Hook "${hook.name}" failed:`, error);
306
+ return undefined;
307
+ }
308
+ }
309
+ }