bonecode 1.0.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 (605) hide show
  1. package/ARCHITECTURE.md +183 -0
  2. package/README.md +71 -0
  3. package/bin/bonecode +62 -0
  4. package/bone/migrations/rag_vectors.sql +258 -0
  5. package/bone/output/agent/.dockerignore +7 -0
  6. package/bone/output/agent/.env.example +36 -0
  7. package/bone/output/agent/.github/workflows/ci.yaml +58 -0
  8. package/bone/output/agent/AgentDomain.bone.map +350 -0
  9. package/bone/output/agent/AgentDomain.postman_collection.json +958 -0
  10. package/bone/output/agent/Dockerfile +22 -0
  11. package/bone/output/agent/README.md +47 -0
  12. package/bone/output/agent/admin/index.html +740 -0
  13. package/bone/output/agent/docker-compose.yaml +22 -0
  14. package/bone/output/agent/k8s/deployment.yaml +75 -0
  15. package/bone/output/agent/migrations/agent.sql +36 -0
  16. package/bone/output/agent/migrations/agent_instance.sql +36 -0
  17. package/bone/output/agent/migrations/audit_log.sql +18 -0
  18. package/bone/output/agent/migrations/build_step.sql +34 -0
  19. package/bone/output/agent/migrations/event_outbox.sql +31 -0
  20. package/bone/output/agent/migrations/plan.sql +30 -0
  21. package/bone/output/agent/migrations/task.sql +30 -0
  22. package/bone/output/agent/migrations/tool_call.sql +33 -0
  23. package/bone/output/agent/openapi.yaml +1116 -0
  24. package/bone/output/agent/package.json +36 -0
  25. package/bone/output/agent/schema.graphql +233 -0
  26. package/bone/output/agent/sdk/client.ts +231 -0
  27. package/bone/output/agent/src/algorithms.ts +2 -0
  28. package/bone/output/agent/src/audit.ts +44 -0
  29. package/bone/output/agent/src/auth.ts +57 -0
  30. package/bone/output/agent/src/cron.ts +12 -0
  31. package/bone/output/agent/src/db.ts +32 -0
  32. package/bone/output/agent/src/debug.ts +66 -0
  33. package/bone/output/agent/src/events.ts +243 -0
  34. package/bone/output/agent/src/extensions.ts +54 -0
  35. package/bone/output/agent/src/failure_rules.ts +323 -0
  36. package/bone/output/agent/src/flows.ts +168 -0
  37. package/bone/output/agent/src/health.ts +43 -0
  38. package/bone/output/agent/src/index.ts +100 -0
  39. package/bone/output/agent/src/logger.ts +66 -0
  40. package/bone/output/agent/src/metrics.ts +75 -0
  41. package/bone/output/agent/src/migrate.ts +352 -0
  42. package/bone/output/agent/src/migration_diff.ts +108 -0
  43. package/bone/output/agent/src/notify.ts +125 -0
  44. package/bone/output/agent/src/routes/agent_instance.ts +234 -0
  45. package/bone/output/agent/src/routes/build_step.ts +105 -0
  46. package/bone/output/agent/src/routes/plan.ts +91 -0
  47. package/bone/output/agent/src/routes/task.ts +105 -0
  48. package/bone/output/agent/src/routes/tool_call.ts +166 -0
  49. package/bone/output/agent/src/schemas.ts +384 -0
  50. package/bone/output/agent/src/state_machines/agent_instance.ts +24 -0
  51. package/bone/output/agent/src/state_machines/build_step.ts +22 -0
  52. package/bone/output/agent/src/state_machines/plan.ts +22 -0
  53. package/bone/output/agent/src/state_machines/task.ts +22 -0
  54. package/bone/output/agent/src/state_machines/tool_call.ts +22 -0
  55. package/bone/output/agent/src/tests.ts +362 -0
  56. package/bone/output/agent/src/websocket.ts +201 -0
  57. package/bone/output/agent/tsconfig.json +25 -0
  58. package/bone/output/rag/.dockerignore +7 -0
  59. package/bone/output/rag/.env.example +36 -0
  60. package/bone/output/rag/.github/workflows/ci.yaml +58 -0
  61. package/bone/output/rag/Dockerfile +22 -0
  62. package/bone/output/rag/RAGDomain.bone.map +287 -0
  63. package/bone/output/rag/RAGDomain.postman_collection.json +923 -0
  64. package/bone/output/rag/README.md +47 -0
  65. package/bone/output/rag/admin/index.html +818 -0
  66. package/bone/output/rag/docker-compose.yaml +22 -0
  67. package/bone/output/rag/k8s/deployment.yaml +75 -0
  68. package/bone/output/rag/migrations/audit_log.sql +18 -0
  69. package/bone/output/rag/migrations/code_chunk.sql +34 -0
  70. package/bone/output/rag/migrations/code_file.sql +33 -0
  71. package/bone/output/rag/migrations/event_outbox.sql +31 -0
  72. package/bone/output/rag/migrations/indexing_job.sql +33 -0
  73. package/bone/output/rag/migrations/knowledge_base.sql +35 -0
  74. package/bone/output/rag/migrations/memory_entry.sql +34 -0
  75. package/bone/output/rag/openapi.yaml +1097 -0
  76. package/bone/output/rag/package.json +36 -0
  77. package/bone/output/rag/schema.graphql +245 -0
  78. package/bone/output/rag/sdk/client.ts +234 -0
  79. package/bone/output/rag/src/algorithms.ts +2 -0
  80. package/bone/output/rag/src/audit.ts +37 -0
  81. package/bone/output/rag/src/auth.ts +57 -0
  82. package/bone/output/rag/src/cron.ts +12 -0
  83. package/bone/output/rag/src/db.ts +32 -0
  84. package/bone/output/rag/src/debug.ts +66 -0
  85. package/bone/output/rag/src/events.ts +243 -0
  86. package/bone/output/rag/src/extensions.ts +350 -0
  87. package/bone/output/rag/src/failure_rules.ts +315 -0
  88. package/bone/output/rag/src/flows.ts +239 -0
  89. package/bone/output/rag/src/health.ts +43 -0
  90. package/bone/output/rag/src/index.ts +95 -0
  91. package/bone/output/rag/src/logger.ts +66 -0
  92. package/bone/output/rag/src/metrics.ts +75 -0
  93. package/bone/output/rag/src/migrate.ts +364 -0
  94. package/bone/output/rag/src/migration_diff.ts +108 -0
  95. package/bone/output/rag/src/notify.ts +99 -0
  96. package/bone/output/rag/src/routes/code_chunk.ts +75 -0
  97. package/bone/output/rag/src/routes/code_file.ts +101 -0
  98. package/bone/output/rag/src/routes/indexing_job.ts +87 -0
  99. package/bone/output/rag/src/routes/knowledge_base.ts +230 -0
  100. package/bone/output/rag/src/routes/memory_entry.ts +87 -0
  101. package/bone/output/rag/src/schemas.ts +394 -0
  102. package/bone/output/rag/src/state_machines/code_file.ts +23 -0
  103. package/bone/output/rag/src/state_machines/indexing_job.ts +22 -0
  104. package/bone/output/rag/src/state_machines/knowledge_base.ts +23 -0
  105. package/bone/output/rag/src/state_machines/memory_entry.ts +20 -0
  106. package/bone/output/rag/src/tests.ts +340 -0
  107. package/bone/output/rag/tsconfig.json +25 -0
  108. package/bone/output/session/.dockerignore +7 -0
  109. package/bone/output/session/.env.example +36 -0
  110. package/bone/output/session/.github/workflows/ci.yaml +58 -0
  111. package/bone/output/session/Dockerfile +22 -0
  112. package/bone/output/session/README.md +47 -0
  113. package/bone/output/session/SessionDomain.bone.map +350 -0
  114. package/bone/output/session/SessionDomain.postman_collection.json +958 -0
  115. package/bone/output/session/admin/index.html +667 -0
  116. package/bone/output/session/docker-compose.yaml +22 -0
  117. package/bone/output/session/k8s/deployment.yaml +75 -0
  118. package/bone/output/session/migrations/audit_log.sql +18 -0
  119. package/bone/output/session/migrations/event_outbox.sql +31 -0
  120. package/bone/output/session/migrations/message.sql +31 -0
  121. package/bone/output/session/migrations/part.sql +28 -0
  122. package/bone/output/session/migrations/permission.sql +28 -0
  123. package/bone/output/session/migrations/project.sql +28 -0
  124. package/bone/output/session/migrations/session.sql +38 -0
  125. package/bone/output/session/openapi.yaml +1101 -0
  126. package/bone/output/session/package.json +36 -0
  127. package/bone/output/session/schema.graphql +222 -0
  128. package/bone/output/session/sdk/client.ts +225 -0
  129. package/bone/output/session/src/algorithms.ts +2 -0
  130. package/bone/output/session/src/audit.ts +44 -0
  131. package/bone/output/session/src/auth.ts +57 -0
  132. package/bone/output/session/src/cron.ts +12 -0
  133. package/bone/output/session/src/db.ts +32 -0
  134. package/bone/output/session/src/debug.ts +66 -0
  135. package/bone/output/session/src/events.ts +270 -0
  136. package/bone/output/session/src/extensions.ts +215 -0
  137. package/bone/output/session/src/failure_rules.ts +284 -0
  138. package/bone/output/session/src/flows.ts +168 -0
  139. package/bone/output/session/src/health.ts +43 -0
  140. package/bone/output/session/src/index.ts +100 -0
  141. package/bone/output/session/src/logger.ts +66 -0
  142. package/bone/output/session/src/metrics.ts +75 -0
  143. package/bone/output/session/src/migrate.ts +332 -0
  144. package/bone/output/session/src/migration_diff.ts +108 -0
  145. package/bone/output/session/src/notify.ts +112 -0
  146. package/bone/output/session/src/routes/message.ts +93 -0
  147. package/bone/output/session/src/routes/part.ts +79 -0
  148. package/bone/output/session/src/routes/permission.ts +79 -0
  149. package/bone/output/session/src/routes/project.ts +79 -0
  150. package/bone/output/session/src/routes/session.ts +294 -0
  151. package/bone/output/session/src/schemas.ts +357 -0
  152. package/bone/output/session/src/state_machines/session.ts +23 -0
  153. package/bone/output/session/src/tests.ts +326 -0
  154. package/bone/output/session/src/websocket.ts +201 -0
  155. package/bone/output/session/tsconfig.json +25 -0
  156. package/bone/output/workspace/.dockerignore +7 -0
  157. package/bone/output/workspace/.env.example +36 -0
  158. package/bone/output/workspace/.github/workflows/ci.yaml +58 -0
  159. package/bone/output/workspace/Dockerfile +22 -0
  160. package/bone/output/workspace/README.md +45 -0
  161. package/bone/output/workspace/WorkspaceDomain.bone.map +189 -0
  162. package/bone/output/workspace/WorkspaceDomain.postman_collection.json +621 -0
  163. package/bone/output/workspace/admin/index.html +485 -0
  164. package/bone/output/workspace/docker-compose.yaml +22 -0
  165. package/bone/output/workspace/k8s/deployment.yaml +75 -0
  166. package/bone/output/workspace/migrations/audit_log.sql +18 -0
  167. package/bone/output/workspace/migrations/codebase.sql +34 -0
  168. package/bone/output/workspace/migrations/event_outbox.sql +31 -0
  169. package/bone/output/workspace/migrations/snapshot.sql +32 -0
  170. package/bone/output/workspace/migrations/workspace.sql +33 -0
  171. package/bone/output/workspace/openapi.yaml +721 -0
  172. package/bone/output/workspace/package.json +36 -0
  173. package/bone/output/workspace/schema.graphql +153 -0
  174. package/bone/output/workspace/sdk/client.ts +155 -0
  175. package/bone/output/workspace/src/algorithms.ts +2 -0
  176. package/bone/output/workspace/src/audit.ts +37 -0
  177. package/bone/output/workspace/src/auth.ts +57 -0
  178. package/bone/output/workspace/src/cron.ts +12 -0
  179. package/bone/output/workspace/src/db.ts +32 -0
  180. package/bone/output/workspace/src/debug.ts +66 -0
  181. package/bone/output/workspace/src/events.ts +243 -0
  182. package/bone/output/workspace/src/extensions.ts +44 -0
  183. package/bone/output/workspace/src/failure_rules.ts +153 -0
  184. package/bone/output/workspace/src/health.ts +43 -0
  185. package/bone/output/workspace/src/index.ts +89 -0
  186. package/bone/output/workspace/src/logger.ts +66 -0
  187. package/bone/output/workspace/src/metrics.ts +75 -0
  188. package/bone/output/workspace/src/migrate.ts +220 -0
  189. package/bone/output/workspace/src/migration_diff.ts +108 -0
  190. package/bone/output/workspace/src/notify.ts +73 -0
  191. package/bone/output/workspace/src/routes/codebase.ts +87 -0
  192. package/bone/output/workspace/src/routes/snapshot.ts +127 -0
  193. package/bone/output/workspace/src/routes/workspace.ts +190 -0
  194. package/bone/output/workspace/src/schemas.ts +231 -0
  195. package/bone/output/workspace/src/state_machines/codebase.ts +21 -0
  196. package/bone/output/workspace/src/state_machines/snapshot.ts +20 -0
  197. package/bone/output/workspace/src/state_machines/workspace.ts +21 -0
  198. package/bone/output/workspace/src/tests.ts +249 -0
  199. package/bone/output/workspace/tsconfig.json +25 -0
  200. package/compat/opencode_adapter.ts +410 -0
  201. package/package.json +69 -0
  202. package/scripts/check_benchmark_session.js +34 -0
  203. package/scripts/check_finish_event.js +24 -0
  204. package/scripts/check_parts.js +15 -0
  205. package/scripts/compile.js +79 -0
  206. package/scripts/copy_opencode.ps1 +53 -0
  207. package/scripts/create_functions.sql +129 -0
  208. package/scripts/migrate.js +85 -0
  209. package/scripts/migrate_from_opencode.ts +218 -0
  210. package/scripts/test_agent_loop.js +101 -0
  211. package/scripts/test_api.ps1 +116 -0
  212. package/scripts/test_context_builder.js +136 -0
  213. package/scripts/test_context_builder.ts +97 -0
  214. package/scripts/test_rag.js +189 -0
  215. package/scripts/test_stream_events.js +36 -0
  216. package/scripts/test_websocket_and_saga.js +216 -0
  217. package/src/cli.ts +475 -0
  218. package/src/config.ts +162 -0
  219. package/src/context_builder.ts +598 -0
  220. package/src/engine/account/account.sql.ts +39 -0
  221. package/src/engine/account/account.ts +456 -0
  222. package/src/engine/account/repo.ts +166 -0
  223. package/src/engine/account/schema.ts +99 -0
  224. package/src/engine/account/url.ts +8 -0
  225. package/src/engine/acp/README.md +174 -0
  226. package/src/engine/acp/agent.ts +1968 -0
  227. package/src/engine/acp/runtime.ts +22 -0
  228. package/src/engine/acp/session.ts +122 -0
  229. package/src/engine/acp/types.ts +24 -0
  230. package/src/engine/agent/agent.ts +463 -0
  231. package/src/engine/agent/generate.txt +75 -0
  232. package/src/engine/agent/prompt/compaction.txt +9 -0
  233. package/src/engine/agent/prompt/explore.txt +18 -0
  234. package/src/engine/agent/prompt/scout.txt +36 -0
  235. package/src/engine/agent/prompt/summary.txt +11 -0
  236. package/src/engine/agent/prompt/title.txt +44 -0
  237. package/src/engine/agent/subagent-permissions.ts +34 -0
  238. package/src/engine/auth/index.ts +96 -0
  239. package/src/engine/background/background/job.ts +200 -0
  240. package/src/engine/background/job.ts +200 -0
  241. package/src/engine/bus/bus-event.ts +45 -0
  242. package/src/engine/bus/global.ts +22 -0
  243. package/src/engine/bus/index.ts +203 -0
  244. package/src/engine/command/command/index.ts +181 -0
  245. package/src/engine/command/command/template/initialize.txt +66 -0
  246. package/src/engine/command/command/template/review.txt +101 -0
  247. package/src/engine/command/index.ts +181 -0
  248. package/src/engine/command/template/initialize.txt +66 -0
  249. package/src/engine/command/template/review.txt +101 -0
  250. package/src/engine/config/agent.ts +172 -0
  251. package/src/engine/config/attachment.ts +25 -0
  252. package/src/engine/config/command.ts +62 -0
  253. package/src/engine/config/config.ts +833 -0
  254. package/src/engine/config/console-state.ts +14 -0
  255. package/src/engine/config/entry-name.ts +16 -0
  256. package/src/engine/config/error.ts +23 -0
  257. package/src/engine/config/formatter.ts +13 -0
  258. package/src/engine/config/layout.ts +6 -0
  259. package/src/engine/config/lsp.ts +43 -0
  260. package/src/engine/config/managed.ts +71 -0
  261. package/src/engine/config/markdown.ts +96 -0
  262. package/src/engine/config/mcp.ts +56 -0
  263. package/src/engine/config/model-id.ts +5 -0
  264. package/src/engine/config/parse.ts +79 -0
  265. package/src/engine/config/paths.ts +45 -0
  266. package/src/engine/config/permission.ts +58 -0
  267. package/src/engine/config/plugin.ts +84 -0
  268. package/src/engine/config/provider.ts +111 -0
  269. package/src/engine/config/reference.ts +23 -0
  270. package/src/engine/config/server.ts +19 -0
  271. package/src/engine/config/skills.ts +14 -0
  272. package/src/engine/config/variable.ts +90 -0
  273. package/src/engine/control-plane/adapters/index.ts +41 -0
  274. package/src/engine/control-plane/adapters/worktree.ts +96 -0
  275. package/src/engine/control-plane/dev/README.md +19 -0
  276. package/src/engine/control-plane/dev/debug-workspace-plugin.ts +73 -0
  277. package/src/engine/control-plane/schema.ts +14 -0
  278. package/src/engine/control-plane/types.ts +59 -0
  279. package/src/engine/control-plane/util.ts +39 -0
  280. package/src/engine/control-plane/workspace-adapter-runtime.ts +51 -0
  281. package/src/engine/control-plane/workspace-context.ts +26 -0
  282. package/src/engine/control-plane/workspace.sql.ts +20 -0
  283. package/src/engine/control-plane/workspace.ts +1072 -0
  284. package/src/engine/data-migration.ts +161 -0
  285. package/src/engine/effect/app-runtime.ts +143 -0
  286. package/src/engine/effect/bootstrap-runtime.ts +29 -0
  287. package/src/engine/effect/bridge.ts +84 -0
  288. package/src/engine/effect/config-service.ts +67 -0
  289. package/src/engine/effect/instance-ref.ts +11 -0
  290. package/src/engine/effect/instance-registry.ts +12 -0
  291. package/src/engine/effect/instance-state.ts +72 -0
  292. package/src/engine/effect/promise.ts +17 -0
  293. package/src/engine/effect/run-service.ts +47 -0
  294. package/src/engine/effect/runner.ts +217 -0
  295. package/src/engine/effect/runtime-flags.ts +74 -0
  296. package/src/engine/effect/service-use.ts +38 -0
  297. package/src/engine/env/index.ts +37 -0
  298. package/src/engine/event-v2-bridge.ts +89 -0
  299. package/src/engine/file/file/ignore.ts +81 -0
  300. package/src/engine/file/file/index.ts +651 -0
  301. package/src/engine/file/file/protected.ts +59 -0
  302. package/src/engine/file/file/ripgrep.ts +481 -0
  303. package/src/engine/file/file/watcher.ts +167 -0
  304. package/src/engine/file/ignore.ts +81 -0
  305. package/src/engine/file/index.ts +651 -0
  306. package/src/engine/file/protected.ts +59 -0
  307. package/src/engine/file/ripgrep.ts +481 -0
  308. package/src/engine/file/watcher.ts +167 -0
  309. package/src/engine/format/format/formatter.ts +404 -0
  310. package/src/engine/format/format/index.ts +209 -0
  311. package/src/engine/format/formatter.ts +404 -0
  312. package/src/engine/format/index.ts +209 -0
  313. package/src/engine/git/git/index.ts +347 -0
  314. package/src/engine/git/index.ts +347 -0
  315. package/src/engine/id/id.ts +80 -0
  316. package/src/engine/ide/index.ts +70 -0
  317. package/src/engine/image/image/image.ts +176 -0
  318. package/src/engine/image/image.ts +176 -0
  319. package/src/engine/index.ts +251 -0
  320. package/src/engine/installation/index.ts +327 -0
  321. package/src/engine/lsp/client.ts +707 -0
  322. package/src/engine/lsp/diagnostic.ts +29 -0
  323. package/src/engine/lsp/language.ts +121 -0
  324. package/src/engine/lsp/launch.ts +21 -0
  325. package/src/engine/lsp/lsp/client.ts +707 -0
  326. package/src/engine/lsp/lsp/diagnostic.ts +29 -0
  327. package/src/engine/lsp/lsp/language.ts +121 -0
  328. package/src/engine/lsp/lsp/launch.ts +21 -0
  329. package/src/engine/lsp/lsp/lsp.ts +507 -0
  330. package/src/engine/lsp/lsp/server.ts +2064 -0
  331. package/src/engine/lsp/lsp.ts +507 -0
  332. package/src/engine/lsp/server.ts +2064 -0
  333. package/src/engine/mcp/auth.ts +146 -0
  334. package/src/engine/mcp/index.ts +958 -0
  335. package/src/engine/mcp/mcp/auth.ts +146 -0
  336. package/src/engine/mcp/mcp/index.ts +958 -0
  337. package/src/engine/mcp/mcp/oauth-callback.ts +232 -0
  338. package/src/engine/mcp/mcp/oauth-provider.ts +214 -0
  339. package/src/engine/mcp/oauth-callback.ts +232 -0
  340. package/src/engine/mcp/oauth-provider.ts +214 -0
  341. package/src/engine/node.ts +6 -0
  342. package/src/engine/patch/index.ts +689 -0
  343. package/src/engine/patch/patch/index.ts +689 -0
  344. package/src/engine/permission/arity.ts +163 -0
  345. package/src/engine/permission/evaluate.ts +15 -0
  346. package/src/engine/permission/index.ts +306 -0
  347. package/src/engine/permission/permission/arity.ts +163 -0
  348. package/src/engine/permission/permission/evaluate.ts +15 -0
  349. package/src/engine/permission/permission/index.ts +306 -0
  350. package/src/engine/permission/permission/schema.ts +13 -0
  351. package/src/engine/permission/schema.ts +13 -0
  352. package/src/engine/plugin/azure.ts +26 -0
  353. package/src/engine/plugin/cloudflare.ts +76 -0
  354. package/src/engine/plugin/codex.ts +622 -0
  355. package/src/engine/plugin/digitalocean.ts +411 -0
  356. package/src/engine/plugin/github-copilot/copilot.ts +394 -0
  357. package/src/engine/plugin/github-copilot/models.ts +196 -0
  358. package/src/engine/plugin/index.ts +295 -0
  359. package/src/engine/plugin/install.ts +439 -0
  360. package/src/engine/plugin/loader.ts +216 -0
  361. package/src/engine/plugin/meta.ts +188 -0
  362. package/src/engine/plugin/shared.ts +323 -0
  363. package/src/engine/project/bootstrap-service.ts +9 -0
  364. package/src/engine/project/bootstrap.ts +75 -0
  365. package/src/engine/project/instance-context.ts +24 -0
  366. package/src/engine/project/instance-layer.ts +11 -0
  367. package/src/engine/project/instance-runtime.ts +16 -0
  368. package/src/engine/project/instance-store.ts +193 -0
  369. package/src/engine/project/project.sql.ts +17 -0
  370. package/src/engine/project/project.ts +537 -0
  371. package/src/engine/project/schema.ts +13 -0
  372. package/src/engine/project/vcs.ts +405 -0
  373. package/src/engine/provider/auth.ts +225 -0
  374. package/src/engine/provider/error.ts +204 -0
  375. package/src/engine/provider/model-status.ts +8 -0
  376. package/src/engine/provider/provider.ts +1843 -0
  377. package/src/engine/provider/schema.ts +30 -0
  378. package/src/engine/provider/sdk/copilot/AGENTS.md +1 -0
  379. package/src/engine/provider/transform.ts +1376 -0
  380. package/src/engine/pty/index.ts +365 -0
  381. package/src/engine/pty/input.ts +24 -0
  382. package/src/engine/pty/pty/index.ts +365 -0
  383. package/src/engine/pty/pty/input.ts +24 -0
  384. package/src/engine/pty/pty/pty.bun.ts +26 -0
  385. package/src/engine/pty/pty/pty.node.ts +27 -0
  386. package/src/engine/pty/pty/pty.ts +25 -0
  387. package/src/engine/pty/pty/schema.ts +14 -0
  388. package/src/engine/pty/pty/ticket.ts +68 -0
  389. package/src/engine/pty/pty.bun.ts +26 -0
  390. package/src/engine/pty/pty.node.ts +27 -0
  391. package/src/engine/pty/pty.ts +25 -0
  392. package/src/engine/pty/schema.ts +14 -0
  393. package/src/engine/pty/ticket.ts +68 -0
  394. package/src/engine/question/index.ts +213 -0
  395. package/src/engine/question/question/index.ts +213 -0
  396. package/src/engine/question/question/schema.ts +10 -0
  397. package/src/engine/question/schema.ts +10 -0
  398. package/src/engine/reference/reference/reference.ts +241 -0
  399. package/src/engine/reference/reference/repository-cache.ts +147 -0
  400. package/src/engine/reference/reference.ts +241 -0
  401. package/src/engine/reference/repository-cache.ts +147 -0
  402. package/src/engine/session/compaction.ts +651 -0
  403. package/src/engine/session/compaction_logic.ts +120 -0
  404. package/src/engine/session/instruction.ts +238 -0
  405. package/src/engine/session/instruction_loader.ts +54 -0
  406. package/src/engine/session/llm.ts +459 -0
  407. package/src/engine/session/message-error.ts +14 -0
  408. package/src/engine/session/message-v2.ts +1202 -0
  409. package/src/engine/session/message.ts +146 -0
  410. package/src/engine/session/overflow.ts +32 -0
  411. package/src/engine/session/overflow_check.ts +46 -0
  412. package/src/engine/session/processor.ts +823 -0
  413. package/src/engine/session/prompt/anthropic.txt +105 -0
  414. package/src/engine/session/prompt/beast.txt +147 -0
  415. package/src/engine/session/prompt/build-switch.txt +5 -0
  416. package/src/engine/session/prompt/codex.txt +79 -0
  417. package/src/engine/session/prompt/copilot-gpt-5.txt +143 -0
  418. package/src/engine/session/prompt/default.txt +105 -0
  419. package/src/engine/session/prompt/gemini.txt +155 -0
  420. package/src/engine/session/prompt/gpt.txt +107 -0
  421. package/src/engine/session/prompt/kimi.txt +95 -0
  422. package/src/engine/session/prompt/max-steps.txt +16 -0
  423. package/src/engine/session/prompt/plan-reminder-anthropic.txt +67 -0
  424. package/src/engine/session/prompt/plan.txt +26 -0
  425. package/src/engine/session/prompt/trinity.txt +97 -0
  426. package/src/engine/session/prompt.ts +671 -0
  427. package/src/engine/session/provider_transform.ts +187 -0
  428. package/src/engine/session/retry.ts +200 -0
  429. package/src/engine/session/retry_logic.ts +65 -0
  430. package/src/engine/session/revert.ts +162 -0
  431. package/src/engine/session/run-state.ts +153 -0
  432. package/src/engine/session/schema.ts +26 -0
  433. package/src/engine/session/session.sql.ts +137 -0
  434. package/src/engine/session/session.ts +1011 -0
  435. package/src/engine/session/status.ts +94 -0
  436. package/src/engine/session/summary.ts +164 -0
  437. package/src/engine/session/system.ts +84 -0
  438. package/src/engine/session/system_prompt.ts +65 -0
  439. package/src/engine/session/todo.ts +81 -0
  440. package/src/engine/session/tool_registry.ts +162 -0
  441. package/src/engine/share/session.ts +61 -0
  442. package/src/engine/share/share-next.ts +376 -0
  443. package/src/engine/share/share.sql.ts +13 -0
  444. package/src/engine/shell/shell/shell.ts +215 -0
  445. package/src/engine/shell/shell.ts +215 -0
  446. package/src/engine/skill/discovery.ts +116 -0
  447. package/src/engine/skill/index.ts +336 -0
  448. package/src/engine/skill/prompt/customize-opencode.md +377 -0
  449. package/src/engine/skill/skill/discovery.ts +116 -0
  450. package/src/engine/skill/skill/index.ts +336 -0
  451. package/src/engine/skill/skill/prompt/customize-opencode.md +377 -0
  452. package/src/engine/snapshot/index.ts +762 -0
  453. package/src/engine/snapshot/snapshot/index.ts +762 -0
  454. package/src/engine/sync/README.md +179 -0
  455. package/src/engine/sync/event.sql.ts +17 -0
  456. package/src/engine/sync/index.ts +410 -0
  457. package/src/engine/sync/schema.ts +11 -0
  458. package/src/engine/temporary.ts +33 -0
  459. package/src/engine/tool/apply_patch.ts +313 -0
  460. package/src/engine/tool/apply_patch.txt +33 -0
  461. package/src/engine/tool/edit.ts +711 -0
  462. package/src/engine/tool/edit.txt +10 -0
  463. package/src/engine/tool/external-directory.ts +49 -0
  464. package/src/engine/tool/glob.ts +103 -0
  465. package/src/engine/tool/glob.txt +6 -0
  466. package/src/engine/tool/grep.ts +156 -0
  467. package/src/engine/tool/grep.txt +8 -0
  468. package/src/engine/tool/invalid.ts +21 -0
  469. package/src/engine/tool/json-schema.ts +164 -0
  470. package/src/engine/tool/lsp.ts +113 -0
  471. package/src/engine/tool/lsp.txt +24 -0
  472. package/src/engine/tool/mcp-websearch.ts +96 -0
  473. package/src/engine/tool/plan-enter.txt +14 -0
  474. package/src/engine/tool/plan-exit.txt +13 -0
  475. package/src/engine/tool/plan.ts +78 -0
  476. package/src/engine/tool/question.ts +44 -0
  477. package/src/engine/tool/question.txt +10 -0
  478. package/src/engine/tool/read.ts +337 -0
  479. package/src/engine/tool/read.txt +14 -0
  480. package/src/engine/tool/registry.ts +472 -0
  481. package/src/engine/tool/repo_clone.ts +80 -0
  482. package/src/engine/tool/repo_clone.txt +5 -0
  483. package/src/engine/tool/repo_overview.ts +279 -0
  484. package/src/engine/tool/repo_overview.txt +4 -0
  485. package/src/engine/tool/schema.ts +14 -0
  486. package/src/engine/tool/shell/id.ts +19 -0
  487. package/src/engine/tool/shell/prompt.ts +295 -0
  488. package/src/engine/tool/shell/shell.txt +77 -0
  489. package/src/engine/tool/shell.ts +647 -0
  490. package/src/engine/tool/skill.ts +75 -0
  491. package/src/engine/tool/skill.txt +5 -0
  492. package/src/engine/tool/task.ts +337 -0
  493. package/src/engine/tool/task.txt +58 -0
  494. package/src/engine/tool/task_status.ts +179 -0
  495. package/src/engine/tool/task_status.txt +13 -0
  496. package/src/engine/tool/todo.ts +57 -0
  497. package/src/engine/tool/todowrite.txt +167 -0
  498. package/src/engine/tool/tool/apply_patch.ts +313 -0
  499. package/src/engine/tool/tool/apply_patch.txt +33 -0
  500. package/src/engine/tool/tool/edit.ts +711 -0
  501. package/src/engine/tool/tool/edit.txt +10 -0
  502. package/src/engine/tool/tool/external-directory.ts +49 -0
  503. package/src/engine/tool/tool/glob.ts +103 -0
  504. package/src/engine/tool/tool/glob.txt +6 -0
  505. package/src/engine/tool/tool/grep.ts +156 -0
  506. package/src/engine/tool/tool/grep.txt +8 -0
  507. package/src/engine/tool/tool/invalid.ts +21 -0
  508. package/src/engine/tool/tool/json-schema.ts +164 -0
  509. package/src/engine/tool/tool/lsp.ts +113 -0
  510. package/src/engine/tool/tool/lsp.txt +24 -0
  511. package/src/engine/tool/tool/mcp-websearch.ts +96 -0
  512. package/src/engine/tool/tool/plan-enter.txt +14 -0
  513. package/src/engine/tool/tool/plan-exit.txt +13 -0
  514. package/src/engine/tool/tool/plan.ts +78 -0
  515. package/src/engine/tool/tool/question.ts +44 -0
  516. package/src/engine/tool/tool/question.txt +10 -0
  517. package/src/engine/tool/tool/read.ts +337 -0
  518. package/src/engine/tool/tool/read.txt +14 -0
  519. package/src/engine/tool/tool/registry.ts +472 -0
  520. package/src/engine/tool/tool/repo_clone.ts +80 -0
  521. package/src/engine/tool/tool/repo_clone.txt +5 -0
  522. package/src/engine/tool/tool/repo_overview.ts +279 -0
  523. package/src/engine/tool/tool/repo_overview.txt +4 -0
  524. package/src/engine/tool/tool/schema.ts +14 -0
  525. package/src/engine/tool/tool/shell/id.ts +19 -0
  526. package/src/engine/tool/tool/shell/prompt.ts +295 -0
  527. package/src/engine/tool/tool/shell/shell.txt +77 -0
  528. package/src/engine/tool/tool/shell.ts +647 -0
  529. package/src/engine/tool/tool/skill.ts +75 -0
  530. package/src/engine/tool/tool/skill.txt +5 -0
  531. package/src/engine/tool/tool/task.ts +337 -0
  532. package/src/engine/tool/tool/task.txt +58 -0
  533. package/src/engine/tool/tool/task_status.ts +179 -0
  534. package/src/engine/tool/tool/task_status.txt +13 -0
  535. package/src/engine/tool/tool/todo.ts +57 -0
  536. package/src/engine/tool/tool/todowrite.txt +167 -0
  537. package/src/engine/tool/tool/tool.ts +164 -0
  538. package/src/engine/tool/tool/truncate.ts +160 -0
  539. package/src/engine/tool/tool/truncation-dir.ts +4 -0
  540. package/src/engine/tool/tool/webfetch.ts +192 -0
  541. package/src/engine/tool/tool/webfetch.txt +13 -0
  542. package/src/engine/tool/tool/websearch.ts +143 -0
  543. package/src/engine/tool/tool/websearch.txt +14 -0
  544. package/src/engine/tool/tool/write.ts +104 -0
  545. package/src/engine/tool/tool/write.txt +8 -0
  546. package/src/engine/tool/tool.ts +164 -0
  547. package/src/engine/tool/truncate.ts +160 -0
  548. package/src/engine/tool/truncation-dir.ts +4 -0
  549. package/src/engine/tool/webfetch.ts +192 -0
  550. package/src/engine/tool/webfetch.txt +13 -0
  551. package/src/engine/tool/websearch.ts +143 -0
  552. package/src/engine/tool/websearch.txt +14 -0
  553. package/src/engine/tool/write.ts +104 -0
  554. package/src/engine/tool/write.txt +8 -0
  555. package/src/engine/util/archive.ts +17 -0
  556. package/src/engine/util/bom.ts +31 -0
  557. package/src/engine/util/data-url.ts +9 -0
  558. package/src/engine/util/defer.ts +10 -0
  559. package/src/engine/util/effect-http-client.ts +11 -0
  560. package/src/engine/util/error.ts +88 -0
  561. package/src/engine/util/filesystem.ts +252 -0
  562. package/src/engine/util/format.ts +20 -0
  563. package/src/engine/util/iife.ts +3 -0
  564. package/src/engine/util/lazy.ts +20 -0
  565. package/src/engine/util/local-context.ts +25 -0
  566. package/src/engine/util/locale.ts +86 -0
  567. package/src/engine/util/media.ts +26 -0
  568. package/src/engine/util/process.ts +176 -0
  569. package/src/engine/util/queue.ts +32 -0
  570. package/src/engine/util/record.ts +3 -0
  571. package/src/engine/util/repository.ts +158 -0
  572. package/src/engine/util/rpc.ts +66 -0
  573. package/src/engine/util/signal.ts +12 -0
  574. package/src/engine/util/timeout.ts +13 -0
  575. package/src/engine/util/token.ts +7 -0
  576. package/src/engine/util/util/archive.ts +17 -0
  577. package/src/engine/util/util/bom.ts +31 -0
  578. package/src/engine/util/util/data-url.ts +9 -0
  579. package/src/engine/util/util/defer.ts +10 -0
  580. package/src/engine/util/util/effect-http-client.ts +11 -0
  581. package/src/engine/util/util/error.ts +88 -0
  582. package/src/engine/util/util/filesystem.ts +252 -0
  583. package/src/engine/util/util/format.ts +20 -0
  584. package/src/engine/util/util/iife.ts +3 -0
  585. package/src/engine/util/util/lazy.ts +20 -0
  586. package/src/engine/util/util/local-context.ts +25 -0
  587. package/src/engine/util/util/locale.ts +86 -0
  588. package/src/engine/util/util/media.ts +26 -0
  589. package/src/engine/util/util/process.ts +176 -0
  590. package/src/engine/util/util/queue.ts +32 -0
  591. package/src/engine/util/util/record.ts +3 -0
  592. package/src/engine/util/util/repository.ts +158 -0
  593. package/src/engine/util/util/rpc.ts +66 -0
  594. package/src/engine/util/util/signal.ts +12 -0
  595. package/src/engine/util/util/timeout.ts +13 -0
  596. package/src/engine/util/util/token.ts +7 -0
  597. package/src/engine/util/util/which.ts +14 -0
  598. package/src/engine/util/util/wildcard.ts +59 -0
  599. package/src/engine/util/which.ts +14 -0
  600. package/src/engine/util/wildcard.ts +59 -0
  601. package/src/engine/worktree/index.ts +621 -0
  602. package/src/rag_worker.ts +519 -0
  603. package/src/server.ts +201 -0
  604. package/src/tui.ts +637 -0
  605. package/tsconfig.json +24 -0
@@ -0,0 +1,93 @@
1
+ // Generated by BoneScript compiler. DO NOT EDIT.
2
+ // Service: MessageService
3
+ import { Router, Request, Response } from "express";
4
+ import { v4 as uuid } from "uuid";
5
+ import { query, queryOne, execute, pool } from "../db";
6
+ import { eventBus } from "../events";
7
+ import { requireAuth, AuthContext } from "../auth";
8
+ import rateLimit from "express-rate-limit";
9
+ import { auditLog } from "../audit";
10
+ import { logger } from "../logger";
11
+ import { counter } from "../metrics";
12
+ import * as __algorithms from "../algorithms";
13
+ const { shortestPath, topologicalSort, binarySearch, bipartiteMatching, roundRobin, weightedAverage, percentile, rankBy, consistentHash } = __algorithms as any;
14
+
15
+ export const messagesRouter = Router();
16
+
17
+ // Rate limiter from policy declaration
18
+ const __routeRateLimit = rateLimit({ windowMs: 60000, max: 500, standardHeaders: true, legacyHeaders: false });
19
+
20
+ // CREATE
21
+ messagesRouter.post("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
22
+ try {
23
+ const id = uuid();
24
+ const { session_id, role, model_id, provider_id, tokens_input, tokens_output, cost_usd, error } = req.body;
25
+ const sql = `INSERT INTO messages (id, session_id, role, model_id, provider_id, tokens_input, tokens_output, cost_usd, error) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING *`;
26
+ const rows = await query(sql, [id, session_id, role, model_id, provider_id, tokens_input, tokens_output, cost_usd, error]);
27
+ counter("entity.created", { entity: "Message" });
28
+ res.status(201).json(rows[0]);
29
+ } catch (e: any) {
30
+ res.status(400).json({ error: { code: "CREATE_FAILED", message: e.message } });
31
+ }
32
+ });
33
+
34
+ // READ
35
+ messagesRouter.get("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
36
+ try {
37
+ const row = await queryOne(`SELECT * FROM messages WHERE id = $1`, [req.params.id]);
38
+ if (!row) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
39
+ res.json(row);
40
+ } catch (e: any) {
41
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
42
+ }
43
+ });
44
+
45
+ // LIST
46
+ messagesRouter.get("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
47
+ try {
48
+ const page = parseInt(req.query.page as string) || 1;
49
+ const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
50
+ const offset = (page - 1) * pageSize;
51
+ const rows = await query(`SELECT messages.*, row_to_json(session.*) as owner_session FROM messages LEFT JOIN sessions session ON messages.session_id = session.id ORDER BY messages.created_at DESC LIMIT $1 OFFSET $2`, [pageSize, offset]);
52
+ const [{ count }] = await query(`SELECT COUNT(*) as count FROM messages`);
53
+ res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
54
+ } catch (e: any) {
55
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
56
+ }
57
+ });
58
+
59
+ // UPDATE
60
+ messagesRouter.put("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
61
+ const fields = { ...req.body };
62
+ const sets = Object.keys(fields).map((k, i) => `${k} = $${i + 2}`).join(", ");
63
+ const values = Object.values(fields);
64
+ const sql = `UPDATE messages SET ${sets}, updated_at = NOW() WHERE id = $1 RETURNING *`;
65
+ const rows = await query(sql, [req.params.id, ...values]);
66
+ if (rows.length === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
67
+ res.json(rows[0]);
68
+ });
69
+
70
+ // DELETE
71
+ messagesRouter.delete("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
72
+ try {
73
+ const count = await execute(`DELETE FROM messages WHERE id = $1`, [req.params.id]);
74
+ if (count === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
75
+ res.status(204).send();
76
+ } catch (e: any) {
77
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
78
+ }
79
+ });
80
+
81
+ // RELATION: parts (has_many Part)
82
+ messagesRouter.get("/:id/parts", requireAuth, async (req: Request, res: Response) => {
83
+ try {
84
+ const page = parseInt(req.query.page as string) || 1;
85
+ const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
86
+ const offset = (page - 1) * pageSize;
87
+ const rows = await query(`SELECT * FROM parts WHERE message_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3`, [req.params.id, pageSize, offset]);
88
+ const [{ count }] = await query(`SELECT COUNT(*) as count FROM parts WHERE message_id = $1`, [req.params.id]);
89
+ res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
90
+ } catch (e: any) {
91
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
92
+ }
93
+ });
@@ -0,0 +1,79 @@
1
+ // Generated by BoneScript compiler. DO NOT EDIT.
2
+ // Service: PartService
3
+ import { Router, Request, Response } from "express";
4
+ import { v4 as uuid } from "uuid";
5
+ import { query, queryOne, execute, pool } from "../db";
6
+ import { eventBus } from "../events";
7
+ import { requireAuth, AuthContext } from "../auth";
8
+ import rateLimit from "express-rate-limit";
9
+ import { auditLog } from "../audit";
10
+ import { logger } from "../logger";
11
+ import { counter } from "../metrics";
12
+ import * as __algorithms from "../algorithms";
13
+ const { shortestPath, topologicalSort, binarySearch, bipartiteMatching, roundRobin, weightedAverage, percentile, rankBy, consistentHash } = __algorithms as any;
14
+
15
+ export const partsRouter = Router();
16
+
17
+ // Rate limiter from policy declaration
18
+ const __routeRateLimit = rateLimit({ windowMs: 60000, max: 500, standardHeaders: true, legacyHeaders: false });
19
+
20
+ // CREATE
21
+ partsRouter.post("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
22
+ try {
23
+ const id = uuid();
24
+ const { message_id, session_id, part_type, data, order_index } = req.body;
25
+ const sql = `INSERT INTO parts (id, message_id, session_id, part_type, data, order_index) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *`;
26
+ const rows = await query(sql, [id, message_id, session_id, part_type, data, order_index]);
27
+ counter("entity.created", { entity: "Part" });
28
+ res.status(201).json(rows[0]);
29
+ } catch (e: any) {
30
+ res.status(400).json({ error: { code: "CREATE_FAILED", message: e.message } });
31
+ }
32
+ });
33
+
34
+ // READ
35
+ partsRouter.get("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
36
+ try {
37
+ const row = await queryOne(`SELECT * FROM parts WHERE id = $1`, [req.params.id]);
38
+ if (!row) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
39
+ res.json(row);
40
+ } catch (e: any) {
41
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
42
+ }
43
+ });
44
+
45
+ // LIST
46
+ partsRouter.get("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
47
+ try {
48
+ const page = parseInt(req.query.page as string) || 1;
49
+ const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
50
+ const offset = (page - 1) * pageSize;
51
+ const rows = await query(`SELECT parts.*, row_to_json(message.*) as owner_message FROM parts LEFT JOIN messages message ON parts.message_id = message.id ORDER BY parts.created_at DESC LIMIT $1 OFFSET $2`, [pageSize, offset]);
52
+ const [{ count }] = await query(`SELECT COUNT(*) as count FROM parts`);
53
+ res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
54
+ } catch (e: any) {
55
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
56
+ }
57
+ });
58
+
59
+ // UPDATE
60
+ partsRouter.put("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
61
+ const fields = { ...req.body };
62
+ const sets = Object.keys(fields).map((k, i) => `${k} = $${i + 2}`).join(", ");
63
+ const values = Object.values(fields);
64
+ const sql = `UPDATE parts SET ${sets}, updated_at = NOW() WHERE id = $1 RETURNING *`;
65
+ const rows = await query(sql, [req.params.id, ...values]);
66
+ if (rows.length === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
67
+ res.json(rows[0]);
68
+ });
69
+
70
+ // DELETE
71
+ partsRouter.delete("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
72
+ try {
73
+ const count = await execute(`DELETE FROM parts WHERE id = $1`, [req.params.id]);
74
+ if (count === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
75
+ res.status(204).send();
76
+ } catch (e: any) {
77
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
78
+ }
79
+ });
@@ -0,0 +1,79 @@
1
+ // Generated by BoneScript compiler. DO NOT EDIT.
2
+ // Service: PermissionService
3
+ import { Router, Request, Response } from "express";
4
+ import { v4 as uuid } from "uuid";
5
+ import { query, queryOne, execute, pool } from "../db";
6
+ import { eventBus } from "../events";
7
+ import { requireAuth, AuthContext } from "../auth";
8
+ import rateLimit from "express-rate-limit";
9
+ import { auditLog } from "../audit";
10
+ import { logger } from "../logger";
11
+ import { counter } from "../metrics";
12
+ import * as __algorithms from "../algorithms";
13
+ const { shortestPath, topologicalSort, binarySearch, bipartiteMatching, roundRobin, weightedAverage, percentile, rankBy, consistentHash } = __algorithms as any;
14
+
15
+ export const permissionsRouter = Router();
16
+
17
+ // Rate limiter from policy declaration
18
+ const __routeRateLimit = rateLimit({ windowMs: 60000, max: 500, standardHeaders: true, legacyHeaders: false });
19
+
20
+ // CREATE
21
+ permissionsRouter.post("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
22
+ try {
23
+ const id = uuid();
24
+ const { session_id, tool_name, pattern, decision, expires_at } = req.body;
25
+ const sql = `INSERT INTO permissions (id, session_id, tool_name, pattern, decision, expires_at) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *`;
26
+ const rows = await query(sql, [id, session_id, tool_name, pattern, decision, expires_at]);
27
+ counter("entity.created", { entity: "Permission" });
28
+ res.status(201).json(rows[0]);
29
+ } catch (e: any) {
30
+ res.status(400).json({ error: { code: "CREATE_FAILED", message: e.message } });
31
+ }
32
+ });
33
+
34
+ // READ
35
+ permissionsRouter.get("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
36
+ try {
37
+ const row = await queryOne(`SELECT * FROM permissions WHERE id = $1`, [req.params.id]);
38
+ if (!row) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
39
+ res.json(row);
40
+ } catch (e: any) {
41
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
42
+ }
43
+ });
44
+
45
+ // LIST
46
+ permissionsRouter.get("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
47
+ try {
48
+ const page = parseInt(req.query.page as string) || 1;
49
+ const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
50
+ const offset = (page - 1) * pageSize;
51
+ const rows = await query(`SELECT * FROM permissions ORDER BY created_at DESC LIMIT $1 OFFSET $2`, [pageSize, offset]);
52
+ const [{ count }] = await query(`SELECT COUNT(*) as count FROM permissions`);
53
+ res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
54
+ } catch (e: any) {
55
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
56
+ }
57
+ });
58
+
59
+ // UPDATE
60
+ permissionsRouter.put("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
61
+ const fields = { ...req.body };
62
+ const sets = Object.keys(fields).map((k, i) => `${k} = $${i + 2}`).join(", ");
63
+ const values = Object.values(fields);
64
+ const sql = `UPDATE permissions SET ${sets}, updated_at = NOW() WHERE id = $1 RETURNING *`;
65
+ const rows = await query(sql, [req.params.id, ...values]);
66
+ if (rows.length === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
67
+ res.json(rows[0]);
68
+ });
69
+
70
+ // DELETE
71
+ permissionsRouter.delete("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
72
+ try {
73
+ const count = await execute(`DELETE FROM permissions WHERE id = $1`, [req.params.id]);
74
+ if (count === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
75
+ res.status(204).send();
76
+ } catch (e: any) {
77
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
78
+ }
79
+ });
@@ -0,0 +1,79 @@
1
+ // Generated by BoneScript compiler. DO NOT EDIT.
2
+ // Service: ProjectService
3
+ import { Router, Request, Response } from "express";
4
+ import { v4 as uuid } from "uuid";
5
+ import { query, queryOne, execute, pool } from "../db";
6
+ import { eventBus } from "../events";
7
+ import { requireAuth, AuthContext } from "../auth";
8
+ import rateLimit from "express-rate-limit";
9
+ import { auditLog } from "../audit";
10
+ import { logger } from "../logger";
11
+ import { counter } from "../metrics";
12
+ import * as __algorithms from "../algorithms";
13
+ const { shortestPath, topologicalSort, binarySearch, bipartiteMatching, roundRobin, weightedAverage, percentile, rankBy, consistentHash } = __algorithms as any;
14
+
15
+ export const projectsRouter = Router();
16
+
17
+ // Rate limiter from policy declaration
18
+ const __routeRateLimit = rateLimit({ windowMs: 60000, max: 500, standardHeaders: true, legacyHeaders: false });
19
+
20
+ // CREATE
21
+ projectsRouter.post("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
22
+ try {
23
+ const id = uuid();
24
+ const { root_commit_hash, worktree, vcs, name, sandboxes } = req.body;
25
+ const sql = `INSERT INTO projects (id, root_commit_hash, worktree, vcs, name, sandboxes) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *`;
26
+ const rows = await query(sql, [id, root_commit_hash, worktree, vcs, name, sandboxes]);
27
+ counter("entity.created", { entity: "Project" });
28
+ res.status(201).json(rows[0]);
29
+ } catch (e: any) {
30
+ res.status(400).json({ error: { code: "CREATE_FAILED", message: e.message } });
31
+ }
32
+ });
33
+
34
+ // READ
35
+ projectsRouter.get("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
36
+ try {
37
+ const row = await queryOne(`SELECT * FROM projects WHERE id = $1`, [req.params.id]);
38
+ if (!row) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
39
+ res.json(row);
40
+ } catch (e: any) {
41
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
42
+ }
43
+ });
44
+
45
+ // LIST
46
+ projectsRouter.get("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
47
+ try {
48
+ const page = parseInt(req.query.page as string) || 1;
49
+ const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
50
+ const offset = (page - 1) * pageSize;
51
+ const rows = await query(`SELECT * FROM projects ORDER BY created_at DESC LIMIT $1 OFFSET $2`, [pageSize, offset]);
52
+ const [{ count }] = await query(`SELECT COUNT(*) as count FROM projects`);
53
+ res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
54
+ } catch (e: any) {
55
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
56
+ }
57
+ });
58
+
59
+ // UPDATE
60
+ projectsRouter.put("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
61
+ const fields = { ...req.body };
62
+ const sets = Object.keys(fields).map((k, i) => `${k} = $${i + 2}`).join(", ");
63
+ const values = Object.values(fields);
64
+ const sql = `UPDATE projects SET ${sets}, updated_at = NOW() WHERE id = $1 RETURNING *`;
65
+ const rows = await query(sql, [req.params.id, ...values]);
66
+ if (rows.length === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
67
+ res.json(rows[0]);
68
+ });
69
+
70
+ // DELETE
71
+ projectsRouter.delete("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
72
+ try {
73
+ const count = await execute(`DELETE FROM projects WHERE id = $1`, [req.params.id]);
74
+ if (count === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
75
+ res.status(204).send();
76
+ } catch (e: any) {
77
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
78
+ }
79
+ });
@@ -0,0 +1,294 @@
1
+ // Generated by BoneScript compiler. DO NOT EDIT.
2
+ // Service: SessionService
3
+ import { Router, Request, Response } from "express";
4
+ import { v4 as uuid } from "uuid";
5
+ import { query, queryOne, execute, pool } from "../db";
6
+ import { eventBus } from "../events";
7
+ import { requireAuth, AuthContext } from "../auth";
8
+ import rateLimit from "express-rate-limit";
9
+ import { auditLog } from "../audit";
10
+ import { logger } from "../logger";
11
+ import { counter } from "../metrics";
12
+ import * as __algorithms from "../algorithms";
13
+ const { shortestPath, topologicalSort, binarySearch, bipartiteMatching, roundRobin, weightedAverage, percentile, rankBy, consistentHash } = __algorithms as any;
14
+
15
+ import { transitionSession, SESSION_INITIAL } from "../state_machines/session";
16
+
17
+ export const sessionsRouter = Router();
18
+
19
+ // Rate limiter from policy declaration
20
+ const __routeRateLimit = rateLimit({ windowMs: 60000, max: 500, standardHeaders: true, legacyHeaders: false });
21
+
22
+ // CREATE
23
+ sessionsRouter.post("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
24
+ try {
25
+ const id = uuid();
26
+ const { slug, project_id, workspace_id, parent_id, directory, title, version, share_url, summary_additions, summary_deletions, summary_files, summary_diffs, revert_data, permission_ruleset } = req.body;
27
+ const state = SESSION_INITIAL;
28
+ const sql = `INSERT INTO sessions (id, slug, project_id, workspace_id, parent_id, directory, title, version, share_url, summary_additions, summary_deletions, summary_files, summary_diffs, revert_data, permission_ruleset, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) RETURNING *`;
29
+ const rows = await query(sql, [id, slug, project_id, workspace_id, parent_id, directory, title, version, share_url, summary_additions, summary_deletions, summary_files, summary_diffs, revert_data, permission_ruleset, state]);
30
+ counter("entity.created", { entity: "Session" });
31
+ res.status(201).json(rows[0]);
32
+ } catch (e: any) {
33
+ res.status(400).json({ error: { code: "CREATE_FAILED", message: e.message } });
34
+ }
35
+ });
36
+
37
+ // READ
38
+ sessionsRouter.get("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
39
+ try {
40
+ const row = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.params.id]);
41
+ if (!row) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
42
+ res.json(row);
43
+ } catch (e: any) {
44
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
45
+ }
46
+ });
47
+
48
+ // LIST
49
+ sessionsRouter.get("/", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
50
+ try {
51
+ const page = parseInt(req.query.page as string) || 1;
52
+ const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
53
+ const offset = (page - 1) * pageSize;
54
+ const rows = await query(`SELECT * FROM sessions ORDER BY created_at DESC LIMIT $1 OFFSET $2`, [pageSize, offset]);
55
+ const [{ count }] = await query(`SELECT COUNT(*) as count FROM sessions`);
56
+ res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
57
+ } catch (e: any) {
58
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
59
+ }
60
+ });
61
+
62
+ // UPDATE
63
+ sessionsRouter.put("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
64
+ const fields = { ...req.body };
65
+ // State machine enforcement
66
+ if (fields.state !== undefined) {
67
+ const current = await queryOne<{ state: string }>(`SELECT state FROM sessions WHERE id = $1`, [req.params.id]);
68
+ if (!current) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
69
+ // Find the trigger for this state transition
70
+ const trigger = `${current.state}_to_${fields.state}`;
71
+ const tr = transitionSession(current.state as any, trigger);
72
+ if (!tr.ok) return res.status(422).json({ error: { code: "INVALID_TRANSITION", message: `Cannot transition from ${current.state} to ${fields.state}` } });
73
+ }
74
+ const sets = Object.keys(fields).map((k, i) => `${k} = $${i + 2}`).join(", ");
75
+ const values = Object.values(fields);
76
+ const sql = `UPDATE sessions SET ${sets}, updated_at = NOW() WHERE id = $1 RETURNING *`;
77
+ const rows = await query(sql, [req.params.id, ...values]);
78
+ if (rows.length === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
79
+ res.json(rows[0]);
80
+ });
81
+
82
+ // DELETE
83
+ sessionsRouter.delete("/:id", __routeRateLimit, requireAuth, async (req: Request, res: Response) => {
84
+ try {
85
+ const count = await execute(`DELETE FROM sessions WHERE id = $1`, [req.params.id]);
86
+ if (count === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
87
+ res.status(204).send();
88
+ } catch (e: any) {
89
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
90
+ }
91
+ });
92
+
93
+ // CAPABILITY: archive_session [transactional]
94
+ sessionsRouter.post("/archive-session", __routeRateLimit, requireAuth, auditLog("archive_session", "Session"), async (req: Request, res: Response) => {
95
+ const auth: AuthContext = (req as any).auth;
96
+ const __client = await pool.connect();
97
+ try {
98
+ await __client.query("BEGIN");
99
+ // Fetch entities
100
+ const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
101
+ if (!session) {
102
+ return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
103
+ }
104
+
105
+ // Preconditions
106
+ if (!([["active", "busy", "compacting"]].flat().includes(session?.state))) {
107
+ return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state in [\\\"active\\\", \\\"busy\\\", \\\"compacting\\\"]" } });
108
+ }
109
+
110
+ // Effects (applied in declaration order)
111
+ const __effect_0 = await query(`UPDATE sessions SET state = $1, updated_at = NOW() WHERE id = $2 RETURNING *`, ["archived", req.body.session_id || req.params.id]);
112
+ if (!__effect_0 || __effect_0.length === 0) {
113
+ throw new Error("Effect failed: session.state = \"archived\"");
114
+ }
115
+
116
+ // Emit events
117
+ await eventBus.publish("SessionStateChanged", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
118
+
119
+ res.json({ ok: true, action: "archive_session", entity: session });
120
+ await __client.query("COMMIT");
121
+ } catch (e: any) {
122
+ await __client.query("ROLLBACK");
123
+ res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
124
+ } finally {
125
+ __client.release();
126
+ }
127
+ });
128
+
129
+ // CAPABILITY: delete_session [transactional]
130
+ sessionsRouter.post("/delete-session", __routeRateLimit, requireAuth, auditLog("delete_session", "Session"), async (req: Request, res: Response) => {
131
+ const auth: AuthContext = (req as any).auth;
132
+ const __client = await pool.connect();
133
+ try {
134
+ await __client.query("BEGIN");
135
+ // Fetch entities
136
+ const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
137
+ if (!session) {
138
+ return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
139
+ }
140
+
141
+ // Preconditions
142
+ if (!(session?.state !== "deleted")) {
143
+ return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state != \\\"deleted\\\"" } });
144
+ }
145
+
146
+ // Effects (applied in declaration order)
147
+ const __effect_0 = await query(`UPDATE sessions SET state = $1, updated_at = NOW() WHERE id = $2 RETURNING *`, ["deleted", req.body.session_id || req.params.id]);
148
+ if (!__effect_0 || __effect_0.length === 0) {
149
+ throw new Error("Effect failed: session.state = \"deleted\"");
150
+ }
151
+
152
+ // Emit events
153
+ await eventBus.publish("SessionStateChanged", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
154
+
155
+ res.json({ ok: true, action: "delete_session", entity: session });
156
+ await __client.query("COMMIT");
157
+ } catch (e: any) {
158
+ await __client.query("ROLLBACK");
159
+ res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
160
+ } finally {
161
+ __client.release();
162
+ }
163
+ });
164
+
165
+ // CAPABILITY: add_message [transactional]
166
+ sessionsRouter.post("/add-message", __routeRateLimit, requireAuth, auditLog("add_message", "Session"), async (req: Request, res: Response) => {
167
+ const auth: AuthContext = (req as any).auth;
168
+ const __client = await pool.connect();
169
+ try {
170
+ await __client.query("BEGIN");
171
+ const { role, data } = req.body;
172
+
173
+ // Fetch entities
174
+ const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
175
+ if (!session) {
176
+ return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
177
+ }
178
+
179
+ // Preconditions
180
+ if (!([["active", "busy"]].flat().includes(session?.state))) {
181
+ return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state in [\\\"active\\\", \\\"busy\\\"]" } });
182
+ }
183
+ if (!([["user", "assistant", "system", "tool"]].flat().includes(role))) {
184
+ return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "role in [\\\"user\\\", \\\"assistant\\\", \\\"system\\\", \\\"tool\\\"]" } });
185
+ }
186
+
187
+ // Emit events
188
+ await eventBus.publish("MessageAdded", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
189
+
190
+ res.json({ ok: true, action: "add_message", entity: session });
191
+ await __client.query("COMMIT");
192
+ } catch (e: any) {
193
+ await __client.query("ROLLBACK");
194
+ res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
195
+ } finally {
196
+ __client.release();
197
+ }
198
+ });
199
+
200
+ // CAPABILITY: update_part
201
+ sessionsRouter.post("/update-part", __routeRateLimit, requireAuth, auditLog("update_part", "Session"), async (req: Request, res: Response) => {
202
+ const auth: AuthContext = (req as any).auth;
203
+ try {
204
+ // sync: realtime — execute then broadcast to WebSocket channel
205
+ const { message_id, part_id, data } = req.body;
206
+
207
+ // Fetch entities
208
+ const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
209
+ if (!session) {
210
+ return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
211
+ }
212
+
213
+ // Preconditions
214
+ if (!([["active", "busy"]].flat().includes(session?.state))) {
215
+ return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state in [\\\"active\\\", \\\"busy\\\"]" } });
216
+ }
217
+
218
+ // Emit events
219
+ await eventBus.publish("PartUpdated", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id);
220
+
221
+ res.json({ ok: true, action: "update_part", entity: session });
222
+ // Broadcast to WebSocket subscribers after successful execution
223
+ const { broadcastToChannel: _broadcast } = require("../websocket") as any;
224
+ if (typeof _broadcast === "function") {
225
+ _broadcast("SessionService", { type: "update_part", payload: req.body, actor: auth.actor_id });
226
+ }
227
+ } catch (e: any) {
228
+ res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
229
+ }
230
+ });
231
+
232
+ // CAPABILITY: compact_session [transactional]
233
+ sessionsRouter.post("/compact-session", __routeRateLimit, requireAuth, auditLog("compact_session", "Session"), async (req: Request, res: Response) => {
234
+ const auth: AuthContext = (req as any).auth;
235
+ const __client = await pool.connect();
236
+ try {
237
+ await __client.query("BEGIN");
238
+ // Fetch entities
239
+ const session = await queryOne(`SELECT * FROM sessions WHERE id = $1`, [req.body.session_id || req.params.id]);
240
+ if (!session) {
241
+ return res.status(404).json({ error: { code: "NOT_FOUND", message: "session not found" } });
242
+ }
243
+
244
+ // Preconditions
245
+ if (!(session?.state === "active")) {
246
+ return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "session.state == \\\"active\\\"" } });
247
+ }
248
+
249
+ // Effects (applied in declaration order)
250
+ const __effect_0 = await query(`UPDATE sessions SET state = $1, updated_at = NOW() WHERE id = $2 RETURNING *`, ["compacting", req.body.session_id || req.params.id]);
251
+ if (!__effect_0 || __effect_0.length === 0) {
252
+ throw new Error("Effect failed: session.state = \"compacting\"");
253
+ }
254
+
255
+ // Emit events
256
+ await eventBus.publish("SessionStateChanged", { session_id: session?.id, timestamp: new Date().toISOString(), actor_id: auth.actor_id }, "SessionService", auth.trace_id, __client);
257
+
258
+ res.json({ ok: true, action: "compact_session", entity: session });
259
+ await __client.query("COMMIT");
260
+ } catch (e: any) {
261
+ await __client.query("ROLLBACK");
262
+ res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
263
+ } finally {
264
+ __client.release();
265
+ }
266
+ });
267
+
268
+ // RELATION: messages (has_many Message)
269
+ sessionsRouter.get("/:id/messages", requireAuth, async (req: Request, res: Response) => {
270
+ try {
271
+ const page = parseInt(req.query.page as string) || 1;
272
+ const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
273
+ const offset = (page - 1) * pageSize;
274
+ const rows = await query(`SELECT * FROM messages WHERE session_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3`, [req.params.id, pageSize, offset]);
275
+ const [{ count }] = await query(`SELECT COUNT(*) as count FROM messages WHERE session_id = $1`, [req.params.id]);
276
+ res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
277
+ } catch (e: any) {
278
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
279
+ }
280
+ });
281
+
282
+ // RELATION: tool_calls (has_many ToolCall)
283
+ sessionsRouter.get("/:id/tool_calls", requireAuth, async (req: Request, res: Response) => {
284
+ try {
285
+ const page = parseInt(req.query.page as string) || 1;
286
+ const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
287
+ const offset = (page - 1) * pageSize;
288
+ const rows = await query(`SELECT * FROM tool_calls WHERE session_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3`, [req.params.id, pageSize, offset]);
289
+ const [{ count }] = await query(`SELECT COUNT(*) as count FROM tool_calls WHERE session_id = $1`, [req.params.id]);
290
+ res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
291
+ } catch (e: any) {
292
+ res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
293
+ }
294
+ });