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,176 @@
1
+ import { type ChildProcess } from "child_process"
2
+ import launch from "cross-spawn"
3
+ import { buffer } from "node:stream/consumers"
4
+ import { errorMessage } from "./error"
5
+
6
+ export type Stdio = "inherit" | "pipe" | "ignore"
7
+ export type Shell = boolean | string
8
+
9
+ export interface Options {
10
+ cwd?: string
11
+ env?: NodeJS.ProcessEnv | null
12
+ stdin?: Stdio
13
+ stdout?: Stdio
14
+ stderr?: Stdio
15
+ shell?: Shell
16
+ abort?: AbortSignal
17
+ kill?: NodeJS.Signals | number
18
+ timeout?: number
19
+ }
20
+
21
+ export interface RunOptions extends Omit<Options, "stdout" | "stderr"> {
22
+ nothrow?: boolean
23
+ }
24
+
25
+ export interface Result {
26
+ code: number
27
+ stdout: Buffer
28
+ stderr: Buffer
29
+ }
30
+
31
+ export interface TextResult extends Result {
32
+ text: string
33
+ }
34
+
35
+ export class RunFailedError extends Error {
36
+ readonly cmd: string[]
37
+ readonly code: number
38
+ readonly stdout: Buffer
39
+ readonly stderr: Buffer
40
+
41
+ constructor(cmd: string[], code: number, stdout: Buffer, stderr: Buffer) {
42
+ const text = stderr.toString().trim()
43
+ super(
44
+ text
45
+ ? `Command failed with code ${code}: ${cmd.join(" ")}\n${text}`
46
+ : `Command failed with code ${code}: ${cmd.join(" ")}`,
47
+ )
48
+ this.name = "ProcessRunFailedError"
49
+ this.cmd = [...cmd]
50
+ this.code = code
51
+ this.stdout = stdout
52
+ this.stderr = stderr
53
+ }
54
+ }
55
+
56
+ export type Child = ChildProcess & { exited: Promise<number> }
57
+
58
+ export function spawn(cmd: string[], opts: Options = {}): Child {
59
+ if (cmd.length === 0) throw new Error("Command is required")
60
+ opts.abort?.throwIfAborted()
61
+
62
+ const proc = launch(cmd[0], cmd.slice(1), {
63
+ cwd: opts.cwd,
64
+ shell: opts.shell,
65
+ env: opts.env === null ? {} : opts.env ? { ...process.env, ...opts.env } : undefined,
66
+ stdio: [opts.stdin ?? "ignore", opts.stdout ?? "ignore", opts.stderr ?? "ignore"],
67
+ windowsHide: process.platform === "win32",
68
+ })
69
+
70
+ let closed = false
71
+ let timer: ReturnType<typeof setTimeout> | undefined
72
+
73
+ const abort = () => {
74
+ if (closed) return
75
+ if (proc.exitCode !== null || proc.signalCode !== null) return
76
+ closed = true
77
+
78
+ proc.kill(opts.kill ?? "SIGTERM")
79
+
80
+ const ms = opts.timeout ?? 5_000
81
+ if (ms <= 0) return
82
+ timer = setTimeout(() => proc.kill("SIGKILL"), ms)
83
+ }
84
+
85
+ const exited = new Promise<number>((resolve, reject) => {
86
+ const done = () => {
87
+ opts.abort?.removeEventListener("abort", abort)
88
+ if (timer) clearTimeout(timer)
89
+ }
90
+
91
+ proc.once("exit", (code, signal) => {
92
+ done()
93
+ resolve(code ?? (signal ? 1 : 0))
94
+ })
95
+
96
+ proc.once("error", (error) => {
97
+ done()
98
+ reject(error)
99
+ })
100
+ })
101
+ void exited.catch(() => undefined)
102
+
103
+ if (opts.abort) {
104
+ opts.abort.addEventListener("abort", abort, { once: true })
105
+ if (opts.abort.aborted) abort()
106
+ }
107
+
108
+ const child = proc as Child
109
+ child.exited = exited
110
+ return child
111
+ }
112
+
113
+ export async function run(cmd: string[], opts: RunOptions = {}): Promise<Result> {
114
+ const proc = spawn(cmd, {
115
+ cwd: opts.cwd,
116
+ env: opts.env,
117
+ stdin: opts.stdin,
118
+ shell: opts.shell,
119
+ abort: opts.abort,
120
+ kill: opts.kill,
121
+ timeout: opts.timeout,
122
+ stdout: "pipe",
123
+ stderr: "pipe",
124
+ })
125
+
126
+ if (!proc.stdout || !proc.stderr) throw new Error("Process output not available")
127
+
128
+ const out = await Promise.all([proc.exited, buffer(proc.stdout), buffer(proc.stderr)])
129
+ .then(([code, stdout, stderr]) => ({
130
+ code,
131
+ stdout,
132
+ stderr,
133
+ }))
134
+ .catch((err: unknown) => {
135
+ if (!opts.nothrow) throw err
136
+ return {
137
+ code: 1,
138
+ stdout: Buffer.alloc(0),
139
+ stderr: Buffer.from(errorMessage(err)),
140
+ }
141
+ })
142
+ if (out.code === 0 || opts.nothrow) return out
143
+ throw new RunFailedError(cmd, out.code, out.stdout, out.stderr)
144
+ }
145
+
146
+ // Duplicated in `packages/sdk/js/src/process.ts` because the SDK cannot import
147
+ // `opencode` without creating a cycle. Keep both copies in sync.
148
+ export async function stop(proc: ChildProcess) {
149
+ if (proc.exitCode !== null || proc.signalCode !== null) return
150
+
151
+ if (process.platform !== "win32" || !proc.pid) {
152
+ proc.kill()
153
+ return
154
+ }
155
+
156
+ const out = await run(["taskkill", "/pid", String(proc.pid), "/T", "/F"], {
157
+ nothrow: true,
158
+ })
159
+
160
+ if (out.code === 0) return
161
+ proc.kill()
162
+ }
163
+
164
+ export async function text(cmd: string[], opts: RunOptions = {}): Promise<TextResult> {
165
+ const out = await run(cmd, opts)
166
+ return {
167
+ ...out,
168
+ text: out.stdout.toString(),
169
+ }
170
+ }
171
+
172
+ export async function lines(cmd: string[], opts: RunOptions = {}): Promise<string[]> {
173
+ return (await text(cmd, opts)).text.split(/\r?\n/).filter(Boolean)
174
+ }
175
+
176
+ export * as Process from "./process"
@@ -0,0 +1,32 @@
1
+ export class AsyncQueue<T> implements AsyncIterable<T> {
2
+ private queue: T[] = []
3
+ private resolvers: ((value: T) => void)[] = []
4
+
5
+ push(item: T) {
6
+ const resolve = this.resolvers.shift()
7
+ if (resolve) resolve(item)
8
+ else this.queue.push(item)
9
+ }
10
+
11
+ async next(): Promise<T> {
12
+ if (this.queue.length > 0) return this.queue.shift()!
13
+ return new Promise((resolve) => this.resolvers.push(resolve))
14
+ }
15
+
16
+ async *[Symbol.asyncIterator]() {
17
+ while (true) yield await this.next()
18
+ }
19
+ }
20
+
21
+ export async function work<T>(concurrency: number, items: T[], fn: (item: T) => Promise<void>) {
22
+ const pending = [...items]
23
+ await Promise.all(
24
+ Array.from({ length: concurrency }, async () => {
25
+ while (true) {
26
+ const item = pending.pop()
27
+ if (item === undefined) return
28
+ await fn(item)
29
+ }
30
+ }),
31
+ )
32
+ }
@@ -0,0 +1,3 @@
1
+ export function isRecord(value: unknown): value is Record<string, unknown> {
2
+ return !!value && typeof value === "object" && !Array.isArray(value)
3
+ }
@@ -0,0 +1,158 @@
1
+ import path from "path"
2
+ import { fileURLToPath } from "url"
3
+ import { Global } from "@opencode-ai/core/global"
4
+
5
+ export type Reference = {
6
+ host: string
7
+ path: string
8
+ segments: string[]
9
+ owner?: string
10
+ repo: string
11
+ remote: string
12
+ label: string
13
+ protocol?: string
14
+ }
15
+
16
+ function normalize(input: string) {
17
+ return input
18
+ .trim()
19
+ .replace(/^git\+/, "")
20
+ .replace(/#.*$/, "")
21
+ .replace(/\/+$/, "")
22
+ }
23
+
24
+ function trimGitSuffix(input: string) {
25
+ return input.replace(/\.git$/, "")
26
+ }
27
+
28
+ function parts(input: string) {
29
+ return input
30
+ .split("/")
31
+ .map((item) => trimGitSuffix(item.trim()))
32
+ .filter(Boolean)
33
+ }
34
+
35
+ function safeHost(input: string) {
36
+ return Boolean(input) && !input.startsWith("-") && !/[\s/\\]/.test(input)
37
+ }
38
+
39
+ function safeSegment(input: string) {
40
+ return input !== "." && input !== ".." && !input.includes(":") && !/[\s/\\]/.test(input)
41
+ }
42
+
43
+ function hostLike(input: string) {
44
+ return input.includes(".") || input.includes(":") || input === "localhost"
45
+ }
46
+
47
+ function withSlash(input: string) {
48
+ return input.endsWith("/") ? input : `${input}/`
49
+ }
50
+
51
+ function githubRemote(pathname: string) {
52
+ const base = process.env.OPENCODE_REPO_CLONE_GITHUB_BASE_URL
53
+ if (!base) return `https://github.com/${pathname}.git`
54
+ return new URL(`${pathname}.git`, withSlash(base)).href
55
+ }
56
+
57
+ function build(input: { host: string; segments: string[]; remote?: string; protocol?: string }) {
58
+ const segments = input.segments.map(trimGitSuffix).filter(Boolean)
59
+ if (!safeHost(input.host) || !segments.length || segments.some((segment) => !safeSegment(segment))) return null
60
+ const pathname = segments.join("/")
61
+ const repo = segments[segments.length - 1]
62
+ const host = input.host.toLowerCase()
63
+ return {
64
+ host,
65
+ path: pathname,
66
+ segments,
67
+ owner: segments.length === 2 ? segments[0] : undefined,
68
+ repo,
69
+ remote: input.remote ?? (host === "github.com" ? githubRemote(pathname) : `https://${host}/${pathname}.git`),
70
+ label: host === "github.com" && segments.length === 2 ? pathname : `${host}/${pathname}`,
71
+ protocol: input.protocol,
72
+ } satisfies Reference
73
+ }
74
+
75
+ function buildFile(input: { url: URL; remote: string }) {
76
+ const filePath = path.normalize(fileURLToPath(input.url))
77
+ const segments = filePath.split(/[\\/]+/).filter(Boolean)
78
+ if (!segments.length) return null
79
+ return {
80
+ host: "file",
81
+ path: filePath,
82
+ segments: segments.map((segment) => segment.replace(/:$/, "")),
83
+ owner: undefined,
84
+ repo: trimGitSuffix(segments[segments.length - 1]),
85
+ remote: input.remote,
86
+ label: filePath,
87
+ protocol: "file:",
88
+ } satisfies Reference
89
+ }
90
+
91
+ export function parseRepositoryReference(input: string) {
92
+ const cleaned = normalize(input)
93
+ if (!cleaned) return null
94
+
95
+ const githubPrefixed = cleaned.match(/^github:([^/\s]+)\/([^/\s]+)$/)
96
+ if (githubPrefixed) return build({ host: "github.com", segments: [githubPrefixed[1], githubPrefixed[2]] })
97
+
98
+ if (!cleaned.includes("://")) {
99
+ const scp = cleaned.match(/^(?:[^@/\s]+@)?([^:/\s]+):(.+)$/)
100
+ if (scp) return build({ host: scp[1], segments: parts(scp[2]), remote: cleaned })
101
+
102
+ const direct = parts(cleaned)
103
+ if (direct.length >= 2 && hostLike(direct[0])) {
104
+ return build({ host: direct[0], segments: direct.slice(1) })
105
+ }
106
+
107
+ if (direct.length === 2) {
108
+ return build({ host: "github.com", segments: direct })
109
+ }
110
+ }
111
+
112
+ try {
113
+ const url = new URL(cleaned)
114
+ if (url.protocol === "file:") return buildFile({ url, remote: cleaned })
115
+ const pathname = parts(url.pathname)
116
+ const host = url.host
117
+ return build({
118
+ host,
119
+ segments: pathname,
120
+ remote: host === "github.com" ? githubRemote(pathname.join("/")) : cleaned,
121
+ protocol: url.protocol,
122
+ })
123
+ } catch {
124
+ return null
125
+ }
126
+ }
127
+
128
+ export function parseRemoteRepositoryReference(input: string) {
129
+ const reference = parseRepositoryReference(input)
130
+ if (!reference) throw new Error("Repository must be a git URL, host/path reference, or GitHub owner/repo shorthand")
131
+ if (reference.protocol === "file:") throw new Error("Local file repositories are not supported")
132
+ return reference
133
+ }
134
+
135
+ export function validateRepositoryBranch(branch: string) {
136
+ if (!/^[A-Za-z0-9/_.-]+$/.test(branch) || branch.startsWith("-") || branch.includes("..")) {
137
+ throw new Error(
138
+ "Branch must contain only alphanumeric characters, /, _, ., and -, and cannot start with - or contain ..",
139
+ )
140
+ }
141
+ }
142
+
143
+ export function parseGitHubRemote(input: string) {
144
+ const cleaned = normalize(input)
145
+ if (!cleaned.includes("://") && !cleaned.match(/^(?:[^@/\s]+@)?github\.com:/)) return null
146
+
147
+ const parsed = parseRepositoryReference(cleaned)
148
+ if (!parsed || parsed.host !== "github.com" || !parsed.owner || parsed.segments.length !== 2) return null
149
+ return { owner: parsed.owner, repo: parsed.repo }
150
+ }
151
+
152
+ export function repositoryCachePath(input: Reference) {
153
+ return path.join(Global.Path.repos, ...input.host.split(":"), ...input.segments)
154
+ }
155
+
156
+ export function sameRepositoryReference(left: Reference, right: Reference) {
157
+ return left.host === right.host && left.path === right.path
158
+ }
@@ -0,0 +1,66 @@
1
+ type Definition = {
2
+ [method: string]: (input: any) => any
3
+ }
4
+
5
+ export function listen(rpc: Definition) {
6
+ onmessage = async (evt) => {
7
+ const parsed = JSON.parse(evt.data)
8
+ if (parsed.type === "rpc.request") {
9
+ const result = await rpc[parsed.method](parsed.input)
10
+ postMessage(JSON.stringify({ type: "rpc.result", result, id: parsed.id }))
11
+ }
12
+ }
13
+ }
14
+
15
+ export function emit(event: string, data: unknown) {
16
+ postMessage(JSON.stringify({ type: "rpc.event", event, data }))
17
+ }
18
+
19
+ export function client<T extends Definition>(target: {
20
+ postMessage: (data: string) => void | null
21
+ onmessage: ((this: Worker, ev: MessageEvent<any>) => any) | null
22
+ }) {
23
+ const pending = new Map<number, (result: any) => void>()
24
+ const listeners = new Map<string, Set<(data: any) => void>>()
25
+ let id = 0
26
+ target.onmessage = async (evt) => {
27
+ const parsed = JSON.parse(evt.data)
28
+ if (parsed.type === "rpc.result") {
29
+ const resolve = pending.get(parsed.id)
30
+ if (resolve) {
31
+ resolve(parsed.result)
32
+ pending.delete(parsed.id)
33
+ }
34
+ }
35
+ if (parsed.type === "rpc.event") {
36
+ const handlers = listeners.get(parsed.event)
37
+ if (handlers) {
38
+ for (const handler of handlers) {
39
+ handler(parsed.data)
40
+ }
41
+ }
42
+ }
43
+ }
44
+ return {
45
+ call<Method extends keyof T>(method: Method, input: Parameters<T[Method]>[0]): Promise<ReturnType<T[Method]>> {
46
+ const requestId = id++
47
+ return new Promise((resolve) => {
48
+ pending.set(requestId, resolve)
49
+ target.postMessage(JSON.stringify({ type: "rpc.request", method, input, id: requestId }))
50
+ })
51
+ },
52
+ on<Data>(event: string, handler: (data: Data) => void) {
53
+ let handlers = listeners.get(event)
54
+ if (!handlers) {
55
+ handlers = new Set()
56
+ listeners.set(event, handlers)
57
+ }
58
+ handlers.add(handler)
59
+ return () => {
60
+ handlers!.delete(handler)
61
+ }
62
+ },
63
+ }
64
+ }
65
+
66
+ export * as Rpc from "./rpc"
@@ -0,0 +1,12 @@
1
+ export function signal() {
2
+ let resolve: any
3
+ const promise = new Promise((r) => (resolve = r))
4
+ return {
5
+ trigger() {
6
+ return resolve()
7
+ },
8
+ wait() {
9
+ return promise
10
+ },
11
+ }
12
+ }
@@ -0,0 +1,13 @@
1
+ export function withTimeout<T>(promise: Promise<T>, ms: number, label?: string): Promise<T> {
2
+ let timeout: NodeJS.Timeout
3
+ return Promise.race([
4
+ promise.finally(() => {
5
+ clearTimeout(timeout)
6
+ }),
7
+ new Promise<never>((_, reject) => {
8
+ timeout = setTimeout(() => {
9
+ reject(new Error(label ?? `Operation timed out after ${ms}ms`))
10
+ }, ms)
11
+ }),
12
+ ])
13
+ }
@@ -0,0 +1,7 @@
1
+ const CHARS_PER_TOKEN = 4
2
+
3
+ export function estimate(input: string) {
4
+ return Math.max(0, Math.round((input || "").length / CHARS_PER_TOKEN))
5
+ }
6
+
7
+ export * as Token from "./token"
@@ -0,0 +1,17 @@
1
+ import path from "path"
2
+ import * as Process from "./process"
3
+
4
+ export async function extractZip(zipPath: string, destDir: string) {
5
+ if (process.platform === "win32") {
6
+ const winZipPath = path.resolve(zipPath)
7
+ const winDestDir = path.resolve(destDir)
8
+ // $global:ProgressPreference suppresses PowerShell's blue progress bar popup
9
+ const cmd = `$global:ProgressPreference = 'SilentlyContinue'; Expand-Archive -Path '${winZipPath}' -DestinationPath '${winDestDir}' -Force`
10
+ await Process.run(["powershell", "-NoProfile", "-NonInteractive", "-Command", cmd])
11
+ return
12
+ }
13
+
14
+ await Process.run(["unzip", "-o", "-q", zipPath, "-d", destDir])
15
+ }
16
+
17
+ export * as Archive from "./archive"
@@ -0,0 +1,31 @@
1
+ import { Effect } from "effect"
2
+ import { AppFileSystem } from "@opencode-ai/core/filesystem"
3
+
4
+ const BOM_CODE = 0xfeff
5
+ const BOM = String.fromCharCode(BOM_CODE)
6
+
7
+ export function split(text: string) {
8
+ if (text.charCodeAt(0) !== BOM_CODE) return { bom: false, text }
9
+ return { bom: true, text: text.slice(1) }
10
+ }
11
+
12
+ export function join(text: string, bom: boolean) {
13
+ const stripped = split(text).text
14
+ if (!bom) return stripped
15
+ return BOM + stripped
16
+ }
17
+
18
+ export const readFile = Effect.fn("Bom.readFile")(function* (fs: AppFileSystem.Interface, filePath: string) {
19
+ return split(new TextDecoder("utf-8", { ignoreBOM: true }).decode(yield* fs.readFile(filePath)))
20
+ })
21
+
22
+ export const syncFile = Effect.fn("Bom.syncFile")(function* (
23
+ fs: AppFileSystem.Interface,
24
+ filePath: string,
25
+ bom: boolean,
26
+ ) {
27
+ const current = yield* readFile(fs, filePath)
28
+ if (current.bom === bom) return current.text
29
+ yield* fs.writeWithDirs(filePath, join(current.text, bom))
30
+ return current.text
31
+ })
@@ -0,0 +1,9 @@
1
+ export function decodeDataUrl(url: string) {
2
+ const idx = url.indexOf(",")
3
+ if (idx === -1) return ""
4
+
5
+ const head = url.slice(0, idx)
6
+ const body = url.slice(idx + 1)
7
+ if (head.includes(";base64")) return Buffer.from(body, "base64").toString("utf8")
8
+ return decodeURIComponent(body)
9
+ }
@@ -0,0 +1,10 @@
1
+ export function defer(fn: () => void | Promise<void>): AsyncDisposable & Disposable {
2
+ return {
3
+ [Symbol.dispose]() {
4
+ void fn()
5
+ },
6
+ [Symbol.asyncDispose]() {
7
+ return Promise.resolve(fn())
8
+ },
9
+ }
10
+ }
@@ -0,0 +1,11 @@
1
+ import { Schedule } from "effect"
2
+ import { HttpClient } from "effect/unstable/http"
3
+
4
+ export const withTransientReadRetry = <E, R>(client: HttpClient.HttpClient.With<E, R>) =>
5
+ client.pipe(
6
+ HttpClient.retryTransient({
7
+ retryOn: "errors-and-responses",
8
+ times: 2,
9
+ schedule: Schedule.exponential(200).pipe(Schedule.jittered),
10
+ }),
11
+ )
@@ -0,0 +1,88 @@
1
+ import { isRecord } from "./record"
2
+
3
+ export function errorFormat(error: unknown): string {
4
+ if (error instanceof Error) {
5
+ return error.stack ?? `${error.name}: ${error.message}`
6
+ }
7
+
8
+ if (typeof error === "object" && error !== null) {
9
+ try {
10
+ const json = JSON.stringify(error, null, 2)
11
+ // Plain objects whose own properties are all non-enumerable (or empty)
12
+ // serialize to "{}", which prints as a useless bare `{}` on stderr.
13
+ // Fall back to a custom toString first, then to ctor name + own prop names.
14
+ if (json === "{}") {
15
+ const str = String(error)
16
+ if (str && str !== "[object Object]") return str
17
+ const ctor = error.constructor?.name
18
+ const prefix = ctor && ctor !== "Object" ? ctor : "Error"
19
+ const names = Object.getOwnPropertyNames(error)
20
+ return names.length === 0 ? `${prefix} (no message)` : `${prefix} { ${names.join(", ")} }`
21
+ }
22
+ return json
23
+ } catch {
24
+ return "Unexpected error (unserializable)"
25
+ }
26
+ }
27
+
28
+ return String(error)
29
+ }
30
+
31
+ export function errorMessage(error: unknown): string {
32
+ if (error instanceof Error) {
33
+ if (error.message) return error.message
34
+ if (error.name) return error.name
35
+ }
36
+
37
+ if (isRecord(error) && typeof error.message === "string" && error.message) {
38
+ return error.message
39
+ }
40
+
41
+ if (isRecord(error) && isRecord(error.data) && typeof error.data.message === "string" && error.data.message) {
42
+ return error.data.message
43
+ }
44
+
45
+ const text = String(error)
46
+ if (text && text !== "[object Object]") return text
47
+
48
+ const formatted = errorFormat(error)
49
+ if (formatted) return formatted
50
+ return "unknown error"
51
+ }
52
+
53
+ export function errorData(error: unknown) {
54
+ if (error instanceof Error) {
55
+ return {
56
+ type: error.name,
57
+ message: errorMessage(error),
58
+ stack: error.stack,
59
+ cause: error.cause === undefined ? undefined : errorFormat(error.cause),
60
+ formatted: errorFormat(error),
61
+ }
62
+ }
63
+
64
+ if (!isRecord(error)) {
65
+ return {
66
+ type: typeof error,
67
+ message: errorMessage(error),
68
+ formatted: errorFormat(error),
69
+ }
70
+ }
71
+
72
+ const data = Object.getOwnPropertyNames(error).reduce<Record<string, unknown>>((acc, key) => {
73
+ const value = error[key]
74
+ if (value === undefined) return acc
75
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
76
+ acc[key] = value
77
+ return acc
78
+ }
79
+ // oxlint-disable-next-line no-base-to-string -- intentional coercion of arbitrary error properties
80
+ acc[key] = value instanceof Error ? value.message : String(value)
81
+ return acc
82
+ }, {})
83
+
84
+ if (typeof data.message !== "string") data.message = errorMessage(error)
85
+ if (typeof data.type !== "string") data.type = error.constructor?.name
86
+ data.formatted = errorFormat(error)
87
+ return data
88
+ }