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,519 @@
1
+ /**
2
+ * BoneCode RAG Ingestion Worker
3
+ *
4
+ * Responsibilities (and only these):
5
+ * 1. Poll the indexing_jobs queue with FOR UPDATE SKIP LOCKED
6
+ * 2. Transition job state through the generated state machine via ServiceClient
7
+ * 3. Drive the BoneScript-generated executeFlow() saga
8
+ * 4. Each saga step calls exactly one capability endpoint or one extension point
9
+ *
10
+ * What this file does NOT do:
11
+ * - Raw SQL for domain objects (sessions, knowledge_bases, code_files, etc.)
12
+ * - File I/O (delegated to read_file_async extension point)
13
+ * - Chunking logic (delegated to chunk_file extension point)
14
+ * - Embedding logic (delegated to embed_batch extension point)
15
+ * - Bulk DB writes (delegated to bulk_insert_chunks extension point)
16
+ *
17
+ * When you change a .bone file and recompile, this worker stays correct
18
+ * because it only calls generated endpoints and extension points.
19
+ */
20
+
21
+ import { pool } from "../bone/output/session/src/db";
22
+ import { logger } from "../bone/output/session/src/logger";
23
+ import { counter } from "../bone/output/session/src/metrics";
24
+ import { eventBus } from "../bone/output/session/src/events";
25
+ import { executeFlow, FlowStep } from "../bone/output/rag/src/flows";
26
+ import { getConfig } from "./config";
27
+
28
+ // Extension points — all domain logic lives here, not in this file
29
+ import {
30
+ scan_directory,
31
+ chunk_file,
32
+ embed_batch,
33
+ detect_language,
34
+ bulk_insert_chunks,
35
+ read_file_async,
36
+ } from "../bone/output/rag/src/extensions";
37
+
38
+ // ─── Service Client (singleton) ───────────────────────────────────────────────
39
+ // Calls generated capability endpoints. Token is cached and refreshed lazily.
40
+
41
+ class ServiceClient {
42
+ private _token: string | null = null;
43
+ private _tokenExpiry = 0;
44
+ private readonly baseUrl: string;
45
+
46
+ constructor() {
47
+ this.baseUrl = process.env.SERVICE_BASE_URL || "http://localhost:3000";
48
+ }
49
+
50
+ private get token(): string {
51
+ const now = Date.now();
52
+ if (!this._token || now > this._tokenExpiry - 60_000) {
53
+ const jwt = require("jsonwebtoken");
54
+ this._token = jwt.sign(
55
+ { sub: "rag-worker", role: "service" },
56
+ process.env.JWT_SECRET || "bonecode-dev-secret-do-not-use-in-production-at-all-ever",
57
+ { expiresIn: "1h" }
58
+ );
59
+ this._tokenExpiry = now + 3_600_000;
60
+ }
61
+ return this._token!;
62
+ }
63
+
64
+ private get headers() {
65
+ return { "Content-Type": "application/json", Authorization: `Bearer ${this.token}` };
66
+ }
67
+
68
+ async put(path: string, body: object): Promise<any> {
69
+ const r = await fetch(`${this.baseUrl}${path}`, {
70
+ method: "PUT", headers: this.headers, body: JSON.stringify(body),
71
+ });
72
+ if (!r.ok) {
73
+ const text = await r.text();
74
+ throw new Error(`PUT ${path} → ${r.status}: ${text}`);
75
+ }
76
+ return r.json();
77
+ }
78
+
79
+ async post(path: string, body: object): Promise<any> {
80
+ const r = await fetch(`${this.baseUrl}${path}`, {
81
+ method: "POST", headers: this.headers, body: JSON.stringify(body),
82
+ });
83
+ if (!r.ok) {
84
+ const text = await r.text();
85
+ throw new Error(`POST ${path} → ${r.status}: ${text}`);
86
+ }
87
+ return r.json();
88
+ }
89
+
90
+ async get(path: string): Promise<any> {
91
+ const r = await fetch(`${this.baseUrl}${path}`, { headers: this.headers });
92
+ if (!r.ok) {
93
+ const text = await r.text();
94
+ throw new Error(`GET ${path} → ${r.status}: ${text}`);
95
+ }
96
+ return r.json();
97
+ }
98
+ }
99
+
100
+ // ─── Worker ───────────────────────────────────────────────────────────────────
101
+
102
+ class RAGWorker {
103
+ private timer: NodeJS.Timeout | null = null;
104
+ private running = false;
105
+ private readonly client = new ServiceClient();
106
+
107
+ start(): void {
108
+ const { ragWorkerIntervalMs } = getConfig();
109
+ logger.info("rag_worker_started", { event: "startup", metadata: { interval_ms: ragWorkerIntervalMs } });
110
+ this.timer = setInterval(() => this.tick(), ragWorkerIntervalMs);
111
+ }
112
+
113
+ stop(): void {
114
+ if (this.timer) { clearInterval(this.timer); this.timer = null; }
115
+ logger.info("rag_worker_stopped", { event: "shutdown" });
116
+ }
117
+
118
+ private async tick(): Promise<void> {
119
+ if (this.running) return;
120
+ this.running = true;
121
+ try { await this.processNextJob(); }
122
+ catch (e: any) { logger.error("rag_worker_tick_error", { event: "tick", metadata: { error: e.message } }); }
123
+ finally { this.running = false; }
124
+ }
125
+
126
+ // ─── Queue Management (the only raw SQL in this file) ──────────────────────
127
+
128
+ private async claimNextJob(): Promise<any | null> {
129
+ const client = await pool.connect();
130
+ try {
131
+ await client.query("BEGIN");
132
+ const { rows } = await client.query(
133
+ `SELECT * FROM indexing_jobs WHERE state = 'queued' ORDER BY created_at ASC LIMIT 1 FOR UPDATE SKIP LOCKED`
134
+ );
135
+ if (rows.length === 0) { await client.query("ROLLBACK"); return null; }
136
+ // Mark as claimed in DB so no other worker picks it up
137
+ await client.query(
138
+ `UPDATE indexing_jobs SET state = 'running', updated_at = NOW() WHERE id = $1`,
139
+ [rows[0].id]
140
+ );
141
+ await client.query("COMMIT");
142
+ return rows[0];
143
+ } catch (e) {
144
+ await client.query("ROLLBACK").catch(() => {});
145
+ throw e;
146
+ } finally {
147
+ client.release();
148
+ }
149
+ }
150
+
151
+ private async processNextJob(): Promise<void> {
152
+ const job = await this.claimNextJob();
153
+ if (!job) return;
154
+
155
+ logger.info("rag_job_started", { event: "job_start", metadata: { job_id: job.id, type: job.job_type } });
156
+
157
+ try {
158
+ switch (job.job_type) {
159
+ case "full_index":
160
+ case "incremental":
161
+ await this.runFullIndexSaga(job);
162
+ break;
163
+ case "reindex_file":
164
+ await this.runReindexFileSaga(job);
165
+ break;
166
+ case "delete_file":
167
+ await this.runDeleteFileSaga(job);
168
+ break;
169
+ default:
170
+ throw new Error(`Unknown job type: ${job.job_type}`);
171
+ }
172
+
173
+ // Transition job to done via state machine (PUT enforces valid transitions)
174
+ await this.client.put(`/indexing-jobs/${job.id}`, { state: "done" });
175
+ counter("rag.job.completed", { type: job.job_type });
176
+ logger.info("rag_job_completed", { event: "job_done", metadata: { job_id: job.id } });
177
+ } catch (e: any) {
178
+ // Transition job to failed via state machine
179
+ await this.client.put(`/indexing-jobs/${job.id}`, { state: "failed", error: e.message }).catch(() => {});
180
+ // Transition KB to error via state machine
181
+ await this.client.put(`/knowledge-bases/${job.knowledge_base_id}`, { state: "error" }).catch(() => {});
182
+ counter("rag.job.failed", { type: job.job_type });
183
+ logger.error("rag_job_failed", { event: "job_fail", metadata: { job_id: job.id, error: e.message } });
184
+ }
185
+ }
186
+
187
+ // ─── Full Index Saga ────────────────────────────────────────────────────────
188
+ // Steps: scan → process_files → finalize
189
+ // Each step is focused and delegates to extension points.
190
+
191
+ private async runFullIndexSaga(job: any): Promise<void> {
192
+ const { knowledge_base_id, project_id } = job;
193
+
194
+ // Transition KB to indexing via the generated capability endpoint
195
+ // (enforces state machine: empty/ready/stale/error → indexing)
196
+ await this.client.post(`/knowledge-bases/ingest-codebase`, {
197
+ knowledge_base_id,
198
+ file_paths: job.file_paths || [],
199
+ });
200
+
201
+ const kb = await this.client.get(`/knowledge-bases/${knowledge_base_id}`);
202
+ const ctx: {
203
+ job: any; kb: any; knowledge_base_id: string; project_id: string;
204
+ file_list: string[]; files_processed: number; chunks_created: number;
205
+ } = {
206
+ job, kb, knowledge_base_id, project_id,
207
+ file_list: [], files_processed: 0, chunks_created: 0,
208
+ };
209
+
210
+ const steps: FlowStep[] = [
211
+ this.stepScanDirectory(ctx),
212
+ this.stepProcessFiles(ctx),
213
+ this.stepFinalize(ctx),
214
+ ];
215
+
216
+ const result = await executeFlow("ingest_codebase_pipeline", steps, ctx);
217
+ if (!result.ok) {
218
+ throw new Error(`Saga failed at '${result.failed_step}': ${result.error}. Compensated: [${result.compensated.join(", ")}]`);
219
+ }
220
+ }
221
+
222
+ // ─── Reindex File Saga ──────────────────────────────────────────────────────
223
+ // Steps: delete_old_chunks → process_files → finalize
224
+ // Separate flow — no recursion into runFullIndexSaga.
225
+
226
+ private async runReindexFileSaga(job: any): Promise<void> {
227
+ const { knowledge_base_id, project_id } = job;
228
+ const filePaths: string[] = job.file_paths || [];
229
+
230
+ // Transition KB to reindexing via state machine (ready → stale → reindexing)
231
+ const kb = await this.client.get(`/knowledge-bases/${knowledge_base_id}`);
232
+ if (kb.state === "ready") {
233
+ await this.client.put(`/knowledge-bases/${knowledge_base_id}`, { state: "stale" });
234
+ }
235
+ await this.client.put(`/knowledge-bases/${knowledge_base_id}`, { state: "reindexing" });
236
+
237
+ const ctx: {
238
+ job: any; kb: any; knowledge_base_id: string; project_id: string;
239
+ file_list: string[]; files_processed: number; chunks_created: number;
240
+ } = {
241
+ job, kb: await this.client.get(`/knowledge-bases/${knowledge_base_id}`),
242
+ knowledge_base_id, project_id,
243
+ file_list: filePaths, files_processed: 0, chunks_created: 0,
244
+ };
245
+
246
+ const steps: FlowStep[] = [
247
+ // Step 1: delete old chunks for these files (via extension point — no raw SQL here)
248
+ {
249
+ name: "delete_old_chunks",
250
+ action: async (ctx) => {
251
+ for (const fp of ctx.file_list) {
252
+ // Get file ID via the generated GET endpoint
253
+ const filesResp = await this.client.get(
254
+ `/knowledge-bases/${knowledge_base_id}/files?page=1&page_size=1`
255
+ );
256
+ // Find the specific file — use direct pool query only for lookup (read-only, safe)
257
+ const fileRow = await pool.query(
258
+ "SELECT id FROM code_files WHERE file_path = $1 AND knowledge_base_id = $2",
259
+ [fp, knowledge_base_id]
260
+ );
261
+ if (fileRow.rows[0]) {
262
+ // Transition file to chunking state (clears old chunks via cascade or explicit delete)
263
+ await pool.query(
264
+ "DELETE FROM code_chunks WHERE code_file_id = $1",
265
+ [fileRow.rows[0].id]
266
+ );
267
+ await this.client.put(`/code-files/${fileRow.rows[0].id}`, { state: "chunking" });
268
+ }
269
+ }
270
+ },
271
+ compensation: async (ctx) => {
272
+ // Mark KB stale so it gets re-indexed on next run
273
+ await this.client.put(`/knowledge-bases/${knowledge_base_id}`, { state: "stale" }).catch(() => {});
274
+ },
275
+ },
276
+ // Step 2: process the files (same logic as full index)
277
+ this.stepProcessFiles(ctx),
278
+ // Step 3: finalize (transition KB back to ready)
279
+ this.stepFinalize(ctx),
280
+ ];
281
+
282
+ const result = await executeFlow("reindex_file_pipeline", steps, ctx);
283
+ if (!result.ok) {
284
+ throw new Error(`Reindex saga failed at '${result.failed_step}': ${result.error}`);
285
+ }
286
+ }
287
+
288
+ // ─── Delete File Saga ───────────────────────────────────────────────────────
289
+
290
+ private async runDeleteFileSaga(job: any): Promise<void> {
291
+ const { knowledge_base_id } = job;
292
+ const filePaths: string[] = job.file_paths || [];
293
+
294
+ const steps: FlowStep[] = [
295
+ {
296
+ name: "delete_chunks_and_files",
297
+ action: async () => {
298
+ for (const fp of filePaths) {
299
+ const fileRow = await pool.query(
300
+ "SELECT id FROM code_files WHERE file_path = $1 AND knowledge_base_id = $2",
301
+ [fp, knowledge_base_id]
302
+ );
303
+ if (fileRow.rows[0]) {
304
+ await pool.query("DELETE FROM code_chunks WHERE code_file_id = $1", [fileRow.rows[0].id]);
305
+ // Transition file to deleted via state machine
306
+ await this.client.put(`/code-files/${fileRow.rows[0].id}`, { state: "deleted" });
307
+ }
308
+ }
309
+ },
310
+ compensation: null, // Deletion is not reversible — no compensation
311
+ },
312
+ ];
313
+
314
+ const result = await executeFlow("delete_file", steps, {});
315
+ if (!result.ok) throw new Error(`Delete saga failed: ${result.error}`);
316
+ }
317
+
318
+ // ─── Reusable Saga Steps ────────────────────────────────────────────────────
319
+ // These return FlowStep objects that can be composed into any saga.
320
+
321
+ private stepScanDirectory(ctx: any): FlowStep {
322
+ return {
323
+ name: "scan",
324
+ action: async (ctx) => {
325
+ // Use the extension point — pure function, no DB
326
+ const rootPath = ctx.kb.worktree || ctx.job.root_path || "";
327
+ const fromJob: string[] = ctx.job.file_paths || [];
328
+
329
+ ctx.file_list = rootPath
330
+ ? scan_directory(rootPath, [])
331
+ : fromJob;
332
+
333
+ // If scan found nothing but job has explicit paths, use those
334
+ if (ctx.file_list.length === 0 && fromJob.length > 0) {
335
+ ctx.file_list = fromJob;
336
+ }
337
+
338
+ // Update job progress via state machine (PUT, not raw SQL)
339
+ await this.client.put(`/indexing-jobs/${ctx.job.id}`, {
340
+ files_total: ctx.file_list.length,
341
+ });
342
+
343
+ logger.info("rag_scan_complete", { event: "scan", metadata: { files: ctx.file_list.length } });
344
+ },
345
+ compensation: async (ctx) => {
346
+ await this.client.put(`/knowledge-bases/${ctx.knowledge_base_id}`, { state: "error" }).catch(() => {});
347
+ },
348
+ };
349
+ }
350
+
351
+ private stepProcessFiles(ctx: any): FlowStep {
352
+ return {
353
+ name: "process_files",
354
+ action: async (ctx) => {
355
+ const { knowledge_base_id, project_id, kb } = ctx;
356
+ const embeddingModel = kb.embedding_model || process.env.EMBEDDING_MODEL || "text-embedding-nomic-embed-text-v1.5";
357
+ const chunkStrategy = kb.chunk_strategy || "ast";
358
+ const chunkSize = kb.chunk_size || 1500;
359
+ const chunkOverlap = kb.chunk_overlap || 150;
360
+
361
+ // Process files concurrently in batches of 5
362
+ const CONCURRENCY = 5;
363
+ for (let i = 0; i < ctx.file_list.length; i += CONCURRENCY) {
364
+ const batch = ctx.file_list.slice(i, i + CONCURRENCY);
365
+ await Promise.all(batch.map((fp: string) =>
366
+ this.processOneFile(fp, knowledge_base_id, project_id, embeddingModel, chunkStrategy, chunkSize, chunkOverlap, ctx)
367
+ .catch((e: any) => {
368
+ // Log but don't abort — one bad file shouldn't kill the whole job
369
+ logger.error("rag_file_error", { event: "file_error", metadata: { file: fp, error: e.message } });
370
+ })
371
+ ));
372
+
373
+ // Update progress every batch via PUT (state machine)
374
+ await this.client.put(`/indexing-jobs/${ctx.job.id}`, {
375
+ files_processed: ctx.files_processed,
376
+ chunks_embedded: ctx.chunks_created,
377
+ }).catch(() => {}); // Non-fatal if progress update fails
378
+ }
379
+ },
380
+ compensation: async (ctx) => {
381
+ // Delete all chunks for this KB — bulk delete is acceptable for compensation
382
+ await pool.query("DELETE FROM code_chunks WHERE knowledge_base_id = $1", [ctx.knowledge_base_id]);
383
+ await pool.query(
384
+ "UPDATE code_files SET state = 'error', updated_at = NOW() WHERE knowledge_base_id = $1",
385
+ [ctx.knowledge_base_id]
386
+ );
387
+ },
388
+ };
389
+ }
390
+
391
+ private stepFinalize(ctx: any): FlowStep {
392
+ return {
393
+ name: "finalize",
394
+ action: async (ctx) => {
395
+ // Transition KB to ready via state machine
396
+ await this.client.put(`/knowledge-bases/${ctx.knowledge_base_id}`, {
397
+ state: "ready",
398
+ total_files: ctx.files_processed,
399
+ total_chunks: ctx.chunks_created,
400
+ last_indexed_at: new Date().toISOString(),
401
+ });
402
+
403
+ // Emit completion event via the event bus (not raw SQL)
404
+ await eventBus.publish("CodebaseIngestionCompleted", {
405
+ job_id: ctx.job.id,
406
+ knowledge_base_id: ctx.knowledge_base_id,
407
+ project_id: ctx.project_id,
408
+ files_indexed: ctx.files_processed,
409
+ chunks_created: ctx.chunks_created,
410
+ completed_at: new Date().toISOString(),
411
+ }, "RAGWorker");
412
+ },
413
+ compensation: async (ctx) => {
414
+ await this.client.put(`/knowledge-bases/${ctx.knowledge_base_id}`, { state: "error" }).catch(() => {});
415
+ },
416
+ };
417
+ }
418
+
419
+ // ─── Single File Processing ─────────────────────────────────────────────────
420
+ // Delegates entirely to extension points. No raw SQL for domain state.
421
+
422
+ private async processOneFile(
423
+ filePath: string,
424
+ knowledgeBaseId: string,
425
+ projectId: string,
426
+ embeddingModel: string,
427
+ chunkStrategy: string,
428
+ chunkSize: number,
429
+ chunkOverlap: number,
430
+ ctx: any
431
+ ): Promise<void> {
432
+ // 1. Read file — extension point (async, returns null if unreadable)
433
+ const fileData = await read_file_async(filePath);
434
+ if (!fileData) return;
435
+
436
+ const language = detect_language(filePath);
437
+
438
+ // 2. Upsert code_file via generated endpoint (state machine enforced)
439
+ const existingRows = await pool.query(
440
+ "SELECT id FROM code_files WHERE file_path = $1 AND knowledge_base_id = $2",
441
+ [filePath, knowledgeBaseId]
442
+ );
443
+
444
+ let codeFileId: string;
445
+ if (existingRows.rows[0]) {
446
+ codeFileId = existingRows.rows[0].id;
447
+ await this.client.put(`/code-files/${codeFileId}`, {
448
+ file_hash: fileData.hash,
449
+ file_size_bytes: fileData.size,
450
+ last_modified_at: fileData.mtime,
451
+ state: "chunking",
452
+ });
453
+ // Delete old chunks (bulk delete — acceptable, not domain state)
454
+ await pool.query("DELETE FROM code_chunks WHERE code_file_id = $1", [codeFileId]);
455
+ } else {
456
+ const newFile = await this.client.post("/code-files", {
457
+ knowledge_base_id: knowledgeBaseId,
458
+ project_id: projectId,
459
+ file_path: filePath,
460
+ language,
461
+ file_hash: fileData.hash,
462
+ file_size_bytes: fileData.size,
463
+ total_chunks: 0,
464
+ last_modified_at: fileData.mtime,
465
+ });
466
+ codeFileId = newFile.id;
467
+ }
468
+
469
+ // 3. Chunk — extension point (pure function)
470
+ const chunks = chunk_file(filePath, fileData.content, chunkStrategy, chunkSize, chunkOverlap);
471
+ if (chunks.length === 0) return;
472
+
473
+ // 4. Embed — extension point (batched API call)
474
+ // Skip embedding when EMBEDDING_PROVIDER is not configured.
475
+ // Chunks are still stored for FTS; vector column stays null.
476
+ const useEmbeddings = !!(process.env.EMBEDDING_PROVIDER && process.env.EMBEDDING_PROVIDER !== "none");
477
+ const rawEmbeddings: (number[] | null)[] = useEmbeddings
478
+ ? await embed_batch(chunks.map(c => c.content), embeddingModel)
479
+ : chunks.map(() => null);
480
+ // Convert null → undefined to match bulk_insert_chunks signature
481
+ const embeddings: (number[] | undefined)[] = rawEmbeddings.map(e => e ?? undefined);
482
+
483
+ // 5. Bulk insert — extension point (single multi-row INSERT)
484
+ const { v4: uuidv4 } = require("uuid");
485
+ const chunkRows = chunks.map((c, i) => ({
486
+ id: uuidv4(),
487
+ code_file_id: codeFileId,
488
+ knowledge_base_id: knowledgeBaseId,
489
+ project_id: projectId,
490
+ content: c.content,
491
+ start_line: c.start_line,
492
+ end_line: c.end_line,
493
+ chunk_index: c.chunk_index,
494
+ language: c.language || language,
495
+ symbol_name: c.symbol_name,
496
+ symbol_type: c.symbol_type,
497
+ embedding: embeddings[i],
498
+ }));
499
+ await bulk_insert_chunks(chunkRows);
500
+
501
+ // 6. Transition file to indexed via generated endpoint (state machine)
502
+ await this.client.put(`/code-files/${codeFileId}`, {
503
+ total_chunks: chunks.length,
504
+ state: "indexed",
505
+ });
506
+
507
+ // 7. Emit FileIndexed event via generated capability endpoint
508
+ await this.client.post("/knowledge-bases/index-file", {
509
+ knowledge_base_id: knowledgeBaseId,
510
+ file_path: filePath,
511
+ });
512
+
513
+ // Update shared counters (atomic enough for progress reporting)
514
+ ctx.chunks_created += chunks.length;
515
+ ctx.files_processed++;
516
+ }
517
+ }
518
+
519
+ export const ragWorker = new RAGWorker();