comisai 1.0.10 → 1.0.12

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 (251) hide show
  1. package/README.md +3 -3
  2. package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +1 -4
  3. package/node_modules/@comis/agent/package.json +1 -1
  4. package/node_modules/@comis/channels/package.json +1 -1
  5. package/node_modules/@comis/cli/dist/wizard/steps/06-channels.js +88 -11
  6. package/node_modules/@comis/cli/dist/wizard/steps/10-write-config.js +4 -0
  7. package/node_modules/@comis/cli/dist/wizard/types.d.ts +1 -0
  8. package/node_modules/@comis/cli/package.json +1 -1
  9. package/node_modules/@comis/core/package.json +1 -1
  10. package/node_modules/@comis/daemon/package.json +1 -1
  11. package/node_modules/@comis/gateway/package.json +1 -1
  12. package/node_modules/@comis/infra/package.json +1 -1
  13. package/node_modules/@comis/memory/package.json +1 -1
  14. package/node_modules/@comis/scheduler/package.json +1 -1
  15. package/node_modules/@comis/shared/package.json +1 -1
  16. package/node_modules/@comis/skills/package.json +1 -1
  17. package/package.json +18 -18
  18. package/node_modules/@comis/core/dist/approval/approval-gate.test.d.ts +0 -1
  19. package/node_modules/@comis/core/dist/approval/approval-gate.test.js +0 -1003
  20. package/node_modules/@comis/core/dist/bootstrap.test.d.ts +0 -1
  21. package/node_modules/@comis/core/dist/bootstrap.test.js +0 -150
  22. package/node_modules/@comis/core/dist/config/backup.test.d.ts +0 -1
  23. package/node_modules/@comis/core/dist/config/backup.test.js +0 -160
  24. package/node_modules/@comis/core/dist/config/env-substitution.test.d.ts +0 -1
  25. package/node_modules/@comis/core/dist/config/env-substitution.test.js +0 -259
  26. package/node_modules/@comis/core/dist/config/field-metadata.test.d.ts +0 -1
  27. package/node_modules/@comis/core/dist/config/field-metadata.test.js +0 -72
  28. package/node_modules/@comis/core/dist/config/git-manager.test.d.ts +0 -1
  29. package/node_modules/@comis/core/dist/config/git-manager.test.js +0 -1042
  30. package/node_modules/@comis/core/dist/config/immutable-keys.test.d.ts +0 -1
  31. package/node_modules/@comis/core/dist/config/immutable-keys.test.js +0 -283
  32. package/node_modules/@comis/core/dist/config/include-resolver.test.d.ts +0 -1
  33. package/node_modules/@comis/core/dist/config/include-resolver.test.js +0 -292
  34. package/node_modules/@comis/core/dist/config/layered.test.d.ts +0 -1
  35. package/node_modules/@comis/core/dist/config/layered.test.js +0 -211
  36. package/node_modules/@comis/core/dist/config/loader.test.d.ts +0 -1
  37. package/node_modules/@comis/core/dist/config/loader.test.js +0 -300
  38. package/node_modules/@comis/core/dist/config/migrate.test.d.ts +0 -1
  39. package/node_modules/@comis/core/dist/config/migrate.test.js +0 -244
  40. package/node_modules/@comis/core/dist/config/partial-validator.test.d.ts +0 -1
  41. package/node_modules/@comis/core/dist/config/partial-validator.test.js +0 -98
  42. package/node_modules/@comis/core/dist/config/schema-agent-model.test.d.ts +0 -1
  43. package/node_modules/@comis/core/dist/config/schema-agent-model.test.js +0 -279
  44. package/node_modules/@comis/core/dist/config/schema-agent-session.test.d.ts +0 -1
  45. package/node_modules/@comis/core/dist/config/schema-agent-session.test.js +0 -242
  46. package/node_modules/@comis/core/dist/config/schema-agent.test.d.ts +0 -1
  47. package/node_modules/@comis/core/dist/config/schema-agent.test.js +0 -645
  48. package/node_modules/@comis/core/dist/config/schema-channel.test.d.ts +0 -1
  49. package/node_modules/@comis/core/dist/config/schema-channel.test.js +0 -341
  50. package/node_modules/@comis/core/dist/config/schema-coalescer.test.d.ts +0 -1
  51. package/node_modules/@comis/core/dist/config/schema-coalescer.test.js +0 -51
  52. package/node_modules/@comis/core/dist/config/schema-context-engine.test.d.ts +0 -1
  53. package/node_modules/@comis/core/dist/config/schema-context-engine.test.js +0 -797
  54. package/node_modules/@comis/core/dist/config/schema-context-guard.test.d.ts +0 -1
  55. package/node_modules/@comis/core/dist/config/schema-context-guard.test.js +0 -111
  56. package/node_modules/@comis/core/dist/config/schema-daemon.test.d.ts +0 -1
  57. package/node_modules/@comis/core/dist/config/schema-daemon.test.js +0 -107
  58. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.d.ts +0 -1
  59. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.js +0 -51
  60. package/node_modules/@comis/core/dist/config/schema-documentation.test.d.ts +0 -1
  61. package/node_modules/@comis/core/dist/config/schema-documentation.test.js +0 -63
  62. package/node_modules/@comis/core/dist/config/schema-gateway.test.d.ts +0 -1
  63. package/node_modules/@comis/core/dist/config/schema-gateway.test.js +0 -219
  64. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.d.ts +0 -1
  65. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.js +0 -41
  66. package/node_modules/@comis/core/dist/config/schema-integrations.test.d.ts +0 -1
  67. package/node_modules/@comis/core/dist/config/schema-integrations.test.js +0 -92
  68. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.d.ts +0 -1
  69. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.js +0 -61
  70. package/node_modules/@comis/core/dist/config/schema-misc.test.d.ts +0 -1
  71. package/node_modules/@comis/core/dist/config/schema-misc.test.js +0 -394
  72. package/node_modules/@comis/core/dist/config/schema-observability.test.d.ts +0 -1
  73. package/node_modules/@comis/core/dist/config/schema-observability.test.js +0 -76
  74. package/node_modules/@comis/core/dist/config/schema-providers.test.d.ts +0 -1
  75. package/node_modules/@comis/core/dist/config/schema-providers.test.js +0 -294
  76. package/node_modules/@comis/core/dist/config/schema-queue.test.d.ts +0 -1
  77. package/node_modules/@comis/core/dist/config/schema-queue.test.js +0 -234
  78. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.d.ts +0 -1
  79. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.js +0 -36
  80. package/node_modules/@comis/core/dist/config/schema-security.test.d.ts +0 -1
  81. package/node_modules/@comis/core/dist/config/schema-security.test.js +0 -54
  82. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.d.ts +0 -1
  83. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.js +0 -60
  84. package/node_modules/@comis/core/dist/config/schema-serializer.test.d.ts +0 -1
  85. package/node_modules/@comis/core/dist/config/schema-serializer.test.js +0 -73
  86. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.d.ts +0 -1
  87. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.js +0 -39
  88. package/node_modules/@comis/core/dist/context/context.test.d.ts +0 -1
  89. package/node_modules/@comis/core/dist/context/context.test.js +0 -276
  90. package/node_modules/@comis/core/dist/domain/agent-response.test.d.ts +0 -1
  91. package/node_modules/@comis/core/dist/domain/agent-response.test.js +0 -159
  92. package/node_modules/@comis/core/dist/domain/credential-mapping.test.d.ts +0 -1
  93. package/node_modules/@comis/core/dist/domain/credential-mapping.test.js +0 -135
  94. package/node_modules/@comis/core/dist/domain/delivery-origin.test.d.ts +0 -1
  95. package/node_modules/@comis/core/dist/domain/delivery-origin.test.js +0 -68
  96. package/node_modules/@comis/core/dist/domain/execution-graph.test.d.ts +0 -1
  97. package/node_modules/@comis/core/dist/domain/execution-graph.test.js +0 -441
  98. package/node_modules/@comis/core/dist/domain/memory-entry.test.d.ts +0 -1
  99. package/node_modules/@comis/core/dist/domain/memory-entry.test.js +0 -193
  100. package/node_modules/@comis/core/dist/domain/normalized-message.test.d.ts +0 -1
  101. package/node_modules/@comis/core/dist/domain/normalized-message.test.js +0 -255
  102. package/node_modules/@comis/core/dist/domain/session-key.test.d.ts +0 -1
  103. package/node_modules/@comis/core/dist/domain/session-key.test.js +0 -291
  104. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.d.ts +0 -1
  105. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.js +0 -131
  106. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.d.ts +0 -1
  107. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.js +0 -182
  108. package/node_modules/@comis/core/dist/event-bus/bus.test.d.ts +0 -1
  109. package/node_modules/@comis/core/dist/event-bus/bus.test.js +0 -152
  110. package/node_modules/@comis/core/dist/event-bus/events-agent.test.d.ts +0 -1
  111. package/node_modules/@comis/core/dist/event-bus/events-agent.test.js +0 -409
  112. package/node_modules/@comis/core/dist/event-bus/events-channel.test.d.ts +0 -1
  113. package/node_modules/@comis/core/dist/event-bus/events-channel.test.js +0 -240
  114. package/node_modules/@comis/core/dist/event-bus/events-infra.test.d.ts +0 -1
  115. package/node_modules/@comis/core/dist/event-bus/events-infra.test.js +0 -416
  116. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.d.ts +0 -1
  117. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.js +0 -433
  118. package/node_modules/@comis/core/dist/event-bus/events.test.d.ts +0 -1
  119. package/node_modules/@comis/core/dist/event-bus/events.test.js +0 -93
  120. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.d.ts +0 -1
  121. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.js +0 -29
  122. package/node_modules/@comis/core/dist/hooks/hook-runner.test.d.ts +0 -1
  123. package/node_modules/@comis/core/dist/hooks/hook-runner.test.js +0 -490
  124. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.d.ts +0 -1
  125. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.js +0 -209
  126. package/node_modules/@comis/core/dist/hooks/integration.test.d.ts +0 -1
  127. package/node_modules/@comis/core/dist/hooks/integration.test.js +0 -235
  128. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.d.ts +0 -1
  129. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.js +0 -470
  130. package/node_modules/@comis/core/dist/load-env.test.d.ts +0 -1
  131. package/node_modules/@comis/core/dist/load-env.test.js +0 -21
  132. package/node_modules/@comis/core/dist/security/action-classifier.test.d.ts +0 -1
  133. package/node_modules/@comis/core/dist/security/action-classifier.test.js +0 -298
  134. package/node_modules/@comis/core/dist/security/audit-aggregator.test.d.ts +0 -1
  135. package/node_modules/@comis/core/dist/security/audit-aggregator.test.js +0 -128
  136. package/node_modules/@comis/core/dist/security/audit.test.d.ts +0 -1
  137. package/node_modules/@comis/core/dist/security/audit.test.js +0 -154
  138. package/node_modules/@comis/core/dist/security/canary-token.test.d.ts +0 -1
  139. package/node_modules/@comis/core/dist/security/canary-token.test.js +0 -45
  140. package/node_modules/@comis/core/dist/security/config-redaction.test.d.ts +0 -1
  141. package/node_modules/@comis/core/dist/security/config-redaction.test.js +0 -107
  142. package/node_modules/@comis/core/dist/security/external-content.test.d.ts +0 -1
  143. package/node_modules/@comis/core/dist/security/external-content.test.js +0 -210
  144. package/node_modules/@comis/core/dist/security/injection-patterns.test.d.ts +0 -1
  145. package/node_modules/@comis/core/dist/security/injection-patterns.test.js +0 -213
  146. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.d.ts +0 -1
  147. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.js +0 -194
  148. package/node_modules/@comis/core/dist/security/input-guard.test.d.ts +0 -1
  149. package/node_modules/@comis/core/dist/security/input-guard.test.js +0 -215
  150. package/node_modules/@comis/core/dist/security/input-security-guard.test.d.ts +0 -1
  151. package/node_modules/@comis/core/dist/security/input-security-guard.test.js +0 -215
  152. package/node_modules/@comis/core/dist/security/input-validator.test.d.ts +0 -1
  153. package/node_modules/@comis/core/dist/security/input-validator.test.js +0 -133
  154. package/node_modules/@comis/core/dist/security/log-sanitizer.test.d.ts +0 -1
  155. package/node_modules/@comis/core/dist/security/log-sanitizer.test.js +0 -260
  156. package/node_modules/@comis/core/dist/security/memory-write-validator.test.d.ts +0 -1
  157. package/node_modules/@comis/core/dist/security/memory-write-validator.test.js +0 -62
  158. package/node_modules/@comis/core/dist/security/output-guard.test.d.ts +0 -1
  159. package/node_modules/@comis/core/dist/security/output-guard.test.js +0 -397
  160. package/node_modules/@comis/core/dist/security/safe-path.test.d.ts +0 -1
  161. package/node_modules/@comis/core/dist/security/safe-path.test.js +0 -95
  162. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.d.ts +0 -1
  163. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.js +0 -231
  164. package/node_modules/@comis/core/dist/security/secret-access.test.d.ts +0 -1
  165. package/node_modules/@comis/core/dist/security/secret-access.test.js +0 -41
  166. package/node_modules/@comis/core/dist/security/secret-crypto.test.d.ts +0 -1
  167. package/node_modules/@comis/core/dist/security/secret-crypto.test.js +0 -113
  168. package/node_modules/@comis/core/dist/security/secret-manager.test.d.ts +0 -1
  169. package/node_modules/@comis/core/dist/security/secret-manager.test.js +0 -394
  170. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.d.ts +0 -1
  171. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.js +0 -268
  172. package/node_modules/@comis/core/dist/security/secrets-audit.test.d.ts +0 -10
  173. package/node_modules/@comis/core/dist/security/secrets-audit.test.js +0 -295
  174. package/node_modules/@comis/core/dist/security/ssrf-guard.test.d.ts +0 -1
  175. package/node_modules/@comis/core/dist/security/ssrf-guard.test.js +0 -127
  176. package/node_modules/@comis/core/dist/security/token-generator.test.d.ts +0 -1
  177. package/node_modules/@comis/core/dist/security/token-generator.test.js +0 -35
  178. package/node_modules/@comis/core/dist/tool-metadata.test.d.ts +0 -1
  179. package/node_modules/@comis/core/dist/tool-metadata.test.js +0 -112
  180. package/node_modules/@comis/memory/dist/compaction.test.d.ts +0 -1
  181. package/node_modules/@comis/memory/dist/compaction.test.js +0 -298
  182. package/node_modules/@comis/memory/dist/context-schema.test.d.ts +0 -1
  183. package/node_modules/@comis/memory/dist/context-schema.test.js +0 -246
  184. package/node_modules/@comis/memory/dist/context-store.test.d.ts +0 -1
  185. package/node_modules/@comis/memory/dist/context-store.test.js +0 -708
  186. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.d.ts +0 -7
  187. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.js +0 -73
  188. package/node_modules/@comis/memory/dist/credential-mapping-store.test.d.ts +0 -8
  189. package/node_modules/@comis/memory/dist/credential-mapping-store.test.js +0 -340
  190. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.d.ts +0 -1
  191. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.js +0 -165
  192. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.d.ts +0 -1
  193. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.js +0 -263
  194. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.d.ts +0 -1
  195. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.js +0 -202
  196. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.d.ts +0 -1
  197. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.js +0 -241
  198. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.d.ts +0 -8
  199. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.js +0 -678
  200. package/node_modules/@comis/memory/dist/embedding-cache.test.d.ts +0 -1
  201. package/node_modules/@comis/memory/dist/embedding-cache.test.js +0 -213
  202. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.d.ts +0 -1
  203. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.js +0 -87
  204. package/node_modules/@comis/memory/dist/embedding-hash.test.d.ts +0 -1
  205. package/node_modules/@comis/memory/dist/embedding-hash.test.js +0 -31
  206. package/node_modules/@comis/memory/dist/embedding-integration.test.d.ts +0 -8
  207. package/node_modules/@comis/memory/dist/embedding-integration.test.js +0 -232
  208. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.d.ts +0 -1
  209. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.js +0 -176
  210. package/node_modules/@comis/memory/dist/embedding-provider-local.test.d.ts +0 -8
  211. package/node_modules/@comis/memory/dist/embedding-provider-local.test.js +0 -76
  212. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.d.ts +0 -8
  213. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.js +0 -100
  214. package/node_modules/@comis/memory/dist/embedding-queue.test.d.ts +0 -1
  215. package/node_modules/@comis/memory/dist/embedding-queue.test.js +0 -236
  216. package/node_modules/@comis/memory/dist/hybrid-search.test.d.ts +0 -1
  217. package/node_modules/@comis/memory/dist/hybrid-search.test.js +0 -476
  218. package/node_modules/@comis/memory/dist/identity-link-store.test.d.ts +0 -1
  219. package/node_modules/@comis/memory/dist/identity-link-store.test.js +0 -88
  220. package/node_modules/@comis/memory/dist/memory-api.test.d.ts +0 -1
  221. package/node_modules/@comis/memory/dist/memory-api.test.js +0 -495
  222. package/node_modules/@comis/memory/dist/memory-concurrency.test.d.ts +0 -20
  223. package/node_modules/@comis/memory/dist/memory-concurrency.test.js +0 -222
  224. package/node_modules/@comis/memory/dist/named-graph-store.test.d.ts +0 -1
  225. package/node_modules/@comis/memory/dist/named-graph-store.test.js +0 -227
  226. package/node_modules/@comis/memory/dist/observability-store.test.d.ts +0 -1
  227. package/node_modules/@comis/memory/dist/observability-store.test.js +0 -704
  228. package/node_modules/@comis/memory/dist/row-mapper.test.d.ts +0 -1
  229. package/node_modules/@comis/memory/dist/row-mapper.test.js +0 -409
  230. package/node_modules/@comis/memory/dist/schema.test.d.ts +0 -1
  231. package/node_modules/@comis/memory/dist/schema.test.js +0 -240
  232. package/node_modules/@comis/memory/dist/secret-store-schema.test.d.ts +0 -7
  233. package/node_modules/@comis/memory/dist/secret-store-schema.test.js +0 -90
  234. package/node_modules/@comis/memory/dist/session-store.test.d.ts +0 -1
  235. package/node_modules/@comis/memory/dist/session-store.test.js +0 -262
  236. package/node_modules/@comis/memory/dist/setup-secrets.test.d.ts +0 -1
  237. package/node_modules/@comis/memory/dist/setup-secrets.test.js +0 -140
  238. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.d.ts +0 -1
  239. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.js +0 -888
  240. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.d.ts +0 -8
  241. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.js +0 -245
  242. package/node_modules/@comis/shared/dist/abort.test.d.ts +0 -1
  243. package/node_modules/@comis/shared/dist/abort.test.js +0 -71
  244. package/node_modules/@comis/shared/dist/result.test.d.ts +0 -1
  245. package/node_modules/@comis/shared/dist/result.test.js +0 -178
  246. package/node_modules/@comis/shared/dist/suppress-error.test.d.ts +0 -1
  247. package/node_modules/@comis/shared/dist/suppress-error.test.js +0 -50
  248. package/node_modules/@comis/shared/dist/timeout.test.d.ts +0 -1
  249. package/node_modules/@comis/shared/dist/timeout.test.js +0 -75
  250. package/node_modules/@comis/shared/dist/ttl-cache.test.d.ts +0 -1
  251. package/node_modules/@comis/shared/dist/ttl-cache.test.js +0 -81
@@ -1,209 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { BeforeAgentStartResultSchema, BeforeToolCallResultSchema, ToolResultPersistResultSchema, BeforeCompactionResultSchema, mergeBeforeAgentStart, mergeBeforeToolCall, mergeToolResultPersist, mergeBeforeCompaction, } from "./hook-strategies.js";
3
- // ─── Zod Schema Tests ────────────────────────────────────────────
4
- describe("BeforeAgentStartResultSchema", () => {
5
- it("parses a valid result with all fields", () => {
6
- const input = { systemPrompt: "Hello", prependContext: "ctx" };
7
- const result = BeforeAgentStartResultSchema.parse(input);
8
- expect(result).toEqual(input);
9
- });
10
- it("parses an empty object (all fields optional)", () => {
11
- const result = BeforeAgentStartResultSchema.parse({});
12
- expect(result).toEqual({});
13
- });
14
- it("applies defaults for omitted optional fields", () => {
15
- const result = BeforeAgentStartResultSchema.parse({ systemPrompt: "sp" });
16
- expect(result.systemPrompt).toBe("sp");
17
- expect(result.prependContext).toBeUndefined();
18
- });
19
- it("rejects extra properties (strictObject)", () => {
20
- expect(() => BeforeAgentStartResultSchema.parse({ systemPrompt: "sp", extra: true })).toThrow();
21
- });
22
- it("rejects wrong types", () => {
23
- expect(() => BeforeAgentStartResultSchema.parse({ systemPrompt: 42 })).toThrow();
24
- });
25
- it("rejects systemPrompt exceeding 50000 chars (CORE-06)", () => {
26
- const longString = "a".repeat(50_001);
27
- expect(() => BeforeAgentStartResultSchema.parse({ systemPrompt: longString })).toThrow();
28
- });
29
- it("accepts systemPrompt at exactly 50000 chars (CORE-06)", () => {
30
- const maxString = "a".repeat(50_000);
31
- const result = BeforeAgentStartResultSchema.parse({ systemPrompt: maxString });
32
- expect(result.systemPrompt).toBe(maxString);
33
- });
34
- it("rejects prependContext exceeding 50000 chars (CORE-06)", () => {
35
- const longString = "a".repeat(50_001);
36
- expect(() => BeforeAgentStartResultSchema.parse({ prependContext: longString })).toThrow();
37
- });
38
- it("accepts prependContext at exactly 50000 chars (CORE-06)", () => {
39
- const maxString = "a".repeat(50_000);
40
- const result = BeforeAgentStartResultSchema.parse({ prependContext: maxString });
41
- expect(result.prependContext).toBe(maxString);
42
- });
43
- it("round-trips: parse then re-parse produces identical output", () => {
44
- const input = { systemPrompt: "test", prependContext: "ctx" };
45
- const first = BeforeAgentStartResultSchema.parse(input);
46
- const second = BeforeAgentStartResultSchema.parse(first);
47
- expect(second).toEqual(first);
48
- });
49
- });
50
- describe("BeforeToolCallResultSchema", () => {
51
- it("parses valid result with skip=false equivalent (block=false)", () => {
52
- const result = BeforeToolCallResultSchema.parse({ block: false });
53
- expect(result.block).toBe(false);
54
- });
55
- it("parses result with block=true and blockReason", () => {
56
- const input = { block: true, blockReason: "unsafe" };
57
- const result = BeforeToolCallResultSchema.parse(input);
58
- expect(result.block).toBe(true);
59
- expect(result.blockReason).toBe("unsafe");
60
- });
61
- it("parses result with params override", () => {
62
- const input = { params: { key: "value" } };
63
- const result = BeforeToolCallResultSchema.parse(input);
64
- expect(result.params).toEqual({ key: "value" });
65
- });
66
- it("parses an empty object (all fields optional)", () => {
67
- const result = BeforeToolCallResultSchema.parse({});
68
- expect(result).toEqual({});
69
- });
70
- it("rejects extra properties (strictObject)", () => {
71
- expect(() => BeforeToolCallResultSchema.parse({ block: true, unknown: "field" })).toThrow();
72
- });
73
- it("rejects wrong types for block", () => {
74
- expect(() => BeforeToolCallResultSchema.parse({ block: "yes" })).toThrow();
75
- });
76
- });
77
- describe("ToolResultPersistResultSchema", () => {
78
- it("parses a valid result", () => {
79
- const result = ToolResultPersistResultSchema.parse({ result: "modified output" });
80
- expect(result.result).toBe("modified output");
81
- });
82
- it("parses an empty object (result is optional)", () => {
83
- const result = ToolResultPersistResultSchema.parse({});
84
- expect(result.result).toBeUndefined();
85
- });
86
- it("rejects extra properties (strictObject)", () => {
87
- expect(() => ToolResultPersistResultSchema.parse({ result: "ok", extra: true })).toThrow();
88
- });
89
- it("rejects wrong types for result", () => {
90
- expect(() => ToolResultPersistResultSchema.parse({ result: 123 })).toThrow();
91
- });
92
- });
93
- describe("BeforeCompactionResultSchema", () => {
94
- it("parses a valid result with cancel=true", () => {
95
- const input = { cancel: true, cancelReason: "important data" };
96
- const result = BeforeCompactionResultSchema.parse(input);
97
- expect(result.cancel).toBe(true);
98
- expect(result.cancelReason).toBe("important data");
99
- });
100
- it("parses an empty object (all fields optional)", () => {
101
- const result = BeforeCompactionResultSchema.parse({});
102
- expect(result).toEqual({});
103
- });
104
- it("rejects extra properties (strictObject)", () => {
105
- expect(() => BeforeCompactionResultSchema.parse({ cancel: true, unknown: 1 })).toThrow();
106
- });
107
- it("rejects wrong types for cancel", () => {
108
- expect(() => BeforeCompactionResultSchema.parse({ cancel: "true" })).toThrow();
109
- });
110
- });
111
- // ─── Merge Function Tests ────────────────────────────────────────
112
- describe("mergeBeforeAgentStart", () => {
113
- it("applies last-writer-wins for conflicting fields", () => {
114
- const a = { systemPrompt: "first", prependContext: "ctx-a" };
115
- const b = { systemPrompt: "second", prependContext: "ctx-b" };
116
- const merged = mergeBeforeAgentStart(a, b);
117
- expect(merged.systemPrompt).toBe("second");
118
- expect(merged.prependContext).toBe("ctx-b");
119
- });
120
- it("merging with undefined acc preserves next values", () => {
121
- const next = { systemPrompt: "sp", prependContext: "ctx" };
122
- const merged = mergeBeforeAgentStart(undefined, next);
123
- expect(merged).toEqual(next);
124
- });
125
- it("undefined fields in next fall back to acc values", () => {
126
- const acc = { systemPrompt: "keep-this" };
127
- const next = { prependContext: "new-ctx" };
128
- const merged = mergeBeforeAgentStart(acc, next);
129
- expect(merged.systemPrompt).toBe("keep-this");
130
- expect(merged.prependContext).toBe("new-ctx");
131
- });
132
- it("merging multiple results in sequence produces expected final state", () => {
133
- const r1 = { systemPrompt: "first" };
134
- const r2 = { prependContext: "middle-ctx" };
135
- const r3 = { systemPrompt: "final" };
136
- let merged = mergeBeforeAgentStart(undefined, r1);
137
- merged = mergeBeforeAgentStart(merged, r2);
138
- merged = mergeBeforeAgentStart(merged, r3);
139
- expect(merged.systemPrompt).toBe("final");
140
- expect(merged.prependContext).toBe("middle-ctx");
141
- });
142
- });
143
- describe("mergeBeforeToolCall", () => {
144
- it("applies last-writer-wins for block field", () => {
145
- const a = { block: false };
146
- const b = { block: true, blockReason: "security" };
147
- const merged = mergeBeforeToolCall(a, b);
148
- expect(merged.block).toBe(true);
149
- expect(merged.blockReason).toBe("security");
150
- });
151
- it("preserves non-conflicting fields across merges", () => {
152
- const a = { params: { key: "val" } };
153
- const b = { block: true, blockReason: "unsafe" };
154
- const merged = mergeBeforeToolCall(a, b);
155
- expect(merged.params).toEqual({ key: "val" });
156
- expect(merged.block).toBe(true);
157
- expect(merged.blockReason).toBe("unsafe");
158
- });
159
- it("merging with undefined acc preserves next", () => {
160
- const next = { block: true, blockReason: "denied" };
161
- const merged = mergeBeforeToolCall(undefined, next);
162
- expect(merged).toEqual(next);
163
- });
164
- });
165
- describe("mergeToolResultPersist", () => {
166
- it("applies last-writer-wins for result field", () => {
167
- const a = { result: "original" };
168
- const b = { result: "modified" };
169
- const merged = mergeToolResultPersist(a, b);
170
- expect(merged.result).toBe("modified");
171
- });
172
- it("undefined result in next falls back to acc", () => {
173
- const a = { result: "keep" };
174
- const b = {};
175
- const merged = mergeToolResultPersist(a, b);
176
- expect(merged.result).toBe("keep");
177
- });
178
- it("merging with undefined acc preserves next", () => {
179
- const next = { result: "output" };
180
- const merged = mergeToolResultPersist(undefined, next);
181
- expect(merged.result).toBe("output");
182
- });
183
- });
184
- describe("mergeBeforeCompaction", () => {
185
- it("applies last-writer-wins for cancel field", () => {
186
- const a = { cancel: false };
187
- const b = { cancel: true, cancelReason: "important" };
188
- const merged = mergeBeforeCompaction(a, b);
189
- expect(merged.cancel).toBe(true);
190
- expect(merged.cancelReason).toBe("important");
191
- });
192
- it("preserves non-conflicting fields across merges", () => {
193
- const a = { cancel: true };
194
- const b = { cancelReason: "new-reason" };
195
- const merged = mergeBeforeCompaction(a, b);
196
- expect(merged.cancel).toBe(true);
197
- expect(merged.cancelReason).toBe("new-reason");
198
- });
199
- it("merging multiple results in sequence", () => {
200
- const r1 = { cancel: true, cancelReason: "first" };
201
- const r2 = { cancel: false };
202
- const r3 = { cancelReason: "final-reason" };
203
- let merged = mergeBeforeCompaction(undefined, r1);
204
- merged = mergeBeforeCompaction(merged, r2);
205
- merged = mergeBeforeCompaction(merged, r3);
206
- expect(merged.cancel).toBe(false);
207
- expect(merged.cancelReason).toBe("final-reason");
208
- });
209
- });
@@ -1,235 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { ok } from "@comis/shared";
3
- import { TypedEventBus } from "../event-bus/index.js";
4
- import { PluginsConfigSchema } from "../config/schema-plugins.js";
5
- import { createPluginRegistry } from "./plugin-registry.js";
6
- import { createHookRunner } from "./hook-runner.js";
7
- /**
8
- * Create a minimal test plugin with sensible defaults.
9
- */
10
- function createTestPlugin(overrides) {
11
- return {
12
- name: overrides.name ?? `test-plugin-${overrides.id}`,
13
- register: overrides.register ?? ((_api) => ok(undefined)),
14
- ...overrides,
15
- };
16
- }
17
- describe("Hook System Integration", () => {
18
- it("full plugin lifecycle: register -> activate -> hook -> deactivate", async () => {
19
- // 1. Create a TypedEventBus instance
20
- const eventBus = new TypedEventBus();
21
- // Collect emitted events for verification
22
- const pluginRegisteredEvents = [];
23
- const hookExecutedEvents = [];
24
- const pluginDeactivatedEvents = [];
25
- eventBus.on("plugin:registered", (e) => pluginRegisteredEvents.push(e));
26
- eventBus.on("hook:executed", (e) => hookExecutedEvents.push(e));
27
- eventBus.on("plugin:deactivated", (e) => pluginDeactivatedEvents.push(e));
28
- // 2. Create a plugin registry with the event bus
29
- const registry = createPluginRegistry({ eventBus });
30
- // 3. Create a hook runner with the registry and event bus
31
- const runner = createHookRunner(registry, { eventBus });
32
- // 4. Define a test plugin
33
- const agentEndCalls = [];
34
- const testPlugin = createTestPlugin({
35
- id: "lifecycle-test",
36
- name: "Lifecycle Test Plugin",
37
- register: (api) => {
38
- // before_agent_start: modifying hook that prepends "[PLUGIN] " to system prompt
39
- api.registerHook("before_agent_start", (event) => ({
40
- systemPrompt: `[PLUGIN] ${event.systemPrompt}`,
41
- }));
42
- // agent_end: void hook that records the call
43
- api.registerHook("agent_end", (event) => {
44
- agentEndCalls.push({ durationMs: event.durationMs, success: event.success });
45
- });
46
- return ok(undefined);
47
- },
48
- activate: async () => ok(undefined),
49
- deactivate: async () => ok(undefined),
50
- });
51
- // 5. Register the plugin -> verify ok result
52
- const registerResult = registry.register(testPlugin);
53
- expect(registerResult.ok).toBe(true);
54
- // 6. Activate all plugins -> verify ok result
55
- const activateResult = await registry.activateAll();
56
- expect(activateResult.ok).toBe(true);
57
- // 7. Run before_agent_start hook -> verify system prompt is modified
58
- const beforeResult = await runner.runBeforeAgentStart({ systemPrompt: "Be helpful.", messages: [] }, { agentId: "agent-1" });
59
- expect(beforeResult?.systemPrompt).toBe("[PLUGIN] Be helpful.");
60
- // 8. Run agent_end hook -> verify tracking array has the call
61
- await runner.runAgentEnd({ durationMs: 250, success: true }, { agentId: "agent-1" });
62
- expect(agentEndCalls).toHaveLength(1);
63
- expect(agentEndCalls[0]).toEqual({ durationMs: 250, success: true });
64
- // 9. Deactivate all plugins -> verify ok result
65
- const deactivateResult = await registry.deactivateAll();
66
- expect(deactivateResult.ok).toBe(true);
67
- // 10. Verify plugin:registered event was emitted on the event bus
68
- expect(pluginRegisteredEvents).toHaveLength(1);
69
- expect(pluginRegisteredEvents[0].pluginId).toBe("lifecycle-test");
70
- expect(pluginRegisteredEvents[0].hookCount).toBe(2);
71
- // 11. Verify hook:executed events were emitted for both hook calls
72
- expect(hookExecutedEvents).toHaveLength(2);
73
- expect(hookExecutedEvents[0].hookName).toBe("before_agent_start");
74
- expect(hookExecutedEvents[1].hookName).toBe("agent_end");
75
- expect(hookExecutedEvents.every((e) => e.success)).toBe(true);
76
- // Verify deactivation event
77
- expect(pluginDeactivatedEvents).toHaveLength(1);
78
- expect(pluginDeactivatedEvents[0].pluginId).toBe("lifecycle-test");
79
- });
80
- it("multiple plugins with priority ordering", async () => {
81
- const eventBus = new TypedEventBus();
82
- const registry = createPluginRegistry({ eventBus });
83
- const runner = createHookRunner(registry, { eventBus });
84
- const executionOrder = [];
85
- // Plugin A: priority 10 (runs first)
86
- registry.register(createTestPlugin({
87
- id: "plugin-a",
88
- register: (api) => {
89
- api.registerHook("before_tool_call", (event) => {
90
- executionOrder.push("A");
91
- return { params: { ...event.params, fromA: true } };
92
- }, { priority: 10 });
93
- return ok(undefined);
94
- },
95
- }));
96
- // Plugin B: priority 5 (runs second)
97
- registry.register(createTestPlugin({
98
- id: "plugin-b",
99
- register: (api) => {
100
- api.registerHook("before_tool_call", (event) => {
101
- executionOrder.push("B");
102
- return { params: { ...event.params, fromB: true } };
103
- }, { priority: 5 });
104
- return ok(undefined);
105
- },
106
- }));
107
- const result = await runner.runBeforeToolCall({ toolName: "read_file", params: { path: "/tmp" } }, { agentId: "a" });
108
- // A ran before B (higher priority first)
109
- expect(executionOrder).toEqual(["A", "B"]);
110
- // Both modifications present (B's params override A's via merge)
111
- expect(result?.params).toBeDefined();
112
- expect(result.params.fromB).toBe(true);
113
- });
114
- it("plugin error isolation", async () => {
115
- const eventBus = new TypedEventBus();
116
- const registry = createPluginRegistry({ eventBus });
117
- const runner = createHookRunner(registry, { eventBus, catchErrors: true });
118
- const hookEvents = [];
119
- eventBus.on("hook:executed", (e) => hookEvents.push(e));
120
- // First plugin: throws an error
121
- registry.register(createTestPlugin({
122
- id: "broken",
123
- register: (api) => {
124
- api.registerHook("before_agent_start", () => {
125
- throw new Error("intentional failure");
126
- }, { priority: 10 });
127
- return ok(undefined);
128
- },
129
- }));
130
- // Second plugin: normal behavior
131
- registry.register(createTestPlugin({
132
- id: "healthy",
133
- register: (api) => {
134
- api.registerHook("before_agent_start", () => ({ systemPrompt: "from-healthy" }), { priority: 5 });
135
- return ok(undefined);
136
- },
137
- }));
138
- const result = await runner.runBeforeAgentStart({ systemPrompt: "original", messages: [] }, { agentId: "a" });
139
- // The second plugin's result is returned (first was caught)
140
- expect(result?.systemPrompt).toBe("from-healthy");
141
- // Verify hook:executed events
142
- expect(hookEvents).toHaveLength(2);
143
- const brokenEvent = hookEvents.find((e) => e.pluginId === "broken");
144
- expect(brokenEvent?.success).toBe(false);
145
- expect(brokenEvent?.error).toBe("intentional failure");
146
- const healthyEvent = hookEvents.find((e) => e.pluginId === "healthy");
147
- expect(healthyEvent?.success).toBe(true);
148
- });
149
- it("before_tool_call blocks tool execution", async () => {
150
- const registry = createPluginRegistry();
151
- const runner = createHookRunner(registry);
152
- registry.register(createTestPlugin({
153
- id: "security-gate",
154
- register: (api) => {
155
- api.registerHook("before_tool_call", () => ({
156
- block: true,
157
- blockReason: "forbidden",
158
- }));
159
- return ok(undefined);
160
- },
161
- }));
162
- const result = await runner.runBeforeToolCall({ toolName: "shell:exec", params: { command: "rm -rf /" } }, { agentId: "a" });
163
- expect(result?.block).toBe(true);
164
- expect(result?.blockReason).toBe("forbidden");
165
- });
166
- it("config-driven plugin enablement (schema validation)", () => {
167
- // Validate PluginsConfigSchema correctly parses plugin configurations
168
- // Parse a config with one enabled and one disabled plugin
169
- const config = PluginsConfigSchema.parse({
170
- enabled: true,
171
- plugins: {
172
- "audit-logger": {
173
- enabled: true,
174
- priority: 10,
175
- config: { logLevel: "debug" },
176
- },
177
- "webhook-forwarder": {
178
- enabled: false,
179
- priority: -5,
180
- config: { url: "https://example.com/webhook" },
181
- },
182
- },
183
- });
184
- expect(config.enabled).toBe(true);
185
- expect(Object.keys(config.plugins)).toHaveLength(2);
186
- const audit = config.plugins["audit-logger"];
187
- expect(audit.enabled).toBe(true);
188
- expect(audit.priority).toBe(10);
189
- expect(audit.config.logLevel).toBe("debug");
190
- const webhook = config.plugins["webhook-forwarder"];
191
- expect(webhook.enabled).toBe(false);
192
- expect(webhook.priority).toBe(-5);
193
- // Validate defaults work
194
- const defaultConfig = PluginsConfigSchema.parse({});
195
- expect(defaultConfig.enabled).toBe(true);
196
- expect(Object.keys(defaultConfig.plugins)).toHaveLength(0);
197
- });
198
- it("lifecycle scenario: unregister/re-register", async () => {
199
- const registry = createPluginRegistry();
200
- const runner = createHookRunner(registry);
201
- // 1. Register a plugin
202
- const calls = [];
203
- registry.register(createTestPlugin({
204
- id: "hot-plugin",
205
- register: (api) => {
206
- api.registerHook("agent_end", () => {
207
- calls.push("v1");
208
- });
209
- return ok(undefined);
210
- },
211
- }));
212
- // 2. Run a hook -> verify it fires
213
- await runner.runAgentEnd({ durationMs: 100, success: true }, { agentId: "a" });
214
- expect(calls).toEqual(["v1"]);
215
- // 3. Unregister the plugin
216
- const unregResult = registry.unregister("hot-plugin");
217
- expect(unregResult.ok).toBe(true);
218
- // 4. Run the same hook -> verify it does NOT fire
219
- await runner.runAgentEnd({ durationMs: 100, success: true }, { agentId: "a" });
220
- expect(calls).toEqual(["v1"]); // still just one call
221
- // 5. Register a new plugin for the same hook
222
- registry.register(createTestPlugin({
223
- id: "hot-plugin-v2",
224
- register: (api) => {
225
- api.registerHook("agent_end", () => {
226
- calls.push("v2");
227
- });
228
- return ok(undefined);
229
- },
230
- }));
231
- // 6. Run the hook -> verify the new plugin fires
232
- await runner.runAgentEnd({ durationMs: 100, success: true }, { agentId: "a" });
233
- expect(calls).toEqual(["v1", "v2"]);
234
- });
235
- });