comisai 1.0.11 → 1.0.13

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 (255) hide show
  1. package/node_modules/@comis/agent/dist/model/operation-model-defaults.js +1 -0
  2. package/node_modules/@comis/agent/dist/session/comis-session-manager.js +9 -9
  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/package.json +1 -1
  6. package/node_modules/@comis/core/dist/event-bus/events-infra.d.ts +2 -0
  7. package/node_modules/@comis/core/package.json +1 -1
  8. package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +12 -1
  9. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.js +1 -0
  10. package/node_modules/@comis/daemon/dist/wiring/setup-schedulers.js +1 -0
  11. package/node_modules/@comis/daemon/package.json +1 -1
  12. package/node_modules/@comis/gateway/package.json +1 -1
  13. package/node_modules/@comis/infra/package.json +1 -1
  14. package/node_modules/@comis/memory/package.json +1 -1
  15. package/node_modules/@comis/scheduler/dist/cron/cron-types.d.ts +6 -0
  16. package/node_modules/@comis/scheduler/dist/cron/cron-types.js +2 -0
  17. package/node_modules/@comis/scheduler/package.json +1 -1
  18. package/node_modules/@comis/shared/package.json +1 -1
  19. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.d.ts +1 -1
  20. package/node_modules/@comis/skills/package.json +1 -1
  21. package/package.json +18 -18
  22. package/node_modules/@comis/core/dist/approval/approval-gate.test.d.ts +0 -1
  23. package/node_modules/@comis/core/dist/approval/approval-gate.test.js +0 -1003
  24. package/node_modules/@comis/core/dist/bootstrap.test.d.ts +0 -1
  25. package/node_modules/@comis/core/dist/bootstrap.test.js +0 -150
  26. package/node_modules/@comis/core/dist/config/backup.test.d.ts +0 -1
  27. package/node_modules/@comis/core/dist/config/backup.test.js +0 -160
  28. package/node_modules/@comis/core/dist/config/env-substitution.test.d.ts +0 -1
  29. package/node_modules/@comis/core/dist/config/env-substitution.test.js +0 -259
  30. package/node_modules/@comis/core/dist/config/field-metadata.test.d.ts +0 -1
  31. package/node_modules/@comis/core/dist/config/field-metadata.test.js +0 -72
  32. package/node_modules/@comis/core/dist/config/git-manager.test.d.ts +0 -1
  33. package/node_modules/@comis/core/dist/config/git-manager.test.js +0 -1042
  34. package/node_modules/@comis/core/dist/config/immutable-keys.test.d.ts +0 -1
  35. package/node_modules/@comis/core/dist/config/immutable-keys.test.js +0 -283
  36. package/node_modules/@comis/core/dist/config/include-resolver.test.d.ts +0 -1
  37. package/node_modules/@comis/core/dist/config/include-resolver.test.js +0 -292
  38. package/node_modules/@comis/core/dist/config/layered.test.d.ts +0 -1
  39. package/node_modules/@comis/core/dist/config/layered.test.js +0 -211
  40. package/node_modules/@comis/core/dist/config/loader.test.d.ts +0 -1
  41. package/node_modules/@comis/core/dist/config/loader.test.js +0 -300
  42. package/node_modules/@comis/core/dist/config/migrate.test.d.ts +0 -1
  43. package/node_modules/@comis/core/dist/config/migrate.test.js +0 -244
  44. package/node_modules/@comis/core/dist/config/partial-validator.test.d.ts +0 -1
  45. package/node_modules/@comis/core/dist/config/partial-validator.test.js +0 -98
  46. package/node_modules/@comis/core/dist/config/schema-agent-model.test.d.ts +0 -1
  47. package/node_modules/@comis/core/dist/config/schema-agent-model.test.js +0 -279
  48. package/node_modules/@comis/core/dist/config/schema-agent-session.test.d.ts +0 -1
  49. package/node_modules/@comis/core/dist/config/schema-agent-session.test.js +0 -242
  50. package/node_modules/@comis/core/dist/config/schema-agent.test.d.ts +0 -1
  51. package/node_modules/@comis/core/dist/config/schema-agent.test.js +0 -645
  52. package/node_modules/@comis/core/dist/config/schema-channel.test.d.ts +0 -1
  53. package/node_modules/@comis/core/dist/config/schema-channel.test.js +0 -341
  54. package/node_modules/@comis/core/dist/config/schema-coalescer.test.d.ts +0 -1
  55. package/node_modules/@comis/core/dist/config/schema-coalescer.test.js +0 -51
  56. package/node_modules/@comis/core/dist/config/schema-context-engine.test.d.ts +0 -1
  57. package/node_modules/@comis/core/dist/config/schema-context-engine.test.js +0 -797
  58. package/node_modules/@comis/core/dist/config/schema-context-guard.test.d.ts +0 -1
  59. package/node_modules/@comis/core/dist/config/schema-context-guard.test.js +0 -111
  60. package/node_modules/@comis/core/dist/config/schema-daemon.test.d.ts +0 -1
  61. package/node_modules/@comis/core/dist/config/schema-daemon.test.js +0 -107
  62. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.d.ts +0 -1
  63. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.js +0 -51
  64. package/node_modules/@comis/core/dist/config/schema-documentation.test.d.ts +0 -1
  65. package/node_modules/@comis/core/dist/config/schema-documentation.test.js +0 -63
  66. package/node_modules/@comis/core/dist/config/schema-gateway.test.d.ts +0 -1
  67. package/node_modules/@comis/core/dist/config/schema-gateway.test.js +0 -219
  68. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.d.ts +0 -1
  69. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.js +0 -41
  70. package/node_modules/@comis/core/dist/config/schema-integrations.test.d.ts +0 -1
  71. package/node_modules/@comis/core/dist/config/schema-integrations.test.js +0 -92
  72. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.d.ts +0 -1
  73. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.js +0 -61
  74. package/node_modules/@comis/core/dist/config/schema-misc.test.d.ts +0 -1
  75. package/node_modules/@comis/core/dist/config/schema-misc.test.js +0 -394
  76. package/node_modules/@comis/core/dist/config/schema-observability.test.d.ts +0 -1
  77. package/node_modules/@comis/core/dist/config/schema-observability.test.js +0 -76
  78. package/node_modules/@comis/core/dist/config/schema-providers.test.d.ts +0 -1
  79. package/node_modules/@comis/core/dist/config/schema-providers.test.js +0 -294
  80. package/node_modules/@comis/core/dist/config/schema-queue.test.d.ts +0 -1
  81. package/node_modules/@comis/core/dist/config/schema-queue.test.js +0 -234
  82. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.d.ts +0 -1
  83. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.js +0 -36
  84. package/node_modules/@comis/core/dist/config/schema-security.test.d.ts +0 -1
  85. package/node_modules/@comis/core/dist/config/schema-security.test.js +0 -54
  86. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.d.ts +0 -1
  87. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.js +0 -60
  88. package/node_modules/@comis/core/dist/config/schema-serializer.test.d.ts +0 -1
  89. package/node_modules/@comis/core/dist/config/schema-serializer.test.js +0 -73
  90. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.d.ts +0 -1
  91. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.js +0 -39
  92. package/node_modules/@comis/core/dist/context/context.test.d.ts +0 -1
  93. package/node_modules/@comis/core/dist/context/context.test.js +0 -276
  94. package/node_modules/@comis/core/dist/domain/agent-response.test.d.ts +0 -1
  95. package/node_modules/@comis/core/dist/domain/agent-response.test.js +0 -159
  96. package/node_modules/@comis/core/dist/domain/credential-mapping.test.d.ts +0 -1
  97. package/node_modules/@comis/core/dist/domain/credential-mapping.test.js +0 -135
  98. package/node_modules/@comis/core/dist/domain/delivery-origin.test.d.ts +0 -1
  99. package/node_modules/@comis/core/dist/domain/delivery-origin.test.js +0 -68
  100. package/node_modules/@comis/core/dist/domain/execution-graph.test.d.ts +0 -1
  101. package/node_modules/@comis/core/dist/domain/execution-graph.test.js +0 -441
  102. package/node_modules/@comis/core/dist/domain/memory-entry.test.d.ts +0 -1
  103. package/node_modules/@comis/core/dist/domain/memory-entry.test.js +0 -193
  104. package/node_modules/@comis/core/dist/domain/normalized-message.test.d.ts +0 -1
  105. package/node_modules/@comis/core/dist/domain/normalized-message.test.js +0 -255
  106. package/node_modules/@comis/core/dist/domain/session-key.test.d.ts +0 -1
  107. package/node_modules/@comis/core/dist/domain/session-key.test.js +0 -291
  108. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.d.ts +0 -1
  109. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.js +0 -131
  110. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.d.ts +0 -1
  111. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.js +0 -182
  112. package/node_modules/@comis/core/dist/event-bus/bus.test.d.ts +0 -1
  113. package/node_modules/@comis/core/dist/event-bus/bus.test.js +0 -152
  114. package/node_modules/@comis/core/dist/event-bus/events-agent.test.d.ts +0 -1
  115. package/node_modules/@comis/core/dist/event-bus/events-agent.test.js +0 -409
  116. package/node_modules/@comis/core/dist/event-bus/events-channel.test.d.ts +0 -1
  117. package/node_modules/@comis/core/dist/event-bus/events-channel.test.js +0 -240
  118. package/node_modules/@comis/core/dist/event-bus/events-infra.test.d.ts +0 -1
  119. package/node_modules/@comis/core/dist/event-bus/events-infra.test.js +0 -416
  120. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.d.ts +0 -1
  121. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.js +0 -433
  122. package/node_modules/@comis/core/dist/event-bus/events.test.d.ts +0 -1
  123. package/node_modules/@comis/core/dist/event-bus/events.test.js +0 -93
  124. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.d.ts +0 -1
  125. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.js +0 -29
  126. package/node_modules/@comis/core/dist/hooks/hook-runner.test.d.ts +0 -1
  127. package/node_modules/@comis/core/dist/hooks/hook-runner.test.js +0 -490
  128. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.d.ts +0 -1
  129. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.js +0 -209
  130. package/node_modules/@comis/core/dist/hooks/integration.test.d.ts +0 -1
  131. package/node_modules/@comis/core/dist/hooks/integration.test.js +0 -235
  132. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.d.ts +0 -1
  133. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.js +0 -470
  134. package/node_modules/@comis/core/dist/load-env.test.d.ts +0 -1
  135. package/node_modules/@comis/core/dist/load-env.test.js +0 -21
  136. package/node_modules/@comis/core/dist/security/action-classifier.test.d.ts +0 -1
  137. package/node_modules/@comis/core/dist/security/action-classifier.test.js +0 -298
  138. package/node_modules/@comis/core/dist/security/audit-aggregator.test.d.ts +0 -1
  139. package/node_modules/@comis/core/dist/security/audit-aggregator.test.js +0 -128
  140. package/node_modules/@comis/core/dist/security/audit.test.d.ts +0 -1
  141. package/node_modules/@comis/core/dist/security/audit.test.js +0 -154
  142. package/node_modules/@comis/core/dist/security/canary-token.test.d.ts +0 -1
  143. package/node_modules/@comis/core/dist/security/canary-token.test.js +0 -45
  144. package/node_modules/@comis/core/dist/security/config-redaction.test.d.ts +0 -1
  145. package/node_modules/@comis/core/dist/security/config-redaction.test.js +0 -107
  146. package/node_modules/@comis/core/dist/security/external-content.test.d.ts +0 -1
  147. package/node_modules/@comis/core/dist/security/external-content.test.js +0 -210
  148. package/node_modules/@comis/core/dist/security/injection-patterns.test.d.ts +0 -1
  149. package/node_modules/@comis/core/dist/security/injection-patterns.test.js +0 -213
  150. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.d.ts +0 -1
  151. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.js +0 -194
  152. package/node_modules/@comis/core/dist/security/input-guard.test.d.ts +0 -1
  153. package/node_modules/@comis/core/dist/security/input-guard.test.js +0 -215
  154. package/node_modules/@comis/core/dist/security/input-security-guard.test.d.ts +0 -1
  155. package/node_modules/@comis/core/dist/security/input-security-guard.test.js +0 -215
  156. package/node_modules/@comis/core/dist/security/input-validator.test.d.ts +0 -1
  157. package/node_modules/@comis/core/dist/security/input-validator.test.js +0 -133
  158. package/node_modules/@comis/core/dist/security/log-sanitizer.test.d.ts +0 -1
  159. package/node_modules/@comis/core/dist/security/log-sanitizer.test.js +0 -260
  160. package/node_modules/@comis/core/dist/security/memory-write-validator.test.d.ts +0 -1
  161. package/node_modules/@comis/core/dist/security/memory-write-validator.test.js +0 -62
  162. package/node_modules/@comis/core/dist/security/output-guard.test.d.ts +0 -1
  163. package/node_modules/@comis/core/dist/security/output-guard.test.js +0 -397
  164. package/node_modules/@comis/core/dist/security/safe-path.test.d.ts +0 -1
  165. package/node_modules/@comis/core/dist/security/safe-path.test.js +0 -95
  166. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.d.ts +0 -1
  167. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.js +0 -231
  168. package/node_modules/@comis/core/dist/security/secret-access.test.d.ts +0 -1
  169. package/node_modules/@comis/core/dist/security/secret-access.test.js +0 -41
  170. package/node_modules/@comis/core/dist/security/secret-crypto.test.d.ts +0 -1
  171. package/node_modules/@comis/core/dist/security/secret-crypto.test.js +0 -113
  172. package/node_modules/@comis/core/dist/security/secret-manager.test.d.ts +0 -1
  173. package/node_modules/@comis/core/dist/security/secret-manager.test.js +0 -394
  174. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.d.ts +0 -1
  175. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.js +0 -268
  176. package/node_modules/@comis/core/dist/security/secrets-audit.test.d.ts +0 -10
  177. package/node_modules/@comis/core/dist/security/secrets-audit.test.js +0 -295
  178. package/node_modules/@comis/core/dist/security/ssrf-guard.test.d.ts +0 -1
  179. package/node_modules/@comis/core/dist/security/ssrf-guard.test.js +0 -127
  180. package/node_modules/@comis/core/dist/security/token-generator.test.d.ts +0 -1
  181. package/node_modules/@comis/core/dist/security/token-generator.test.js +0 -35
  182. package/node_modules/@comis/core/dist/tool-metadata.test.d.ts +0 -1
  183. package/node_modules/@comis/core/dist/tool-metadata.test.js +0 -112
  184. package/node_modules/@comis/memory/dist/compaction.test.d.ts +0 -1
  185. package/node_modules/@comis/memory/dist/compaction.test.js +0 -298
  186. package/node_modules/@comis/memory/dist/context-schema.test.d.ts +0 -1
  187. package/node_modules/@comis/memory/dist/context-schema.test.js +0 -246
  188. package/node_modules/@comis/memory/dist/context-store.test.d.ts +0 -1
  189. package/node_modules/@comis/memory/dist/context-store.test.js +0 -708
  190. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.d.ts +0 -7
  191. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.js +0 -73
  192. package/node_modules/@comis/memory/dist/credential-mapping-store.test.d.ts +0 -8
  193. package/node_modules/@comis/memory/dist/credential-mapping-store.test.js +0 -340
  194. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.d.ts +0 -1
  195. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.js +0 -165
  196. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.d.ts +0 -1
  197. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.js +0 -263
  198. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.d.ts +0 -1
  199. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.js +0 -202
  200. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.d.ts +0 -1
  201. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.js +0 -241
  202. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.d.ts +0 -8
  203. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.js +0 -678
  204. package/node_modules/@comis/memory/dist/embedding-cache.test.d.ts +0 -1
  205. package/node_modules/@comis/memory/dist/embedding-cache.test.js +0 -213
  206. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.d.ts +0 -1
  207. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.js +0 -87
  208. package/node_modules/@comis/memory/dist/embedding-hash.test.d.ts +0 -1
  209. package/node_modules/@comis/memory/dist/embedding-hash.test.js +0 -31
  210. package/node_modules/@comis/memory/dist/embedding-integration.test.d.ts +0 -8
  211. package/node_modules/@comis/memory/dist/embedding-integration.test.js +0 -232
  212. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.d.ts +0 -1
  213. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.js +0 -176
  214. package/node_modules/@comis/memory/dist/embedding-provider-local.test.d.ts +0 -8
  215. package/node_modules/@comis/memory/dist/embedding-provider-local.test.js +0 -76
  216. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.d.ts +0 -8
  217. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.js +0 -100
  218. package/node_modules/@comis/memory/dist/embedding-queue.test.d.ts +0 -1
  219. package/node_modules/@comis/memory/dist/embedding-queue.test.js +0 -236
  220. package/node_modules/@comis/memory/dist/hybrid-search.test.d.ts +0 -1
  221. package/node_modules/@comis/memory/dist/hybrid-search.test.js +0 -476
  222. package/node_modules/@comis/memory/dist/identity-link-store.test.d.ts +0 -1
  223. package/node_modules/@comis/memory/dist/identity-link-store.test.js +0 -88
  224. package/node_modules/@comis/memory/dist/memory-api.test.d.ts +0 -1
  225. package/node_modules/@comis/memory/dist/memory-api.test.js +0 -495
  226. package/node_modules/@comis/memory/dist/memory-concurrency.test.d.ts +0 -20
  227. package/node_modules/@comis/memory/dist/memory-concurrency.test.js +0 -222
  228. package/node_modules/@comis/memory/dist/named-graph-store.test.d.ts +0 -1
  229. package/node_modules/@comis/memory/dist/named-graph-store.test.js +0 -227
  230. package/node_modules/@comis/memory/dist/observability-store.test.d.ts +0 -1
  231. package/node_modules/@comis/memory/dist/observability-store.test.js +0 -704
  232. package/node_modules/@comis/memory/dist/row-mapper.test.d.ts +0 -1
  233. package/node_modules/@comis/memory/dist/row-mapper.test.js +0 -409
  234. package/node_modules/@comis/memory/dist/schema.test.d.ts +0 -1
  235. package/node_modules/@comis/memory/dist/schema.test.js +0 -240
  236. package/node_modules/@comis/memory/dist/secret-store-schema.test.d.ts +0 -7
  237. package/node_modules/@comis/memory/dist/secret-store-schema.test.js +0 -90
  238. package/node_modules/@comis/memory/dist/session-store.test.d.ts +0 -1
  239. package/node_modules/@comis/memory/dist/session-store.test.js +0 -262
  240. package/node_modules/@comis/memory/dist/setup-secrets.test.d.ts +0 -1
  241. package/node_modules/@comis/memory/dist/setup-secrets.test.js +0 -140
  242. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.d.ts +0 -1
  243. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.js +0 -888
  244. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.d.ts +0 -8
  245. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.js +0 -245
  246. package/node_modules/@comis/shared/dist/abort.test.d.ts +0 -1
  247. package/node_modules/@comis/shared/dist/abort.test.js +0 -71
  248. package/node_modules/@comis/shared/dist/result.test.d.ts +0 -1
  249. package/node_modules/@comis/shared/dist/result.test.js +0 -178
  250. package/node_modules/@comis/shared/dist/suppress-error.test.d.ts +0 -1
  251. package/node_modules/@comis/shared/dist/suppress-error.test.js +0 -50
  252. package/node_modules/@comis/shared/dist/timeout.test.d.ts +0 -1
  253. package/node_modules/@comis/shared/dist/timeout.test.js +0 -75
  254. package/node_modules/@comis/shared/dist/ttl-cache.test.d.ts +0 -1
  255. package/node_modules/@comis/shared/dist/ttl-cache.test.js +0 -81
@@ -1,90 +0,0 @@
1
- /**
2
- * Tests for secret store schema DDL and canary validation.
3
- *
4
- * Uses in-memory SQLite databases and real crypto from @comis/core
5
- * to validate schema creation and master key mismatch detection.
6
- */
7
- import { describe, it, expect, beforeEach } from "vitest";
8
- import Database from "better-sqlite3";
9
- import { randomBytes } from "node:crypto";
10
- import { createSecretsCrypto } from "@comis/core";
11
- import { initSecretSchema, validateCanary, CANARY_NAME, } from "./secret-store-schema.js";
12
- function makeCrypto() {
13
- const key = randomBytes(32);
14
- return createSecretsCrypto(key);
15
- }
16
- describe("initSecretSchema", () => {
17
- let db;
18
- beforeEach(() => {
19
- db = new Database(":memory:");
20
- });
21
- it("creates secrets table with expected columns", () => {
22
- initSecretSchema(db);
23
- const columns = db
24
- .prepare("PRAGMA table_info(secrets)")
25
- .all();
26
- const columnNames = columns.map((c) => c.name);
27
- expect(columnNames).toContain("name");
28
- expect(columnNames).toContain("ciphertext");
29
- expect(columnNames).toContain("iv");
30
- expect(columnNames).toContain("auth_tag");
31
- expect(columnNames).toContain("salt");
32
- expect(columnNames).toContain("provider");
33
- expect(columnNames).toContain("description");
34
- expect(columnNames).toContain("expires_at");
35
- expect(columnNames).toContain("last_used_at");
36
- expect(columnNames).toContain("usage_count");
37
- expect(columnNames).toContain("created_at");
38
- expect(columnNames).toContain("updated_at");
39
- // Should have exactly 12 columns
40
- expect(columns).toHaveLength(12);
41
- // Verify BLOB types for encrypted fields
42
- const blobColumns = columns.filter((c) => c.type === "BLOB");
43
- expect(blobColumns.map((c) => c.name).sort()).toEqual(["auth_tag", "ciphertext", "iv", "salt"]);
44
- // Verify name is primary key
45
- const pkColumn = columns.find((c) => c.pk === 1);
46
- expect(pkColumn?.name).toBe("name");
47
- });
48
- it("is idempotent (safe to call multiple times)", () => {
49
- initSecretSchema(db);
50
- initSecretSchema(db);
51
- const columns = db
52
- .prepare("PRAGMA table_info(secrets)")
53
- .all();
54
- expect(columns).toHaveLength(12);
55
- });
56
- });
57
- describe("validateCanary", () => {
58
- let db;
59
- beforeEach(() => {
60
- db = new Database(":memory:");
61
- initSecretSchema(db);
62
- });
63
- it("creates canary row on fresh database", () => {
64
- const crypto = makeCrypto();
65
- validateCanary(db, crypto);
66
- const row = db
67
- .prepare("SELECT name FROM secrets WHERE name = ?")
68
- .get(CANARY_NAME);
69
- expect(row).toBeDefined();
70
- expect(row.name).toBe(CANARY_NAME);
71
- });
72
- it("succeeds silently on existing database with correct key", () => {
73
- const crypto = makeCrypto();
74
- // First call: creates canary
75
- validateCanary(db, crypto);
76
- // Second call: validates canary (should not throw)
77
- expect(() => validateCanary(db, crypto)).not.toThrow();
78
- });
79
- it("throws DECRYPTION_FAILED with wrong master key", () => {
80
- const crypto1 = makeCrypto();
81
- const crypto2 = makeCrypto();
82
- // Create canary with key 1
83
- validateCanary(db, crypto1);
84
- // Validate with key 2 -- should fail
85
- expect(() => validateCanary(db, crypto2)).toThrow(/DECRYPTION_FAILED/);
86
- });
87
- it("exports CANARY_NAME for downstream exclusion", () => {
88
- expect(CANARY_NAME).toBe("__comis_canary__");
89
- });
90
- });
@@ -1,262 +0,0 @@
1
- import { formatSessionKey } from "@comis/core";
2
- import Database from "better-sqlite3";
3
- import { randomUUID } from "node:crypto";
4
- import { tmpdir } from "node:os";
5
- import { join } from "node:path";
6
- import { describe, it, expect, beforeEach } from "vitest";
7
- import { initSchema } from "./schema.js";
8
- import { createSessionStore, MAX_SESSION_BYTES } from "./session-store.js";
9
- describe("createSessionStore", () => {
10
- let db;
11
- let store;
12
- const testKey = {
13
- tenantId: "default",
14
- userId: "user-1",
15
- channelId: "telegram",
16
- };
17
- const otherKey = {
18
- tenantId: "default",
19
- userId: "user-2",
20
- channelId: "discord",
21
- };
22
- beforeEach(() => {
23
- db = new Database(":memory:");
24
- initSchema(db, 1536);
25
- store = createSessionStore(db);
26
- });
27
- it("save and load roundtrip -- messages array preserved exactly", () => {
28
- const messages = [
29
- { role: "user", content: "Hello" },
30
- { role: "assistant", content: "Hi there!" },
31
- ];
32
- store.save(testKey, messages);
33
- const loaded = store.load(testKey);
34
- expect(loaded).toBeDefined();
35
- expect(loaded.messages).toEqual(messages);
36
- });
37
- it("save with metadata -- metadata object preserved", () => {
38
- const messages = [{ role: "user", content: "test" }];
39
- const metadata = { model: "gpt-4", temperature: 0.7, tags: ["debug"] };
40
- store.save(testKey, messages, metadata);
41
- const loaded = store.load(testKey);
42
- expect(loaded).toBeDefined();
43
- expect(loaded.metadata).toEqual(metadata);
44
- });
45
- it("load returns undefined for non-existent session", () => {
46
- const result = store.load({
47
- tenantId: "default",
48
- userId: "nobody",
49
- channelId: "nowhere",
50
- });
51
- expect(result).toBeUndefined();
52
- });
53
- it("save overwrites existing session (upsert) -- messages updated", () => {
54
- const original = [{ role: "user", content: "first" }];
55
- const updated = [
56
- { role: "user", content: "first" },
57
- { role: "assistant", content: "reply" },
58
- ];
59
- store.save(testKey, original);
60
- store.save(testKey, updated);
61
- const loaded = store.load(testKey);
62
- expect(loaded).toBeDefined();
63
- expect(loaded.messages).toEqual(updated);
64
- });
65
- it("save preserves createdAt on update (only updatedAt changes)", () => {
66
- store.save(testKey, [{ msg: "first" }]);
67
- const first = store.load(testKey);
68
- // Small delay to ensure different timestamps
69
- const createdAt = first.createdAt;
70
- // Manually set a known created_at in the past for deterministic testing
71
- db.prepare("UPDATE sessions SET created_at = 1000, updated_at = 1000 WHERE session_key = ?").run("default:user-1:telegram");
72
- store.save(testKey, [{ msg: "second" }]);
73
- const second = store.load(testKey);
74
- // createdAt should stay at 1000 (the original ON CONFLICT preserves it)
75
- expect(second.createdAt).toBe(1000);
76
- // updatedAt should be fresh (not 1000)
77
- expect(second.updatedAt).toBeGreaterThan(1000);
78
- });
79
- it("list returns sessions ordered by updatedAt DESC", () => {
80
- // Insert with explicit timestamps for deterministic ordering
81
- db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
82
- VALUES ('s1', 'default', 'u1', 'ch1', '[]', 1000, 1000, '{}')`).run();
83
- db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
84
- VALUES ('s2', 'default', 'u2', 'ch2', '[]', 2000, 3000, '{}')`).run();
85
- db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
86
- VALUES ('s3', 'default', 'u3', 'ch3', '[]', 1500, 2000, '{}')`).run();
87
- const list = store.list();
88
- expect(list).toHaveLength(3);
89
- expect(list[0].sessionKey).toBe("s2"); // updatedAt 3000
90
- expect(list[1].sessionKey).toBe("s3"); // updatedAt 2000
91
- expect(list[2].sessionKey).toBe("s1"); // updatedAt 1000
92
- });
93
- it("list with tenantId filter returns only matching sessions", () => {
94
- const tenantAKey = { tenantId: "tenant-a", userId: "u1", channelId: "ch1" };
95
- const tenantBKey = { tenantId: "tenant-b", userId: "u2", channelId: "ch2" };
96
- store.save(tenantAKey, [{ msg: "a" }]);
97
- store.save(tenantBKey, [{ msg: "b" }]);
98
- const filtered = store.list("tenant-a");
99
- expect(filtered).toHaveLength(1);
100
- expect(filtered[0].sessionKey).toContain("tenant-a");
101
- });
102
- it("delete removes session and returns true", () => {
103
- store.save(testKey, [{ msg: "test" }]);
104
- const deleted = store.delete(testKey);
105
- expect(deleted).toBe(true);
106
- const loaded = store.load(testKey);
107
- expect(loaded).toBeUndefined();
108
- });
109
- it("delete returns false for non-existent session", () => {
110
- const deleted = store.delete({
111
- tenantId: "default",
112
- userId: "nonexistent",
113
- channelId: "none",
114
- });
115
- expect(deleted).toBe(false);
116
- });
117
- it("deleteStale removes sessions older than threshold", () => {
118
- // Insert sessions with specific updatedAt timestamps
119
- db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
120
- VALUES ('old-session', 'default', 'u1', 'ch1', '[]', 1000, 1000, '{}')`).run();
121
- store.save(testKey, [{ msg: "fresh" }]); // This will have a current timestamp
122
- // Delete sessions older than 1 hour (the old session at timestamp 1000ms will be deleted)
123
- const deleted = store.deleteStale(60 * 60 * 1000);
124
- expect(deleted).toBe(1);
125
- // Fresh session should survive
126
- const loaded = store.load(testKey);
127
- expect(loaded).toBeDefined();
128
- });
129
- it("deleteStale returns count of deleted sessions", () => {
130
- // Insert multiple old sessions
131
- db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
132
- VALUES ('old1', 'default', 'u1', 'ch1', '[]', 100, 100, '{}')`).run();
133
- db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
134
- VALUES ('old2', 'default', 'u2', 'ch2', '[]', 200, 200, '{}')`).run();
135
- const deleted = store.deleteStale(60 * 60 * 1000);
136
- expect(deleted).toBe(2);
137
- });
138
- it("session survives db close/reopen cycle (file-backed)", () => {
139
- const dbPath = join(tmpdir(), `comis-test-${randomUUID()}.db`);
140
- // Create and populate
141
- const fileDb = new Database(dbPath);
142
- initSchema(fileDb, 1536);
143
- const fileStore = createSessionStore(fileDb);
144
- const messages = [
145
- { role: "user", content: "persist me" },
146
- { role: "assistant", content: "I will be remembered" },
147
- ];
148
- fileStore.save(testKey, messages, { persistent: true });
149
- fileDb.close();
150
- // Reopen and verify
151
- const reopened = new Database(dbPath);
152
- initSchema(reopened, 1536); // Safe to call again (idempotent)
153
- const reopenedStore = createSessionStore(reopened);
154
- const loaded = reopenedStore.load(testKey);
155
- expect(loaded).toBeDefined();
156
- expect(loaded.messages).toEqual(messages);
157
- expect(loaded.metadata).toEqual({ persistent: true });
158
- reopened.close();
159
- // Cleanup
160
- try {
161
- const { unlinkSync } = require("node:fs");
162
- unlinkSync(dbPath);
163
- unlinkSync(dbPath + "-wal");
164
- unlinkSync(dbPath + "-shm");
165
- }
166
- catch {
167
- // Ignore cleanup errors
168
- }
169
- });
170
- it("multiple sessions with different keys are independent", () => {
171
- const msgs1 = [{ msg: "session 1" }];
172
- const msgs2 = [{ msg: "session 2" }];
173
- store.save(testKey, msgs1);
174
- store.save(otherKey, msgs2);
175
- const loaded1 = store.load(testKey);
176
- const loaded2 = store.load(otherKey);
177
- expect(loaded1.messages).toEqual(msgs1);
178
- expect(loaded2.messages).toEqual(msgs2);
179
- });
180
- it("empty messages array is valid (new session with no history)", () => {
181
- store.save(testKey, []);
182
- const loaded = store.load(testKey);
183
- expect(loaded).toBeDefined();
184
- expect(loaded.messages).toEqual([]);
185
- });
186
- it("default metadata is empty object when not provided", () => {
187
- store.save(testKey, [{ msg: "test" }]);
188
- const loaded = store.load(testKey);
189
- expect(loaded).toBeDefined();
190
- expect(loaded.metadata).toEqual({});
191
- });
192
- describe("loadByFormattedKey", () => {
193
- it("loads session by formatted key string", () => {
194
- const key = { tenantId: "default", userId: "u1", channelId: "c1" };
195
- store.save(key, [{ role: "user", content: "hello" }], { foo: "bar" });
196
- const formatted = formatSessionKey(key);
197
- const data = store.loadByFormattedKey(formatted);
198
- expect(data).toBeDefined();
199
- expect(data.messages).toEqual([{ role: "user", content: "hello" }]);
200
- expect(data.metadata).toEqual({ foo: "bar" });
201
- });
202
- it("returns undefined for non-existent key", () => {
203
- expect(store.loadByFormattedKey("nonexistent:key:string")).toBeUndefined();
204
- });
205
- });
206
- // ── DATA-07: session size limits ────────────────────────────────
207
- describe("session size limits", () => {
208
- it("saves session with small messages successfully", () => {
209
- const messages = [{ role: "user", content: "hello" }];
210
- expect(() => store.save(testKey, messages)).not.toThrow();
211
- const loaded = store.load(testKey);
212
- expect(loaded).toBeDefined();
213
- expect(loaded.messages).toEqual(messages);
214
- });
215
- it("throws when messages JSON exceeds 10MB", () => {
216
- // Create a message array that exceeds 10MB when serialized
217
- const largeContent = "x".repeat(11 * 1024 * 1024); // 11MB string
218
- const messages = [{ role: "user", content: largeContent }];
219
- expect(() => store.save(testKey, messages)).toThrow(/Session data exceeds maximum size/);
220
- expect(() => store.save(testKey, messages)).toThrow(/10MB limit/);
221
- });
222
- it("saves session right at the limit", () => {
223
- // Create messages that are close to but under 10MB
224
- // MAX_SESSION_BYTES = 10 * 1024 * 1024 = 10485760
225
- // We need messages + metadata JSON to be <= 10485760 bytes
226
- // JSON overhead: {"role":"user","content":"..."} -> ~30 bytes + content
227
- // Outer array: [...] -> ~2 bytes
228
- // metadata: {} -> 2 bytes
229
- const targetContentSize = MAX_SESSION_BYTES - 100; // leave room for JSON overhead + metadata
230
- const content = "a".repeat(targetContentSize);
231
- const messages = [{ content }];
232
- expect(() => store.save(testKey, messages)).not.toThrow();
233
- });
234
- it("MAX_SESSION_BYTES is 10MB", () => {
235
- expect(MAX_SESSION_BYTES).toBe(10 * 1024 * 1024);
236
- });
237
- });
238
- describe("listDetailed", () => {
239
- it("returns detailed session entries with metadata", () => {
240
- const key1 = { tenantId: "t1", userId: "u1", channelId: "c1" };
241
- const key2 = { tenantId: "t1", userId: "u2", channelId: "c2" };
242
- store.save(key1, [], { parentSessionKey: "some-parent" });
243
- store.save(key2, [], {});
244
- const entries = store.listDetailed("t1");
245
- expect(entries).toHaveLength(2);
246
- // Most recent first
247
- const subAgent = entries.find(e => e.metadata.parentSessionKey !== undefined);
248
- expect(subAgent).toBeDefined();
249
- expect(subAgent.userId).toBe("u1");
250
- expect(subAgent.metadata.parentSessionKey).toBe("some-parent");
251
- });
252
- it("filters by tenantId", () => {
253
- const key1 = { tenantId: "t1", userId: "u1", channelId: "c1" };
254
- const key2 = { tenantId: "t2", userId: "u2", channelId: "c2" };
255
- store.save(key1, []);
256
- store.save(key2, []);
257
- expect(store.listDetailed("t1")).toHaveLength(1);
258
- expect(store.listDetailed("t2")).toHaveLength(1);
259
- expect(store.listDetailed()).toHaveLength(2);
260
- });
261
- });
262
- });
@@ -1,140 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { randomBytes } from "node:crypto";
3
- import { tmpdir } from "node:os";
4
- import { setupSecrets } from "./setup-secrets.js";
5
- // Generate valid test keys
6
- const VALID_HEX_KEY = randomBytes(32).toString("hex"); // 64 hex chars = 32 bytes
7
- const VALID_BASE64_KEY = randomBytes(32).toString("base64"); // 44+ base64 chars = 32+ bytes
8
- describe("setupSecrets", () => {
9
- // -----------------------------------------------------------
10
- // Branch 1: SECRETS_MASTER_KEY absent → ok(null) (legacy mode)
11
- // -----------------------------------------------------------
12
- describe("when SECRETS_MASTER_KEY is absent", () => {
13
- it("returns ok(null) when env has no SECRETS_MASTER_KEY", () => {
14
- const result = setupSecrets({ env: {}, dataDir: tmpdir() });
15
- expect(result.ok).toBe(true);
16
- expect(result.ok && result.value).toBeNull();
17
- });
18
- it("returns ok(null) when SECRETS_MASTER_KEY is undefined", () => {
19
- const result = setupSecrets({
20
- env: { SECRETS_MASTER_KEY: undefined },
21
- dataDir: tmpdir(),
22
- });
23
- expect(result.ok).toBe(true);
24
- expect(result.ok && result.value).toBeNull();
25
- });
26
- it("returns ok(null) when SECRETS_MASTER_KEY is empty string", () => {
27
- const result = setupSecrets({
28
- env: { SECRETS_MASTER_KEY: "" },
29
- dataDir: tmpdir(),
30
- });
31
- expect(result.ok).toBe(true);
32
- expect(result.ok && result.value).toBeNull();
33
- });
34
- it("returns ok(null) when SECRETS_MASTER_KEY is whitespace-only", () => {
35
- const result = setupSecrets({
36
- env: { SECRETS_MASTER_KEY: " " },
37
- dataDir: tmpdir(),
38
- });
39
- expect(result.ok).toBe(true);
40
- expect(result.ok && result.value).toBeNull();
41
- });
42
- });
43
- // -----------------------------------------------------------
44
- // Branch 2: SECRETS_MASTER_KEY set but invalid → err()
45
- // -----------------------------------------------------------
46
- describe("when SECRETS_MASTER_KEY is invalid", () => {
47
- it("returns err() for too-short key", () => {
48
- const result = setupSecrets({
49
- env: { SECRETS_MASTER_KEY: "abc" },
50
- dataDir: tmpdir(),
51
- });
52
- expect(result.ok).toBe(false);
53
- if (!result.ok) {
54
- expect(result.error.message).toContain("Invalid SECRETS_MASTER_KEY");
55
- }
56
- });
57
- it("returns err() for invalid encoding", () => {
58
- const result = setupSecrets({
59
- env: { SECRETS_MASTER_KEY: "!!not-valid!!" },
60
- dataDir: tmpdir(),
61
- });
62
- expect(result.ok).toBe(false);
63
- if (!result.ok) {
64
- expect(result.error.message).toContain("Invalid SECRETS_MASTER_KEY");
65
- }
66
- });
67
- it("includes actionable guidance in error message", () => {
68
- const result = setupSecrets({
69
- env: { SECRETS_MASTER_KEY: "short" },
70
- dataDir: tmpdir(),
71
- });
72
- expect(result.ok).toBe(false);
73
- if (!result.ok) {
74
- expect(result.error.message).toMatch(/hex.*64\+|base64.*44\+/i);
75
- expect(result.error.message).toContain("legacy mode");
76
- }
77
- });
78
- });
79
- // -----------------------------------------------------------
80
- // Branch 3: SECRETS_MASTER_KEY set and valid → ok({ crypto, dbPath })
81
- // -----------------------------------------------------------
82
- describe("when SECRETS_MASTER_KEY is valid", () => {
83
- it("returns ok({ crypto, dbPath }) for valid hex key", () => {
84
- const result = setupSecrets({
85
- env: { SECRETS_MASTER_KEY: VALID_HEX_KEY },
86
- dataDir: tmpdir(),
87
- });
88
- expect(result.ok).toBe(true);
89
- if (result.ok) {
90
- expect(result.value).not.toBeNull();
91
- expect(result.value.crypto).toBeDefined();
92
- expect(result.value.dbPath).toBeDefined();
93
- }
94
- });
95
- it("returns ok({ crypto, dbPath }) for valid base64 key", () => {
96
- const result = setupSecrets({
97
- env: { SECRETS_MASTER_KEY: VALID_BASE64_KEY },
98
- dataDir: tmpdir(),
99
- });
100
- expect(result.ok).toBe(true);
101
- if (result.ok) {
102
- expect(result.value).not.toBeNull();
103
- expect(result.value.crypto).toBeDefined();
104
- expect(result.value.dbPath).toBeDefined();
105
- }
106
- });
107
- it("computes dbPath from dataDir ending with secrets.db", () => {
108
- const dataDir = tmpdir();
109
- const result = setupSecrets({
110
- env: { SECRETS_MASTER_KEY: VALID_HEX_KEY },
111
- dataDir,
112
- });
113
- expect(result.ok).toBe(true);
114
- if (result.ok && result.value) {
115
- expect(result.value.dbPath).toMatch(/secrets\.db$/);
116
- expect(result.value.dbPath).toContain(dataDir);
117
- }
118
- });
119
- it("returned crypto can encrypt and decrypt a round-trip value", () => {
120
- const result = setupSecrets({
121
- env: { SECRETS_MASTER_KEY: VALID_HEX_KEY },
122
- dataDir: tmpdir(),
123
- });
124
- expect(result.ok).toBe(true);
125
- if (result.ok && result.value) {
126
- const { crypto } = result.value;
127
- const plaintext = "my-secret-api-key-12345";
128
- const encResult = crypto.encrypt(plaintext);
129
- expect(encResult.ok).toBe(true);
130
- if (encResult.ok) {
131
- const decResult = crypto.decrypt(encResult.value);
132
- expect(decResult.ok).toBe(true);
133
- if (decResult.ok) {
134
- expect(decResult.value).toBe(plaintext);
135
- }
136
- }
137
- }
138
- });
139
- });
140
- });