@sixthsummit/ship-api 0.0.0-stage → 4.1.1

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 (556) hide show
  1. package/CHANGELOG.md +605 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +4 -0
  4. package/README.md +58 -2
  5. package/cli/commands/add.js +537 -0
  6. package/cli/commands/contract.js +2 -0
  7. package/cli/commands/create.js +250 -0
  8. package/cli/commands/dev.js +227 -0
  9. package/cli/commands/doctor.js +286 -0
  10. package/cli/commands/generate.js +937 -0
  11. package/cli/commands/graph.js +2 -0
  12. package/cli/commands/migrate-orm.js +1171 -0
  13. package/cli/commands/update.js +37 -0
  14. package/cli/ship-api.js +285 -0
  15. package/lib/app/auth/AuthProvider.d.ts +91 -0
  16. package/lib/app/auth/AuthProvider.d.ts.map +1 -0
  17. package/lib/app/auth/AuthProvider.js +13 -0
  18. package/lib/app/auth/AuthProvider.js.map +1 -0
  19. package/lib/app/auth/adapters/firebase.d.ts +79 -0
  20. package/lib/app/auth/adapters/firebase.d.ts.map +1 -0
  21. package/lib/app/auth/adapters/firebase.js +122 -0
  22. package/lib/app/auth/adapters/firebase.js.map +1 -0
  23. package/lib/app/auth/adapters/jwtCookie.d.ts +55 -0
  24. package/lib/app/auth/adapters/jwtCookie.d.ts.map +1 -0
  25. package/lib/app/auth/adapters/jwtCookie.js +120 -0
  26. package/lib/app/auth/adapters/jwtCookie.js.map +1 -0
  27. package/lib/app/auth/index.d.ts +8 -0
  28. package/lib/app/auth/index.d.ts.map +1 -0
  29. package/lib/app/auth/index.js +7 -0
  30. package/lib/app/auth/index.js.map +1 -0
  31. package/lib/app/auth/jwt/AuthFlow.d.ts +94 -0
  32. package/lib/app/auth/jwt/AuthFlow.d.ts.map +1 -0
  33. package/lib/app/auth/jwt/AuthFlow.js +127 -0
  34. package/lib/app/auth/jwt/AuthFlow.js.map +1 -0
  35. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.d.ts +80 -0
  36. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.d.ts.map +1 -0
  37. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.js +134 -0
  38. package/lib/app/auth/jwt/DrizzleRefreshTokenStore.js.map +1 -0
  39. package/lib/app/auth/jwt/JwtSigner.d.ts +123 -0
  40. package/lib/app/auth/jwt/JwtSigner.d.ts.map +1 -0
  41. package/lib/app/auth/jwt/JwtSigner.js +118 -0
  42. package/lib/app/auth/jwt/JwtSigner.js.map +1 -0
  43. package/lib/app/auth/jwt/RefreshTokenStore.d.ts +97 -0
  44. package/lib/app/auth/jwt/RefreshTokenStore.d.ts.map +1 -0
  45. package/lib/app/auth/jwt/RefreshTokenStore.js +122 -0
  46. package/lib/app/auth/jwt/RefreshTokenStore.js.map +1 -0
  47. package/lib/app/auth/permissionDefinition.d.ts +20 -0
  48. package/lib/app/auth/permissionDefinition.d.ts.map +1 -0
  49. package/lib/app/auth/permissionDefinition.js +2 -0
  50. package/lib/app/auth/permissionDefinition.js.map +1 -0
  51. package/lib/app/context/RequestContext.d.ts +59 -0
  52. package/lib/app/context/RequestContext.d.ts.map +1 -0
  53. package/lib/app/context/RequestContext.js +25 -0
  54. package/lib/app/context/RequestContext.js.map +1 -0
  55. package/lib/app/db/QueryOptions.d.ts +82 -0
  56. package/lib/app/db/QueryOptions.d.ts.map +1 -0
  57. package/lib/app/db/QueryOptions.js +37 -0
  58. package/lib/app/db/QueryOptions.js.map +1 -0
  59. package/lib/app/db/baseFields.d.ts +60 -0
  60. package/lib/app/db/baseFields.d.ts.map +1 -0
  61. package/lib/app/db/baseFields.js +54 -0
  62. package/lib/app/db/baseFields.js.map +1 -0
  63. package/lib/app/db/buildWhere.d.ts +22 -0
  64. package/lib/app/db/buildWhere.d.ts.map +1 -0
  65. package/lib/app/db/buildWhere.js +75 -0
  66. package/lib/app/db/buildWhere.js.map +1 -0
  67. package/lib/app/db/client.d.ts +111 -0
  68. package/lib/app/db/client.d.ts.map +1 -0
  69. package/lib/app/db/client.js +99 -0
  70. package/lib/app/db/client.js.map +1 -0
  71. package/lib/app/db/tenantScoped.d.ts +59 -0
  72. package/lib/app/db/tenantScoped.d.ts.map +1 -0
  73. package/lib/app/db/tenantScoped.js +54 -0
  74. package/lib/app/db/tenantScoped.js.map +1 -0
  75. package/lib/app/db/transaction.d.ts +58 -0
  76. package/lib/app/db/transaction.d.ts.map +1 -0
  77. package/lib/app/db/transaction.js +106 -0
  78. package/lib/app/db/transaction.js.map +1 -0
  79. package/lib/app/health/HealthCheck.d.ts +121 -0
  80. package/lib/app/health/HealthCheck.d.ts.map +1 -0
  81. package/lib/app/health/HealthCheck.js +151 -0
  82. package/lib/app/health/HealthCheck.js.map +1 -0
  83. package/lib/app/health/redisHealthCheck.d.ts +14 -0
  84. package/lib/app/health/redisHealthCheck.d.ts.map +1 -0
  85. package/lib/app/health/redisHealthCheck.js +21 -0
  86. package/lib/app/health/redisHealthCheck.js.map +1 -0
  87. package/lib/app/lifecycle/Bootstrapper.d.ts +92 -0
  88. package/lib/app/lifecycle/Bootstrapper.d.ts.map +1 -0
  89. package/lib/app/lifecycle/Bootstrapper.js +99 -0
  90. package/lib/app/lifecycle/Bootstrapper.js.map +1 -0
  91. package/lib/app/registry/routes.d.ts +89 -0
  92. package/lib/app/registry/routes.d.ts.map +1 -0
  93. package/lib/app/registry/routes.js +72 -0
  94. package/lib/app/registry/routes.js.map +1 -0
  95. package/lib/app/services/DrizzleEntityService.d.ts +123 -0
  96. package/lib/app/services/DrizzleEntityService.d.ts.map +1 -0
  97. package/lib/app/services/DrizzleEntityService.js +342 -0
  98. package/lib/app/services/DrizzleEntityService.js.map +1 -0
  99. package/lib/app/services/RedisProvider.d.ts +52 -0
  100. package/lib/app/services/RedisProvider.d.ts.map +1 -0
  101. package/lib/app/services/RedisProvider.js +75 -0
  102. package/lib/app/services/RedisProvider.js.map +1 -0
  103. package/lib/app/services/cache/Cache.d.ts +70 -0
  104. package/lib/app/services/cache/Cache.d.ts.map +1 -0
  105. package/lib/app/services/cache/Cache.js +18 -0
  106. package/lib/app/services/cache/Cache.js.map +1 -0
  107. package/lib/app/services/cache/InMemoryCache.d.ts +35 -0
  108. package/lib/app/services/cache/InMemoryCache.d.ts.map +1 -0
  109. package/lib/app/services/cache/InMemoryCache.js +76 -0
  110. package/lib/app/services/cache/InMemoryCache.js.map +1 -0
  111. package/lib/app/services/cache/RedisCache.d.ts +99 -0
  112. package/lib/app/services/cache/RedisCache.d.ts.map +1 -0
  113. package/lib/app/services/cache/RedisCache.js +150 -0
  114. package/lib/app/services/cache/RedisCache.js.map +1 -0
  115. package/lib/app/services/cache/cached.d.ts +30 -0
  116. package/lib/app/services/cache/cached.d.ts.map +1 -0
  117. package/lib/app/services/cache/cached.js +38 -0
  118. package/lib/app/services/cache/cached.js.map +1 -0
  119. package/lib/app/services/cache/index.d.ts +5 -0
  120. package/lib/app/services/cache/index.d.ts.map +1 -0
  121. package/lib/app/services/cache/index.js +4 -0
  122. package/lib/app/services/cache/index.js.map +1 -0
  123. package/lib/app/services/cron/defineCron.d.ts +57 -0
  124. package/lib/app/services/cron/defineCron.d.ts.map +1 -0
  125. package/lib/app/services/cron/defineCron.js +15 -0
  126. package/lib/app/services/cron/defineCron.js.map +1 -0
  127. package/lib/app/services/cron/index.d.ts +2 -0
  128. package/lib/app/services/cron/index.d.ts.map +1 -0
  129. package/lib/app/services/cron/index.js +2 -0
  130. package/lib/app/services/cron/index.js.map +1 -0
  131. package/lib/app/services/hooks/LifecycleHooks.d.ts +61 -0
  132. package/lib/app/services/hooks/LifecycleHooks.d.ts.map +1 -0
  133. package/lib/app/services/hooks/LifecycleHooks.js +85 -0
  134. package/lib/app/services/hooks/LifecycleHooks.js.map +1 -0
  135. package/lib/app/services/jobs/JobsManager.d.ts +67 -0
  136. package/lib/app/services/jobs/JobsManager.d.ts.map +1 -0
  137. package/lib/app/services/jobs/JobsManager.js +121 -0
  138. package/lib/app/services/jobs/JobsManager.js.map +1 -0
  139. package/lib/app/services/jobs/bullBoard.d.ts +72 -0
  140. package/lib/app/services/jobs/bullBoard.d.ts.map +1 -0
  141. package/lib/app/services/jobs/bullBoard.js +96 -0
  142. package/lib/app/services/jobs/bullBoard.js.map +1 -0
  143. package/lib/app/services/jobs/defineJob.d.ts +81 -0
  144. package/lib/app/services/jobs/defineJob.d.ts.map +1 -0
  145. package/lib/app/services/jobs/defineJob.js +49 -0
  146. package/lib/app/services/jobs/defineJob.js.map +1 -0
  147. package/lib/app/services/jobs/index.d.ts +4 -0
  148. package/lib/app/services/jobs/index.d.ts.map +1 -0
  149. package/lib/app/services/jobs/index.js +4 -0
  150. package/lib/app/services/jobs/index.js.map +1 -0
  151. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.d.ts +23 -0
  152. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.d.ts.map +1 -0
  153. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.js +51 -0
  154. package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.js.map +1 -0
  155. package/lib/app/services/rateLimit/RateLimitBackend.d.ts +41 -0
  156. package/lib/app/services/rateLimit/RateLimitBackend.d.ts.map +1 -0
  157. package/lib/app/services/rateLimit/RateLimitBackend.js +19 -0
  158. package/lib/app/services/rateLimit/RateLimitBackend.js.map +1 -0
  159. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.d.ts +16 -0
  160. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.d.ts.map +1 -0
  161. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.js +80 -0
  162. package/lib/app/services/rateLimit/RedisSlidingWindowBackend.js.map +1 -0
  163. package/lib/app/services/rateLimit/index.d.ts +4 -0
  164. package/lib/app/services/rateLimit/index.d.ts.map +1 -0
  165. package/lib/app/services/rateLimit/index.js +3 -0
  166. package/lib/app/services/rateLimit/index.js.map +1 -0
  167. package/lib/app/services/storage/DiskStorageAdapter.d.ts +62 -0
  168. package/lib/app/services/storage/DiskStorageAdapter.d.ts.map +1 -0
  169. package/lib/app/services/storage/DiskStorageAdapter.js +295 -0
  170. package/lib/app/services/storage/DiskStorageAdapter.js.map +1 -0
  171. package/lib/app/services/storage/GCSStorageAdapter.d.ts +44 -0
  172. package/lib/app/services/storage/GCSStorageAdapter.d.ts.map +1 -0
  173. package/lib/app/services/storage/GCSStorageAdapter.js +133 -0
  174. package/lib/app/services/storage/GCSStorageAdapter.js.map +1 -0
  175. package/lib/app/services/storage/S3StorageAdapter.d.ts +57 -0
  176. package/lib/app/services/storage/S3StorageAdapter.d.ts.map +1 -0
  177. package/lib/app/services/storage/S3StorageAdapter.js +162 -0
  178. package/lib/app/services/storage/S3StorageAdapter.js.map +1 -0
  179. package/lib/app/services/storage/StorageService.d.ts +88 -0
  180. package/lib/app/services/storage/StorageService.d.ts.map +1 -0
  181. package/lib/app/services/storage/StorageService.js +18 -0
  182. package/lib/app/services/storage/StorageService.js.map +1 -0
  183. package/lib/app/services/storage/index.d.ts +5 -0
  184. package/lib/app/services/storage/index.d.ts.map +1 -0
  185. package/lib/app/services/storage/index.js +4 -0
  186. package/lib/app/services/storage/index.js.map +1 -0
  187. package/lib/app/utils/ContextValidators.d.ts +46 -0
  188. package/lib/app/utils/ContextValidators.d.ts.map +1 -0
  189. package/lib/app/utils/ContextValidators.js +81 -0
  190. package/lib/app/utils/ContextValidators.js.map +1 -0
  191. package/lib/app/utils/defineEnv.d.ts +80 -0
  192. package/lib/app/utils/defineEnv.d.ts.map +1 -0
  193. package/lib/app/utils/defineEnv.js +95 -0
  194. package/lib/app/utils/defineEnv.js.map +1 -0
  195. package/lib/client.d.ts +139 -0
  196. package/lib/client.d.ts.map +1 -0
  197. package/lib/client.js +98 -0
  198. package/lib/client.js.map +1 -0
  199. package/lib/contract/application.d.ts +3 -0
  200. package/lib/contract/application.d.ts.map +1 -0
  201. package/lib/contract/application.js +2 -0
  202. package/lib/contract/application.js.map +1 -0
  203. package/lib/contract/client.d.ts +3 -0
  204. package/lib/contract/client.d.ts.map +1 -0
  205. package/lib/contract/client.js +3 -0
  206. package/lib/contract/client.js.map +1 -0
  207. package/lib/contract/index.d.ts +3 -0
  208. package/lib/contract/index.d.ts.map +1 -0
  209. package/lib/contract/index.js +3 -0
  210. package/lib/contract/index.js.map +1 -0
  211. package/lib/contract/manifest.d.ts +3 -0
  212. package/lib/contract/manifest.d.ts.map +1 -0
  213. package/lib/contract/manifest.js +2 -0
  214. package/lib/contract/manifest.js.map +1 -0
  215. package/lib/contract/openapi.d.ts +3 -0
  216. package/lib/contract/openapi.d.ts.map +1 -0
  217. package/lib/contract/openapi.js +3 -0
  218. package/lib/contract/openapi.js.map +1 -0
  219. package/lib/contract/project.d.ts +3 -0
  220. package/lib/contract/project.d.ts.map +1 -0
  221. package/lib/contract/project.js +3 -0
  222. package/lib/contract/project.js.map +1 -0
  223. package/lib/contract/schema.d.ts +3 -0
  224. package/lib/contract/schema.d.ts.map +1 -0
  225. package/lib/contract/schema.js +3 -0
  226. package/lib/contract/schema.js.map +1 -0
  227. package/lib/drizzle/index.d.ts +3 -0
  228. package/lib/drizzle/index.d.ts.map +1 -0
  229. package/lib/drizzle/index.js +3 -0
  230. package/lib/drizzle/index.js.map +1 -0
  231. package/lib/hono/auth.d.ts +6 -0
  232. package/lib/hono/auth.d.ts.map +1 -0
  233. package/lib/hono/auth.js +54 -0
  234. package/lib/hono/auth.js.map +1 -0
  235. package/lib/hono/index.d.ts +4 -0
  236. package/lib/hono/index.d.ts.map +1 -0
  237. package/lib/hono/index.js +4 -0
  238. package/lib/hono/index.js.map +1 -0
  239. package/lib/http/app/createApp.d.ts +132 -0
  240. package/lib/http/app/createApp.d.ts.map +1 -0
  241. package/lib/http/app/createApp.js +215 -0
  242. package/lib/http/app/createApp.js.map +1 -0
  243. package/lib/http/app/devRoutes.d.ts +31 -0
  244. package/lib/http/app/devRoutes.d.ts.map +1 -0
  245. package/lib/http/app/devRoutes.js +145 -0
  246. package/lib/http/app/devRoutes.js.map +1 -0
  247. package/lib/http/app/errors.d.ts +45 -0
  248. package/lib/http/app/errors.d.ts.map +1 -0
  249. package/lib/http/app/errors.js +93 -0
  250. package/lib/http/app/errors.js.map +1 -0
  251. package/lib/http/app/health.d.ts +66 -0
  252. package/lib/http/app/health.d.ts.map +1 -0
  253. package/lib/http/app/health.js +104 -0
  254. package/lib/http/app/health.js.map +1 -0
  255. package/lib/http/errors/AppError.d.ts +10 -0
  256. package/lib/http/errors/AppError.d.ts.map +1 -0
  257. package/lib/http/errors/AppError.js +19 -0
  258. package/lib/http/errors/AppError.js.map +1 -0
  259. package/lib/http/errors/AuthenticationError.d.ts +8 -0
  260. package/lib/http/errors/AuthenticationError.d.ts.map +1 -0
  261. package/lib/http/errors/AuthenticationError.js +10 -0
  262. package/lib/http/errors/AuthenticationError.js.map +1 -0
  263. package/lib/http/errors/AuthorizationError.d.ts +8 -0
  264. package/lib/http/errors/AuthorizationError.d.ts.map +1 -0
  265. package/lib/http/errors/AuthorizationError.js +10 -0
  266. package/lib/http/errors/AuthorizationError.js.map +1 -0
  267. package/lib/http/errors/BadRequestError.d.ts +8 -0
  268. package/lib/http/errors/BadRequestError.d.ts.map +1 -0
  269. package/lib/http/errors/BadRequestError.js +10 -0
  270. package/lib/http/errors/BadRequestError.js.map +1 -0
  271. package/lib/http/errors/ConflictError.d.ts +8 -0
  272. package/lib/http/errors/ConflictError.d.ts.map +1 -0
  273. package/lib/http/errors/ConflictError.js +10 -0
  274. package/lib/http/errors/ConflictError.js.map +1 -0
  275. package/lib/http/errors/InternalServerError.d.ts +8 -0
  276. package/lib/http/errors/InternalServerError.d.ts.map +1 -0
  277. package/lib/http/errors/InternalServerError.js +10 -0
  278. package/lib/http/errors/InternalServerError.js.map +1 -0
  279. package/lib/http/errors/NotFoundError.d.ts +8 -0
  280. package/lib/http/errors/NotFoundError.d.ts.map +1 -0
  281. package/lib/http/errors/NotFoundError.js +10 -0
  282. package/lib/http/errors/NotFoundError.js.map +1 -0
  283. package/lib/http/errors/RateLimitError.d.ts +13 -0
  284. package/lib/http/errors/RateLimitError.d.ts.map +1 -0
  285. package/lib/http/errors/RateLimitError.js +16 -0
  286. package/lib/http/errors/RateLimitError.js.map +1 -0
  287. package/lib/http/errors/ServiceUnavailableError.d.ts +8 -0
  288. package/lib/http/errors/ServiceUnavailableError.d.ts.map +1 -0
  289. package/lib/http/errors/ServiceUnavailableError.js +10 -0
  290. package/lib/http/errors/ServiceUnavailableError.js.map +1 -0
  291. package/lib/http/errors/ValidationError.d.ts +9 -0
  292. package/lib/http/errors/ValidationError.d.ts.map +1 -0
  293. package/lib/http/errors/ValidationError.js +12 -0
  294. package/lib/http/errors/ValidationError.js.map +1 -0
  295. package/lib/http/errors/index.d.ts +11 -0
  296. package/lib/http/errors/index.d.ts.map +1 -0
  297. package/lib/http/errors/index.js +12 -0
  298. package/lib/http/errors/index.js.map +1 -0
  299. package/lib/http/middleware/apiKey.d.ts +9 -0
  300. package/lib/http/middleware/apiKey.d.ts.map +1 -0
  301. package/lib/http/middleware/apiKey.js +71 -0
  302. package/lib/http/middleware/apiKey.js.map +1 -0
  303. package/lib/http/middleware/csrf.d.ts +63 -0
  304. package/lib/http/middleware/csrf.d.ts.map +1 -0
  305. package/lib/http/middleware/csrf.js +169 -0
  306. package/lib/http/middleware/csrf.js.map +1 -0
  307. package/lib/http/middleware/httpLogger.d.ts +39 -0
  308. package/lib/http/middleware/httpLogger.d.ts.map +1 -0
  309. package/lib/http/middleware/httpLogger.js +118 -0
  310. package/lib/http/middleware/httpLogger.js.map +1 -0
  311. package/lib/http/middleware/idempotency.d.ts +48 -0
  312. package/lib/http/middleware/idempotency.d.ts.map +1 -0
  313. package/lib/http/middleware/idempotency.js +180 -0
  314. package/lib/http/middleware/idempotency.js.map +1 -0
  315. package/lib/http/middleware/rateLimit.d.ts +105 -0
  316. package/lib/http/middleware/rateLimit.d.ts.map +1 -0
  317. package/lib/http/middleware/rateLimit.js +84 -0
  318. package/lib/http/middleware/rateLimit.js.map +1 -0
  319. package/lib/http/middleware/requireAuth.d.ts +58 -0
  320. package/lib/http/middleware/requireAuth.d.ts.map +1 -0
  321. package/lib/http/middleware/requireAuth.js +63 -0
  322. package/lib/http/middleware/requireAuth.js.map +1 -0
  323. package/lib/http/middleware/requirePermission.d.ts +23 -0
  324. package/lib/http/middleware/requirePermission.d.ts.map +1 -0
  325. package/lib/http/middleware/requirePermission.js +50 -0
  326. package/lib/http/middleware/requirePermission.js.map +1 -0
  327. package/lib/http/middleware/resolveTenant.d.ts +41 -0
  328. package/lib/http/middleware/resolveTenant.d.ts.map +1 -0
  329. package/lib/http/middleware/resolveTenant.js +17 -0
  330. package/lib/http/middleware/resolveTenant.js.map +1 -0
  331. package/lib/http/streaming/sse.d.ts +31 -0
  332. package/lib/http/streaming/sse.d.ts.map +1 -0
  333. package/lib/http/streaming/sse.js +11 -0
  334. package/lib/http/streaming/sse.js.map +1 -0
  335. package/lib/http/streaming/streamLLM.d.ts +94 -0
  336. package/lib/http/streaming/streamLLM.d.ts.map +1 -0
  337. package/lib/http/streaming/streamLLM.js +94 -0
  338. package/lib/http/streaming/streamLLM.js.map +1 -0
  339. package/lib/http/utils/authCookies.d.ts +74 -0
  340. package/lib/http/utils/authCookies.d.ts.map +1 -0
  341. package/lib/http/utils/authCookies.js +102 -0
  342. package/lib/http/utils/authCookies.js.map +1 -0
  343. package/lib/http/utils/clientIp.d.ts +85 -0
  344. package/lib/http/utils/clientIp.d.ts.map +1 -0
  345. package/lib/http/utils/clientIp.js +249 -0
  346. package/lib/http/utils/clientIp.js.map +1 -0
  347. package/lib/http/utils/index.d.ts +4 -0
  348. package/lib/http/utils/index.d.ts.map +1 -0
  349. package/lib/http/utils/index.js +5 -0
  350. package/lib/http/utils/index.js.map +1 -0
  351. package/lib/http/utils/metaTags.d.ts +49 -0
  352. package/lib/http/utils/metaTags.d.ts.map +1 -0
  353. package/lib/http/utils/metaTags.js +32 -0
  354. package/lib/http/utils/metaTags.js.map +1 -0
  355. package/lib/http/utils/publicSuffix.d.ts +34 -0
  356. package/lib/http/utils/publicSuffix.d.ts.map +1 -0
  357. package/lib/http/utils/publicSuffix.js +276 -0
  358. package/lib/http/utils/publicSuffix.js.map +1 -0
  359. package/lib/http/utils/uploads.d.ts +92 -0
  360. package/lib/http/utils/uploads.d.ts.map +1 -0
  361. package/lib/http/utils/uploads.js +126 -0
  362. package/lib/http/utils/uploads.js.map +1 -0
  363. package/lib/http/utils/validate.d.ts +41 -0
  364. package/lib/http/utils/validate.d.ts.map +1 -0
  365. package/lib/http/utils/validate.js +55 -0
  366. package/lib/http/utils/validate.js.map +1 -0
  367. package/lib/http/utils/webhooks.d.ts +63 -0
  368. package/lib/http/utils/webhooks.d.ts.map +1 -0
  369. package/lib/http/utils/webhooks.js +133 -0
  370. package/lib/http/utils/webhooks.js.map +1 -0
  371. package/lib/http/ws/auth.d.ts +46 -0
  372. package/lib/http/ws/auth.d.ts.map +1 -0
  373. package/lib/http/ws/auth.js +123 -0
  374. package/lib/http/ws/auth.js.map +1 -0
  375. package/lib/index.d.ts +80 -0
  376. package/lib/index.d.ts.map +1 -0
  377. package/lib/index.js +61 -0
  378. package/lib/index.js.map +1 -0
  379. package/lib/kernel/index.d.ts +3 -0
  380. package/lib/kernel/index.d.ts.map +1 -0
  381. package/lib/kernel/index.js +3 -0
  382. package/lib/kernel/index.js.map +1 -0
  383. package/lib/libraries/.gitkeep +0 -0
  384. package/lib/libraries/ai/CHANGELOG.md +17 -0
  385. package/lib/libraries/ai/README.md +164 -0
  386. package/lib/libraries/ai/adapters/AnthropicAdapter.ts +382 -0
  387. package/lib/libraries/ai/adapters/LLMProvider.ts +76 -0
  388. package/lib/libraries/ai/adapters/OpenAIAdapter.ts +466 -0
  389. package/lib/libraries/ai/experimental/index.ts +20 -0
  390. package/lib/libraries/ai/index.ts +128 -0
  391. package/lib/libraries/ai/library.json +19 -0
  392. package/lib/libraries/ai/loop/agentLoop.ts +377 -0
  393. package/lib/libraries/ai/prompts/definePrompt.ts +0 -0
  394. package/lib/libraries/ai/rag/retrieveAndAnswer.ts +177 -0
  395. package/lib/libraries/ai/streaming/streamLLM.ts +94 -0
  396. package/lib/libraries/ai/structured/completeStructured.ts +143 -0
  397. package/lib/libraries/ai/tokens/Tokenizer.ts +216 -0
  398. package/lib/libraries/ai/tools/defineTool.ts +208 -0
  399. package/lib/libraries/ai/types.ts +260 -0
  400. package/lib/libraries/chunking/ChunkingService.ts +103 -0
  401. package/lib/libraries/chunking/README.md +104 -0
  402. package/lib/libraries/chunking/docs/api-reference.md +549 -0
  403. package/lib/libraries/chunking/docs/best-practices.md +321 -0
  404. package/lib/libraries/chunking/docs/code-organization.md +538 -0
  405. package/lib/libraries/chunking/docs/configuration.md +418 -0
  406. package/lib/libraries/chunking/docs/index.md +236 -0
  407. package/lib/libraries/chunking/docs/quick-start.md +298 -0
  408. package/lib/libraries/chunking/docs/strategies.md +407 -0
  409. package/lib/libraries/chunking/docs/summary.md +258 -0
  410. package/lib/libraries/chunking/docs/troubleshooting.md +527 -0
  411. package/lib/libraries/chunking/index.ts +17 -0
  412. package/lib/libraries/chunking/library.json +16 -0
  413. package/lib/libraries/chunking/strategies/ChunkingStrategy.ts +13 -0
  414. package/lib/libraries/chunking/strategies/FixedLengthChunkingStrategy.ts +88 -0
  415. package/lib/libraries/chunking/strategies/SemanticChunkingStrategy.ts +389 -0
  416. package/lib/libraries/chunking/strategies/SlidingWindowChunkingStrategy.ts +258 -0
  417. package/lib/libraries/chunking/types/index.ts +63 -0
  418. package/lib/libraries/email/EmailService.ts +591 -0
  419. package/lib/libraries/email/README.md +777 -0
  420. package/lib/libraries/email/TemplateRegistry.ts +148 -0
  421. package/lib/libraries/email/TemplateRenderer.ts +273 -0
  422. package/lib/libraries/email/index.ts +4 -0
  423. package/lib/libraries/email/initializeEmailService.ts +60 -0
  424. package/lib/libraries/email/library.json +12 -0
  425. package/lib/libraries/email/types/EmailAddress.ts +4 -0
  426. package/lib/libraries/email/types/EmailAttachment.ts +11 -0
  427. package/lib/libraries/email/types/EmailTag.ts +9 -0
  428. package/lib/libraries/email/types/EmailTemplate.ts +124 -0
  429. package/lib/libraries/email/types/SendBatchEmailsOptions.ts +9 -0
  430. package/lib/libraries/email/types/SendBatchEmailsResult.ts +9 -0
  431. package/lib/libraries/email/types/SendEmailOptions.ts +33 -0
  432. package/lib/libraries/email/types/SendEmailResult.ts +9 -0
  433. package/lib/libraries/email/types/index.ts +8 -0
  434. package/lib/libraries/weaviate/QueryBuilder.ts +292 -0
  435. package/lib/libraries/weaviate/README.md +284 -0
  436. package/lib/libraries/weaviate/Weaviate.ts +1419 -0
  437. package/lib/libraries/weaviate/WeaviateConfig.ts +268 -0
  438. package/lib/libraries/weaviate/docs/.gitkeep +1 -0
  439. package/lib/libraries/weaviate/docs/API_REFERENCE.md +1067 -0
  440. package/lib/libraries/weaviate/docs/CONFIGURATION.md +320 -0
  441. package/lib/libraries/weaviate/docs/ERROR_HANDLING.md +271 -0
  442. package/lib/libraries/weaviate/docs/MULTI_TENANCY.md +348 -0
  443. package/lib/libraries/weaviate/docs/PERFORMANCE.md +602 -0
  444. package/lib/libraries/weaviate/docs/PLUGIN_DEVELOPMENT.md +547 -0
  445. package/lib/libraries/weaviate/docs/QUICK_START.md +443 -0
  446. package/lib/libraries/weaviate/docs/README.md +269 -0
  447. package/lib/libraries/weaviate/docs/SCHEMA_GUIDE.md +630 -0
  448. package/lib/libraries/weaviate/docs/WEAVIATE_README.md +520 -0
  449. package/lib/libraries/weaviate/errors/WeaviateError.ts +92 -0
  450. package/lib/libraries/weaviate/errors/index.ts +1 -0
  451. package/lib/libraries/weaviate/index.ts +35 -0
  452. package/lib/libraries/weaviate/library.json +26 -0
  453. package/lib/libraries/weaviate/plugins/index.ts +2 -0
  454. package/lib/libraries/weaviate/schemas/SchemaRegistry.ts +284 -0
  455. package/lib/libraries/weaviate/schemas/index.ts +2 -0
  456. package/lib/libraries/weaviate/types/BM25SearchOptions.ts +9 -0
  457. package/lib/libraries/weaviate/types/ExtendedWeaviateClient.ts +7 -0
  458. package/lib/libraries/weaviate/types/HybridSearchOptions.ts +11 -0
  459. package/lib/libraries/weaviate/types/MultiTenancy.ts +81 -0
  460. package/lib/libraries/weaviate/types/Plugin.ts +17 -0
  461. package/lib/libraries/weaviate/types/SchemaConfig.ts +25 -0
  462. package/lib/libraries/weaviate/types/SearchMethod.ts +8 -0
  463. package/lib/libraries/weaviate/types/SearchOptions.ts +16 -0
  464. package/lib/libraries/weaviate/types/SearchRequest.ts +19 -0
  465. package/lib/libraries/weaviate/types/SearchResult.ts +16 -0
  466. package/lib/libraries/weaviate/types/SearchableField.ts +87 -0
  467. package/lib/libraries/weaviate/types/VectorIndexConfig.ts +19 -0
  468. package/lib/libraries/weaviate/types/VectorSearchOptions.ts +18 -0
  469. package/lib/libraries/weaviate/types/VectorizerConfig.ts +8 -0
  470. package/lib/libraries/weaviate/types/index.ts +29 -0
  471. package/lib/libraries/weaviate/utils/TenantContextManager.ts +94 -0
  472. package/lib/modules/accounts/index.ts +47 -0
  473. package/lib/modules/accounts/module.json +15 -0
  474. package/lib/modules/accounts/permissions.ts +33 -0
  475. package/lib/modules/accounts/routes.ts +200 -0
  476. package/lib/modules/accounts/schema.ts +219 -0
  477. package/lib/modules/accounts/services/AccountService.ts +44 -0
  478. package/lib/modules/accounts/validation/schemas.ts +70 -0
  479. package/lib/modules/oauth/adapters/GmailOAuthAdapter.ts +35 -0
  480. package/lib/modules/oauth/adapters/GoogleOAuthAdapter.ts +278 -0
  481. package/lib/modules/oauth/adapters/MicrosoftOAuthAdapter.ts +269 -0
  482. package/lib/modules/oauth/adapters/MockOAuthAdapter.ts +138 -0
  483. package/lib/modules/oauth/adapters/OAuthAdapter.ts +211 -0
  484. package/lib/modules/oauth/adapters/OAuthAdapterRegistry.ts +77 -0
  485. package/lib/modules/oauth/adapters/OutlookOAuthAdapter.ts +38 -0
  486. package/lib/modules/oauth/index.ts +79 -0
  487. package/lib/modules/oauth/module.json +23 -0
  488. package/lib/modules/oauth/permissions.ts +39 -0
  489. package/lib/modules/oauth/routes.ts +497 -0
  490. package/lib/modules/oauth/schema.ts +127 -0
  491. package/lib/modules/oauth/services/OAuthConnectionService.ts +147 -0
  492. package/lib/modules/oauth/state.ts +234 -0
  493. package/lib/modules/oauth/stateJtiCache.ts +85 -0
  494. package/lib/modules/oauth/verifyIdToken.ts +178 -0
  495. package/lib/modules/outbox/EventEmitter.ts +106 -0
  496. package/lib/modules/outbox/OutboxDrainer.ts +163 -0
  497. package/lib/modules/outbox/handlers/EventHandler.ts +115 -0
  498. package/lib/modules/outbox/index.ts +43 -0
  499. package/lib/modules/outbox/module.json +15 -0
  500. package/lib/modules/outbox/permissions.ts +36 -0
  501. package/lib/modules/outbox/routes.ts +219 -0
  502. package/lib/modules/outbox/schema.ts +207 -0
  503. package/lib/modules/outbox/services/OutboxEventService.ts +223 -0
  504. package/lib/observability/logger.d.ts +30 -0
  505. package/lib/observability/logger.d.ts.map +1 -0
  506. package/lib/observability/logger.js +110 -0
  507. package/lib/observability/logger.js.map +1 -0
  508. package/lib/observability/metrics.d.ts +3 -0
  509. package/lib/observability/metrics.d.ts.map +1 -0
  510. package/lib/observability/metrics.js +3 -0
  511. package/lib/observability/metrics.js.map +1 -0
  512. package/lib/observability/otel.d.ts +3 -0
  513. package/lib/observability/otel.d.ts.map +1 -0
  514. package/lib/observability/otel.js +3 -0
  515. package/lib/observability/otel.js.map +1 -0
  516. package/lib/observability/safeErrorFields.d.ts +14 -0
  517. package/lib/observability/safeErrorFields.d.ts.map +1 -0
  518. package/lib/observability/safeErrorFields.js +14 -0
  519. package/lib/observability/safeErrorFields.js.map +1 -0
  520. package/lib/observability/tracing.d.ts +3 -0
  521. package/lib/observability/tracing.d.ts.map +1 -0
  522. package/lib/observability/tracing.js +3 -0
  523. package/lib/observability/tracing.js.map +1 -0
  524. package/lib/package.json +4 -0
  525. package/lib/testing.d.ts +3 -0
  526. package/lib/testing.d.ts.map +1 -0
  527. package/lib/testing.js +3 -0
  528. package/lib/testing.js.map +1 -0
  529. package/package.json +193 -3
  530. package/templates/default/.claude/agents/qa-brief.md +106 -0
  531. package/templates/default/.claude/commands/sherpa-brief.md +23 -0
  532. package/templates/default/.cursor/rules/api.mdc +80 -0
  533. package/templates/default/.cursor/rules/commits.mdc +88 -0
  534. package/templates/default/.cursor/rules/security.mdc +92 -0
  535. package/templates/default/.cursor/rules/testing.mdc +123 -0
  536. package/templates/default/.cursor/rules/typescript.mdc +86 -0
  537. package/templates/default/.env.example +79 -0
  538. package/templates/default/.github/workflows/sherpa-brief.yml +180 -0
  539. package/templates/default/AGENTS.md +166 -0
  540. package/templates/default/CLAUDE.md +17 -0
  541. package/templates/default/README.md +97 -0
  542. package/templates/default/_gitignore +27 -0
  543. package/templates/default/docker-compose.yml +83 -0
  544. package/templates/default/drizzle.config.ts +34 -0
  545. package/templates/default/eslint.config.mjs +106 -0
  546. package/templates/default/package.json +57 -0
  547. package/templates/default/ship-api.config.ts +21 -0
  548. package/templates/default/src/client.ts +34 -0
  549. package/templates/default/src/config/modules.ts +23 -0
  550. package/templates/default/src/db/schema.ts +26 -0
  551. package/templates/default/src/environment.ts +81 -0
  552. package/templates/default/src/index.test.ts +53 -0
  553. package/templates/default/src/index.ts +11 -0
  554. package/templates/default/src/instrumentation.ts +13 -0
  555. package/templates/default/src/server.ts +90 -0
  556. package/templates/default/tsconfig.json +24 -0
@@ -0,0 +1,143 @@
1
+ import { z } from "zod";
2
+ import type { LLMProvider } from "../adapters/LLMProvider.js";
3
+ import type { CompleteOptions, CompleteResult, ToolDefinition, ToolUsePart } from "../types.js";
4
+
5
+ /**
6
+ * `completeStructured<TSchema>({ llm, schema, ... })` — single-shot
7
+ * call that returns a typed object matching the supplied Zod schema.
8
+ *
9
+ * Pattern: defines a synthetic "respond" tool whose `input_schema` is
10
+ * the JSON-schema view of the user's Zod schema, forces
11
+ * `tool_choice: { type: "tool", name }` so the model MUST invoke it,
12
+ * then parses the tool_use input back through the Zod schema (catches
13
+ * any drift the JSON-schema view didn't constrain — e.g. Zod
14
+ * refinements that don't translate).
15
+ *
16
+ * Provider-portable by design — works against any `LLMProvider` whose
17
+ * `complete()` honors `tools` + `toolChoice`. Provider-specific
18
+ * structured-output APIs (OpenAI `response_format: json_schema`,
19
+ * Anthropic `parse()` helper) can be wired in adapter-specific
20
+ * overrides in a later commit; this primitive ships the load-bearing
21
+ * cross-provider path first.
22
+ *
23
+ * Why a synthetic tool instead of "ask the model for JSON in a code
24
+ * block":
25
+ * - Tool-use is the model's native structured-output channel —
26
+ * providers train it explicitly. JSON-in-text is best-effort and
27
+ * drifts (markdown fences, trailing commentary, hallucinated keys).
28
+ * - The tool's `input_schema` is forced upstream in the request, so
29
+ * the provider can constrain decoding (Anthropic does shape-aware
30
+ * decoding for tool inputs).
31
+ * - Tool inputs come back already-parsed JSON — no re-parsing /
32
+ * stripping markdown.
33
+ *
34
+ * Errors: `StructuredOutputError` thrown when (a) the model returns
35
+ * text instead of invoking the tool (rare with `toolChoice: tool` but
36
+ * possible on `max_tokens` cutoff), (b) the tool input fails Zod
37
+ * validation. Both carry the raw `CompleteResult` for debugging.
38
+ */
39
+
40
+ export interface CompleteStructuredOptions<TSchema extends z.ZodTypeAny>
41
+ extends Omit<CompleteOptions, "tools" | "toolChoice"> {
42
+ /** Provider that runs the request. */
43
+ llm: LLMProvider;
44
+ /** Zod schema describing the desired output shape. */
45
+ schema: TSchema;
46
+ /**
47
+ * Override the synthetic tool's name. Default `"respond"`. Useful
48
+ * when the tool name appears in the model's reasoning trace and you
49
+ * want it to read more naturally.
50
+ */
51
+ responseToolName?: string;
52
+ /** Override the synthetic tool's description shown to the model. */
53
+ responseToolDescription?: string;
54
+ }
55
+
56
+ export interface CompleteStructuredResult<T> {
57
+ /** The parsed, schema-validated output. */
58
+ data: T;
59
+ /** The raw provider response (usage / id / model / etc.). */
60
+ raw: CompleteResult;
61
+ }
62
+
63
+ export class StructuredOutputError extends Error {
64
+ constructor(
65
+ message: string,
66
+ public readonly raw: CompleteResult,
67
+ ) {
68
+ super(message);
69
+ this.name = "StructuredOutputError";
70
+ }
71
+ }
72
+
73
+ const DEFAULT_TOOL_NAME = "respond";
74
+ const DEFAULT_TOOL_DESCRIPTION =
75
+ "Respond with the structured output. Call this tool exactly once with the final answer matching the input schema.";
76
+
77
+ export async function completeStructured<TSchema extends z.ZodTypeAny>(
78
+ opts: CompleteStructuredOptions<TSchema>,
79
+ ): Promise<CompleteStructuredResult<z.infer<TSchema>>> {
80
+ const inputSchema = z.toJSONSchema(opts.schema, {
81
+ target: "draft-2020-12",
82
+ }) as Record<string, unknown>;
83
+ delete inputSchema["$schema"];
84
+
85
+ const responseTool: ToolDefinition = {
86
+ name: opts.responseToolName ?? DEFAULT_TOOL_NAME,
87
+ description: opts.responseToolDescription ?? DEFAULT_TOOL_DESCRIPTION,
88
+ inputSchema,
89
+ };
90
+
91
+ // Drop the keys we own from the forwarded options.
92
+ const {
93
+ llm,
94
+ schema: _schema,
95
+ responseToolName: _name,
96
+ responseToolDescription: _desc,
97
+ ...providerOpts
98
+ } = opts;
99
+ void _schema;
100
+ void _name;
101
+ void _desc;
102
+
103
+ const raw = await llm.complete({
104
+ ...providerOpts,
105
+ tools: [responseTool],
106
+ toolChoice: { type: "tool", name: responseTool.name },
107
+ });
108
+
109
+ const toolUse = raw.content.find(
110
+ (p): p is ToolUsePart => p.type === "tool_use" && p.name === responseTool.name,
111
+ );
112
+ if (!toolUse) {
113
+ throw new StructuredOutputError(
114
+ `Model did not invoke the "${responseTool.name}" tool — got stop_reason="${raw.stopReason}"`,
115
+ raw,
116
+ );
117
+ }
118
+
119
+ const parsed = opts.schema.safeParse(toolUse.input);
120
+ if (!parsed.success) {
121
+ throw new StructuredOutputError(
122
+ `Response did not match schema: ${formatZodIssues(parsed.error.issues)}`,
123
+ raw,
124
+ );
125
+ }
126
+
127
+ return { data: parsed.data as z.infer<TSchema>, raw };
128
+ }
129
+
130
+ interface ZodLikeIssue {
131
+ path?: Array<string | number>;
132
+ message: string;
133
+ }
134
+
135
+ function formatZodIssues(issues: readonly ZodLikeIssue[]): string {
136
+ if (!issues.length) return "validation failed";
137
+ return issues
138
+ .map((issue) => {
139
+ const path = (issue.path ?? []).join(".") || "(root)";
140
+ return `${path}: ${issue.message}`;
141
+ })
142
+ .join("; ");
143
+ }
@@ -0,0 +1,216 @@
1
+ import type { Message, MessageContentPart } from "../types.js";
2
+
3
+ /**
4
+ * Pluggable tokenizer contract — counts tokens for a given model
5
+ * without committing the library to a specific tokenizer
6
+ * implementation (tiktoken / claude-tokenizer / model-bundled
7
+ * /encoding-rs / online API). Consumers inject the right tokenizer
8
+ * for their provider; this library never imports a tokenizer SDK
9
+ * itself, so the dep graph stays narrow.
10
+ *
11
+ * Why an interface instead of "just use tiktoken":
12
+ * - Tokenization is provider-specific. OpenAI uses tiktoken (cl100k /
13
+ * o200k); Anthropic uses a Claude-specific BPE; Llama / Mistral
14
+ * have their own. One library, three tokenizers.
15
+ * - Tiktoken pulls a 5+ MB WASM blob — fine for server-side, hostile
16
+ * for edge runtimes. An "estimate" tokenizer is preferable when
17
+ * exactness doesn't matter (rate-limit budgeting, prompt-fit
18
+ * gating).
19
+ * - Tests need a predictable in-process tokenizer; consumers can
20
+ * register `HeuristicTokenizer` for cheap deterministic counts.
21
+ *
22
+ * The library ships `HeuristicTokenizer` as a baseline (~4 chars per
23
+ * token, the well-known rule-of-thumb for English). Real tokenizers
24
+ * (tiktoken-backed for OpenAI, claude-tokenizer for Anthropic) are
25
+ * straightforward to implement against this interface and can land in
26
+ * v4.x adapter sub-packages so they're tree-shake-friendly.
27
+ */
28
+
29
+ export interface Tokenizer {
30
+ /** Stable model identifier the tokenizer is calibrated for. */
31
+ readonly model: string;
32
+ /**
33
+ * Count tokens in a single string. Synchronous so callers can use it
34
+ * inside hot prompt-assembly loops without await ceremony.
35
+ */
36
+ count(text: string): number;
37
+ /**
38
+ * Optional encode (text → tokens). Provided when the tokenizer is
39
+ * exact (tiktoken / claude); omitted on heuristic backends.
40
+ */
41
+ encode?(text: string): number[];
42
+ /** Optional decode (tokens → text). Same caveat as `encode`. */
43
+ decode?(tokens: number[]): string;
44
+ /**
45
+ * Free any resources the tokenizer holds (tiktoken WASM handles,
46
+ * file mappings). Idempotent. Safe to call when nothing was
47
+ * allocated.
48
+ */
49
+ dispose?(): void;
50
+ }
51
+
52
+ /**
53
+ * Sum tokens across a `Message[]` history — text parts, tool_use
54
+ * input JSON, tool_result content, image part overhead. Provider-
55
+ * specific message-formatting overhead (per-turn separator tokens,
56
+ * role-name tokens) is approximated by `perMessageOverhead`; refine
57
+ * per provider when exactness matters.
58
+ */
59
+ export interface CountMessagesOptions {
60
+ /** Tokens added per message (separators / role name). Default 4. */
61
+ perMessageOverhead?: number;
62
+ /**
63
+ * Tokens budgeted per image part. Anthropic / OpenAI both charge a
64
+ * fixed-ish range (~85–1500 depending on resolution). Default 1024
65
+ * — middle of the range; pass a tighter estimate when known.
66
+ */
67
+ perImageTokens?: number;
68
+ }
69
+
70
+ const DEFAULT_PER_MESSAGE_OVERHEAD = 4;
71
+ const DEFAULT_PER_IMAGE_TOKENS = 1024;
72
+
73
+ /**
74
+ * @deprecated AI-R3. Token *truth* comes back in the provider response — read
75
+ * `CompleteResult.usage` / `StreamStopEvent.usage` (real, billed counts). This
76
+ * heuristic-driven count is inaccurate (±15%) and a per-model maintenance
77
+ * burden. For pre-call budgeting only, use `estimateMessageTokens`.
78
+ */
79
+ export function countMessageTokens(
80
+ tokenizer: Tokenizer,
81
+ messages: Message[],
82
+ opts: CountMessagesOptions = {},
83
+ ): number {
84
+ const perMessage = opts.perMessageOverhead ?? DEFAULT_PER_MESSAGE_OVERHEAD;
85
+ const perImage = opts.perImageTokens ?? DEFAULT_PER_IMAGE_TOKENS;
86
+
87
+ let total = 0;
88
+ for (const msg of messages) {
89
+ total += perMessage;
90
+ if (typeof msg.content === "string") {
91
+ total += tokenizer.count(msg.content);
92
+ } else {
93
+ total += countParts(tokenizer, msg.content, perImage);
94
+ }
95
+ if (msg.name) total += tokenizer.count(msg.name);
96
+ }
97
+ return total;
98
+ }
99
+
100
+ function countParts(tokenizer: Tokenizer, parts: MessageContentPart[], perImage: number): number {
101
+ let n = 0;
102
+ for (const p of parts) {
103
+ switch (p.type) {
104
+ case "text":
105
+ n += tokenizer.count(p.text);
106
+ break;
107
+ case "tool_use":
108
+ n += tokenizer.count(p.name);
109
+ // input JSON shows up to the model verbatim — count it.
110
+ try {
111
+ n += tokenizer.count(JSON.stringify(p.input ?? {}));
112
+ } catch {
113
+ // unrenderable input → conservative estimate
114
+ n += 16;
115
+ }
116
+ break;
117
+ case "tool_result":
118
+ n += tokenizer.count(p.content);
119
+ break;
120
+ case "image":
121
+ n += perImage;
122
+ break;
123
+ }
124
+ }
125
+ return n;
126
+ }
127
+
128
+ /**
129
+ * Heuristic tokenizer — `Math.ceil(text.length / 4)`, the canonical
130
+ * rule-of-thumb for English text. ±15% accuracy; good enough for
131
+ * rate-limit budgeting and prompt-fit gating, not for exact billing.
132
+ *
133
+ * Ships zero deps and works in every runtime (Node, Workers, Bun,
134
+ * browser). Real tokenizers swap in via the `Tokenizer` interface
135
+ * without changing call sites.
136
+ *
137
+ * @deprecated AI-R3. Token truth comes back in the provider response — read
138
+ * `CompleteResult.usage`. Use this only as a pre-call estimate; the standalone
139
+ * `estimateTokens` / `estimateMessageTokens` helpers are the lighter, honestly-
140
+ * labelled way to do that without a pluggable-tokenizer subsystem. The
141
+ * `Tokenizer` interface itself is NOT deprecated — a real tiktoken/claude
142
+ * tokenizer still implements it.
143
+ */
144
+ export class HeuristicTokenizer implements Tokenizer {
145
+ readonly model: string;
146
+ private readonly charsPerToken: number;
147
+
148
+ constructor(opts: { model?: string; charsPerToken?: number } = {}) {
149
+ this.model = opts.model ?? "heuristic";
150
+ this.charsPerToken = opts.charsPerToken ?? 4;
151
+ }
152
+
153
+ count(text: string): number {
154
+ if (!text) return 0;
155
+ return Math.ceil(text.length / this.charsPerToken);
156
+ }
157
+ }
158
+
159
+ const ESTIMATE_CHARS_PER_TOKEN = 4;
160
+
161
+ /**
162
+ * Rough pre-call token **estimate** for a single string (`~chars/4`). For
163
+ * prompt-fit / rate-limit gating *before* a request exists — NOT a billing
164
+ * figure (the real count is returned by the provider on the response,
165
+ * `CompleteResult.usage`). ±15%; zero-dep; works in every runtime.
166
+ */
167
+ export function estimateTokens(text: string): number {
168
+ if (!text) return 0;
169
+ return Math.ceil(text.length / ESTIMATE_CHARS_PER_TOKEN);
170
+ }
171
+
172
+ /**
173
+ * Rough pre-call token **estimate** for a `Message[]` history — sums text,
174
+ * tool-use input JSON, tool-result content, plus per-message and per-image
175
+ * overhead. ESTIMATE ONLY, for prompt-fit gating before the request exists;
176
+ * read the response `usage` for real counts. (This is the honest replacement
177
+ * for the deprecated `countMessageTokens`.)
178
+ */
179
+ export function estimateMessageTokens(
180
+ messages: Message[],
181
+ opts: CountMessagesOptions = {},
182
+ ): number {
183
+ const perMessage = opts.perMessageOverhead ?? DEFAULT_PER_MESSAGE_OVERHEAD;
184
+ const perImage = opts.perImageTokens ?? DEFAULT_PER_IMAGE_TOKENS;
185
+ let total = 0;
186
+ for (const msg of messages) {
187
+ total += perMessage;
188
+ if (typeof msg.content === "string") {
189
+ total += estimateTokens(msg.content);
190
+ } else {
191
+ for (const p of msg.content) {
192
+ switch (p.type) {
193
+ case "text":
194
+ total += estimateTokens(p.text);
195
+ break;
196
+ case "tool_use":
197
+ total += estimateTokens(p.name);
198
+ try {
199
+ total += estimateTokens(JSON.stringify(p.input ?? {}));
200
+ } catch {
201
+ total += 16;
202
+ }
203
+ break;
204
+ case "tool_result":
205
+ total += estimateTokens(p.content);
206
+ break;
207
+ case "image":
208
+ total += perImage;
209
+ break;
210
+ }
211
+ }
212
+ }
213
+ if (msg.name) total += estimateTokens(msg.name);
214
+ }
215
+ return total;
216
+ }
@@ -0,0 +1,208 @@
1
+ import { z } from "zod";
2
+ import type { ToolDefinition } from "../types.js";
3
+
4
+ /**
5
+ * `defineTool({ name, description, schema, handler })` — the load-bearing
6
+ * primitive the agent loop dispatches against. Pairs a Zod schema (the
7
+ * tool's input contract) with a typed handler that consumes the parsed
8
+ * input.
9
+ *
10
+ * Why a factory instead of a class:
11
+ * - The handler's input type is inferred from the Zod schema via
12
+ * `z.infer<typeof schema>`. A factory carries the inferred type
13
+ * through naturally; class generics force the consumer to repeat
14
+ * the inference.
15
+ * - The factory produces a `Tool` value that satisfies both the
16
+ * `ToolDefinition` shape (what providers see) and an `execute`
17
+ * surface (what the agent loop calls), without any inheritance
18
+ * ceremony.
19
+ * - `definition` is computed once at registration time — the
20
+ * `zodToJsonSchema` call doesn't run per-invocation.
21
+ *
22
+ * The handler receives the parsed input, plus a `ToolContext` carrying
23
+ * cancellation + caller metadata. Handlers MAY return any JSON-
24
+ * serializable value; the agent loop stringifies the result back into
25
+ * a `tool_result` content part. Throwing inside the handler short-
26
+ * circuits with `isError: true` (visible to the model) — the loop
27
+ * doesn't crash, it lets the model recover.
28
+ *
29
+ * Strictness: by default, schema parsing is strict (extra keys throw)
30
+ * to catch model output drift early. Pass `strict: false` to switch
31
+ * to lenient parsing if a provider tends to wrap or annotate fields.
32
+ */
33
+
34
+ export interface ToolContext {
35
+ /** Caller-supplied abort signal. Honored by long-running handlers. */
36
+ signal?: AbortSignal;
37
+ /**
38
+ * Free-form caller metadata. The agent loop forwards what it was
39
+ * called with — typical contents: `{ requestId, userId }`.
40
+ */
41
+ metadata?: Record<string, unknown>;
42
+ }
43
+
44
+ export type ToolHandler<TInput, TOutput = unknown> = (
45
+ input: TInput,
46
+ ctx: ToolContext,
47
+ ) => TOutput | Promise<TOutput>;
48
+
49
+ export interface DefineToolOptions<TSchema extends z.ZodTypeAny, TOutput> {
50
+ /** Stable name. Models reference tools by name; keep it snake_case. */
51
+ name: string;
52
+ /**
53
+ * One-line description shown to the model. The model uses this to
54
+ * decide *when* to call the tool — make it precise. Bad: "Get data."
55
+ * Good: "Look up the current weather forecast for a single city."
56
+ */
57
+ description: string;
58
+ /**
59
+ * Zod schema for the tool's input. Object schemas are strongly
60
+ * recommended (providers expect JSON Schema with `type: "object"`).
61
+ */
62
+ schema: TSchema;
63
+ /**
64
+ * Receives the parsed input + a `ToolContext`. Return value is
65
+ * stringified back to the model as the tool result; throwing produces
66
+ * an `isError: true` tool_result the model can see and recover from.
67
+ */
68
+ handler: ToolHandler<z.infer<TSchema>, TOutput>;
69
+ /**
70
+ * Strict parsing (extra keys throw). Default true — catches model
71
+ * output drift early. Set false for permissive providers.
72
+ */
73
+ strict?: boolean;
74
+ }
75
+
76
+ export interface Tool<TSchema extends z.ZodTypeAny = z.ZodTypeAny, TOutput = unknown> {
77
+ name: string;
78
+ description: string;
79
+ schema: TSchema;
80
+ /** JSON Schema view used by `LLMProvider` adapters. Built once at registration. */
81
+ definition: ToolDefinition;
82
+ /**
83
+ * Run the tool with raw provider-supplied input. Validates against the
84
+ * Zod schema first; on validation failure returns `{ ok: false,
85
+ * isError: true, content }` with the Zod issue path so the model can
86
+ * see what was wrong.
87
+ *
88
+ * On handler success: `{ ok: true, output }` with the raw return
89
+ * value. The agent loop is responsible for serializing `output` for
90
+ * the `tool_result` content part.
91
+ *
92
+ * On handler throw: `{ ok: false, isError: true, content }` with the
93
+ * error message — *not* re-thrown, so the loop survives and the model
94
+ * can decide whether to retry.
95
+ */
96
+ execute(input: unknown, ctx: ToolContext): Promise<ToolExecuteResult<TOutput>>;
97
+ }
98
+
99
+ export type ToolExecuteResult<TOutput> =
100
+ | { ok: true; output: TOutput }
101
+ | { ok: false; isError: true; content: string };
102
+
103
+ export function defineTool<TSchema extends z.ZodTypeAny, TOutput>(
104
+ opts: DefineToolOptions<TSchema, TOutput>,
105
+ ): Tool<TSchema, TOutput> {
106
+ const inputSchema = z.toJSONSchema(opts.schema, {
107
+ target: "draft-2020-12",
108
+ }) as Record<string, unknown>;
109
+ // Strip the $schema header so providers (which don't expect it) accept the schema.
110
+ delete inputSchema["$schema"];
111
+
112
+ const definition: ToolDefinition = {
113
+ name: opts.name,
114
+ description: opts.description,
115
+ inputSchema,
116
+ };
117
+
118
+ const strict = opts.strict ?? true;
119
+
120
+ return {
121
+ name: opts.name,
122
+ description: opts.description,
123
+ schema: opts.schema,
124
+ definition,
125
+ async execute(input: unknown, ctx: ToolContext): Promise<ToolExecuteResult<TOutput>> {
126
+ const parsed = strict ? opts.schema.safeParse(input) : opts.schema.safeParse(input ?? {});
127
+ if (!parsed.success) {
128
+ return {
129
+ ok: false,
130
+ isError: true,
131
+ content: formatZodIssues(parsed.error.issues),
132
+ };
133
+ }
134
+ try {
135
+ const output = await opts.handler(parsed.data as z.infer<TSchema>, ctx);
136
+ return { ok: true, output };
137
+ } catch (err) {
138
+ const message = err instanceof Error ? err.message : String(err ?? "unknown error");
139
+ return {
140
+ ok: false,
141
+ isError: true,
142
+ content: `tool "${opts.name}" failed: ${message}`,
143
+ };
144
+ }
145
+ },
146
+ };
147
+ }
148
+
149
+ interface ZodLikeIssue {
150
+ path?: Array<string | number>;
151
+ message: string;
152
+ }
153
+
154
+ function formatZodIssues(issues: readonly ZodLikeIssue[]): string {
155
+ if (!issues.length) return "validation failed";
156
+ return issues
157
+ .map((issue) => {
158
+ const path = (issue.path ?? []).join(".") || "(root)";
159
+ return `${path}: ${issue.message}`;
160
+ })
161
+ .join("; ");
162
+ }
163
+
164
+ /**
165
+ * `ToolRegistry` — ordered map keyed by tool name, with lookup helpers
166
+ * the agent loop needs (`getDefinitions()` for the provider request,
167
+ * `lookup(name)` for dispatch). Constructible standalone (tests) or via
168
+ * the convenience `toolRegistry(...tools)` factory.
169
+ */
170
+ export class ToolRegistry {
171
+ private readonly tools = new Map<string, Tool<z.ZodTypeAny, unknown>>();
172
+
173
+ constructor(tools: ReadonlyArray<Tool<z.ZodTypeAny, unknown>> = []) {
174
+ for (const tool of tools) this.add(tool);
175
+ }
176
+
177
+ add(tool: Tool<z.ZodTypeAny, unknown>): void {
178
+ if (this.tools.has(tool.name)) {
179
+ throw new Error(`ToolRegistry: duplicate tool name "${tool.name}"`);
180
+ }
181
+ this.tools.set(tool.name, tool);
182
+ }
183
+
184
+ has(name: string): boolean {
185
+ return this.tools.has(name);
186
+ }
187
+
188
+ lookup(name: string): Tool<z.ZodTypeAny, unknown> | undefined {
189
+ return this.tools.get(name);
190
+ }
191
+
192
+ /** Tool definitions the agent loop attaches to provider requests. */
193
+ getDefinitions(): ToolDefinition[] {
194
+ return Array.from(this.tools.values()).map((t) => t.definition);
195
+ }
196
+
197
+ size(): number {
198
+ return this.tools.size;
199
+ }
200
+
201
+ list(): ReadonlyArray<Tool<z.ZodTypeAny, unknown>> {
202
+ return Array.from(this.tools.values());
203
+ }
204
+ }
205
+
206
+ export function toolRegistry(...tools: Array<Tool<z.ZodTypeAny, unknown>>): ToolRegistry {
207
+ return new ToolRegistry(tools);
208
+ }