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,8 +0,0 @@
1
- /**
2
- * Tests for SqliteSecretStore — SecretStorePort implementation with
3
- * AES-256-GCM encrypted BLOB storage in SQLite.
4
- *
5
- * Uses real crypto (no mocks) and temp files for persistence testing.
6
- * Each test gets a unique temp DB path cleaned up in afterEach.
7
- */
8
- export {};
@@ -1,245 +0,0 @@
1
- /**
2
- * Tests for SqliteSecretStore — SecretStorePort implementation with
3
- * AES-256-GCM encrypted BLOB storage in SQLite.
4
- *
5
- * Uses real crypto (no mocks) and temp files for persistence testing.
6
- * Each test gets a unique temp DB path cleaned up in afterEach.
7
- */
8
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
9
- import Database from "better-sqlite3";
10
- import { randomBytes } from "node:crypto";
11
- import * as fs from "node:fs";
12
- import * as os from "node:os";
13
- import { createSecretsCrypto } from "@comis/core";
14
- import { createSqliteSecretStore } from "./sqlite-secret-store.js";
15
- function makeCrypto() {
16
- return createSecretsCrypto(randomBytes(32));
17
- }
18
- function tempDbPath() {
19
- const dir = os.tmpdir();
20
- const name = `comis-test-secrets-${randomBytes(8).toString("hex")}.db`;
21
- return `${dir}/${name}`;
22
- }
23
- /** Unwrap a Result or fail the test. */
24
- function unwrap(result) {
25
- if (!result.ok) {
26
- throw new Error(`Expected ok result, got error: ${result.error.message}`);
27
- }
28
- return result.value;
29
- }
30
- describe("createSqliteSecretStore", () => {
31
- let dbPath;
32
- let crypto;
33
- beforeEach(() => {
34
- dbPath = tempDbPath();
35
- crypto = makeCrypto();
36
- });
37
- afterEach(() => {
38
- // Clean up temp database files
39
- for (const suffix of ["", "-wal", "-shm"]) {
40
- try {
41
- fs.unlinkSync(dbPath + suffix);
42
- }
43
- catch {
44
- // File may not exist
45
- }
46
- }
47
- });
48
- describe("set + getDecrypted round-trip", () => {
49
- it("stores and retrieves a secret", () => {
50
- const store = createSqliteSecretStore(dbPath, crypto);
51
- const setResult = store.set("API_KEY", "sk-secret-123");
52
- expect(setResult.ok).toBe(true);
53
- const plaintext = unwrap(store.getDecrypted("API_KEY"));
54
- expect(plaintext).toBe("sk-secret-123");
55
- store.close();
56
- });
57
- });
58
- describe("UPSERT behavior", () => {
59
- it("preserves created_at on update, changes updated_at", () => {
60
- const store = createSqliteSecretStore(dbPath, crypto);
61
- store.set("MY_SECRET", "original-value");
62
- // Get metadata before update
63
- const beforeItems = unwrap(store.list());
64
- const beforeMeta = beforeItems.find((m) => m.name === "MY_SECRET");
65
- expect(beforeMeta).toBeDefined();
66
- const createdBefore = beforeMeta.createdAt;
67
- // Small delay to ensure timestamp difference
68
- const now = Date.now();
69
- while (Date.now() === now) {
70
- // busy-wait for at least 1ms
71
- }
72
- store.set("MY_SECRET", "updated-value");
73
- const afterItems = unwrap(store.list());
74
- const afterMeta = afterItems.find((m) => m.name === "MY_SECRET");
75
- expect(afterMeta).toBeDefined();
76
- // created_at preserved
77
- expect(afterMeta.createdAt).toBe(createdBefore);
78
- // updated_at changed
79
- expect(afterMeta.updatedAt).toBeGreaterThanOrEqual(createdBefore);
80
- // Value updated
81
- const plaintext = unwrap(store.getDecrypted("MY_SECRET"));
82
- expect(plaintext).toBe("updated-value");
83
- store.close();
84
- });
85
- });
86
- describe("getDecrypted", () => {
87
- it("returns ok(undefined) for missing secret", () => {
88
- const store = createSqliteSecretStore(dbPath, crypto);
89
- const plaintext = unwrap(store.getDecrypted("NONEXISTENT"));
90
- expect(plaintext).toBeUndefined();
91
- store.close();
92
- });
93
- });
94
- describe("decryptAll", () => {
95
- it("returns all stored secrets as Map", () => {
96
- const store = createSqliteSecretStore(dbPath, crypto);
97
- store.set("KEY_A", "value-a");
98
- store.set("KEY_B", "value-b");
99
- store.set("KEY_C", "value-c");
100
- const map = unwrap(store.decryptAll());
101
- expect(map.size).toBe(3);
102
- expect(map.get("KEY_A")).toBe("value-a");
103
- expect(map.get("KEY_B")).toBe("value-b");
104
- expect(map.get("KEY_C")).toBe("value-c");
105
- store.close();
106
- });
107
- it("returns empty Map on empty store", () => {
108
- const store = createSqliteSecretStore(dbPath, crypto);
109
- const map = unwrap(store.decryptAll());
110
- expect(map.size).toBe(0);
111
- store.close();
112
- });
113
- it("excludes canary from results", () => {
114
- const store = createSqliteSecretStore(dbPath, crypto);
115
- store.set("USER_SECRET", "my-value");
116
- const map = unwrap(store.decryptAll());
117
- // Should only contain user secret, not canary
118
- expect(map.has("__comis_canary__")).toBe(false);
119
- expect(map.size).toBe(1);
120
- expect(map.get("USER_SECRET")).toBe("my-value");
121
- store.close();
122
- });
123
- });
124
- describe("exists", () => {
125
- it("returns true for stored secret, false for missing", () => {
126
- const store = createSqliteSecretStore(dbPath, crypto);
127
- expect(store.exists("ABSENT")).toBe(false);
128
- store.set("PRESENT", "value");
129
- expect(store.exists("PRESENT")).toBe(true);
130
- store.close();
131
- });
132
- });
133
- describe("list", () => {
134
- it("returns metadata without secret values", () => {
135
- const store = createSqliteSecretStore(dbPath, crypto);
136
- store.set("DB_PASSWORD", "secret123", {
137
- provider: "postgres",
138
- description: "Main database password",
139
- });
140
- const items = unwrap(store.list());
141
- expect(items).toHaveLength(1);
142
- const item = items[0];
143
- expect(item.name).toBe("DB_PASSWORD");
144
- expect(item.provider).toBe("postgres");
145
- expect(item.description).toBe("Main database password");
146
- expect(item.usageCount).toBe(0);
147
- expect(item.createdAt).toBeTypeOf("number");
148
- expect(item.updatedAt).toBeTypeOf("number");
149
- // No secret value in metadata
150
- expect(item).not.toHaveProperty("ciphertext");
151
- expect(item).not.toHaveProperty("iv");
152
- expect(item).not.toHaveProperty("authTag");
153
- expect(item).not.toHaveProperty("salt");
154
- expect(item).not.toHaveProperty("plaintext");
155
- store.close();
156
- });
157
- it("excludes canary from list results", () => {
158
- const store = createSqliteSecretStore(dbPath, crypto);
159
- store.set("VISIBLE_SECRET", "hello");
160
- const items = unwrap(store.list());
161
- const names = items.map((i) => i.name);
162
- expect(names).not.toContain("__comis_canary__");
163
- expect(names).toContain("VISIBLE_SECRET");
164
- store.close();
165
- });
166
- });
167
- describe("delete", () => {
168
- it("returns ok(true) for existing secret", () => {
169
- const store = createSqliteSecretStore(dbPath, crypto);
170
- store.set("TO_DELETE", "value");
171
- const deleted = unwrap(store.delete("TO_DELETE"));
172
- expect(deleted).toBe(true);
173
- // Confirm deleted
174
- expect(store.exists("TO_DELETE")).toBe(false);
175
- store.close();
176
- });
177
- it("returns ok(false) for non-existent secret", () => {
178
- const store = createSqliteSecretStore(dbPath, crypto);
179
- const deleted = unwrap(store.delete("DOES_NOT_EXIST"));
180
- expect(deleted).toBe(false);
181
- store.close();
182
- });
183
- });
184
- describe("recordUsage", () => {
185
- it("increments usage_count and updates last_used_at", () => {
186
- const store = createSqliteSecretStore(dbPath, crypto);
187
- store.set("TRACKED", "value");
188
- // Initial state
189
- const beforeItems = unwrap(store.list());
190
- const before = beforeItems.find((m) => m.name === "TRACKED");
191
- expect(before.usageCount).toBe(0);
192
- expect(before.lastUsedAt).toBeUndefined();
193
- // Record usage
194
- store.recordUsage("TRACKED");
195
- const afterItems = unwrap(store.list());
196
- const after = afterItems.find((m) => m.name === "TRACKED");
197
- expect(after.usageCount).toBe(1);
198
- expect(after.lastUsedAt).toBeTypeOf("number");
199
- // Record again
200
- store.recordUsage("TRACKED");
201
- const finalItems = unwrap(store.list());
202
- const final = finalItems.find((m) => m.name === "TRACKED");
203
- expect(final.usageCount).toBe(2);
204
- store.close();
205
- });
206
- });
207
- describe("close", () => {
208
- it("does not throw", () => {
209
- const store = createSqliteSecretStore(dbPath, crypto);
210
- expect(() => store.close()).not.toThrow();
211
- });
212
- });
213
- describe("WAL mode", () => {
214
- it("enables WAL journal mode", () => {
215
- const store = createSqliteSecretStore(dbPath, crypto);
216
- // Open a new connection to verify WAL mode persists
217
- const db = new Database(dbPath);
218
- const row = db.prepare("PRAGMA journal_mode").get();
219
- expect(row.journal_mode).toBe("wal");
220
- db.close();
221
- store.close();
222
- });
223
- });
224
- describe("file permissions", () => {
225
- it("sets 0o600 on secrets.db", () => {
226
- const store = createSqliteSecretStore(dbPath, crypto);
227
- const stat = fs.statSync(dbPath);
228
- // Check file mode (lower 9 bits)
229
- const mode = stat.mode & 0o777;
230
- expect(mode).toBe(0o600);
231
- store.close();
232
- });
233
- });
234
- describe("persistence", () => {
235
- it("survives close and reopen", () => {
236
- const store1 = createSqliteSecretStore(dbPath, crypto);
237
- store1.set("PERSIST_KEY", "persist-value");
238
- store1.close();
239
- const store2 = createSqliteSecretStore(dbPath, crypto);
240
- const plaintext = unwrap(store2.getDecrypted("PERSIST_KEY"));
241
- expect(plaintext).toBe("persist-value");
242
- store2.close();
243
- });
244
- });
245
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,71 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { checkAborted } from "./abort.js";
3
- describe("checkAborted", () => {
4
- it("returns ok when signal is undefined", () => {
5
- const result = checkAborted(undefined);
6
- expect(result.ok).toBe(true);
7
- if (result.ok) {
8
- expect(result.value).toBeUndefined();
9
- }
10
- });
11
- it("returns ok when signal is not aborted", () => {
12
- const controller = new AbortController();
13
- const result = checkAborted(controller.signal);
14
- expect(result.ok).toBe(true);
15
- if (result.ok) {
16
- expect(result.value).toBeUndefined();
17
- }
18
- });
19
- it("returns err when signal is aborted", () => {
20
- const controller = new AbortController();
21
- controller.abort("custom reason");
22
- const result = checkAborted(controller.signal);
23
- expect(result.ok).toBe(false);
24
- if (!result.ok) {
25
- expect(result.error).toBeInstanceOf(Error);
26
- expect(result.error.message).toBe("custom reason");
27
- }
28
- });
29
- it("preserves Error reason directly when signal.reason is an Error", () => {
30
- const controller = new AbortController();
31
- const originalError = new Error("specific abort reason");
32
- controller.abort(originalError);
33
- const result = checkAborted(controller.signal);
34
- expect(result.ok).toBe(false);
35
- if (!result.ok) {
36
- expect(result.error).toBe(originalError);
37
- expect(result.error.message).toBe("specific abort reason");
38
- }
39
- });
40
- it("wraps string reason in Error", () => {
41
- const controller = new AbortController();
42
- controller.abort("string reason");
43
- const result = checkAborted(controller.signal);
44
- expect(result.ok).toBe(false);
45
- if (!result.ok) {
46
- expect(result.error).toBeInstanceOf(Error);
47
- expect(result.error.message).toBe("string reason");
48
- }
49
- });
50
- it("defaults to 'Aborted' when no reason is set", () => {
51
- const controller = new AbortController();
52
- controller.abort();
53
- const result = checkAborted(controller.signal);
54
- expect(result.ok).toBe(false);
55
- if (!result.ok) {
56
- expect(result.error).toBeInstanceOf(Error);
57
- // AbortController.abort() without args sets reason to a DOMException
58
- // in Node.js, but our function handles the general case
59
- expect(result.error.message).toBeTruthy();
60
- }
61
- });
62
- it("returns err immediately for pre-aborted signal (AbortSignal.abort())", () => {
63
- const signal = AbortSignal.abort("pre-aborted");
64
- const result = checkAborted(signal);
65
- expect(result.ok).toBe(false);
66
- if (!result.ok) {
67
- expect(result.error).toBeInstanceOf(Error);
68
- expect(result.error.message).toBe("pre-aborted");
69
- }
70
- });
71
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,178 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { ok, err, tryCatch, fromPromise } from "./result.js";
3
- describe("Result<T, E>", () => {
4
- describe("ok()", () => {
5
- it("returns { ok: true, value: T }", () => {
6
- const result = ok(42);
7
- expect(result).toEqual({ ok: true, value: 42 });
8
- });
9
- it("allows access to .value when narrowed via ok === true", () => {
10
- const result = ok(42);
11
- if (result.ok) {
12
- // TypeScript narrows to { ok: true, value: number }
13
- expect(result.value).toBe(42);
14
- }
15
- else {
16
- throw new Error("Should not reach here");
17
- }
18
- });
19
- it("works with complex types", () => {
20
- const result = ok({ name: "test", count: 3 });
21
- expect(result.ok).toBe(true);
22
- if (result.ok) {
23
- expect(result.value.name).toBe("test");
24
- expect(result.value.count).toBe(3);
25
- }
26
- });
27
- });
28
- describe("err()", () => {
29
- it("returns { ok: false, error: E }", () => {
30
- const error = new Error("fail");
31
- const result = err(error);
32
- expect(result).toEqual({ ok: false, error });
33
- });
34
- it("allows access to .error when narrowed via ok === false", () => {
35
- const result = err(new Error("fail"));
36
- if (!result.ok) {
37
- // TypeScript narrows to { ok: false, error: Error }
38
- expect(result.error.message).toBe("fail");
39
- }
40
- else {
41
- throw new Error("Should not reach here");
42
- }
43
- });
44
- it("works with custom error types", () => {
45
- const result = err({ code: "NOT_FOUND", message: "not found" });
46
- expect(result.ok).toBe(false);
47
- if (!result.ok) {
48
- expect(result.error.code).toBe("NOT_FOUND");
49
- }
50
- });
51
- });
52
- describe("tryCatch()", () => {
53
- it("returns ok(value) when function succeeds", () => {
54
- const result = tryCatch(() => 42);
55
- expect(result).toEqual({ ok: true, value: 42 });
56
- });
57
- it("returns err(Error) when function throws Error", () => {
58
- const result = tryCatch(() => {
59
- throw new Error("boom");
60
- });
61
- expect(result.ok).toBe(false);
62
- if (!result.ok) {
63
- expect(result.error).toBeInstanceOf(Error);
64
- expect(result.error.message).toBe("boom");
65
- }
66
- });
67
- it("wraps non-Error thrown values in Error", () => {
68
- const result = tryCatch(() => {
69
- throw "string error";
70
- });
71
- expect(result.ok).toBe(false);
72
- if (!result.ok) {
73
- expect(result.error).toBeInstanceOf(Error);
74
- expect(result.error.message).toBe("string error");
75
- }
76
- });
77
- it("wraps thrown numbers in Error", () => {
78
- const result = tryCatch(() => {
79
- throw 404;
80
- });
81
- expect(result.ok).toBe(false);
82
- if (!result.ok) {
83
- expect(result.error).toBeInstanceOf(Error);
84
- expect(result.error.message).toBe("404");
85
- }
86
- });
87
- it("handles malicious object with toString() that throws", () => {
88
- const malicious = {
89
- toString() {
90
- throw new Error("toString attack");
91
- },
92
- };
93
- const result = tryCatch(() => {
94
- throw malicious;
95
- });
96
- expect(result.ok).toBe(false);
97
- if (!result.ok) {
98
- expect(result.error).toBeInstanceOf(Error);
99
- expect(result.error.message).toBe("[non-stringifiable value]");
100
- }
101
- });
102
- });
103
- describe("fromPromise()", () => {
104
- it("returns ok(value) when promise resolves", async () => {
105
- const result = await fromPromise(Promise.resolve(42));
106
- expect(result).toEqual({ ok: true, value: 42 });
107
- });
108
- it("returns err(Error) when promise rejects with Error", async () => {
109
- const result = await fromPromise(Promise.reject(new Error("boom")));
110
- expect(result.ok).toBe(false);
111
- if (!result.ok) {
112
- expect(result.error).toBeInstanceOf(Error);
113
- expect(result.error.message).toBe("boom");
114
- }
115
- });
116
- it("wraps non-Error rejection in Error", async () => {
117
- const result = await fromPromise(Promise.reject("string"));
118
- expect(result.ok).toBe(false);
119
- if (!result.ok) {
120
- expect(result.error).toBeInstanceOf(Error);
121
- expect(result.error.message).toBe("string");
122
- }
123
- });
124
- it("wraps null rejection in Error", async () => {
125
- const result = await fromPromise(Promise.reject(null));
126
- expect(result.ok).toBe(false);
127
- if (!result.ok) {
128
- expect(result.error).toBeInstanceOf(Error);
129
- expect(result.error.message).toBe("null");
130
- }
131
- });
132
- it("handles malicious object with toString() that throws", async () => {
133
- const malicious = {
134
- toString() {
135
- throw new Error("toString attack");
136
- },
137
- };
138
- const result = await fromPromise(Promise.reject(malicious));
139
- expect(result.ok).toBe(false);
140
- if (!result.ok) {
141
- expect(result.error).toBeInstanceOf(Error);
142
- expect(result.error.message).toBe("[non-stringifiable value]");
143
- }
144
- });
145
- it("wraps undefined rejection in Error", async () => {
146
- const result = await fromPromise(Promise.reject(undefined));
147
- expect(result.ok).toBe(false);
148
- if (!result.ok) {
149
- expect(result.error).toBeInstanceOf(Error);
150
- expect(result.error.message).toBe("undefined");
151
- }
152
- });
153
- });
154
- describe("tryCatch() - undefined edge cases", () => {
155
- it("wraps thrown undefined in Error", () => {
156
- const result = tryCatch(() => {
157
- throw undefined;
158
- });
159
- expect(result.ok).toBe(false);
160
- if (!result.ok) {
161
- expect(result.error).toBeInstanceOf(Error);
162
- expect(result.error.message).toBe("undefined");
163
- }
164
- });
165
- it("wraps thrown void (undefined) in Error", () => {
166
- // eslint-disable-next-line @typescript-eslint/no-throw-literal
167
- const result = tryCatch(() => {
168
- // This explicitly tests the edge case of a void throw
169
- throw void 0;
170
- });
171
- expect(result.ok).toBe(false);
172
- if (!result.ok) {
173
- expect(result.error).toBeInstanceOf(Error);
174
- expect(result.error.message).toBe("undefined");
175
- }
176
- });
177
- });
178
- });
@@ -1,50 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { suppressError } from "./suppress-error.js";
3
- describe("suppressError()", () => {
4
- it("does not throw when promise rejects", () => {
5
- expect(() => {
6
- suppressError(Promise.reject(new Error("test")), "cleanup");
7
- }).not.toThrow();
8
- });
9
- it("logs the error reason at debug level when no logger provided", async () => {
10
- const debugSpy = vi.spyOn(console, "debug").mockImplementation(() => { });
11
- suppressError(Promise.reject(new Error("test error")), "cleanup task");
12
- // Wait for the microtask queue to flush
13
- await new Promise((resolve) => setTimeout(resolve, 10));
14
- expect(debugSpy).toHaveBeenCalledWith("Suppressed error (cleanup task): test error");
15
- expect(debugSpy).toHaveBeenCalledTimes(1);
16
- debugSpy.mockRestore();
17
- });
18
- it("uses custom logger when provided", async () => {
19
- const debugSpy = vi.spyOn(console, "debug").mockImplementation(() => { });
20
- const customLogger = vi.fn();
21
- suppressError(Promise.reject(new Error("custom error")), "custom task", customLogger);
22
- await new Promise((resolve) => setTimeout(resolve, 10));
23
- expect(customLogger).toHaveBeenCalledTimes(1);
24
- expect(customLogger).toHaveBeenCalledWith("Suppressed error (custom task): custom error");
25
- // console.debug should NOT be called when custom logger is provided
26
- expect(debugSpy).not.toHaveBeenCalled();
27
- debugSpy.mockRestore();
28
- });
29
- it("passes formatted error message string to custom logger", async () => {
30
- const customLogger = vi.fn();
31
- suppressError(Promise.reject(new Error("something broke")), "retry cleanup", customLogger);
32
- await new Promise((resolve) => setTimeout(resolve, 10));
33
- expect(customLogger).toHaveBeenCalledWith("Suppressed error (retry cleanup): something broke");
34
- });
35
- it("handles non-Error rejection with custom logger", async () => {
36
- const customLogger = vi.fn();
37
- suppressError(Promise.reject("plain string rejection"), "string reject", customLogger);
38
- await new Promise((resolve) => setTimeout(resolve, 10));
39
- expect(customLogger).toHaveBeenCalledWith("Suppressed error (string reject): plain string rejection");
40
- });
41
- it("does not cause unhandled rejection", async () => {
42
- const unhandledHandler = vi.fn();
43
- process.on("unhandledRejection", unhandledHandler);
44
- suppressError(Promise.reject(new Error("should be caught")), "test");
45
- // Wait enough for unhandledRejection to fire if it were going to
46
- await new Promise((resolve) => setTimeout(resolve, 50));
47
- expect(unhandledHandler).not.toHaveBeenCalled();
48
- process.removeListener("unhandledRejection", unhandledHandler);
49
- });
50
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,75 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { withTimeout, TimeoutError } from "./timeout.js";
3
- describe("TimeoutError", () => {
4
- it("has name set to 'TimeoutError'", () => {
5
- const error = new TimeoutError(5000);
6
- expect(error.name).toBe("TimeoutError");
7
- });
8
- it("is instanceof Error", () => {
9
- const error = new TimeoutError(5000);
10
- expect(error).toBeInstanceOf(Error);
11
- });
12
- it("has correct timeoutMs property", () => {
13
- const error = new TimeoutError(3000);
14
- expect(error.timeoutMs).toBe(3000);
15
- });
16
- it("formats message with label", () => {
17
- const error = new TimeoutError(5000, "MCP connect");
18
- expect(error.message).toBe("MCP connect timed out after 5000ms");
19
- });
20
- it("formats message without label", () => {
21
- const error = new TimeoutError(5000);
22
- expect(error.message).toBe("Operation timed out after 5000ms");
23
- });
24
- });
25
- describe("withTimeout", () => {
26
- it("resolves when promise completes before timeout", async () => {
27
- const result = await withTimeout(Promise.resolve(42), 1000);
28
- expect(result).toBe(42);
29
- });
30
- it("rejects with TimeoutError when timeout fires first", async () => {
31
- const neverResolves = new Promise(() => { });
32
- await expect(withTimeout(neverResolves, 10, "test op")).rejects.toThrow(TimeoutError);
33
- });
34
- it("TimeoutError has correct timeoutMs on rejection", async () => {
35
- const neverResolves = new Promise(() => { });
36
- try {
37
- await withTimeout(neverResolves, 25, "test op");
38
- throw new Error("Should not reach here");
39
- }
40
- catch (e) {
41
- expect(e).toBeInstanceOf(TimeoutError);
42
- expect(e.timeoutMs).toBe(25);
43
- }
44
- });
45
- it("timer is cleaned up on success", async () => {
46
- vi.useFakeTimers();
47
- try {
48
- const promise = Promise.resolve("ok");
49
- await withTimeout(promise, 60_000);
50
- // After resolution, advancing time should not cause issues
51
- // (timer was cleared, no pending timers)
52
- expect(vi.getTimerCount()).toBe(0);
53
- }
54
- finally {
55
- vi.useRealTimers();
56
- }
57
- });
58
- it("propagates original error when promise rejects before timeout", async () => {
59
- const originalError = new Error("original failure");
60
- const failing = Promise.reject(originalError);
61
- await expect(withTimeout(failing, 5000)).rejects.toThrow("original failure");
62
- await expect(withTimeout(Promise.reject(originalError), 5000)).rejects.not.toBeInstanceOf(TimeoutError);
63
- });
64
- it("no unhandled rejection when original promise rejects after timeout", async () => {
65
- // Create a promise that rejects after a short delay
66
- const delayedReject = new Promise((_resolve, reject) => {
67
- setTimeout(() => reject(new Error("late rejection")), 50);
68
- });
69
- // The timeout fires first (10ms < 50ms)
70
- await expect(withTimeout(delayedReject, 10, "test")).rejects.toThrow(TimeoutError);
71
- // Wait for the delayed rejection to fire -- if unhandled rejection
72
- // suppression is missing, this would crash the test runner
73
- await new Promise((r) => setTimeout(r, 100));
74
- });
75
- });
@@ -1 +0,0 @@
1
- export {};