@zackbart/connecta 0.34.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. package/CHANGELOG.md +393 -0
  2. package/README.md +62 -105
  3. package/SECURITY.md +3 -2
  4. package/bin/connecta.mjs +41 -16
  5. package/bin/version.mjs +1 -1
  6. package/dist/access-tokens.d.ts +2 -1
  7. package/dist/access-tokens.js +66 -30
  8. package/dist/activity.d.ts +1 -1
  9. package/dist/activity.js +2 -0
  10. package/dist/agent-config.d.ts +23 -0
  11. package/dist/agent-config.js +59 -0
  12. package/dist/agent-description.js +16 -0
  13. package/dist/agent-identity.js +4 -4
  14. package/dist/agent-observation.js +39 -0
  15. package/dist/auth/clerk-sdk/client.d.ts +2 -0
  16. package/dist/auth/clerk-sdk/generated.js +554 -563
  17. package/dist/auth/clerk-transport.js +70 -3
  18. package/dist/auth/clerk.d.ts +13 -0
  19. package/dist/auth/clerk.js +653 -246
  20. package/dist/auth/cloudflare-access.js +46 -42
  21. package/dist/auth/downstream-client-metadata.js +2 -2
  22. package/dist/auth/downstream-oauth.js +2051 -1160
  23. package/dist/auth/downstream-revocation.js +88 -88
  24. package/dist/auth/native-call.js +20 -0
  25. package/dist/auth/native.js +184 -0
  26. package/dist/auth/oauth-start-reset.js +11 -5
  27. package/dist/auth/oauth-token-response.js +121 -102
  28. package/dist/auth/oauth-v2-migration.js +97 -78
  29. package/dist/auth/renewable-grant.js +10 -0
  30. package/dist/auth/static-oauth.js +663 -271
  31. package/dist/auth/vercel-agent.js +266 -0
  32. package/dist/auth-admission.js +204 -0
  33. package/dist/auth-elicitation.js +350 -241
  34. package/dist/authorization-handoff.js +164 -90
  35. package/dist/call-admission-context.js +3 -10
  36. package/dist/call-admission.js +2 -0
  37. package/dist/call-classification.js +9 -0
  38. package/dist/call-recovery.js +32 -13
  39. package/dist/canonical-json.js +8 -0
  40. package/dist/catalog-cache.js +369 -213
  41. package/dist/catalog-service.js +659 -530
  42. package/dist/catalog.js +5 -1
  43. package/dist/concurrency.js +0 -25
  44. package/dist/config-defaults.d.ts +1 -0
  45. package/dist/config-defaults.js +1 -0
  46. package/dist/config-schema.d.ts +3 -1
  47. package/dist/config-schema.js +13 -3
  48. package/dist/config.d.ts +40 -6
  49. package/dist/config.js +40 -26
  50. package/dist/connector-caller.d.ts +4 -0
  51. package/dist/connector-caller.js +17 -4
  52. package/dist/connectors/api-connector.d.ts +15 -7
  53. package/dist/connectors/api-connector.js +147 -57
  54. package/dist/connectors/guarded-fetch.d.ts +51 -17
  55. package/dist/connectors/guarded-fetch.js +215 -121
  56. package/dist/connectors/negotiation-cache.js +20 -10
  57. package/dist/connectors/option-shapes.js +1 -1
  58. package/dist/connectors/remote-mcp.d.ts +12 -30
  59. package/dist/connectors/remote-mcp.js +960 -564
  60. package/dist/d1.js +10 -243
  61. package/dist/derived-context.js +5 -0
  62. package/dist/describe-config.d.ts +5 -1
  63. package/dist/describe-config.js +3 -0
  64. package/dist/downstream-input.js +347 -260
  65. package/dist/errors.d.ts +87 -6
  66. package/dist/errors.js +114 -4
  67. package/dist/execute.js +87 -50
  68. package/dist/executor-admission.js +3 -0
  69. package/dist/executors/quickjs.js +163 -112
  70. package/dist/guarded-transport.js +50 -0
  71. package/dist/guest-runtime.js +1 -1
  72. package/dist/http/client.js +439 -0
  73. package/dist/http/errors.js +558 -0
  74. package/dist/http/fields.js +49 -0
  75. package/dist/http/hatch-paging.js +318 -0
  76. package/dist/http/hatch.js +1279 -0
  77. package/dist/http/json-schema.js +267 -0
  78. package/dist/http/node-transport.js +241 -0
  79. package/dist/http/oauth.js +162 -0
  80. package/dist/http/paging.js +228 -0
  81. package/dist/http/provider.js +221 -0
  82. package/dist/http/safety.js +82 -0
  83. package/dist/http/services.js +79 -0
  84. package/dist/http/tools.js +383 -0
  85. package/dist/http/vendor-index.js +138 -0
  86. package/dist/http/vendor.js +448 -0
  87. package/dist/http/write-request.js +66 -0
  88. package/dist/http-policy.d.ts +11 -0
  89. package/dist/http-policy.js +45 -0
  90. package/dist/inbound-credential.js +1 -1
  91. package/dist/index.d.ts +2 -2
  92. package/dist/index.js +4 -0
  93. package/dist/invocation-auth.js +30 -19
  94. package/dist/invocation.js +221 -87
  95. package/dist/mcp-result.js +0 -4
  96. package/dist/membership.d.ts +4 -0
  97. package/dist/meta-output.js +1 -1
  98. package/dist/meta-tools.js +534 -408
  99. package/dist/native-recovery.js +52 -0
  100. package/dist/native-tools.js +382 -0
  101. package/dist/node.d.ts +4 -3
  102. package/dist/node.js +45 -8
  103. package/dist/oauth-handoff.js +177 -104
  104. package/dist/oauth-partition.js +6 -20
  105. package/dist/oauth-sealing.js +6 -7
  106. package/dist/operation-vocabulary.js +101 -0
  107. package/dist/operator-record.d.ts +2 -2
  108. package/dist/operator-record.js +17 -4
  109. package/dist/operator-ui/agents.d.ts +5 -4
  110. package/dist/operator-ui/agents.js +17 -7
  111. package/dist/operator-ui/config-summary.js +8 -4
  112. package/dist/operator-ui/connection-map.js +9 -6
  113. package/dist/operator-ui/contract.d.ts +7 -3
  114. package/dist/operator-ui/endpoints.js +5 -14
  115. package/dist/operator-ui/fix-prompts.d.ts +1 -1
  116. package/dist/operator-ui/fix-prompts.js +0 -8
  117. package/dist/operator-ui/generated.js +3 -3
  118. package/dist/operator-ui/health.js +52 -0
  119. package/dist/operator-ui/model.d.ts +2 -3
  120. package/dist/operator-ui/overview.js +11 -19
  121. package/dist/operator-ui/setup-commands.js +0 -4
  122. package/dist/operator-ui/view.d.ts +5 -29
  123. package/dist/operator-ui/view.js +3 -59
  124. package/dist/program-writes.js +47 -26
  125. package/dist/provider-call-facts.d.ts +115 -0
  126. package/dist/provider-call-facts.js +182 -0
  127. package/dist/provider-call.d.ts +112 -0
  128. package/dist/provider-call.js +271 -0
  129. package/dist/provider.d.ts +71 -32
  130. package/dist/provider.js +134 -40
  131. package/dist/providers/_shared/google/hatch.js +91 -0
  132. package/dist/providers/_shared/google/kit.js +537 -0
  133. package/dist/providers/_shared/google/result-size.js +15 -2
  134. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  135. package/dist/providers/_shared/google/service-account.js +8 -4
  136. package/dist/providers/_shared/google/workspace.d.ts +8 -209
  137. package/dist/providers/_shared/google/workspace.js +7 -426
  138. package/dist/providers/_shared/rest/compact-index.js +86 -0
  139. package/dist/providers/_shared/rest/dispatch.js +3 -23
  140. package/dist/providers/_shared/rest/kit.js +546 -0
  141. package/dist/providers/_shared/rest/operation-index.js +230 -14
  142. package/dist/providers/_shared/rest/response-media.js +11 -0
  143. package/dist/providers/_shared/rest/tools.js +101 -78
  144. package/dist/providers/_shared/rest/value-safety.js +353 -195
  145. package/dist/providers/_shared/sensitive-fields.js +27 -0
  146. package/dist/providers/breeze/api.js +584 -0
  147. package/dist/providers/breeze/index.d.ts +3 -3
  148. package/dist/providers/breeze/index.js +67 -1420
  149. package/dist/providers/breeze/openapi.generated.js +60 -0
  150. package/dist/providers/breeze/skill.generated.js +2 -6
  151. package/dist/providers/breeze/tools.js +696 -0
  152. package/dist/providers/ccb/api.js +496 -0
  153. package/dist/providers/ccb/index.d.ts +17 -37
  154. package/dist/providers/ccb/index.js +77 -1702
  155. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  156. package/dist/providers/ccb/lib/constants.js +74 -0
  157. package/dist/providers/ccb/lib/guide.js +9 -0
  158. package/dist/providers/ccb/lib/verdicts.js +387 -0
  159. package/dist/providers/ccb/openapi.generated.js +397 -0
  160. package/dist/providers/ccb/safety.js +295 -0
  161. package/dist/providers/ccb/skill.generated.js +2 -6
  162. package/dist/providers/ccb/tools.js +853 -0
  163. package/dist/providers/cloudflare/api.js +1066 -0
  164. package/dist/providers/cloudflare/index.d.ts +7 -22
  165. package/dist/providers/cloudflare/index.js +80 -194
  166. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  167. package/dist/providers/cloudflare/lib/config.js +2 -0
  168. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  169. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  170. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  171. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  172. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  173. package/dist/providers/cloudflare/openapi.generated.js +3299 -3208
  174. package/dist/providers/cloudflare/{value-safety.js → safety.js} +538 -18
  175. package/dist/providers/cloudflare/skill.generated.js +2 -10
  176. package/dist/providers/cloudflare/tools.js +360 -0
  177. package/dist/providers/docs/api.js +51 -0
  178. package/dist/providers/docs/index.d.ts +1 -12
  179. package/dist/providers/docs/index.js +53 -1165
  180. package/dist/providers/docs/lib/constants.d.ts +18 -0
  181. package/dist/providers/docs/lib/constants.js +18 -0
  182. package/dist/providers/docs/lib/discovery.js +26 -0
  183. package/dist/providers/docs/lib/requests.js +48 -0
  184. package/dist/providers/docs/lib/schemas.js +168 -0
  185. package/dist/providers/docs/openapi.generated.js +16 -0
  186. package/dist/providers/docs/safety.js +54 -0
  187. package/dist/providers/docs/skill.generated.js +2 -6
  188. package/dist/providers/docs/tools.js +802 -0
  189. package/dist/providers/drive/api.js +177 -0
  190. package/dist/providers/drive/index.d.ts +1 -12
  191. package/dist/providers/drive/index.js +38 -1448
  192. package/dist/providers/drive/lib/constants.d.ts +6 -0
  193. package/dist/providers/drive/lib/constants.js +6 -0
  194. package/dist/providers/drive/lib/contracts.js +532 -0
  195. package/dist/providers/drive/lib/hatch.js +197 -0
  196. package/dist/providers/drive/openapi.generated.js +77 -0
  197. package/dist/providers/drive/safety.js +90 -0
  198. package/dist/providers/drive/skill.generated.js +2 -6
  199. package/dist/providers/drive/tools.js +1290 -0
  200. package/dist/providers/forms/api.js +71 -0
  201. package/dist/providers/forms/index.d.ts +1 -12
  202. package/dist/providers/forms/index.js +49 -1145
  203. package/dist/providers/forms/lib/constants.d.ts +14 -0
  204. package/dist/providers/forms/lib/constants.js +19 -0
  205. package/dist/providers/forms/lib/hatch.js +72 -0
  206. package/dist/providers/forms/openapi.generated.js +23 -0
  207. package/dist/providers/forms/safety.js +34 -0
  208. package/dist/providers/forms/skill.generated.js +2 -8
  209. package/dist/providers/forms/tools.js +1024 -0
  210. package/dist/providers/github/api.js +150 -0
  211. package/dist/providers/github/index.d.ts +4 -5
  212. package/dist/providers/github/index.js +30 -87
  213. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  214. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  215. package/dist/providers/github/lib/discovery.js +132 -0
  216. package/dist/providers/github/lib/operations.js +58 -0
  217. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  218. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  219. package/dist/providers/github/openapi.generated.js +1216 -0
  220. package/dist/providers/github/safety.js +216 -0
  221. package/dist/providers/github/skill.generated.js +2 -5
  222. package/dist/providers/github/tools.js +506 -0
  223. package/dist/providers/gmail/api.js +114 -0
  224. package/dist/providers/gmail/index.d.ts +1 -12
  225. package/dist/providers/gmail/index.js +73 -1621
  226. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  227. package/dist/providers/gmail/lib/constants.js +16 -0
  228. package/dist/providers/gmail/lib/index.js +173 -0
  229. package/dist/providers/gmail/lib/schemas.js +176 -0
  230. package/dist/providers/gmail/lib/threading.js +120 -0
  231. package/dist/providers/gmail/openapi.generated.js +92 -0
  232. package/dist/providers/gmail/safety.js +21 -0
  233. package/dist/providers/gmail/skill.generated.js +2 -6
  234. package/dist/providers/gmail/tools.js +1435 -0
  235. package/dist/providers/overflow/api.js +1008 -0
  236. package/dist/providers/overflow/index.d.ts +3 -17
  237. package/dist/providers/overflow/index.js +60 -1488
  238. package/dist/providers/overflow/skill.generated.js +2 -5
  239. package/dist/providers/overflow/tools.js +873 -0
  240. package/dist/providers/planning-center/api.js +467 -0
  241. package/dist/providers/planning-center/index.d.ts +6 -35
  242. package/dist/providers/planning-center/index.js +69 -2445
  243. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  244. package/dist/providers/planning-center/lib/constants.js +83 -0
  245. package/dist/providers/planning-center/lib/discovery.js +40 -0
  246. package/dist/providers/planning-center/lib/guide.js +39 -0
  247. package/dist/providers/planning-center/lib/json-api.js +83 -0
  248. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  249. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  250. package/dist/providers/planning-center/safety.js +188 -0
  251. package/dist/providers/planning-center/skill.generated.js +2 -27
  252. package/dist/providers/planning-center/tools.js +1010 -0
  253. package/dist/providers/sheets/api.js +133 -0
  254. package/dist/providers/sheets/index.d.ts +4 -16
  255. package/dist/providers/sheets/index.js +61 -1172
  256. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  257. package/dist/providers/sheets/lib/constants.js +14 -0
  258. package/dist/providers/sheets/lib/hatch.js +163 -0
  259. package/dist/providers/sheets/lib/requests.js +105 -0
  260. package/dist/providers/sheets/lib/schemas.js +138 -0
  261. package/dist/providers/sheets/openapi.generated.js +30 -0
  262. package/dist/providers/sheets/safety.js +27 -0
  263. package/dist/providers/sheets/skill.generated.js +2 -7
  264. package/dist/providers/sheets/tools.js +734 -0
  265. package/dist/providers/slides/api.js +147 -0
  266. package/dist/providers/slides/index.d.ts +2 -10
  267. package/dist/providers/slides/index.js +48 -2555
  268. package/dist/providers/slides/lib/constants.d.ts +11 -0
  269. package/dist/providers/slides/lib/constants.js +11 -0
  270. package/dist/providers/slides/lib/requests.js +60 -0
  271. package/dist/providers/slides/lib/schemas.js +565 -0
  272. package/dist/providers/slides/openapi.generated.js +18 -0
  273. package/dist/providers/slides/skill.generated.js +2 -6
  274. package/dist/providers/slides/tools.js +1968 -0
  275. package/dist/providers/stripe/api.js +401 -0
  276. package/dist/providers/stripe/index.d.ts +7 -27
  277. package/dist/providers/stripe/index.js +75 -191
  278. package/dist/providers/stripe/lib/config.d.ts +4 -0
  279. package/dist/providers/stripe/lib/config.js +2 -0
  280. package/dist/providers/stripe/openapi.generated.js +4 -3
  281. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  282. package/dist/providers/stripe/skill.generated.js +2 -10
  283. package/dist/providers/stripe/tools.js +77 -0
  284. package/dist/providers/tithely/api.js +531 -0
  285. package/dist/providers/tithely/index.d.ts +19 -0
  286. package/dist/providers/tithely/index.js +86 -965
  287. package/dist/providers/tithely/skill.generated.js +2 -5
  288. package/dist/providers/tithely/tools.js +426 -0
  289. package/dist/providers/vercel/api.js +551 -0
  290. package/dist/providers/vercel/index.d.ts +11 -25
  291. package/dist/providers/vercel/index.js +67 -261
  292. package/dist/providers/vercel/lib/config.d.ts +2 -0
  293. package/dist/providers/vercel/lib/config.js +2 -0
  294. package/dist/providers/vercel/lib/index.js +117 -0
  295. package/dist/providers/vercel/lib/logs.js +100 -0
  296. package/dist/providers/vercel/lib/pin.js +270 -0
  297. package/dist/providers/vercel/openapi.generated.js +398 -376
  298. package/dist/providers/vercel/{value-safety.js → safety.js} +261 -42
  299. package/dist/providers/vercel/skill.generated.js +2 -7
  300. package/dist/providers/vercel/tools.js +642 -0
  301. package/dist/redaction-identity.js +47 -0
  302. package/dist/redaction-marker.js +125 -0
  303. package/dist/registry.d.ts +30 -28
  304. package/dist/registry.js +446 -413
  305. package/dist/routes/access-tokens.js +1 -1
  306. package/dist/routes/actor-labels.js +1 -1
  307. package/dist/routes/connect.js +1 -1
  308. package/dist/routes/dispatch.js +103 -0
  309. package/dist/routes/mcp.js +170 -79
  310. package/dist/routes/oauth.js +3 -1
  311. package/dist/routes/operator.js +2 -2
  312. package/dist/routes/shared.d.ts +5 -4
  313. package/dist/routes/shared.js +244 -177
  314. package/dist/routes/skills.js +10 -8
  315. package/dist/routes/ui-config.js +27 -3
  316. package/dist/routes/ui-data.js +29 -22
  317. package/dist/routes/ui.js +1 -1
  318. package/dist/runtime/call-admission.js +0 -26
  319. package/dist/runtime/call-entry.js +30 -0
  320. package/dist/runtime/call.js +556 -0
  321. package/dist/runtime/connector-scope.js +7 -0
  322. package/dist/runtime/credential-probe.js +34 -0
  323. package/dist/runtime/executor.js +40 -0
  324. package/dist/runtime/native-storage.js +63 -0
  325. package/dist/runtime/registry.js +27 -0
  326. package/dist/runtime/request-scope.js +72 -0
  327. package/dist/runtime/run.js +15 -7
  328. package/dist/runtime/shared-read.js +34 -5
  329. package/dist/runtime/storage.js +34 -21
  330. package/dist/sent-secrets.d.ts +194 -37
  331. package/dist/sent-secrets.js +1743 -340
  332. package/dist/server.js +5 -56
  333. package/dist/skills.js +330 -224
  334. package/dist/sqlite.js +15 -14
  335. package/dist/storage/d1-copy.js +255 -0
  336. package/dist/storage/d1-driver.js +15 -0
  337. package/dist/storage/keys.js +28 -0
  338. package/dist/storage/sql-driver.js +88 -0
  339. package/dist/storage/sql-native.js +544 -0
  340. package/dist/storage/sql-schema.d.ts +6 -0
  341. package/dist/storage/sql-schema.js +15 -0
  342. package/dist/storage/sql.d.ts +14 -20
  343. package/dist/storage/sql.js +29 -535
  344. package/dist/timeout.js +0 -26
  345. package/dist/tool-safety.js +20 -10
  346. package/dist/types.d.ts +11 -99
  347. package/dist/upward.js +3 -0
  348. package/dist/usage-guide.js +3 -1
  349. package/dist/validate.d.ts +4 -2
  350. package/dist/validate.js +86 -9
  351. package/dist/version.d.ts +1 -1
  352. package/dist/version.js +1 -1
  353. package/dist/worker.js +312 -292
  354. package/dist/workspace-subject.js +5 -1
  355. package/dist/write-outcome.js +454 -34
  356. package/documentation/README.md +27 -7
  357. package/documentation/architecture.md +2550 -186
  358. package/documentation/auth.md +821 -98
  359. package/documentation/code-mode.md +56 -21
  360. package/documentation/deploying.md +164 -20
  361. package/documentation/hosted-mcp-migration.md +460 -0
  362. package/documentation/integrating.md +144 -105
  363. package/documentation/meta-tools.md +411 -34
  364. package/documentation/operating.md +28 -4
  365. package/documentation/operator-tests.md +11 -2
  366. package/documentation/operator-ui.md +103 -33
  367. package/documentation/provider-auth-migration.md +38 -63
  368. package/documentation/provider-migration-0.29.md +10 -5
  369. package/documentation/provider-migration-0.35.md +975 -0
  370. package/documentation/providers.md +965 -0
  371. package/examples/worker/AGENTS.md +23 -9
  372. package/examples/worker/README.md +254 -135
  373. package/examples/worker/alchemy.run.ts +116 -0
  374. package/examples/worker/gitignore +10 -0
  375. package/examples/worker/src/connecta.config.ts +23 -21
  376. package/examples/worker/wrangler.jsonc +14 -5
  377. package/guides/connecting-agents.md +157 -0
  378. package/guides/how-it-works.md +156 -0
  379. package/guides/safety-and-trust.md +153 -0
  380. package/package.json +27 -42
  381. package/templates/node/.env.example +3 -0
  382. package/templates/node/README.md +22 -2
  383. package/templates/node/docker-compose.yml +1 -0
  384. package/templates/node/package.json +3 -2
  385. package/templates/node/src/connecta.config.ts +8 -0
  386. package/dist/catalog-drift.d.ts +0 -134
  387. package/dist/catalog-drift.js +0 -493
  388. package/dist/providers/_shared/request-token.js +0 -83
  389. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  390. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  391. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  392. package/dist/providers/basecamp/index.d.ts +0 -43
  393. package/dist/providers/basecamp/index.js +0 -997
  394. package/dist/providers/basecamp/skill.generated.js +0 -9
  395. package/dist/providers/cloudflare/rest.d.ts +0 -37
  396. package/dist/providers/cloudflare/rest.js +0 -1078
  397. package/dist/providers/github/hosted.js +0 -218
  398. package/dist/providers/github/rest.js +0 -321
  399. package/dist/providers/infisical/index.d.ts +0 -7
  400. package/dist/providers/infisical/index.js +0 -713
  401. package/dist/providers/infisical/skill.generated.js +0 -8
  402. package/dist/providers/linear/index.d.ts +0 -55
  403. package/dist/providers/linear/index.js +0 -352
  404. package/dist/providers/linear/skill.generated.js +0 -8
  405. package/dist/providers/mixpanel/index.d.ts +0 -57
  406. package/dist/providers/mixpanel/index.js +0 -468
  407. package/dist/providers/mixpanel/operations.js +0 -20
  408. package/dist/providers/mixpanel/rest.js +0 -603
  409. package/dist/providers/mixpanel/skill.generated.js +0 -10
  410. package/dist/providers/mixpanel/value-safety.js +0 -16
  411. package/dist/providers/notion/index.d.ts +0 -65
  412. package/dist/providers/notion/index.js +0 -368
  413. package/dist/providers/notion/openapi.generated.js +0 -75
  414. package/dist/providers/notion/rest.d.ts +0 -24
  415. package/dist/providers/notion/rest.js +0 -1226
  416. package/dist/providers/notion/skill.generated.js +0 -11
  417. package/dist/providers/notion/value-safety.js +0 -56
  418. package/dist/providers/revenuecat/index.d.ts +0 -49
  419. package/dist/providers/revenuecat/index.js +0 -557
  420. package/dist/providers/revenuecat/skill.generated.js +0 -11
  421. package/dist/providers/stripe/rest.d.ts +0 -14
  422. package/dist/providers/stripe/rest.js +0 -402
  423. package/dist/providers/vercel/rest.d.ts +0 -20
  424. package/dist/providers/vercel/rest.js +0 -1020
  425. package/dist/providers/wispr-flow/index.d.ts +0 -14
  426. package/dist/providers/wispr-flow/index.js +0 -117
  427. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  428. /package/dist/providers/github/{key.js → lib/key.js} +0 -0
@@ -0,0 +1,544 @@
1
+ // One SQL key-value store and one SQL activity store, over two drivers.
2
+ //
3
+ // D1 (`src/d1.ts`) and Node's built-in SQLite (`src/sqlite.ts`) speak the same
4
+ // SQLite dialect, so every statement here runs unchanged on both. A driver is
5
+ // three methods; nothing in this module knows which one it has. It imports no
6
+ // platform module, so the Worker subpath can carry it.
7
+ //
8
+ // Atomicity. Every compare-and-set is one statement. SQLite executes a
9
+ // statement atomically against the database file, and D1 runs one database's
10
+ // statements one at a time against its primary, so a comparison and its write
11
+ // cannot interleave with another request's: of fifty concurrent claims on an
12
+ // absent key, exactly one changes a row.
13
+ //
14
+ // The database clock creates and checks KV expiry inside each statement.
15
+ // Isolate clock skew cannot shorten another holder's TTL. An expired row reads
16
+ // as absent at once and is removed
17
+ // physically by later writes, a bounded batch at a time, so no request starts
18
+ // a background job and no cron is required.
19
+ //
20
+ // Schema. Each store creates its own tables and indexes the first time one of
21
+ // its methods runs in an isolate or process, with idempotent statements, so a
22
+ // deployment applies no migration by hand. The flag that records it is a
23
+ // boolean, never a shared promise: a request that sees it unset runs the
24
+ // statements itself (INV-7).
25
+ import { KV_SCHEMA } from "./sql-schema.js";
26
+ import { Effect } from "effect";
27
+ import { activityBehaviorFacts, activityPackageVersion, activityClientFact, InvalidActivityCursorError, } from "../activity.js";
28
+ import { assertKnownOptions, ConfigError, keys, optionsOf } from "../config-schema.js";
29
+ import { agentFrictionForCode } from "../activity-friction.js";
30
+ import { validateStorageKey } from "./keys.js";
31
+ const sql = (text, ...params) => ({
32
+ sql: text,
33
+ params,
34
+ });
35
+ /** Select `column`, and beside it `<column>_bytes` when it holds a NUL. */
36
+ const textColumn = (column) => `${column}, CASE WHEN instr(CAST(${column} AS BLOB), x'00') > 0
37
+ THEN CAST(${column} AS BLOB) END AS ${column}_bytes`;
38
+ // Everything written here was a JavaScript string, so the bytes are UTF-8;
39
+ // a stored row that is not is refused rather than read wrong. A leading
40
+ // U+FEFF is part of the value, not a byte order mark.
41
+ const utf8 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
42
+ /** A text column's value, from its bytes when the read selected them. */
43
+ function textOf(text, bytes, what) {
44
+ if (bytes == null)
45
+ return text;
46
+ try {
47
+ return utf8.decode(bytes instanceof Uint8Array ? bytes : Uint8Array.from(bytes));
48
+ }
49
+ catch {
50
+ throw new TypeError(`${what} is not valid UTF-8`);
51
+ }
52
+ }
53
+ /** Run `ddl` once per store object; a failure leaves it to the next call. */
54
+ function schemaOnce(driver, ddl) {
55
+ let ready = false;
56
+ return () => Effect.gen(function* () {
57
+ if (ready)
58
+ return;
59
+ yield* ddl(driver);
60
+ ready = true;
61
+ });
62
+ }
63
+ // --- key-value ----------------------------------------------------------
64
+ /** Expired rows one write removes on its way. */
65
+ const SWEEP_ROWS = 16;
66
+ function ttlMillis(ttlSeconds) {
67
+ if (ttlSeconds === undefined || ttlSeconds === 0)
68
+ return null;
69
+ if (!Number.isFinite(ttlSeconds) || !Number.isFinite(ttlSeconds * 1000)) {
70
+ throw new RangeError("ttlSeconds must produce a finite expiration timestamp");
71
+ }
72
+ return Math.ceil(ttlSeconds * 1000);
73
+ }
74
+ /** `KVStorage` over one `connecta_kv` table. */
75
+ export function nativeSqlStorage(driver) {
76
+ const ensure = schemaOnce(driver, (d) => Effect.asVoid(d.batch(KV_SCHEMA.map((statement) => sql(statement)))));
77
+ // SQLite and D1 evaluate 'now' in the database, never in a caller isolate.
78
+ const now = "CAST((julianday('now') - 2440587.5) * 86400000 AS INTEGER)";
79
+ const live = `(expires_at_ms IS NULL OR expires_at_ms > ${now})`;
80
+ const expiryOptions = (opts) => {
81
+ if (opts?.expiresAtMs !== undefined) {
82
+ if (!Number.isSafeInteger(opts.expiresAtMs) || opts.ttlSeconds !== undefined) {
83
+ throw new RangeError("expiresAtMs must be a safe integer epoch timestamp without ttlSeconds");
84
+ }
85
+ return { value: opts.expiresAtMs, expression: "?" };
86
+ }
87
+ return { value: ttlMillis(opts?.ttlSeconds), expression: `(${now} + ?)` };
88
+ };
89
+ const current = (key) => Effect.gen(function* () {
90
+ const [row] = yield* driver.all(sql(`SELECT ${textColumn("value")} FROM connecta_kv WHERE key = ? AND ${live}`, key));
91
+ return row ? textOf(row.value, row.value_bytes, `the stored value of ${JSON.stringify(key)}`) : null;
92
+ });
93
+ return {
94
+ get(key) {
95
+ return Effect.gen(function* () {
96
+ validateStorageKey(key);
97
+ yield* ensure();
98
+ return yield* current(key);
99
+ });
100
+ },
101
+ set(key, value, opts) {
102
+ return Effect.gen(function* () {
103
+ validateStorageKey(key);
104
+ yield* ensure();
105
+ const expiry = expiryOptions(opts);
106
+ yield* driver.batch([
107
+ sql(`DELETE FROM connecta_kv WHERE key IN (
108
+ SELECT key FROM connecta_kv WHERE expires_at_ms <= ${now} LIMIT ${SWEEP_ROWS}
109
+ )`),
110
+ sql(`INSERT INTO connecta_kv (key, value, expires_at_ms)
111
+ VALUES (?, ?, ${expiry.expression})
112
+ ON CONFLICT (key) DO UPDATE SET
113
+ value = excluded.value, expires_at_ms = excluded.expires_at_ms`, key, value, expiry.value),
114
+ ]);
115
+ });
116
+ },
117
+ delete(key) {
118
+ return Effect.gen(function* () {
119
+ validateStorageKey(key);
120
+ yield* ensure();
121
+ yield* driver.run(sql("DELETE FROM connecta_kv WHERE key = ?", key));
122
+ });
123
+ },
124
+ list(prefix) {
125
+ return Effect.gen(function* () {
126
+ validateStorageKey(prefix);
127
+ yield* ensure();
128
+ const rows = yield* driver.all(sql(`SELECT key FROM connecta_kv
129
+ WHERE key >= ?
130
+ AND substr(CAST(key AS BLOB), 1, length(CAST(? AS BLOB))) = CAST(? AS BLOB)
131
+ AND ${live}`, prefix, prefix, prefix));
132
+ // Sort in JavaScript: SQLite orders UTF-8 bytes, the contract orders
133
+ // the UTF-16 code units every other adapter sorts by.
134
+ return rows.map((row) => row.key).sort();
135
+ });
136
+ },
137
+ compareAndSet(key, expected, next, opts) {
138
+ return Effect.gen(function* () {
139
+ validateStorageKey(key);
140
+ yield* ensure();
141
+ if (next === null && expected === null) {
142
+ // Nothing to write; the claim holds exactly when no live row exists.
143
+ return (yield* current(key)) === null;
144
+ }
145
+ if (next === null) {
146
+ return ((yield* driver.run(sql(`DELETE FROM connecta_kv WHERE key = ? AND ${live} AND value = ?`, key, expected))) >
147
+ 0);
148
+ }
149
+ let expiry;
150
+ try {
151
+ expiry = expiryOptions(opts);
152
+ }
153
+ catch (error) {
154
+ // Invalid write options do not change a failed comparison's result.
155
+ // Ordinary claims still use one atomic statement without this read.
156
+ if ((yield* current(key)) !== expected)
157
+ return false;
158
+ throw error;
159
+ }
160
+ if (expected === null) {
161
+ // Insert, or take over a row that has expired. A live row makes the
162
+ // upsert's WHERE false, so nothing changes and the claim is refused.
163
+ return ((yield* driver.run(sql(`INSERT INTO connecta_kv (key, value, expires_at_ms)
164
+ VALUES (?, ?, ${expiry.expression})
165
+ ON CONFLICT (key) DO UPDATE SET
166
+ value = excluded.value, expires_at_ms = excluded.expires_at_ms
167
+ WHERE connecta_kv.expires_at_ms IS NOT NULL
168
+ AND connecta_kv.expires_at_ms <= ${now}`, key, next, expiry.value))) > 0);
169
+ }
170
+ return ((yield* driver.run(sql(`UPDATE connecta_kv SET value = ?, expires_at_ms = ${expiry.expression}
171
+ WHERE key = ? AND ${live} AND value = ?`, next, expiry.value, key, expected))) > 0);
172
+ });
173
+ },
174
+ };
175
+ }
176
+ /** Keys one read compares: D1 binds at most 100 parameters, one is `now`. */
177
+ const COPY_READ_KEYS = 99;
178
+ /** Writes one transaction carries, by count and by UTF-8 bytes. */
179
+ const COPY_BATCH_STATEMENTS = 50;
180
+ const COPY_BATCH_BYTES = 4 * 1024 * 1024;
181
+ /**
182
+ * Copy entries into the key-value table, verbatim: same key, same value,
183
+ * same absolute expiry. A live row holding a different value is kept unless
184
+ * `overwrite` is set, so a second copy of the same entries writes nothing.
185
+ * Writes go out in bounded transactions; the outcomes follow `entries`.
186
+ */
187
+ export function copyIntoSqlEffect(driver, entries, options) {
188
+ return Effect.gen(function* () {
189
+ const { overwrite, now } = options;
190
+ for (const entry of entries)
191
+ validateStorageKey(entry.key);
192
+ yield* driver.batch(KV_SCHEMA.map((statement) => sql(statement)));
193
+ const live = "(expires_at_ms IS NULL OR expires_at_ms > ?)";
194
+ const currentValues = (keys) => Effect.gen(function* () {
195
+ const values = new Map();
196
+ for (let start = 0; start < keys.length; start += COPY_READ_KEYS) {
197
+ const chunk = keys.slice(start, start + COPY_READ_KEYS);
198
+ const rows = yield* driver.all(sql(`SELECT key, ${textColumn("value")}, expires_at_ms FROM connecta_kv
199
+ WHERE key IN (${chunk.map(() => "?").join(", ")}) AND ${live}`, ...chunk, now));
200
+ // The message names no key: a copy's errors reach operator output.
201
+ for (const row of rows) {
202
+ values.set(row.key, {
203
+ value: textOf(row.value, row.value_bytes, "a stored value") ?? "",
204
+ expiresAtMs: row.expires_at_ms,
205
+ });
206
+ }
207
+ }
208
+ return values;
209
+ });
210
+ const outcomes = Array.from({ length: entries.length });
211
+ const writes = [];
212
+ const existing = yield* currentValues(entries.map((entry) => entry.key));
213
+ for (const [index, entry] of entries.entries()) {
214
+ const current = existing.get(entry.key);
215
+ if (current?.value === entry.value && current.expiresAtMs === entry.expiresAtMs) {
216
+ outcomes[index] = "unchanged";
217
+ }
218
+ else if (current !== undefined && !overwrite) {
219
+ outcomes[index] = "conflict";
220
+ }
221
+ else {
222
+ outcomes[index] = current === undefined ? "copied" : "overwritten";
223
+ writes.push({
224
+ index,
225
+ bytes: new TextEncoder().encode(entry.key).byteLength + new TextEncoder().encode(entry.value).byteLength + 32,
226
+ statement: overwrite
227
+ ? sql(`INSERT INTO connecta_kv (key, value, expires_at_ms)
228
+ VALUES (?, ?, ?)
229
+ ON CONFLICT (key) DO UPDATE SET
230
+ value = excluded.value, expires_at_ms = excluded.expires_at_ms`, entry.key, entry.value, entry.expiresAtMs)
231
+ : // Absent when read; a live row written since is kept, not replaced.
232
+ sql(`INSERT INTO connecta_kv (key, value, expires_at_ms)
233
+ VALUES (?, ?, ?)
234
+ ON CONFLICT (key) DO UPDATE SET
235
+ value = excluded.value, expires_at_ms = excluded.expires_at_ms
236
+ WHERE connecta_kv.expires_at_ms IS NOT NULL
237
+ AND connecta_kv.expires_at_ms <= ?`, entry.key, entry.value, entry.expiresAtMs, now),
238
+ });
239
+ }
240
+ }
241
+ const raced = [];
242
+ let batch = [];
243
+ let batchBytes = 0;
244
+ const flush = () => Effect.gen(function* () {
245
+ if (batch.length === 0)
246
+ return;
247
+ const changes = yield* driver.batch(batch.map((write) => write.statement));
248
+ for (const [position, write] of batch.entries()) {
249
+ if (!(changes[position] > 0))
250
+ raced.push(write.index);
251
+ }
252
+ batch = [];
253
+ batchBytes = 0;
254
+ });
255
+ for (const write of writes) {
256
+ if (batch.length > 0 && (batch.length >= COPY_BATCH_STATEMENTS || batchBytes + write.bytes > COPY_BATCH_BYTES)) {
257
+ yield* flush();
258
+ }
259
+ batch.push(write);
260
+ batchBytes += write.bytes;
261
+ }
262
+ yield* flush();
263
+ // A row another writer added between the read and the write: report what
264
+ // it holds, and leave it.
265
+ if (raced.length > 0) {
266
+ const after = yield* currentValues(raced.map((index) => entries[index].key));
267
+ for (const index of raced) {
268
+ const entry = entries[index];
269
+ const current = after.get(entry.key);
270
+ outcomes[index] =
271
+ current?.value === entry.value && current.expiresAtMs === entry.expiresAtMs ? "unchanged" : "conflict";
272
+ }
273
+ }
274
+ return outcomes;
275
+ });
276
+ }
277
+ // --- activity -----------------------------------------------------------
278
+ /**
279
+ * The activity table, with keyset paging on `(occurred_at_ms, id)`. Its shape
280
+ * is the 0.28 Worker example's `tool_call_activity`; a table created before
281
+ * later actor, friction, approval, client, or package columns existed gets
282
+ * those columns added without changing old rows.
283
+ */
284
+ const ACTIVITY_SCHEMA = [
285
+ `CREATE TABLE IF NOT EXISTS tool_call_activity (
286
+ id TEXT PRIMARY KEY,
287
+ occurred_at_ms INTEGER NOT NULL,
288
+ request_id TEXT NOT NULL,
289
+ actor_kind TEXT NOT NULL,
290
+ actor_id TEXT,
291
+ actor_namespace TEXT,
292
+ connector_id TEXT NOT NULL,
293
+ tool_name TEXT NOT NULL,
294
+ source TEXT NOT NULL,
295
+ outcome TEXT NOT NULL,
296
+ duration_ms INTEGER NOT NULL,
297
+ attempts INTEGER NOT NULL,
298
+ error_code TEXT,
299
+ friction TEXT,
300
+ approval TEXT,
301
+ package_version TEXT,
302
+ server_name TEXT NOT NULL,
303
+ server_version TEXT NOT NULL,
304
+ client_name TEXT,
305
+ client_version TEXT,
306
+ deployment_id TEXT,
307
+ classification TEXT,
308
+ result_bytes INTEGER,
309
+ event_kind TEXT,
310
+ drift_kind TEXT,
311
+ added_tools INTEGER,
312
+ removed_tools INTEGER,
313
+ changed_tools INTEGER,
314
+ pool_name TEXT,
315
+ actor_basis TEXT
316
+ )`,
317
+ `CREATE INDEX IF NOT EXISTS tool_call_activity_recent
318
+ ON tool_call_activity (occurred_at_ms DESC, id DESC)`,
319
+ ];
320
+ /** Columns added after the table first shipped, in the order they arrived. */
321
+ const LATER_ACTIVITY_COLUMNS = [
322
+ "actor_namespace",
323
+ "friction",
324
+ "approval",
325
+ "client_name",
326
+ "client_version",
327
+ "package_version",
328
+ "classification",
329
+ "result_bytes",
330
+ "event_kind",
331
+ "drift_kind",
332
+ "added_tools",
333
+ "removed_tools",
334
+ "changed_tools",
335
+ "pool_name",
336
+ "actor_basis",
337
+ ];
338
+ /** Every activity column but the three integers, read through `textOf`. */
339
+ const ACTIVITY_TEXT_COLUMNS = [
340
+ "id",
341
+ "request_id",
342
+ "actor_kind",
343
+ "actor_id",
344
+ "actor_namespace",
345
+ "connector_id",
346
+ "tool_name",
347
+ "source",
348
+ "outcome",
349
+ "error_code",
350
+ "friction",
351
+ "approval",
352
+ "package_version",
353
+ "server_name",
354
+ "server_version",
355
+ "client_name",
356
+ "client_version",
357
+ "deployment_id",
358
+ "classification",
359
+ "event_kind",
360
+ "drift_kind",
361
+ "pool_name",
362
+ "actor_basis",
363
+ ];
364
+ const ACTIVITY_SELECT = `SELECT occurred_at_ms, duration_ms, attempts, result_bytes, added_tools, removed_tools, changed_tools,
365
+ ${ACTIVITY_TEXT_COLUMNS.map(textColumn).join(",\n ")}
366
+ FROM tool_call_activity`;
367
+ function activityRow(read) {
368
+ const row = {
369
+ occurred_at_ms: read.occurred_at_ms,
370
+ duration_ms: read.duration_ms,
371
+ attempts: read.attempts,
372
+ result_bytes: read.result_bytes,
373
+ added_tools: read.added_tools,
374
+ removed_tools: read.removed_tools,
375
+ changed_tools: read.changed_tools,
376
+ };
377
+ for (const column of ACTIVITY_TEXT_COLUMNS) {
378
+ row[column] = textOf(read[column], read[`${column}_bytes`], `activity column ${column}`);
379
+ }
380
+ return row;
381
+ }
382
+ function rowToEvent(row) {
383
+ // Rows written before `friction` had a column derive it from the code.
384
+ // Friction without a code — an oversized but successful result — exists
385
+ // only in the column, which is why the column exists.
386
+ const friction = row.friction ?? agentFrictionForCode(row.error_code ?? undefined);
387
+ const packageVersion = activityPackageVersion(row.package_version);
388
+ const clientName = activityClientFact(row.client_name, "name");
389
+ const clientVersion = activityClientFact(row.client_version, "version");
390
+ return {
391
+ schemaVersion: 1,
392
+ id: row.id,
393
+ occurredAt: new Date(row.occurred_at_ms).toISOString(),
394
+ requestId: row.request_id,
395
+ ...activityBehaviorFacts({
396
+ classification: row.classification,
397
+ resultBytes: row.result_bytes,
398
+ kind: row.event_kind,
399
+ pool: row.pool_name,
400
+ actorBasis: row.actor_basis,
401
+ drift: {
402
+ kind: row.drift_kind,
403
+ addedTools: row.added_tools,
404
+ removedTools: row.removed_tools,
405
+ changedTools: row.changed_tools,
406
+ },
407
+ }),
408
+ actor: {
409
+ kind: row.actor_kind,
410
+ ...(row.actor_id ? { id: row.actor_id } : {}),
411
+ ...(row.actor_namespace ? { namespace: row.actor_namespace } : {}),
412
+ },
413
+ connectorId: row.connector_id,
414
+ toolName: row.tool_name,
415
+ address: `${row.connector_id}.${row.tool_name}`,
416
+ source: row.source,
417
+ outcome: row.outcome,
418
+ durationMs: row.duration_ms,
419
+ attempts: row.attempts,
420
+ ...(row.error_code ? { errorCode: row.error_code } : {}),
421
+ ...(friction ? { friction } : {}),
422
+ ...(row.approval ? { approval: row.approval } : {}),
423
+ ...(packageVersion !== undefined ? { packageVersion } : {}),
424
+ serverName: row.server_name,
425
+ serverVersion: row.server_version,
426
+ ...(clientName !== undefined ? { clientName } : {}),
427
+ ...(clientVersion !== undefined ? { clientVersion } : {}),
428
+ ...(row.deployment_id ? { deploymentId: row.deployment_id } : {}),
429
+ };
430
+ }
431
+ function encodeCursor(row) {
432
+ return btoa(`${row.occurred_at_ms}:${row.id}`);
433
+ }
434
+ function decodeCursor(value) {
435
+ let decoded;
436
+ try {
437
+ decoded = atob(value);
438
+ }
439
+ catch {
440
+ throw new InvalidActivityCursorError();
441
+ }
442
+ const separator = decoded.indexOf(":");
443
+ const occurredAtMs = Number(decoded.slice(0, separator));
444
+ const id = decoded.slice(separator + 1);
445
+ if (separator < 1 || !Number.isSafeInteger(occurredAtMs) || occurredAtMs < 0 || !/^[0-9a-f-]{36}$/i.test(id)) {
446
+ throw new InvalidActivityCursorError();
447
+ }
448
+ return { occurredAtMs, id };
449
+ }
450
+ /** The closed options both activity factories accept; see `assertKnownOptions`. */
451
+ const SQL_ACTIVITY_OPTIONS = optionsOf()(keys("retentionDays"));
452
+ /** Older rows one write removes on its way. Above one: writes catch up. */
453
+ const RETENTION_SWEEP_ROWS = 16;
454
+ /**
455
+ * One append-only row per completed downstream call. Rows carry no arguments,
456
+ * results, generated code, or raw error messages — the store never has a
457
+ * payload to leak.
458
+ */
459
+ export function nativeSqlActivityStore(driver, kind, options = {}) {
460
+ const factory = kind === "d1" ? "d1ActivityStore()" : "sqliteActivityStore()";
461
+ const { retentionDays = 90 } = assertKnownOptions(options, factory, SQL_ACTIVITY_OPTIONS);
462
+ if (typeof retentionDays !== "number" || !(retentionDays > 0) || !Number.isFinite(retentionDays)) {
463
+ throw new ConfigError(`${factory}.retentionDays must be a positive number of days.`);
464
+ }
465
+ const retentionMs = retentionDays * 24 * 60 * 60 * 1000;
466
+ const ensure = schemaOnce(driver, (d) => Effect.gen(function* () {
467
+ yield* d.batch(ACTIVITY_SCHEMA.map((statement) => sql(statement)));
468
+ const columns = () => Effect.gen(function* () {
469
+ return new Set((yield* d.all(sql("PRAGMA table_info(tool_call_activity)"))).map((column) => column.name));
470
+ });
471
+ // Isolates and processes upgrade an old table concurrently, each from its
472
+ // own read of the columns. One column per statement, and a refused ALTER
473
+ // re-reads the table: if another upgrader added the column, this one
474
+ // moves on to the next instead of failing the write that started it.
475
+ let present = yield* columns();
476
+ for (const name of LATER_ACTIVITY_COLUMNS) {
477
+ if (present.has(name))
478
+ continue;
479
+ const altered = yield* Effect.result(d.run(sql(`ALTER TABLE tool_call_activity ADD COLUMN ${name} ${["result_bytes", "added_tools", "removed_tools", "changed_tools"].includes(name) ? "INTEGER" : "TEXT"}`)));
480
+ if (altered._tag === "Failure") {
481
+ present = yield* columns();
482
+ if (!present.has(name))
483
+ return yield* Effect.fail(altered.failure);
484
+ }
485
+ }
486
+ }));
487
+ return {
488
+ describe: () => ({
489
+ kind,
490
+ retentionDays,
491
+ optionSources: { retentionDays: options.retentionDays === undefined ? "default" : "config" },
492
+ }),
493
+ record(event) {
494
+ return Effect.gen(function* () {
495
+ yield* ensure();
496
+ const occurredAtMs = Date.parse(event.occurredAt);
497
+ const facts = activityBehaviorFacts(event);
498
+ yield* driver.batch([
499
+ sql(`INSERT INTO tool_call_activity (
500
+ id, occurred_at_ms, request_id, actor_kind, actor_id,
501
+ actor_namespace, connector_id, tool_name, source, outcome,
502
+ duration_ms, attempts, error_code, friction, approval,
503
+ package_version, server_name, server_version, client_name, client_version, deployment_id,
504
+ classification, result_bytes, event_kind, drift_kind, added_tools, removed_tools, changed_tools, pool_name, actor_basis
505
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, event.id, occurredAtMs, event.requestId, event.actor.kind, event.actor.id ?? null, event.actor.namespace ?? null, event.connectorId, event.toolName, event.source, event.outcome, event.durationMs, event.attempts, event.errorCode ?? null,
506
+ // Stored beside the code rather than derived from it: a truncated
507
+ // result is friction on a call that succeeded, and
508
+ // `error_code IS NOT NULL` stays an honest count of failures.
509
+ event.friction ?? null, event.approval ?? null, activityPackageVersion(event.packageVersion) ?? null, event.serverName, event.serverVersion, activityClientFact(event.clientName, "name") ?? null, activityClientFact(event.clientVersion, "version") ?? null, event.deploymentId ?? null, facts.classification ?? null, facts.resultBytes ?? null, facts.kind ?? null, facts.drift?.kind ?? null, facts.drift?.addedTools ?? null, facts.drift?.removedTools ?? null, facts.drift?.changedTools ?? null, facts.pool ?? null, facts.actorBasis ?? null),
510
+ sql(`DELETE FROM tool_call_activity WHERE id IN (
511
+ SELECT id FROM tool_call_activity
512
+ WHERE occurred_at_ms < ?
513
+ ORDER BY occurred_at_ms ASC
514
+ LIMIT ${RETENTION_SWEEP_ROWS}
515
+ )`, Date.now() - retentionMs),
516
+ ]);
517
+ });
518
+ },
519
+ list({ cursor, limit }) {
520
+ return Effect.gen(function* () {
521
+ const boundedLimit = Math.min(100, Math.max(1, Math.trunc(limit)));
522
+ const pageSize = boundedLimit + 1;
523
+ const position = cursor ? decodeCursor(cursor) : undefined;
524
+ yield* ensure();
525
+ const rows = (yield* driver.all(position
526
+ ? sql(`${ACTIVITY_SELECT}
527
+ WHERE occurred_at_ms < ?
528
+ OR (occurred_at_ms = ? AND id < ?)
529
+ ORDER BY occurred_at_ms DESC, id DESC
530
+ LIMIT ?`, position.occurredAtMs, position.occurredAtMs, position.id, pageSize)
531
+ : sql(`${ACTIVITY_SELECT}
532
+ ORDER BY occurred_at_ms DESC, id DESC
533
+ LIMIT ?`, pageSize))).map(activityRow);
534
+ const hasMore = rows.length > boundedLimit;
535
+ const visible = hasMore ? rows.slice(0, boundedLimit) : rows;
536
+ const last = visible.at(-1);
537
+ return {
538
+ events: visible.map(rowToEvent),
539
+ ...(hasMore && last ? { nextCursor: encodeCursor(last) } : {}),
540
+ };
541
+ });
542
+ },
543
+ };
544
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The key-value table. Its shape is the one the 0.28 Worker example's
3
+ * `d1-storage.ts` documented, so a D1 database that already holds it is read
4
+ * as is.
5
+ */
6
+ export declare const KV_SCHEMA: readonly string[];
@@ -0,0 +1,15 @@
1
+ // The existing on-disk schema, shared by native stores and synchronous import.
2
+ /**
3
+ * The key-value table. Its shape is the one the 0.28 Worker example's
4
+ * `d1-storage.ts` documented, so a D1 database that already holds it is read
5
+ * as is.
6
+ */
7
+ export const KV_SCHEMA = [
8
+ `CREATE TABLE IF NOT EXISTS connecta_kv (
9
+ key TEXT PRIMARY KEY,
10
+ value TEXT NOT NULL,
11
+ expires_at_ms INTEGER
12
+ )`,
13
+ `CREATE INDEX IF NOT EXISTS connecta_kv_expiry
14
+ ON connecta_kv (expires_at_ms)`,
15
+ ];
@@ -1,5 +1,7 @@
1
1
  import type { ActivityStore } from "../activity.js";
2
2
  import type { KVStorage } from "../types.js";
3
+ /** The 0.28-compatible key-value table and expiry index. */
4
+ export { KV_SCHEMA } from "./sql-schema.js";
3
5
  type SqlValue = string | number | null;
4
6
  export interface SqlStatement {
5
7
  readonly sql: string;
@@ -17,17 +19,8 @@ export interface SqlDriver {
17
19
  */
18
20
  batch(statements: readonly SqlStatement[]): Promise<number[]>;
19
21
  }
20
- /**
21
- * The key-value table. Its shape is the one the 0.28 Worker example's
22
- * `d1-storage.ts` documented, so a D1 database that already holds it is read
23
- * as is.
24
- */
25
- export declare const KV_SCHEMA: readonly string[];
26
22
  /** The two drivers, as `describe()` names them. */
27
23
  export type SqlKind = "d1" | "sqlite";
28
- /** `KVStorage` over one `connecta_kv` table. */
29
- export declare function sqlStorage(driver: SqlDriver, kind: SqlKind): KVStorage;
30
- /** One entry copied from another store, with its absolute expiry. */
31
24
  export interface SqlCopyEntry {
32
25
  readonly key: string;
33
26
  readonly value: string;
@@ -40,16 +33,6 @@ export interface SqlCopyEntry {
40
33
  * another (`conflict`), or replaced under `overwrite` (`overwritten`).
41
34
  */
42
35
  export type SqlCopyOutcome = "copied" | "unchanged" | "conflict" | "overwritten";
43
- /**
44
- * Copy entries into the key-value table, verbatim: same key, same value,
45
- * same absolute expiry. A live row holding a different value is kept unless
46
- * `overwrite` is set, so a second copy of the same entries writes nothing.
47
- * Writes go out in bounded transactions; the outcomes follow `entries`.
48
- */
49
- export declare function copyIntoSql(driver: SqlDriver, entries: readonly SqlCopyEntry[], options: {
50
- overwrite: boolean;
51
- now: number;
52
- }): Promise<SqlCopyOutcome[]>;
53
36
  export interface SqlActivityOptions {
54
37
  /**
55
38
  * Days of history kept. Each write removes a bounded batch of older rows,
@@ -57,10 +40,21 @@ export interface SqlActivityOptions {
57
40
  */
58
41
  retentionDays?: number;
59
42
  }
43
+ /** `KVStorage` over one `connecta_kv` table. */
44
+ export declare function sqlStorage(driver: SqlDriver, kind: SqlKind): KVStorage;
60
45
  /**
61
46
  * One append-only row per completed downstream call. Rows carry no arguments,
62
47
  * results, generated code, or raw error messages — the store never has a
63
48
  * payload to leak.
64
49
  */
65
50
  export declare function sqlActivityStore(driver: SqlDriver, kind: SqlKind, options?: SqlActivityOptions): ActivityStore;
66
- export {};
51
+ /**
52
+ * Copy entries into the key-value table, verbatim: same key, same value,
53
+ * same absolute expiry. A live row holding a different value is kept unless
54
+ * `overwrite` is set, so a second copy of the same entries writes nothing.
55
+ * Writes go out in bounded transactions; the outcomes follow `entries`.
56
+ */
57
+ export declare function copyIntoSql(driver: SqlDriver, entries: readonly SqlCopyEntry[], options: {
58
+ overwrite: boolean;
59
+ now: number;
60
+ }): Promise<SqlCopyOutcome[]>;