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,218 @@
1
+ /**
2
+ * BoneCode: Migrate from OpenCode SQLite → BoneCode PostgreSQL
3
+ *
4
+ * Usage:
5
+ * npx ts-node scripts/migrate_from_opencode.ts --db ~/.local/share/opencode/opencode.db
6
+ *
7
+ * What it migrates:
8
+ * ProjectTable → projects
9
+ * SessionTable → sessions
10
+ * MessageTable → messages
11
+ * PartTable → parts
12
+ *
13
+ * Requires:
14
+ * - DATABASE_URL env var pointing to the BoneCode Postgres DB
15
+ * - The BoneCode migrations already run (npm run migrate)
16
+ * - better-sqlite3 installed: npm install better-sqlite3 @types/better-sqlite3
17
+ */
18
+
19
+ import * as path from "path";
20
+ import * as os from "os";
21
+ import { Pool } from "pg";
22
+
23
+ // Parse CLI args
24
+ const args = process.argv.slice(2);
25
+ const dbFlagIdx = args.indexOf("--db");
26
+ const sqlitePath = dbFlagIdx !== -1
27
+ ? path.resolve(args[dbFlagIdx + 1])
28
+ : path.join(os.homedir(), ".local", "share", "opencode", "opencode.db");
29
+
30
+ const dryRun = args.includes("--dry-run");
31
+
32
+ async function main() {
33
+ console.log(`[BoneCode Migration] Source: ${sqlitePath}`);
34
+ console.log(`[BoneCode Migration] Target: ${process.env.DATABASE_URL || "(DATABASE_URL not set)"}`);
35
+ if (dryRun) console.log("[BoneCode Migration] DRY RUN — no writes will occur");
36
+
37
+ // Load SQLite
38
+ let Database: any;
39
+ try {
40
+ Database = require("better-sqlite3");
41
+ } catch {
42
+ console.error("Error: better-sqlite3 not installed. Run: npm install better-sqlite3");
43
+ process.exit(1);
44
+ }
45
+
46
+ const sqlite = new Database(sqlitePath, { readonly: true });
47
+ const pg = new Pool({ connectionString: process.env.DATABASE_URL });
48
+
49
+ try {
50
+ await migrate(sqlite, pg, dryRun);
51
+ console.log("\n[BoneCode Migration] Complete.");
52
+ } finally {
53
+ sqlite.close();
54
+ await pg.end();
55
+ }
56
+ }
57
+
58
+ async function migrate(sqlite: any, pg: Pool, dryRun: boolean) {
59
+ const client = await pg.connect();
60
+ try {
61
+ if (!dryRun) await client.query("BEGIN");
62
+
63
+ // ─── Projects ─────────────────────────────────────────────────────────────
64
+ const projects = sqlite.prepare("SELECT * FROM ProjectTable").all();
65
+ console.log(`\nProjects: ${projects.length}`);
66
+ let projectsInserted = 0;
67
+
68
+ for (const p of projects) {
69
+ if (!dryRun) {
70
+ await client.query(
71
+ `INSERT INTO projects (id, root_commit_hash, worktree, vcs, name, sandboxes)
72
+ VALUES ($1, $2, $3, $4, $5, $6)
73
+ ON CONFLICT (id) DO NOTHING`,
74
+ [
75
+ p.id,
76
+ p.id, // root_commit_hash — OpenCode uses git root hash as project ID
77
+ p.worktree || "",
78
+ p.vcs || "git",
79
+ p.name || path.basename(p.worktree || "project"),
80
+ JSON.stringify(p.sandboxes || []),
81
+ ]
82
+ );
83
+ }
84
+ projectsInserted++;
85
+ }
86
+ console.log(` Inserted: ${projectsInserted}`);
87
+
88
+ // ─── Sessions ─────────────────────────────────────────────────────────────
89
+ const sessions = sqlite.prepare("SELECT * FROM SessionTable ORDER BY time_created ASC").all();
90
+ console.log(`\nSessions: ${sessions.length}`);
91
+ let sessionsInserted = 0;
92
+ let sessionsSkipped = 0;
93
+
94
+ for (const s of sessions) {
95
+ // Skip sessions whose project doesn't exist
96
+ const projectExists = projects.find((p: any) => p.id === s.project_id);
97
+ if (!projectExists) { sessionsSkipped++; continue; }
98
+
99
+ if (!dryRun) {
100
+ await client.query(
101
+ `INSERT INTO sessions (id, slug, project_id, parent_id, directory, title, version, state,
102
+ share_url, summary_additions, summary_deletions, summary_files, summary_diffs,
103
+ revert_data, permission_ruleset, created_at, updated_at)
104
+ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17)
105
+ ON CONFLICT (id) DO NOTHING`,
106
+ [
107
+ s.id,
108
+ s.slug || `session-${s.id.slice(0, 8)}`,
109
+ s.project_id,
110
+ s.parent_id || null,
111
+ s.directory || "",
112
+ s.title || "Imported Session",
113
+ s.version || "1.0.0",
114
+ s.time_archived ? "archived" : "active",
115
+ s.share_url || null,
116
+ s.summary_additions || null,
117
+ s.summary_deletions || null,
118
+ s.summary_files || null,
119
+ s.summary_diffs ? JSON.stringify(s.summary_diffs) : null,
120
+ s.revert ? JSON.stringify(s.revert) : null,
121
+ s.permission ? JSON.stringify(s.permission) : null,
122
+ new Date(s.time_created),
123
+ new Date(s.time_updated || s.time_created),
124
+ ]
125
+ );
126
+ }
127
+ sessionsInserted++;
128
+ }
129
+ console.log(` Inserted: ${sessionsInserted}, Skipped (orphan): ${sessionsSkipped}`);
130
+
131
+ // ─── Messages ─────────────────────────────────────────────────────────────
132
+ const messages = sqlite.prepare("SELECT * FROM MessageTable ORDER BY time_created ASC").all();
133
+ console.log(`\nMessages: ${messages.length}`);
134
+ let messagesInserted = 0;
135
+
136
+ for (const m of messages) {
137
+ const data = typeof m.data === "string" ? JSON.parse(m.data) : m.data || {};
138
+ if (!dryRun) {
139
+ await client.query(
140
+ `INSERT INTO messages (id, session_id, role, model_id, provider_id, tokens_input, tokens_output, cost_usd, created_at, updated_at)
141
+ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$9)
142
+ ON CONFLICT (id) DO NOTHING`,
143
+ [
144
+ m.id,
145
+ m.session_id,
146
+ data.role || "user",
147
+ data.modelID || null,
148
+ data.providerID || null,
149
+ data.tokens?.input || null,
150
+ data.tokens?.output || null,
151
+ data.cost || null,
152
+ new Date(m.time_created),
153
+ ]
154
+ );
155
+ }
156
+ messagesInserted++;
157
+ }
158
+ console.log(` Inserted: ${messagesInserted}`);
159
+
160
+ // ─── Parts ────────────────────────────────────────────────────────────────
161
+ const parts = sqlite.prepare("SELECT * FROM PartTable ORDER BY time_created ASC").all();
162
+ console.log(`\nParts: ${parts.length}`);
163
+ let partsInserted = 0;
164
+
165
+ for (let i = 0; i < parts.length; i++) {
166
+ const p = parts[i];
167
+ const data = typeof p.data === "string" ? JSON.parse(p.data) : p.data || {};
168
+ const partType = mapPartType(data.type || "text");
169
+
170
+ if (!dryRun) {
171
+ await client.query(
172
+ `INSERT INTO parts (id, message_id, session_id, part_type, data, order_index, created_at, updated_at)
173
+ VALUES ($1,$2,$3,$4,$5,$6,$7,$7)
174
+ ON CONFLICT (id) DO NOTHING`,
175
+ [
176
+ p.id,
177
+ p.message_id,
178
+ p.session_id,
179
+ partType,
180
+ JSON.stringify(data),
181
+ i, // approximate order
182
+ new Date(p.time_created),
183
+ ]
184
+ );
185
+ }
186
+ partsInserted++;
187
+ }
188
+ console.log(` Inserted: ${partsInserted}`);
189
+
190
+ if (!dryRun) {
191
+ await client.query("COMMIT");
192
+ console.log("\n[BoneCode Migration] Transaction committed.");
193
+ }
194
+ } catch (e: any) {
195
+ if (!dryRun) await client.query("ROLLBACK");
196
+ console.error("\n[BoneCode Migration] FAILED:", e.message);
197
+ throw e;
198
+ } finally {
199
+ client.release();
200
+ }
201
+ }
202
+
203
+ function mapPartType(openCodeType: string): string {
204
+ const map: Record<string, string> = {
205
+ text: "text",
206
+ "tool-invocation": "tool_invocation",
207
+ "tool-result": "tool_result",
208
+ file: "file",
209
+ reasoning: "reasoning",
210
+ "step-start": "step_start",
211
+ };
212
+ return map[openCodeType] || "text";
213
+ }
214
+
215
+ main().catch(e => {
216
+ console.error(e);
217
+ process.exit(1);
218
+ });
@@ -0,0 +1,101 @@
1
+ require("dotenv").config();
2
+ const jwt = require("jsonwebtoken");
3
+ const token = jwt.sign({ sub: "test-user" }, process.env.JWT_SECRET, { expiresIn: "1h" });
4
+ const auth = { Authorization: "Bearer " + token, "Content-Type": "application/json" };
5
+
6
+ let pass = 0, fail = 0;
7
+ const check = (label, ok, detail) => {
8
+ console.log((ok ? "PASS" : "FAIL"), label, detail || "");
9
+ ok ? pass++ : fail++;
10
+ };
11
+
12
+ (async () => {
13
+ console.log("\n[BoneCode Agent Loop Test]\n");
14
+
15
+ // Create session
16
+ let r = await fetch("http://localhost:3000/v2/session", {
17
+ method: "POST", headers: auth,
18
+ body: JSON.stringify({ title: "Agent Loop Test", directory: "C:/tmp" }),
19
+ });
20
+ const sess = await r.json();
21
+ check("Create session", r.status === 201, sess.id);
22
+ const sessionId = sess.id;
23
+
24
+ // Send prompt — the new agent loop handles multi-turn, tools, compaction, retry
25
+ const ctrl = new AbortController();
26
+ const timeout = setTimeout(() => ctrl.abort(), 45000);
27
+
28
+ let sseStarted = false;
29
+ let sseEvents = [];
30
+
31
+ try {
32
+ r = await fetch(`http://localhost:3000/v2/session/${sessionId}/prompt`, {
33
+ method: "POST", headers: auth,
34
+ body: JSON.stringify({
35
+ content: "What is 2+2? Answer in exactly one sentence.",
36
+ modelID: process.env.DEFAULT_MODEL,
37
+ providerID: process.env.DEFAULT_PROVIDER || "openai_compatible",
38
+ }),
39
+ signal: ctrl.signal,
40
+ });
41
+ clearTimeout(timeout);
42
+ sseStarted = r.status === 200 && r.headers.get("content-type")?.includes("text/event-stream");
43
+ check("Prompt returns SSE stream", sseStarted, `status=${r.status}`);
44
+
45
+ // Read a few SSE events
46
+ const reader = r.body.getReader();
47
+ const decoder = new TextDecoder();
48
+ let chunks = 0;
49
+ while (chunks < 10) {
50
+ const { value, done } = await reader.read();
51
+ if (done) break;
52
+ if (value) {
53
+ sseEvents.push(decoder.decode(value).trim());
54
+ chunks++;
55
+ }
56
+ }
57
+ reader.cancel();
58
+ } catch (e) {
59
+ clearTimeout(timeout);
60
+ if (e.name !== "AbortError") {
61
+ check("Prompt SSE stream", false, e.message);
62
+ }
63
+ }
64
+
65
+ check("SSE events received", sseEvents.length > 0, `count=${sseEvents.length}`);
66
+
67
+ // Wait for agent loop to complete
68
+ console.log(" Waiting for agent loop to complete...");
69
+ let messages = [];
70
+ for (let i = 0; i < 15; i++) {
71
+ await new Promise(res => setTimeout(res, 2000));
72
+ r = await fetch(`http://localhost:3000/v2/session/${sessionId}/message`, { headers: auth });
73
+ messages = await r.json();
74
+ // Look for an assistant message with text content
75
+ const hasAssistant = messages.some(m => m.role === "assistant");
76
+ if (hasAssistant) break;
77
+ process.stdout.write(` Waiting... (${messages.length} messages so far)\r`);
78
+ }
79
+ console.log("");
80
+
81
+ const userMsgs = messages.filter(m => m.role === "user");
82
+ const assistantMsgs = messages.filter(m => m.role === "assistant");
83
+ check("User message stored", userMsgs.length >= 1, `count=${userMsgs.length}`);
84
+ check("Assistant message stored", assistantMsgs.length >= 1, `count=${assistantMsgs.length}`);
85
+
86
+ if (assistantMsgs.length > 0) {
87
+ const lastAssistant = assistantMsgs[assistantMsgs.length - 1];
88
+ const textParts = (lastAssistant.parts || []).filter(p => p.type === "text");
89
+ const text = textParts.map(p => p.data?.text || p.text || "").join("");
90
+ check("Assistant has text response", text.length > 0, `text="${text.slice(0, 80)}"`);
91
+ }
92
+
93
+ // Check session state returned to active
94
+ r = await fetch(`http://localhost:3000/v2/session/${sessionId}`, { headers: auth });
95
+ const finalSession = await r.json();
96
+ check("Session state returned to active", finalSession.time?.archived === undefined, `state check`);
97
+
98
+ console.log("\n-------------------------------------");
99
+ console.log(`Results: ${pass} passed, ${fail} failed`);
100
+ if (fail > 0) process.exit(1);
101
+ })().catch(e => { console.error("FATAL:", e.message, e.stack); process.exit(1); });
@@ -0,0 +1,116 @@
1
+ $base = "http://localhost:3000"
2
+ $ct = @{"Content-Type"="application/json"}
3
+ $pass = 0; $fail = 0
4
+
5
+ function Test-Endpoint($label, $method, $url, $body=$null, $expectedStatus=200, $extraHeaders=$null) {
6
+ try {
7
+ $params = @{ Uri=$url; Method=$method; UseBasicParsing=$true; ErrorAction="Stop" }
8
+ $h = @{"Content-Type"="application/json"}
9
+ if ($extraHeaders) { $extraHeaders.GetEnumerator() | ForEach-Object { $h[$_.Key] = $_.Value } }
10
+ if ($body) { $params.Body = $body; $params.Headers = $h }
11
+ elseif ($extraHeaders) { $params.Headers = $h }
12
+ $r = Invoke-WebRequest @params
13
+ if ($r.StatusCode -eq $expectedStatus -or ($expectedStatus -eq 200 -and $r.StatusCode -lt 300)) {
14
+ Write-Host " PASS [$($r.StatusCode)] $label"
15
+ $script:pass++
16
+ return $r.Content
17
+ } else {
18
+ Write-Host " FAIL [$($r.StatusCode)] $label (expected $expectedStatus)"
19
+ $script:fail++
20
+ return $null
21
+ }
22
+ } catch {
23
+ $code = $_.Exception.Response.StatusCode.value__
24
+ if ($code -eq $expectedStatus) {
25
+ Write-Host " PASS [$code] $label"
26
+ $script:pass++
27
+ } else {
28
+ $msg = $_.Exception.Message
29
+ try { $msg = ([System.IO.StreamReader]$_.Exception.Response.GetResponseStream()).ReadToEnd() } catch {}
30
+ Write-Host " FAIL [$code] $label : $msg"
31
+ $script:fail++
32
+ }
33
+ return $null
34
+ }
35
+ }
36
+
37
+ Write-Host ""
38
+ Write-Host "[BoneCode API Tests]"
39
+ Write-Host ""
40
+
41
+ # ── Health ────────────────────────────────────────────────────────────────────
42
+ Test-Endpoint "GET /health" "GET" "$base/health" | Out-Null
43
+
44
+ # ── Generate a dev JWT token ──────────────────────────────────────────────────
45
+ # The server uses HS256 with the dev secret. Generate a minimal token.
46
+ $secret = "bonecode-dev-secret-do-not-use-in-production-at-all-ever"
47
+ $header = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('{"alg":"HS256","typ":"JWT"}')) -replace '=','' -replace '\+','-' -replace '/','_'
48
+ $payload = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("{`"sub`":`"test-user`",`"iat`":$(([DateTimeOffset]::UtcNow).ToUnixTimeSeconds())}")) -replace '=','' -replace '\+','-' -replace '/','_'
49
+ $sigInput = "$header.$payload"
50
+ $hmac = New-Object System.Security.Cryptography.HMACSHA256
51
+ $hmac.Key = [System.Text.Encoding]::UTF8.GetBytes($secret)
52
+ $sig = [Convert]::ToBase64String($hmac.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($sigInput))) -replace '=','' -replace '\+','-' -replace '/','_'
53
+ $jwt = "$sigInput.$sig"
54
+ $authHeaders = @{"Authorization"="Bearer $jwt"}
55
+ Write-Host " JWT generated for test-user"
56
+
57
+ # ── OpenCode v2 compat ────────────────────────────────────────────────────────
58
+ $sc = Test-Endpoint "POST /v2/session" "POST" "$base/v2/session" '{"title":"Test Session","directory":"C:/tmp"}' 201
59
+ $sessionId = ($sc | ConvertFrom-Json).id
60
+ Write-Host " Session ID: $sessionId"
61
+
62
+ Test-Endpoint "GET /v2/session" "GET" "$base/v2/session" | Out-Null
63
+ Test-Endpoint "GET /v2/session/:id" "GET" "$base/v2/session/$sessionId" | Out-Null
64
+ Test-Endpoint "GET /v2/session/:id/message" "GET" "$base/v2/session/$sessionId/message" | Out-Null
65
+ Test-Endpoint "GET /v2/provider" "GET" "$base/v2/provider" | Out-Null
66
+ Test-Endpoint "GET /v2/model" "GET" "$base/v2/model" | Out-Null
67
+ Test-Endpoint "GET /v2/config" "GET" "$base/v2/config" | Out-Null
68
+
69
+ # ── BoneCode domain routes (require JWT) ─────────────────────────────────────
70
+ Test-Endpoint "GET /projects (auth)" "GET" "$base/projects" $null 200 $authHeaders | Out-Null
71
+ Test-Endpoint "GET /sessions (auth)" "GET" "$base/sessions" $null 200 $authHeaders | Out-Null
72
+ Test-Endpoint "GET /messages (auth)" "GET" "$base/messages" $null 200 $authHeaders | Out-Null
73
+ Test-Endpoint "GET /agents (auth)" "GET" "$base/agents" $null 200 $authHeaders | Out-Null
74
+ Test-Endpoint "GET /tasks (auth)" "GET" "$base/tasks" $null 200 $authHeaders | Out-Null
75
+ Test-Endpoint "GET /tool-calls (auth)" "GET" "$base/tool-calls" $null 200 $authHeaders | Out-Null
76
+ Test-Endpoint "GET /knowledge-bases (auth)" "GET" "$base/knowledge-bases" $null 200 $authHeaders | Out-Null
77
+ Test-Endpoint "GET /code-files (auth)" "GET" "$base/code-files" $null 200 $authHeaders | Out-Null
78
+ Test-Endpoint "GET /memory-entries (auth)" "GET" "$base/memory-entries" $null 200 $authHeaders | Out-Null
79
+ Test-Endpoint "GET /indexing-jobs (auth)" "GET" "$base/indexing-jobs" $null 200 $authHeaders | Out-Null
80
+ Test-Endpoint "GET /workspaces (auth)" "GET" "$base/workspaces" $null 200 $authHeaders | Out-Null
81
+ Test-Endpoint "GET /snapshots (auth)" "GET" "$base/snapshots" $null 200 $authHeaders | Out-Null
82
+
83
+ # ── Create entities ───────────────────────────────────────────────────────────
84
+ $projJson = '{"root_commit_hash":"abc123","worktree":"C:/tmp","vcs":"git","name":"test-project","sandboxes":[]}'
85
+ $projResp = Test-Endpoint "POST /projects (auth)" "POST" "$base/projects" $projJson 201 $authHeaders
86
+ $projectId = ($projResp | ConvertFrom-Json).id
87
+ Write-Host " Project ID: $projectId"
88
+
89
+ $kbJson = "{`"project_id`":`"$projectId`",`"name`":`"test-kb`",`"embedding_model`":`"text-embedding-3-small`",`"chunk_strategy`":`"ast`",`"embedding_dimensions`":1536,`"chunk_size`":1500,`"chunk_overlap`":150,`"total_files`":0,`"total_chunks`":0}"
90
+ $kbResp = Test-Endpoint "POST /knowledge-bases (auth)" "POST" "$base/knowledge-bases" $kbJson 201 $authHeaders
91
+ $kbId = ($kbResp | ConvertFrom-Json).id
92
+ Write-Host " KB ID: $kbId"
93
+
94
+ # ── Test the local LLM endpoint ───────────────────────────────────────────────
95
+ Write-Host ""
96
+ Write-Host " Testing local LLM at http://10.0.0.20:1234/v1 ..."
97
+ try {
98
+ $llmBody = '{"model":"local-model","messages":[{"role":"user","content":"Say hello in one word."}],"max_tokens":10}'
99
+ $llmResp = Invoke-WebRequest -Uri "http://10.0.0.20:1234/v1/chat/completions" -Method POST -Body $llmBody -Headers @{"Content-Type"="application/json";"Authorization"="Bearer not-needed"} -UseBasicParsing -TimeoutSec 15 -ErrorAction Stop
100
+ $llmData = $llmResp.Content | ConvertFrom-Json
101
+ $reply = $llmData.choices[0].message.content
102
+ Write-Host " PASS [200] Local LLM responds: '$reply'"
103
+ $script:pass++
104
+ } catch {
105
+ Write-Host " FAIL Local LLM: $($_.Exception.Message)"
106
+ $script:fail++
107
+ }
108
+
109
+ # ── Cleanup ───────────────────────────────────────────────────────────────────
110
+ Test-Endpoint "DELETE /v2/session/:id" "DELETE" "$base/v2/session/$sessionId" $null 204 | Out-Null
111
+ Test-Endpoint "GET /nonexistent (404)" "GET" "$base/nonexistent-route-xyz" $null 404 | Out-Null
112
+
113
+ Write-Host ""
114
+ Write-Host "-------------------------------------"
115
+ Write-Host ("Results: " + $pass + " passed, " + $fail + " failed")
116
+ if ($fail -gt 0) { exit 1 }
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Test the no-embedding context builder against the BoneCode codebase itself.
3
+ */
4
+ require("dotenv").config();
5
+ const path = require("path");
6
+
7
+ // Point at the BoneCode repo as the test worktree
8
+ const WORKTREE = path.resolve(__dirname, "..");
9
+ const SESSION_ID = "test-session-" + Date.now();
10
+ const PROJECT_ID = "test-project";
11
+
12
+ let pass = 0, fail = 0;
13
+ const check = (label, ok, detail = "") => {
14
+ console.log((ok ? "\x1b[32mPASS\x1b[0m" : "\x1b[31mFAIL\x1b[0m"), label, detail || "");
15
+ ok ? pass++ : fail++;
16
+ };
17
+
18
+ (async () => {
19
+ console.log("\n[Context Builder Tests — No Embeddings]\n");
20
+
21
+ // Import the context builder
22
+ const { buildContext, formatContextForPrompt, extractSearchTerms } = (() => {
23
+ // We need to compile it first — use ts-node
24
+ const { execSync } = require("child_process");
25
+ const tsNode = path.join(WORKTREE, "node_modules/.bin/ts-node.cmd");
26
+ // Write a small wrapper
27
+ const wrapperPath = path.join(WORKTREE, "scripts/_ctx_test_wrapper.js");
28
+ require("fs").writeFileSync(wrapperPath, `
29
+ require('dotenv').config();
30
+ const {buildContext, formatContextForPrompt} = require('./src/context_builder');
31
+ module.exports = {buildContext, formatContextForPrompt};
32
+ `);
33
+ // Can't easily require TS from JS — test via the compiled approach
34
+ return null;
35
+ })();
36
+
37
+ // Test via ts-node subprocess instead
38
+ const { spawnSync } = require("child_process");
39
+ const tsNode = path.join(WORKTREE, "node_modules/.bin/ts-node.cmd");
40
+ const tscfg = path.join(WORKTREE, "tsconfig.json");
41
+
42
+ // Write test script
43
+ const testScript = path.join(WORKTREE, "scripts/_ctx_test.ts");
44
+ require("fs").writeFileSync(testScript, `
45
+ import { buildContext, formatContextForPrompt, extractSearchTerms } from "../src/context_builder";
46
+ import * as path from "path";
47
+ import * as assert from "assert";
48
+
49
+ const WORKTREE = path.resolve(__dirname, "..");
50
+
51
+ async function main() {
52
+ console.log("\\n=== Term Extraction ===");
53
+ const terms = extractSearchTerms("how does the agent loop handle tool calls and retries");
54
+ console.log("Terms:", terms);
55
+ assert.ok(terms.includes("agent"), "should extract 'agent'");
56
+ assert.ok(terms.includes("loop"), "should extract 'loop'");
57
+ assert.ok(terms.includes("tool"), "should extract 'tool'");
58
+ assert.ok(!terms.includes("how"), "should filter 'how'");
59
+ assert.ok(!terms.includes("the"), "should filter 'the'");
60
+ console.log("PASS term extraction");
61
+
62
+ console.log("\\n=== Git Recency ===");
63
+ const gitResult = await buildContext({
64
+ session_id: "test",
65
+ project_id: "test",
66
+ worktree: WORKTREE,
67
+ query: "agent loop retry",
68
+ max_chunks: 5,
69
+ max_chars: 5000,
70
+ });
71
+ console.log("Summary:", gitResult.summary);
72
+ console.log("Chunks:", gitResult.chunks.length);
73
+ console.log("Sources:", [...new Set(gitResult.chunks.map(c => c.source))].join(", "));
74
+ assert.ok(gitResult.chunks.length >= 0, "should return chunks array");
75
+ console.log("PASS git recency context");
76
+
77
+ console.log("\\n=== Instruction Files ===");
78
+ const instrResult = await buildContext({
79
+ session_id: "test",
80
+ project_id: "test",
81
+ worktree: WORKTREE,
82
+ query: "how to configure bonecode",
83
+ max_chunks: 3,
84
+ max_chars: 3000,
85
+ });
86
+ console.log("Instruction files:", instrResult.instruction_files);
87
+ console.log("PASS instruction file discovery");
88
+
89
+ console.log("\\n=== Format Output ===");
90
+ const formatted = formatContextForPrompt(gitResult, WORKTREE);
91
+ console.log("Formatted length:", formatted.length, "chars");
92
+ if (formatted.length > 0) {
93
+ assert.ok(formatted.includes("\\`\\`\\`") || formatted.includes("##"), "should contain code blocks or headers");
94
+ }
95
+ console.log("PASS format output");
96
+
97
+ console.log("\\n=== FTS Search (requires indexed code_chunks) ===");
98
+ // FTS will return empty if no code_chunks are indexed — that's fine
99
+ const ftsResult = await buildContext({
100
+ session_id: "test",
101
+ project_id: "test",
102
+ worktree: WORKTREE,
103
+ query: "RateLimiter isAllowed sliding window",
104
+ max_chunks: 5,
105
+ max_chars: 5000,
106
+ });
107
+ console.log("FTS chunks:", ftsResult.chunks.filter(c => c.source === "fts").length);
108
+ console.log("Git chunks:", ftsResult.chunks.filter(c => c.source === "git_recency").length);
109
+ console.log("PASS FTS search (graceful if no index)");
110
+
111
+ console.log("\\nAll context builder tests passed.");
112
+ }
113
+
114
+ main().catch(e => { console.error("FAIL:", e.message); process.exit(1); });
115
+ `);
116
+
117
+ const result = spawnSync(tsNode, ["--project", tscfg, "--transpile-only", testScript], {
118
+ timeout: 30000, encoding: "utf-8",
119
+ env: { ...process.env },
120
+ });
121
+
122
+ const output = (result.stdout || "") + (result.stderr || "");
123
+ console.log(output);
124
+
125
+ require("fs").unlinkSync(testScript);
126
+
127
+ if (result.status === 0 && output.includes("All context builder tests passed")) {
128
+ check("Context builder integration", true, "all strategies work");
129
+ } else {
130
+ check("Context builder integration", false, output.split("\n").find(l => l.includes("FAIL:") || l.includes("Error:")) || "unknown error");
131
+ }
132
+
133
+ console.log("\n-------------------------------------");
134
+ console.log(`Results: ${pass} passed, ${fail} failed`);
135
+ if (fail > 0) process.exit(1);
136
+ })().catch(e => { console.error("FATAL:", e.message); process.exit(1); });
@@ -0,0 +1,97 @@
1
+ import { buildContext, formatContextForPrompt } from "../src/context_builder";
2
+ import * as path from "path";
3
+ import * as assert from "assert";
4
+
5
+ const WORKTREE = path.resolve(__dirname, "..");
6
+
7
+ // Simple term extractor test (inline since we can't import the private function)
8
+ function extractSearchTerms(query: string): string[] {
9
+ const stopWords = new Set(["the","a","an","is","are","how","does","do","to","of","in","for","on","with","and","or","it","this","that","what","which","who","implement","create","make","build","write","add","fix","use","using","get","set","return","function","method","class","file","code","please","want","need","help","show","tell"]);
10
+ return query.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter(t => t.length >= 3 && !stopWords.has(t)).filter((t, i, arr) => arr.indexOf(t) === i).slice(0, 8);
11
+ }
12
+
13
+ async function main() {
14
+ console.log("\n=== Term Extraction ===");
15
+ const terms = extractSearchTerms("how does the agent loop handle tool calls and retries");
16
+ console.log("Terms:", terms);
17
+ assert.ok(terms.includes("agent"), "should extract 'agent'");
18
+ assert.ok(terms.includes("loop"), "should extract 'loop'");
19
+ assert.ok(terms.includes("tool"), "should extract 'tool'");
20
+ assert.ok(!terms.includes("how"), "should filter 'how'");
21
+ assert.ok(!terms.includes("the"), "should filter 'the'");
22
+ console.log("PASS term extraction");
23
+
24
+ console.log("\n=== Git Recency + Import Graph ===");
25
+ const gitResult = await buildContext({
26
+ session_id: "test",
27
+ project_id: "test",
28
+ worktree: WORKTREE,
29
+ query: "agent loop retry finishReason",
30
+ max_chunks: 8,
31
+ max_chars: 8000,
32
+ });
33
+ console.log("Summary:", gitResult.summary);
34
+ console.log("Total chunks:", gitResult.chunks.length);
35
+ const bySource: Record<string, number> = {};
36
+ for (const c of gitResult.chunks) bySource[c.source] = (bySource[c.source] || 0) + 1;
37
+ console.log("By source:", bySource);
38
+ if (gitResult.chunks.length > 0) {
39
+ console.log("Top file:", path.relative(WORKTREE, gitResult.chunks[0].file_path), "score:", gitResult.chunks[0].relevance_score.toFixed(1));
40
+ }
41
+ assert.ok(gitResult.chunks.length >= 0, "should return chunks array");
42
+ console.log("PASS git recency context");
43
+
44
+ console.log("\n=== Instruction Files ===");
45
+ const instrResult = await buildContext({
46
+ session_id: "test",
47
+ project_id: "test",
48
+ worktree: WORKTREE,
49
+ query: "configure bonecode settings",
50
+ max_chunks: 3,
51
+ max_chars: 3000,
52
+ });
53
+ console.log("Instruction files found:", instrResult.instruction_files.length);
54
+ instrResult.instruction_files.forEach(f => console.log(" -", path.relative(WORKTREE, f)));
55
+ console.log("PASS instruction file discovery");
56
+
57
+ console.log("\n=== Format Output ===");
58
+ const formatted = formatContextForPrompt(gitResult, WORKTREE);
59
+ console.log("Formatted length:", formatted.length, "chars");
60
+ if (formatted.length > 0) {
61
+ const hasCodeBlock = formatted.includes("```");
62
+ const hasHeader = formatted.includes("##");
63
+ console.log("Has code blocks:", hasCodeBlock, "Has headers:", hasHeader);
64
+ assert.ok(hasCodeBlock || hasHeader || formatted.length > 0, "should produce output");
65
+ }
66
+ console.log("PASS format output");
67
+
68
+ console.log("\n=== Session History (empty session — graceful) ===");
69
+ const sessionResult = await buildContext({
70
+ session_id: "nonexistent-session-id",
71
+ project_id: "test",
72
+ worktree: WORKTREE,
73
+ query: "rate limiter implementation",
74
+ max_chunks: 5,
75
+ max_chars: 5000,
76
+ });
77
+ console.log("Chunks with no session history:", sessionResult.chunks.length);
78
+ console.log("PASS graceful empty session");
79
+
80
+ console.log("\n=== FTS Search (requires indexed code_chunks) ===");
81
+ // FTS returns empty if no code_chunks indexed — that's fine, other strategies still work
82
+ const ftsResult = await buildContext({
83
+ session_id: "test",
84
+ project_id: "test",
85
+ worktree: WORKTREE,
86
+ query: "RateLimiter isAllowed sliding window timestamps",
87
+ max_chunks: 5,
88
+ max_chars: 5000,
89
+ });
90
+ const ftsSources = ftsResult.chunks.map(c => c.source);
91
+ console.log("Sources:", [...new Set(ftsSources)].join(", ") || "none");
92
+ console.log("PASS FTS search (graceful if no index)");
93
+
94
+ console.log("\nAll context builder tests passed.");
95
+ }
96
+
97
+ main().catch(e => { console.error("FAIL:", e.message, e.stack?.split("\n").slice(0,3).join(" | ")); process.exit(1); });