comisai 1.0.11 → 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 (247) hide show
  1. package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +1 -4
  2. package/node_modules/@comis/agent/package.json +1 -1
  3. package/node_modules/@comis/channels/package.json +1 -1
  4. package/node_modules/@comis/cli/package.json +1 -1
  5. package/node_modules/@comis/core/package.json +1 -1
  6. package/node_modules/@comis/daemon/package.json +1 -1
  7. package/node_modules/@comis/gateway/package.json +1 -1
  8. package/node_modules/@comis/infra/package.json +1 -1
  9. package/node_modules/@comis/memory/package.json +1 -1
  10. package/node_modules/@comis/scheduler/package.json +1 -1
  11. package/node_modules/@comis/shared/package.json +1 -1
  12. package/node_modules/@comis/skills/package.json +1 -1
  13. package/package.json +18 -18
  14. package/node_modules/@comis/core/dist/approval/approval-gate.test.d.ts +0 -1
  15. package/node_modules/@comis/core/dist/approval/approval-gate.test.js +0 -1003
  16. package/node_modules/@comis/core/dist/bootstrap.test.d.ts +0 -1
  17. package/node_modules/@comis/core/dist/bootstrap.test.js +0 -150
  18. package/node_modules/@comis/core/dist/config/backup.test.d.ts +0 -1
  19. package/node_modules/@comis/core/dist/config/backup.test.js +0 -160
  20. package/node_modules/@comis/core/dist/config/env-substitution.test.d.ts +0 -1
  21. package/node_modules/@comis/core/dist/config/env-substitution.test.js +0 -259
  22. package/node_modules/@comis/core/dist/config/field-metadata.test.d.ts +0 -1
  23. package/node_modules/@comis/core/dist/config/field-metadata.test.js +0 -72
  24. package/node_modules/@comis/core/dist/config/git-manager.test.d.ts +0 -1
  25. package/node_modules/@comis/core/dist/config/git-manager.test.js +0 -1042
  26. package/node_modules/@comis/core/dist/config/immutable-keys.test.d.ts +0 -1
  27. package/node_modules/@comis/core/dist/config/immutable-keys.test.js +0 -283
  28. package/node_modules/@comis/core/dist/config/include-resolver.test.d.ts +0 -1
  29. package/node_modules/@comis/core/dist/config/include-resolver.test.js +0 -292
  30. package/node_modules/@comis/core/dist/config/layered.test.d.ts +0 -1
  31. package/node_modules/@comis/core/dist/config/layered.test.js +0 -211
  32. package/node_modules/@comis/core/dist/config/loader.test.d.ts +0 -1
  33. package/node_modules/@comis/core/dist/config/loader.test.js +0 -300
  34. package/node_modules/@comis/core/dist/config/migrate.test.d.ts +0 -1
  35. package/node_modules/@comis/core/dist/config/migrate.test.js +0 -244
  36. package/node_modules/@comis/core/dist/config/partial-validator.test.d.ts +0 -1
  37. package/node_modules/@comis/core/dist/config/partial-validator.test.js +0 -98
  38. package/node_modules/@comis/core/dist/config/schema-agent-model.test.d.ts +0 -1
  39. package/node_modules/@comis/core/dist/config/schema-agent-model.test.js +0 -279
  40. package/node_modules/@comis/core/dist/config/schema-agent-session.test.d.ts +0 -1
  41. package/node_modules/@comis/core/dist/config/schema-agent-session.test.js +0 -242
  42. package/node_modules/@comis/core/dist/config/schema-agent.test.d.ts +0 -1
  43. package/node_modules/@comis/core/dist/config/schema-agent.test.js +0 -645
  44. package/node_modules/@comis/core/dist/config/schema-channel.test.d.ts +0 -1
  45. package/node_modules/@comis/core/dist/config/schema-channel.test.js +0 -341
  46. package/node_modules/@comis/core/dist/config/schema-coalescer.test.d.ts +0 -1
  47. package/node_modules/@comis/core/dist/config/schema-coalescer.test.js +0 -51
  48. package/node_modules/@comis/core/dist/config/schema-context-engine.test.d.ts +0 -1
  49. package/node_modules/@comis/core/dist/config/schema-context-engine.test.js +0 -797
  50. package/node_modules/@comis/core/dist/config/schema-context-guard.test.d.ts +0 -1
  51. package/node_modules/@comis/core/dist/config/schema-context-guard.test.js +0 -111
  52. package/node_modules/@comis/core/dist/config/schema-daemon.test.d.ts +0 -1
  53. package/node_modules/@comis/core/dist/config/schema-daemon.test.js +0 -107
  54. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.d.ts +0 -1
  55. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.js +0 -51
  56. package/node_modules/@comis/core/dist/config/schema-documentation.test.d.ts +0 -1
  57. package/node_modules/@comis/core/dist/config/schema-documentation.test.js +0 -63
  58. package/node_modules/@comis/core/dist/config/schema-gateway.test.d.ts +0 -1
  59. package/node_modules/@comis/core/dist/config/schema-gateway.test.js +0 -219
  60. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.d.ts +0 -1
  61. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.js +0 -41
  62. package/node_modules/@comis/core/dist/config/schema-integrations.test.d.ts +0 -1
  63. package/node_modules/@comis/core/dist/config/schema-integrations.test.js +0 -92
  64. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.d.ts +0 -1
  65. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.js +0 -61
  66. package/node_modules/@comis/core/dist/config/schema-misc.test.d.ts +0 -1
  67. package/node_modules/@comis/core/dist/config/schema-misc.test.js +0 -394
  68. package/node_modules/@comis/core/dist/config/schema-observability.test.d.ts +0 -1
  69. package/node_modules/@comis/core/dist/config/schema-observability.test.js +0 -76
  70. package/node_modules/@comis/core/dist/config/schema-providers.test.d.ts +0 -1
  71. package/node_modules/@comis/core/dist/config/schema-providers.test.js +0 -294
  72. package/node_modules/@comis/core/dist/config/schema-queue.test.d.ts +0 -1
  73. package/node_modules/@comis/core/dist/config/schema-queue.test.js +0 -234
  74. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.d.ts +0 -1
  75. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.js +0 -36
  76. package/node_modules/@comis/core/dist/config/schema-security.test.d.ts +0 -1
  77. package/node_modules/@comis/core/dist/config/schema-security.test.js +0 -54
  78. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.d.ts +0 -1
  79. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.js +0 -60
  80. package/node_modules/@comis/core/dist/config/schema-serializer.test.d.ts +0 -1
  81. package/node_modules/@comis/core/dist/config/schema-serializer.test.js +0 -73
  82. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.d.ts +0 -1
  83. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.js +0 -39
  84. package/node_modules/@comis/core/dist/context/context.test.d.ts +0 -1
  85. package/node_modules/@comis/core/dist/context/context.test.js +0 -276
  86. package/node_modules/@comis/core/dist/domain/agent-response.test.d.ts +0 -1
  87. package/node_modules/@comis/core/dist/domain/agent-response.test.js +0 -159
  88. package/node_modules/@comis/core/dist/domain/credential-mapping.test.d.ts +0 -1
  89. package/node_modules/@comis/core/dist/domain/credential-mapping.test.js +0 -135
  90. package/node_modules/@comis/core/dist/domain/delivery-origin.test.d.ts +0 -1
  91. package/node_modules/@comis/core/dist/domain/delivery-origin.test.js +0 -68
  92. package/node_modules/@comis/core/dist/domain/execution-graph.test.d.ts +0 -1
  93. package/node_modules/@comis/core/dist/domain/execution-graph.test.js +0 -441
  94. package/node_modules/@comis/core/dist/domain/memory-entry.test.d.ts +0 -1
  95. package/node_modules/@comis/core/dist/domain/memory-entry.test.js +0 -193
  96. package/node_modules/@comis/core/dist/domain/normalized-message.test.d.ts +0 -1
  97. package/node_modules/@comis/core/dist/domain/normalized-message.test.js +0 -255
  98. package/node_modules/@comis/core/dist/domain/session-key.test.d.ts +0 -1
  99. package/node_modules/@comis/core/dist/domain/session-key.test.js +0 -291
  100. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.d.ts +0 -1
  101. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.js +0 -131
  102. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.d.ts +0 -1
  103. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.js +0 -182
  104. package/node_modules/@comis/core/dist/event-bus/bus.test.d.ts +0 -1
  105. package/node_modules/@comis/core/dist/event-bus/bus.test.js +0 -152
  106. package/node_modules/@comis/core/dist/event-bus/events-agent.test.d.ts +0 -1
  107. package/node_modules/@comis/core/dist/event-bus/events-agent.test.js +0 -409
  108. package/node_modules/@comis/core/dist/event-bus/events-channel.test.d.ts +0 -1
  109. package/node_modules/@comis/core/dist/event-bus/events-channel.test.js +0 -240
  110. package/node_modules/@comis/core/dist/event-bus/events-infra.test.d.ts +0 -1
  111. package/node_modules/@comis/core/dist/event-bus/events-infra.test.js +0 -416
  112. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.d.ts +0 -1
  113. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.js +0 -433
  114. package/node_modules/@comis/core/dist/event-bus/events.test.d.ts +0 -1
  115. package/node_modules/@comis/core/dist/event-bus/events.test.js +0 -93
  116. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.d.ts +0 -1
  117. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.js +0 -29
  118. package/node_modules/@comis/core/dist/hooks/hook-runner.test.d.ts +0 -1
  119. package/node_modules/@comis/core/dist/hooks/hook-runner.test.js +0 -490
  120. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.d.ts +0 -1
  121. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.js +0 -209
  122. package/node_modules/@comis/core/dist/hooks/integration.test.d.ts +0 -1
  123. package/node_modules/@comis/core/dist/hooks/integration.test.js +0 -235
  124. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.d.ts +0 -1
  125. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.js +0 -470
  126. package/node_modules/@comis/core/dist/load-env.test.d.ts +0 -1
  127. package/node_modules/@comis/core/dist/load-env.test.js +0 -21
  128. package/node_modules/@comis/core/dist/security/action-classifier.test.d.ts +0 -1
  129. package/node_modules/@comis/core/dist/security/action-classifier.test.js +0 -298
  130. package/node_modules/@comis/core/dist/security/audit-aggregator.test.d.ts +0 -1
  131. package/node_modules/@comis/core/dist/security/audit-aggregator.test.js +0 -128
  132. package/node_modules/@comis/core/dist/security/audit.test.d.ts +0 -1
  133. package/node_modules/@comis/core/dist/security/audit.test.js +0 -154
  134. package/node_modules/@comis/core/dist/security/canary-token.test.d.ts +0 -1
  135. package/node_modules/@comis/core/dist/security/canary-token.test.js +0 -45
  136. package/node_modules/@comis/core/dist/security/config-redaction.test.d.ts +0 -1
  137. package/node_modules/@comis/core/dist/security/config-redaction.test.js +0 -107
  138. package/node_modules/@comis/core/dist/security/external-content.test.d.ts +0 -1
  139. package/node_modules/@comis/core/dist/security/external-content.test.js +0 -210
  140. package/node_modules/@comis/core/dist/security/injection-patterns.test.d.ts +0 -1
  141. package/node_modules/@comis/core/dist/security/injection-patterns.test.js +0 -213
  142. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.d.ts +0 -1
  143. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.js +0 -194
  144. package/node_modules/@comis/core/dist/security/input-guard.test.d.ts +0 -1
  145. package/node_modules/@comis/core/dist/security/input-guard.test.js +0 -215
  146. package/node_modules/@comis/core/dist/security/input-security-guard.test.d.ts +0 -1
  147. package/node_modules/@comis/core/dist/security/input-security-guard.test.js +0 -215
  148. package/node_modules/@comis/core/dist/security/input-validator.test.d.ts +0 -1
  149. package/node_modules/@comis/core/dist/security/input-validator.test.js +0 -133
  150. package/node_modules/@comis/core/dist/security/log-sanitizer.test.d.ts +0 -1
  151. package/node_modules/@comis/core/dist/security/log-sanitizer.test.js +0 -260
  152. package/node_modules/@comis/core/dist/security/memory-write-validator.test.d.ts +0 -1
  153. package/node_modules/@comis/core/dist/security/memory-write-validator.test.js +0 -62
  154. package/node_modules/@comis/core/dist/security/output-guard.test.d.ts +0 -1
  155. package/node_modules/@comis/core/dist/security/output-guard.test.js +0 -397
  156. package/node_modules/@comis/core/dist/security/safe-path.test.d.ts +0 -1
  157. package/node_modules/@comis/core/dist/security/safe-path.test.js +0 -95
  158. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.d.ts +0 -1
  159. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.js +0 -231
  160. package/node_modules/@comis/core/dist/security/secret-access.test.d.ts +0 -1
  161. package/node_modules/@comis/core/dist/security/secret-access.test.js +0 -41
  162. package/node_modules/@comis/core/dist/security/secret-crypto.test.d.ts +0 -1
  163. package/node_modules/@comis/core/dist/security/secret-crypto.test.js +0 -113
  164. package/node_modules/@comis/core/dist/security/secret-manager.test.d.ts +0 -1
  165. package/node_modules/@comis/core/dist/security/secret-manager.test.js +0 -394
  166. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.d.ts +0 -1
  167. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.js +0 -268
  168. package/node_modules/@comis/core/dist/security/secrets-audit.test.d.ts +0 -10
  169. package/node_modules/@comis/core/dist/security/secrets-audit.test.js +0 -295
  170. package/node_modules/@comis/core/dist/security/ssrf-guard.test.d.ts +0 -1
  171. package/node_modules/@comis/core/dist/security/ssrf-guard.test.js +0 -127
  172. package/node_modules/@comis/core/dist/security/token-generator.test.d.ts +0 -1
  173. package/node_modules/@comis/core/dist/security/token-generator.test.js +0 -35
  174. package/node_modules/@comis/core/dist/tool-metadata.test.d.ts +0 -1
  175. package/node_modules/@comis/core/dist/tool-metadata.test.js +0 -112
  176. package/node_modules/@comis/memory/dist/compaction.test.d.ts +0 -1
  177. package/node_modules/@comis/memory/dist/compaction.test.js +0 -298
  178. package/node_modules/@comis/memory/dist/context-schema.test.d.ts +0 -1
  179. package/node_modules/@comis/memory/dist/context-schema.test.js +0 -246
  180. package/node_modules/@comis/memory/dist/context-store.test.d.ts +0 -1
  181. package/node_modules/@comis/memory/dist/context-store.test.js +0 -708
  182. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.d.ts +0 -7
  183. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.js +0 -73
  184. package/node_modules/@comis/memory/dist/credential-mapping-store.test.d.ts +0 -8
  185. package/node_modules/@comis/memory/dist/credential-mapping-store.test.js +0 -340
  186. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.d.ts +0 -1
  187. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.js +0 -165
  188. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.d.ts +0 -1
  189. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.js +0 -263
  190. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.d.ts +0 -1
  191. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.js +0 -202
  192. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.d.ts +0 -1
  193. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.js +0 -241
  194. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.d.ts +0 -8
  195. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.js +0 -678
  196. package/node_modules/@comis/memory/dist/embedding-cache.test.d.ts +0 -1
  197. package/node_modules/@comis/memory/dist/embedding-cache.test.js +0 -213
  198. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.d.ts +0 -1
  199. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.js +0 -87
  200. package/node_modules/@comis/memory/dist/embedding-hash.test.d.ts +0 -1
  201. package/node_modules/@comis/memory/dist/embedding-hash.test.js +0 -31
  202. package/node_modules/@comis/memory/dist/embedding-integration.test.d.ts +0 -8
  203. package/node_modules/@comis/memory/dist/embedding-integration.test.js +0 -232
  204. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.d.ts +0 -1
  205. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.js +0 -176
  206. package/node_modules/@comis/memory/dist/embedding-provider-local.test.d.ts +0 -8
  207. package/node_modules/@comis/memory/dist/embedding-provider-local.test.js +0 -76
  208. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.d.ts +0 -8
  209. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.js +0 -100
  210. package/node_modules/@comis/memory/dist/embedding-queue.test.d.ts +0 -1
  211. package/node_modules/@comis/memory/dist/embedding-queue.test.js +0 -236
  212. package/node_modules/@comis/memory/dist/hybrid-search.test.d.ts +0 -1
  213. package/node_modules/@comis/memory/dist/hybrid-search.test.js +0 -476
  214. package/node_modules/@comis/memory/dist/identity-link-store.test.d.ts +0 -1
  215. package/node_modules/@comis/memory/dist/identity-link-store.test.js +0 -88
  216. package/node_modules/@comis/memory/dist/memory-api.test.d.ts +0 -1
  217. package/node_modules/@comis/memory/dist/memory-api.test.js +0 -495
  218. package/node_modules/@comis/memory/dist/memory-concurrency.test.d.ts +0 -20
  219. package/node_modules/@comis/memory/dist/memory-concurrency.test.js +0 -222
  220. package/node_modules/@comis/memory/dist/named-graph-store.test.d.ts +0 -1
  221. package/node_modules/@comis/memory/dist/named-graph-store.test.js +0 -227
  222. package/node_modules/@comis/memory/dist/observability-store.test.d.ts +0 -1
  223. package/node_modules/@comis/memory/dist/observability-store.test.js +0 -704
  224. package/node_modules/@comis/memory/dist/row-mapper.test.d.ts +0 -1
  225. package/node_modules/@comis/memory/dist/row-mapper.test.js +0 -409
  226. package/node_modules/@comis/memory/dist/schema.test.d.ts +0 -1
  227. package/node_modules/@comis/memory/dist/schema.test.js +0 -240
  228. package/node_modules/@comis/memory/dist/secret-store-schema.test.d.ts +0 -7
  229. package/node_modules/@comis/memory/dist/secret-store-schema.test.js +0 -90
  230. package/node_modules/@comis/memory/dist/session-store.test.d.ts +0 -1
  231. package/node_modules/@comis/memory/dist/session-store.test.js +0 -262
  232. package/node_modules/@comis/memory/dist/setup-secrets.test.d.ts +0 -1
  233. package/node_modules/@comis/memory/dist/setup-secrets.test.js +0 -140
  234. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.d.ts +0 -1
  235. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.js +0 -888
  236. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.d.ts +0 -8
  237. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.js +0 -245
  238. package/node_modules/@comis/shared/dist/abort.test.d.ts +0 -1
  239. package/node_modules/@comis/shared/dist/abort.test.js +0 -71
  240. package/node_modules/@comis/shared/dist/result.test.d.ts +0 -1
  241. package/node_modules/@comis/shared/dist/result.test.js +0 -178
  242. package/node_modules/@comis/shared/dist/suppress-error.test.d.ts +0 -1
  243. package/node_modules/@comis/shared/dist/suppress-error.test.js +0 -50
  244. package/node_modules/@comis/shared/dist/timeout.test.d.ts +0 -1
  245. package/node_modules/@comis/shared/dist/timeout.test.js +0 -75
  246. package/node_modules/@comis/shared/dist/ttl-cache.test.d.ts +0 -1
  247. 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
- });