soraacode 0.2.0 → 0.2.2

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 (353) hide show
  1. package/LICENSE +21 -0
  2. package/bin/soraacode.exe +10 -0
  3. package/package.json +17 -25
  4. package/{script/postinstall.mjs → postinstall.mjs} +5 -5
  5. package/AGENTS.md +0 -131
  6. package/Dockerfile +0 -18
  7. package/README.md +0 -15
  8. package/bin/opencode +0 -199
  9. package/bin/soraacode +0 -199
  10. package/bunfig.toml +0 -7
  11. package/git +0 -0
  12. package/migration/20260511173437_session-metadata/migration.sql +0 -1
  13. package/migration/20260511173437_session-metadata/snapshot.json +0 -1500
  14. package/parsers-config.ts +0 -1
  15. package/script/bench-search.ts +0 -94
  16. package/script/bench-test-suite.ts +0 -52
  17. package/script/build-headless.ts +0 -51
  18. package/script/build.ts +0 -245
  19. package/script/generate.ts +0 -14
  20. package/script/httpapi-exercise.ts +0 -1
  21. package/script/profile-test-files.ts +0 -42
  22. package/script/publish.ts +0 -213
  23. package/script/run-workspace-server +0 -106
  24. package/script/schema.ts +0 -77
  25. package/script/time.ts +0 -6
  26. package/script/trace-imports.ts +0 -153
  27. package/soraacode-0.1.7.tgz +0 -0
  28. package/specs/effect/error-boundaries-plan.md +0 -235
  29. package/specs/effect/errors.md +0 -207
  30. package/specs/effect/facades.md +0 -218
  31. package/specs/effect/guide.md +0 -247
  32. package/specs/effect/instance-context.md +0 -13
  33. package/specs/effect/loose-ends.md +0 -30
  34. package/specs/effect/migration.md +0 -62
  35. package/specs/effect/routes.md +0 -61
  36. package/specs/effect/schema.md +0 -88
  37. package/specs/effect/server-package.md +0 -58
  38. package/specs/effect/todo.md +0 -241
  39. package/specs/effect/tools.md +0 -88
  40. package/specs/openapi-translation-cleanup.md +0 -204
  41. package/specs/tui-plugins.md +0 -544
  42. package/specs/v2/api.ts +0 -67
  43. package/specs/v2/message-shape.md +0 -136
  44. package/specs/v2/notifications.md +0 -13
  45. package/specs/v2/tui-command-shim.md +0 -67
  46. package/src/account/account.ts +0 -481
  47. package/src/account/repo.ts +0 -171
  48. package/src/account/schema.ts +0 -99
  49. package/src/account/url.ts +0 -8
  50. package/src/acp/agent.ts +0 -95
  51. package/src/acp/config-option.ts +0 -206
  52. package/src/acp/content.ts +0 -269
  53. package/src/acp/directory.ts +0 -212
  54. package/src/acp/error.ts +0 -97
  55. package/src/acp/event.ts +0 -421
  56. package/src/acp/permission.ts +0 -254
  57. package/src/acp/profile.ts +0 -42
  58. package/src/acp/service.ts +0 -1226
  59. package/src/acp/session.ts +0 -232
  60. package/src/acp/tool.ts +0 -364
  61. package/src/acp/usage.ts +0 -243
  62. package/src/agent/agent.ts +0 -450
  63. package/src/agent/generate.txt +0 -75
  64. package/src/agent/prompt/compaction.txt +0 -5
  65. package/src/agent/prompt/explore.txt +0 -18
  66. package/src/agent/prompt/summary.txt +0 -11
  67. package/src/agent/prompt/title.txt +0 -44
  68. package/src/agent/subagent-permissions.ts +0 -27
  69. package/src/audio.d.ts +0 -14
  70. package/src/auth/index.ts +0 -97
  71. package/src/background/job.ts +0 -37
  72. package/src/bus/global.ts +0 -22
  73. package/src/cli/bootstrap.ts +0 -11
  74. package/src/cli/cmd/cmd.ts +0 -7
  75. package/src/cli/cmd/serve.ts +0 -24
  76. package/src/cli/effect/prompt.ts +0 -37
  77. package/src/cli/effect-cmd.ts +0 -96
  78. package/src/cli/error.ts +0 -130
  79. package/src/cli/heap.ts +0 -45
  80. package/src/cli/logo.ts +0 -2
  81. package/src/cli/network.ts +0 -80
  82. package/src/cli/ui.ts +0 -132
  83. package/src/command/index.ts +0 -177
  84. package/src/command/template/initialize.txt +0 -66
  85. package/src/command/template/review.txt +0 -101
  86. package/src/config/agent.ts +0 -59
  87. package/src/config/command.ts +0 -39
  88. package/src/config/config.ts +0 -707
  89. package/src/config/entry-name.ts +0 -19
  90. package/src/config/managed.ts +0 -69
  91. package/src/config/markdown.ts +0 -36
  92. package/src/config/parse.ts +0 -61
  93. package/src/config/paths.ts +0 -45
  94. package/src/config/plugin.ts +0 -79
  95. package/src/config/v2-compat.ts +0 -449
  96. package/src/config/variable.ts +0 -91
  97. package/src/control-plane/adapters/index.ts +0 -41
  98. package/src/control-plane/adapters/worktree.ts +0 -96
  99. package/src/control-plane/dev/README.md +0 -19
  100. package/src/control-plane/dev/debug-workspace-plugin.ts +0 -73
  101. package/src/control-plane/types.ts +0 -59
  102. package/src/control-plane/util.ts +0 -39
  103. package/src/control-plane/workspace-adapter-runtime.ts +0 -51
  104. package/src/control-plane/workspace-context.ts +0 -26
  105. package/src/control-plane/workspace.ts +0 -966
  106. package/src/effect/app-node-builder-v1.ts +0 -12
  107. package/src/effect/app-runtime.ts +0 -135
  108. package/src/effect/bootstrap-runtime.ts +0 -19
  109. package/src/effect/bridge.ts +0 -84
  110. package/src/effect/config-service.ts +0 -67
  111. package/src/effect/instance-ref.ts +0 -11
  112. package/src/effect/instance-registry.ts +0 -12
  113. package/src/effect/instance-state.ts +0 -69
  114. package/src/effect/promise.ts +0 -17
  115. package/src/effect/run-service.ts +0 -47
  116. package/src/effect/runner.ts +0 -217
  117. package/src/effect/runtime-flags.ts +0 -78
  118. package/src/env/index.ts +0 -41
  119. package/src/event-manifest.ts +0 -3
  120. package/src/event-v2-bridge.ts +0 -71
  121. package/src/format/formatter.ts +0 -404
  122. package/src/format/index.ts +0 -203
  123. package/src/git/index.ts +0 -348
  124. package/src/id/id.ts +0 -80
  125. package/src/ide/index.ts +0 -54
  126. package/src/image/image.ts +0 -172
  127. package/src/index-headless.ts +0 -89
  128. package/src/index.ts +0 -93
  129. package/src/installation/index.ts +0 -336
  130. package/src/lsp/client.ts +0 -650
  131. package/src/lsp/diagnostic.ts +0 -29
  132. package/src/lsp/language.ts +0 -121
  133. package/src/lsp/launch.ts +0 -21
  134. package/src/lsp/lsp.ts +0 -507
  135. package/src/lsp/server.ts +0 -1983
  136. package/src/markdown.d.ts +0 -4
  137. package/src/mcp/auth.ts +0 -163
  138. package/src/mcp/browser.ts +0 -37
  139. package/src/mcp/catalog.ts +0 -170
  140. package/src/mcp/index.ts +0 -1004
  141. package/src/mcp/oauth-callback.ts +0 -194
  142. package/src/mcp/oauth-provider.ts +0 -259
  143. package/src/node.ts +0 -4
  144. package/src/patch/index.ts +0 -686
  145. package/src/permission/arity.ts +0 -163
  146. package/src/permission/evaluate.ts +0 -1
  147. package/src/permission/index.ts +0 -223
  148. package/src/plugin/github-copilot/copilot.ts +0 -415
  149. package/src/plugin/github-copilot/models.ts +0 -261
  150. package/src/plugin/index.ts +0 -298
  151. package/src/plugin/install.ts +0 -439
  152. package/src/plugin/loader.ts +0 -237
  153. package/src/plugin/meta.ts +0 -188
  154. package/src/plugin/openai/README.md +0 -31
  155. package/src/plugin/openai/codex.ts +0 -575
  156. package/src/plugin/openai/ws-pool.ts +0 -271
  157. package/src/plugin/openai/ws.ts +0 -383
  158. package/src/plugin/pty-environment.ts +0 -24
  159. package/src/plugin/shared.ts +0 -323
  160. package/src/project/bootstrap-service.ts +0 -9
  161. package/src/project/bootstrap.ts +0 -58
  162. package/src/project/instance-context.ts +0 -24
  163. package/src/project/instance-runtime.ts +0 -16
  164. package/src/project/instance-store.ts +0 -213
  165. package/src/project/project.ts +0 -483
  166. package/src/project/vcs.ts +0 -423
  167. package/src/provider/auth.ts +0 -229
  168. package/src/provider/error.ts +0 -195
  169. package/src/provider/model-status.ts +0 -8
  170. package/src/provider/provider.ts +0 -1955
  171. package/src/provider/transform.ts +0 -1923
  172. package/src/question/index.ts +0 -161
  173. package/src/question/schema.ts +0 -4
  174. package/src/server/auth.ts +0 -48
  175. package/src/server/event.ts +0 -10
  176. package/src/server/global-lifecycle.ts +0 -28
  177. package/src/server/mdns.ts +0 -47
  178. package/src/server/proxy-util.ts +0 -48
  179. package/src/server/routes/instance/httpapi/AGENTS.md +0 -39
  180. package/src/server/routes/instance/httpapi/api.ts +0 -97
  181. package/src/server/routes/instance/httpapi/errors.ts +0 -193
  182. package/src/server/routes/instance/httpapi/groups/config.ts +0 -65
  183. package/src/server/routes/instance/httpapi/groups/control-plane.ts +0 -35
  184. package/src/server/routes/instance/httpapi/groups/control.ts +0 -76
  185. package/src/server/routes/instance/httpapi/groups/event.ts +0 -29
  186. package/src/server/routes/instance/httpapi/groups/experimental.ts +0 -275
  187. package/src/server/routes/instance/httpapi/groups/file.ts +0 -185
  188. package/src/server/routes/instance/httpapi/groups/global.ts +0 -139
  189. package/src/server/routes/instance/httpapi/groups/instance.ts +0 -206
  190. package/src/server/routes/instance/httpapi/groups/mcp.ts +0 -156
  191. package/src/server/routes/instance/httpapi/groups/metadata.ts +0 -18
  192. package/src/server/routes/instance/httpapi/groups/permission.ts +0 -61
  193. package/src/server/routes/instance/httpapi/groups/project-copy.ts +0 -32
  194. package/src/server/routes/instance/httpapi/groups/project.ts +0 -93
  195. package/src/server/routes/instance/httpapi/groups/provider.ts +0 -101
  196. package/src/server/routes/instance/httpapi/groups/pty.ts +0 -172
  197. package/src/server/routes/instance/httpapi/groups/query.ts +0 -12
  198. package/src/server/routes/instance/httpapi/groups/question.ts +0 -74
  199. package/src/server/routes/instance/httpapi/groups/session.ts +0 -462
  200. package/src/server/routes/instance/httpapi/groups/sync.ts +0 -113
  201. package/src/server/routes/instance/httpapi/groups/tui.ts +0 -208
  202. package/src/server/routes/instance/httpapi/groups/workspace.ts +0 -141
  203. package/src/server/routes/instance/httpapi/handlers/config.ts +0 -34
  204. package/src/server/routes/instance/httpapi/handlers/control-plane.ts +0 -37
  205. package/src/server/routes/instance/httpapi/handlers/control.ts +0 -43
  206. package/src/server/routes/instance/httpapi/handlers/event.ts +0 -99
  207. package/src/server/routes/instance/httpapi/handlers/experimental.ts +0 -193
  208. package/src/server/routes/instance/httpapi/handlers/file.ts +0 -139
  209. package/src/server/routes/instance/httpapi/handlers/global.ts +0 -126
  210. package/src/server/routes/instance/httpapi/handlers/instance.ts +0 -110
  211. package/src/server/routes/instance/httpapi/handlers/mcp.ts +0 -111
  212. package/src/server/routes/instance/httpapi/handlers/permission.ts +0 -41
  213. package/src/server/routes/instance/httpapi/handlers/project-copy.ts +0 -83
  214. package/src/server/routes/instance/httpapi/handlers/project.ts +0 -63
  215. package/src/server/routes/instance/httpapi/handlers/provider.ts +0 -116
  216. package/src/server/routes/instance/httpapi/handlers/pty.ts +0 -273
  217. package/src/server/routes/instance/httpapi/handlers/question.ts +0 -54
  218. package/src/server/routes/instance/httpapi/handlers/session-errors.ts +0 -21
  219. package/src/server/routes/instance/httpapi/handlers/session.ts +0 -442
  220. package/src/server/routes/instance/httpapi/handlers/sync.ts +0 -89
  221. package/src/server/routes/instance/httpapi/handlers/tui.ts +0 -131
  222. package/src/server/routes/instance/httpapi/handlers/workspace.ts +0 -102
  223. package/src/server/routes/instance/httpapi/lifecycle.ts +0 -54
  224. package/src/server/routes/instance/httpapi/middleware/authorization.ts +0 -150
  225. package/src/server/routes/instance/httpapi/middleware/compression.ts +0 -64
  226. package/src/server/routes/instance/httpapi/middleware/cors-vary.ts +0 -29
  227. package/src/server/routes/instance/httpapi/middleware/error.ts +0 -44
  228. package/src/server/routes/instance/httpapi/middleware/fence.ts +0 -25
  229. package/src/server/routes/instance/httpapi/middleware/instance-context.ts +0 -43
  230. package/src/server/routes/instance/httpapi/middleware/proxy.ts +0 -131
  231. package/src/server/routes/instance/httpapi/middleware/schema-error.ts +0 -41
  232. package/src/server/routes/instance/httpapi/middleware/workspace-routing.ts +0 -250
  233. package/src/server/routes/instance/httpapi/public.ts +0 -537
  234. package/src/server/routes/instance/httpapi/server.ts +0 -325
  235. package/src/server/routes/instance/httpapi/websocket-tracker.ts +0 -60
  236. package/src/server/server.ts +0 -224
  237. package/src/server/shared/fence.ts +0 -60
  238. package/src/server/shared/pty-ticket.ts +0 -15
  239. package/src/server/shared/public-ui.ts +0 -12
  240. package/src/server/shared/tui-control.ts +0 -28
  241. package/src/server/shared/ui.ts +0 -108
  242. package/src/server/shared/workspace-routing.ts +0 -45
  243. package/src/server/tui-event.ts +0 -1
  244. package/src/session/compaction.ts +0 -608
  245. package/src/session/instruction.ts +0 -237
  246. package/src/session/llm/AGENTS.md +0 -90
  247. package/src/session/llm/ai-sdk.ts +0 -291
  248. package/src/session/llm/native-request.ts +0 -196
  249. package/src/session/llm/native-runtime.ts +0 -195
  250. package/src/session/llm/request.ts +0 -226
  251. package/src/session/llm.ts +0 -390
  252. package/src/session/message-error.ts +0 -14
  253. package/src/session/message-v2.ts +0 -742
  254. package/src/session/message.ts +0 -148
  255. package/src/session/overflow.ts +0 -34
  256. package/src/session/processor.ts +0 -732
  257. package/src/session/prompt/build-switch.txt +0 -5
  258. package/src/session/prompt/default.txt +0 -35
  259. package/src/session/prompt/plan-mode.txt +0 -70
  260. package/src/session/prompt/plan.txt +0 -26
  261. package/src/session/prompt.ts +0 -1631
  262. package/src/session/reminders.ts +0 -92
  263. package/src/session/retry.ts +0 -209
  264. package/src/session/revert.ts +0 -136
  265. package/src/session/run-state.ts +0 -151
  266. package/src/session/schema.ts +0 -26
  267. package/src/session/session.ts +0 -1016
  268. package/src/session/status.ts +0 -56
  269. package/src/session/summary.ts +0 -160
  270. package/src/session/system.ts +0 -123
  271. package/src/session/todo.ts +0 -74
  272. package/src/session/tools.ts +0 -590
  273. package/src/share/session.ts +0 -58
  274. package/src/share/share-next.ts +0 -371
  275. package/src/skill/discovery.ts +0 -140
  276. package/src/skill/index.ts +0 -354
  277. package/src/snapshot/index.ts +0 -807
  278. package/src/sql.d.ts +0 -4
  279. package/src/storage/schema.ts +0 -5
  280. package/src/storage/storage.ts +0 -327
  281. package/src/sync/README.md +0 -179
  282. package/src/sync/schema.ts +0 -11
  283. package/src/temporary.ts +0 -31
  284. package/src/tool/apply_patch.ts +0 -313
  285. package/src/tool/apply_patch.txt +0 -14
  286. package/src/tool/code-mode.ts +0 -310
  287. package/src/tool/edit.ts +0 -737
  288. package/src/tool/edit.txt +0 -13
  289. package/src/tool/external-directory.ts +0 -49
  290. package/src/tool/glob.ts +0 -76
  291. package/src/tool/glob.txt +0 -7
  292. package/src/tool/grep.ts +0 -115
  293. package/src/tool/grep.txt +0 -7
  294. package/src/tool/invalid.ts +0 -21
  295. package/src/tool/json-schema.ts +0 -164
  296. package/src/tool/lsp.ts +0 -113
  297. package/src/tool/lsp.txt +0 -1
  298. package/src/tool/mcp-websearch.ts +0 -96
  299. package/src/tool/plan-enter.txt +0 -1
  300. package/src/tool/plan-exit.txt +0 -1
  301. package/src/tool/plan.ts +0 -79
  302. package/src/tool/question.ts +0 -44
  303. package/src/tool/question.txt +0 -1
  304. package/src/tool/read.ts +0 -386
  305. package/src/tool/read.txt +0 -13
  306. package/src/tool/registry.ts +0 -455
  307. package/src/tool/schema.ts +0 -14
  308. package/src/tool/shell/id.ts +0 -19
  309. package/src/tool/shell/prompt.ts +0 -293
  310. package/src/tool/shell/shell.txt +0 -21
  311. package/src/tool/shell.ts +0 -645
  312. package/src/tool/skill.ts +0 -70
  313. package/src/tool/skill.txt +0 -1
  314. package/src/tool/task.ts +0 -371
  315. package/src/tool/task.txt +0 -11
  316. package/src/tool/todo.ts +0 -46
  317. package/src/tool/todowrite.txt +0 -11
  318. package/src/tool/tool.ts +0 -183
  319. package/src/tool/truncate.ts +0 -156
  320. package/src/tool/truncation-dir.ts +0 -4
  321. package/src/tool/webfetch.ts +0 -192
  322. package/src/tool/webfetch.txt +0 -9
  323. package/src/tool/websearch.ts +0 -143
  324. package/src/tool/websearch.txt +0 -9
  325. package/src/tool/write.ts +0 -104
  326. package/src/tool/write.txt +0 -11
  327. package/src/util/archive.ts +0 -17
  328. package/src/util/bom.ts +0 -27
  329. package/src/util/data-url.ts +0 -9
  330. package/src/util/defer.ts +0 -10
  331. package/src/util/effect-http-client.ts +0 -11
  332. package/src/util/error.ts +0 -16
  333. package/src/util/filesystem.ts +0 -251
  334. package/src/util/html.ts +0 -8
  335. package/src/util/iife.ts +0 -3
  336. package/src/util/lazy.ts +0 -20
  337. package/src/util/local-context.ts +0 -25
  338. package/src/util/locale.ts +0 -4
  339. package/src/util/media.ts +0 -26
  340. package/src/util/process.ts +0 -177
  341. package/src/util/proxy-env.ts +0 -72
  342. package/src/util/queue.ts +0 -32
  343. package/src/util/record.ts +0 -3
  344. package/src/util/repository.ts +0 -232
  345. package/src/util/rpc.ts +0 -66
  346. package/src/util/signal.ts +0 -12
  347. package/src/util/timeout.ts +0 -13
  348. package/src/util/token.ts +0 -1
  349. package/src/util/wildcard.ts +0 -59
  350. package/src/worktree/index.ts +0 -623
  351. package/sst-env.d.ts +0 -10
  352. package/tsconfig.headless.json +0 -13
  353. package/tsconfig.json +0 -16
@@ -1,455 +0,0 @@
1
- import { LayerNode } from "@soraacode/core/effect/layer-node"
2
- import { httpClient } from "@soraacode/core/effect/app-node-platform"
3
- import { Ripgrep } from "@soraacode/core/ripgrep"
4
- import { PlanExitTool } from "./plan"
5
- import { Session } from "@/session/session"
6
- import { QuestionTool } from "./question"
7
- import { ShellTool } from "./shell"
8
- import { EditTool } from "./edit"
9
- import { GlobTool } from "./glob"
10
- import { GrepTool } from "./grep"
11
- import { ReadTool } from "./read"
12
- import { TaskTool } from "./task"
13
- import { Database } from "@soraacode/core/database/database"
14
- import { TodoWriteTool } from "./todo"
15
- import { WebFetchTool } from "./webfetch"
16
- import { WriteTool } from "./write"
17
- import { InvalidTool } from "./invalid"
18
- import { SkillTool } from "./skill"
19
- import * as Tool from "./tool"
20
- import { Config } from "@/config/config"
21
- import { type ToolContext as PluginToolContext, type ToolDefinition } from "@soraacode/plugin"
22
- import type { JSONSchema7, JSONSchema7Definition } from "@ai-sdk/provider"
23
- import { Schema } from "effect"
24
- import z from "zod"
25
- import { Plugin } from "../plugin"
26
- import { Provider } from "@/provider/provider"
27
-
28
- import { WebSearchTool } from "./websearch"
29
- import { LspTool } from "./lsp"
30
- import * as Truncate from "./truncate"
31
- import { ApplyPatchTool } from "./apply_patch"
32
- import { Glob } from "@soraacode/core/util/glob"
33
- import path from "path"
34
- import { pathToFileURL } from "url"
35
- import { Effect, Layer, Context } from "effect"
36
- import { ChildProcessSpawner } from "effect/unstable/process/ChildProcessSpawner"
37
- import { CrossSpawnSpawner } from "@soraacode/core/cross-spawn-spawner"
38
- import { Format } from "../format"
39
- import { InstanceState } from "@/effect/instance-state"
40
- import { EffectBridge } from "@/effect/bridge"
41
- import { Question } from "../question"
42
- import { Todo } from "../session/todo"
43
- import { LSP } from "@/lsp/lsp"
44
- import { Instruction } from "../session/instruction"
45
- import { FSUtil } from "@soraacode/core/fs-util"
46
- import { EventV2Bridge } from "@/event-v2-bridge"
47
- import { Agent } from "../agent/agent"
48
- import { Skill } from "../skill"
49
- import { Permission } from "@/permission"
50
- import { BackgroundJob } from "@/background/job"
51
- import { RuntimeFlags } from "@/effect/runtime-flags"
52
- import { ProviderV2 } from "@soraacode/core/provider"
53
- import { ModelV2 } from "@soraacode/core/model"
54
- import { MCP } from "@/mcp"
55
- import { PermissionV1 } from "@soraacode/core/v1/permission"
56
- import { McpCatalog } from "@/mcp/catalog"
57
-
58
- export function webSearchEnabled(providerID: ProviderV2.ID, flags = { exa: false, parallel: false }) {
59
- return (
60
- providerID === ProviderV2.ID.opencode ||
61
- providerID === ProviderV2.ID.make("opencode-go") ||
62
- flags.exa ||
63
- flags.parallel
64
- )
65
- }
66
-
67
- type TaskDef = Tool.InferDef<typeof TaskTool>
68
- type ReadDef = Tool.InferDef<typeof ReadTool>
69
-
70
- type State = {
71
- custom: Tool.Def[]
72
- builtin: Tool.Def[]
73
- task: TaskDef
74
- read: ReadDef
75
- }
76
-
77
- export interface Interface {
78
- readonly ids: () => Effect.Effect<string[]>
79
- readonly all: () => Effect.Effect<Tool.Def[]>
80
- readonly named: () => Effect.Effect<{ task: TaskDef; read: ReadDef }>
81
- readonly tools: (model: {
82
- providerID: ProviderV2.ID
83
- modelID: ModelV2.ID
84
- agent: Agent.Info
85
- permission?: PermissionV1.Ruleset
86
- }) => Effect.Effect<Tool.Def[]>
87
- }
88
-
89
- export class Service extends Context.Service<Service, Interface>()("@opencode/ToolRegistry") {}
90
-
91
- const layer = Layer.effect(
92
- Service,
93
- Effect.gen(function* () {
94
- const config = yield* Config.Service
95
- const plugin = yield* Plugin.Service
96
- const agents = yield* Agent.Service
97
- const truncate = yield* Truncate.Service
98
- const flags = yield* RuntimeFlags.Service
99
- const mcp = yield* MCP.Service
100
-
101
- const invalid = yield* InvalidTool
102
- const task = yield* TaskTool
103
- const read = yield* ReadTool
104
- const question = yield* QuestionTool
105
- const todo = yield* TodoWriteTool
106
- const lsptool = yield* LspTool
107
- const plan = yield* PlanExitTool
108
- const webfetch = yield* WebFetchTool
109
- const websearch = yield* WebSearchTool
110
- const shell = yield* ShellTool
111
- const globtool = yield* GlobTool
112
- const writetool = yield* WriteTool
113
- const edit = yield* EditTool
114
- const greptool = yield* GrepTool
115
- const patchtool = yield* ApplyPatchTool
116
- const skilltool = yield* SkillTool
117
- const agent = yield* Agent.Service
118
- const codeMode = flags.experimentalCodeMode ? yield* Effect.promise(() => import("./code-mode")) : undefined
119
- const codeModeTool = codeMode ? yield* codeMode.CodeModeTool : undefined
120
-
121
- const state = yield* InstanceState.make<State>(
122
- Effect.fn("ToolRegistry.state")(function* (ctx) {
123
- const custom: Tool.Def[] = []
124
-
125
- function fromPlugin(id: string, def: ToolDefinition): Tool.Def {
126
- // Plugin tools still expose Zod args publicly; keep that compatibility
127
- // boxed at the registry boundary and give the LLM the original JSON Schema.
128
- // Normalize missing args to `{}` once — pre-1.14.49 the code was
129
- // `z.object(def.args)` and Zod silently tolerated undefined (#27451, #27630).
130
- const args = def.args ?? {}
131
- const entries = Object.entries(args)
132
- const allZod = entries.every((entry) => isZodType(entry[1]))
133
- const zodParams = allZod ? z.object(args) : undefined
134
- const jsonSchema = zodParams ? zodJsonSchema(zodParams) : legacyJsonSchema(entries)
135
- const parameters = zodParams
136
- ? Schema.declare<unknown>((u): u is unknown => zodParams.safeParse(u).success)
137
- : Schema.Unknown
138
- return {
139
- id,
140
- parameters,
141
- jsonSchema,
142
- description: def.description,
143
- execute: (args, toolCtx) =>
144
- Effect.gen(function* () {
145
- // Bridge the host's Effect-based `ask` into a Promise-returning
146
- // function for the plugin to make sure context persists
147
- const bridge = yield* EffectBridge.make()
148
- const pluginCtx: PluginToolContext = {
149
- ...toolCtx,
150
- ask: (req) => bridge.promise(toolCtx.ask(req)),
151
- directory: ctx.directory,
152
- worktree: ctx.worktree,
153
- }
154
- const result = yield* Effect.promise(() => def.execute(args as any, pluginCtx))
155
- const output = typeof result === "string" ? result : result.output
156
- const metadata = typeof result === "string" ? {} : (result.metadata ?? {})
157
- const attachments = typeof result === "string" ? undefined : result.attachments
158
- const info = yield* agent.get(toolCtx.agent)
159
- const out = yield* truncate.output(output, {}, info)
160
- return {
161
- title: typeof result === "string" ? "" : (result.title ?? ""),
162
- output: out.truncated ? out.content : output,
163
- attachments,
164
- metadata: {
165
- ...metadata,
166
- truncated: out.truncated,
167
- ...(out.truncated && { outputPath: out.outputPath }),
168
- },
169
- }
170
- }).pipe(
171
- Effect.withSpan("Tool.execute", {
172
- attributes: {
173
- "tool.name": id,
174
- "session.id": toolCtx.sessionID,
175
- "message.id": toolCtx.messageID,
176
- ...(toolCtx.callID ? { "tool.call_id": toolCtx.callID } : {}),
177
- },
178
- }),
179
- ),
180
- }
181
- }
182
-
183
- const dirs = yield* config.directories()
184
- const matches = dirs.flatMap((dir) =>
185
- Glob.scanSync("{tool,tools}/*.{js,ts}", { cwd: dir, absolute: true, dot: true, symlink: true }),
186
- )
187
- if (matches.length) yield* config.waitForDependencies()
188
- for (const match of matches) {
189
- const namespace = path.basename(match, path.extname(match))
190
- // `match` is an absolute filesystem path from `Glob.scanSync(..., { absolute: true })`.
191
- // Import it as `file://` so Node on Windows accepts the dynamic import.
192
- const mod = yield* Effect.promise(() => import(pathToFileURL(match).href))
193
- for (const [id, def] of Object.entries(mod)) {
194
- if (!isPluginTool(def)) continue
195
- custom.push(fromPlugin(id === "default" ? namespace : `${namespace}_${id}`, def))
196
- }
197
- }
198
-
199
- const plugins = yield* plugin.list()
200
- for (const p of plugins) {
201
- for (const [id, def] of Object.entries(p.tool ?? {})) {
202
- custom.push(fromPlugin(id, def))
203
- }
204
- }
205
-
206
- yield* config.get()
207
- const questionEnabled = ["app", "cli", "desktop"].includes(flags.client) || flags.enableQuestionTool
208
-
209
- const tool = yield* Effect.all({
210
- invalid: Tool.init(invalid),
211
- shell: Tool.init(shell),
212
- read: Tool.init(read),
213
- glob: Tool.init(globtool),
214
- grep: Tool.init(greptool),
215
- edit: Tool.init(edit),
216
- write: Tool.init(writetool),
217
- task: Tool.init(task),
218
- fetch: Tool.init(webfetch),
219
- todo: Tool.init(todo),
220
- search: Tool.init(websearch),
221
- skill: Tool.init(skilltool),
222
- patch: Tool.init(patchtool),
223
- question: Tool.init(question),
224
- lsp: Tool.init(lsptool),
225
- plan: Tool.init(plan),
226
- ...(codeModeTool ? { execute: Tool.init(codeModeTool) } : {}),
227
- })
228
-
229
- return {
230
- custom,
231
- builtin: [
232
- tool.invalid,
233
- ...(questionEnabled ? [tool.question] : []),
234
- tool.shell,
235
- tool.read,
236
- tool.glob,
237
- tool.grep,
238
- tool.edit,
239
- tool.write,
240
- tool.task,
241
- tool.fetch,
242
- tool.todo,
243
- tool.search,
244
- tool.skill,
245
- tool.patch,
246
- ...(tool.execute ? [tool.execute] : []),
247
- ...(flags.experimentalLspTool ? [tool.lsp] : []),
248
- ...(flags.experimentalPlanMode && flags.client === "cli" ? [tool.plan] : []),
249
- ],
250
- task: tool.task,
251
- read: tool.read,
252
- }
253
- }),
254
- )
255
-
256
- const all: Interface["all"] = Effect.fn("ToolRegistry.all")(function* () {
257
- const s = yield* InstanceState.get(state)
258
- return [...s.builtin, ...s.custom] as Tool.Def[]
259
- })
260
-
261
- const ids: Interface["ids"] = Effect.fn("ToolRegistry.ids")(function* () {
262
- return (yield* all()).map((tool) => tool.id)
263
- })
264
-
265
- const describeTask = Effect.fn("ToolRegistry.describeTask")(function* (agent: Agent.Info) {
266
- const items = (yield* agents.list()).filter((item) => item.mode !== "primary")
267
- const filtered = items.filter(
268
- (item) => Permission.evaluate("task", item.name, agent.permission).action !== "deny",
269
- )
270
- const list = filtered.toSorted((a, b) => a.name.localeCompare(b.name))
271
- const description = list
272
- .map(
273
- (item) =>
274
- `- ${item.name}: ${item.description ?? "This subagent should only be called manually by the user."}`,
275
- )
276
- .join("\n")
277
- return ["Available agent types and the tools they have access to:", description].join("\n")
278
- })
279
-
280
- const describeCodeMode = Effect.fn("ToolRegistry.describeCodeMode")(function* (input: {
281
- agent: Agent.Info
282
- permission?: PermissionV1.Ruleset
283
- }) {
284
- if (!codeMode) return
285
- const ruleset = Permission.merge(input.agent.permission, input.permission ?? [])
286
- const tools = Permission.visibleTools(yield* mcp.tools(), ruleset)
287
- if (Object.keys(tools).length === 0) return
288
- return codeMode.describeCatalog(tools, Object.keys(yield* mcp.clients()).map(McpCatalog.sanitize))
289
- })
290
-
291
- const tools: Interface["tools"] = Effect.fn("ToolRegistry.tools")(function* (input) {
292
- const filtered = (yield* all()).filter((tool) => {
293
- if (tool.id === WebSearchTool.id) {
294
- return webSearchEnabled(input.providerID, { exa: flags.enableExa, parallel: flags.enableParallel })
295
- }
296
-
297
- const usePatch =
298
- input.modelID.includes("gpt-") && !input.modelID.includes("oss") && !input.modelID.includes("gpt-4")
299
- if (tool.id === ApplyPatchTool.id) return usePatch
300
- if (tool.id === EditTool.id || tool.id === WriteTool.id) return !usePatch
301
-
302
- return true
303
- })
304
-
305
- const codeModeDescription = filtered.some((tool) => tool.id === "execute")
306
- ? yield* describeCodeMode(input)
307
- : undefined
308
- const visible = filtered.filter((tool) => tool.id !== "execute" || codeModeDescription)
309
-
310
- return yield* Effect.forEach(
311
- visible,
312
- Effect.fnUntraced(function* (tool: Tool.Def) {
313
- const output = {
314
- description: tool.description,
315
- parameters: tool.parameters,
316
- jsonSchema: tool.jsonSchema,
317
- }
318
- yield* plugin.trigger("tool.definition", { toolID: tool.id }, output)
319
- const jsonSchema =
320
- output.parameters === tool.parameters || output.jsonSchema !== tool.jsonSchema
321
- ? output.jsonSchema
322
- : undefined
323
- return {
324
- id: tool.id,
325
- description: [
326
- output.description,
327
- tool.id === TaskTool.id ? yield* describeTask(input.agent) : undefined,
328
- tool.id === "execute" ? codeModeDescription : undefined,
329
- ]
330
- .filter(Boolean)
331
- .join("\n"),
332
- parameters: output.parameters,
333
- jsonSchema,
334
- execute: tool.execute,
335
- formatValidationError: tool.formatValidationError,
336
- }
337
- }),
338
- { concurrency: "unbounded" },
339
- )
340
- })
341
-
342
- const named: Interface["named"] = Effect.fn("ToolRegistry.named")(function* () {
343
- const s = yield* InstanceState.get(state)
344
- return { task: s.task, read: s.read }
345
- })
346
-
347
- return Service.of({ ids, all, named, tools })
348
- }),
349
- )
350
-
351
- function isZodType(value: unknown): value is z.ZodType {
352
- return typeof value === "object" && value !== null && "_zod" in value
353
- }
354
-
355
- function isPluginTool(value: unknown): value is ToolDefinition {
356
- return typeof value === "object" && value !== null && "args" in value && "description" in value && "execute" in value
357
- }
358
-
359
- function isJsonSchemaDefinition(value: unknown): value is JSONSchema7Definition {
360
- return typeof value === "boolean" || (typeof value === "object" && value !== null && !Array.isArray(value))
361
- }
362
-
363
- function legacyJsonSchema(entries: [string, unknown][]): JSONSchema7 {
364
- const properties = Object.fromEntries(
365
- entries.filter((entry): entry is [string, JSONSchema7Definition] => isJsonSchemaDefinition(entry[1])),
366
- )
367
- return {
368
- type: "object",
369
- properties,
370
- required: Object.keys(properties),
371
- }
372
- }
373
-
374
- function zodJsonSchema(schema: z.ZodType): JSONSchema7 {
375
- const result = normalizeZodJsonSchema(z.toJSONSchema(schema, { io: "input", metadata: zodMetadataRegistry(schema) }))
376
- if (!isJsonSchemaObject(result)) throw new Error("plugin tool Zod schema produced a non-object JSON Schema")
377
- const { $defs, ...rest } = result
378
- return (
379
- $defs && isJsonSchemaObject($defs) ? { ...rest, definitions: $defs as JSONSchema7["definitions"] } : rest
380
- ) as JSONSchema7
381
- }
382
-
383
- function zodMetadataRegistry(schema: z.ZodType) {
384
- const registry = z.registry<Record<string, unknown>>()
385
- const seen = new WeakSet<object>()
386
- const collect = (value: unknown) => {
387
- if (typeof value !== "object" || value === null) return
388
- if (seen.has(value)) return
389
- seen.add(value)
390
-
391
- if (isZodType(value)) {
392
- const metadata = typeof value.meta === "function" ? value.meta() : undefined
393
- const description = typeof value.description === "string" ? value.description : undefined
394
- const merged = {
395
- ...(metadata && typeof metadata === "object" ? metadata : {}),
396
- ...(description ? { description } : {}),
397
- }
398
- if (Object.keys(merged).length) registry.add(value, merged)
399
- collect(value._zod.def)
400
- return
401
- }
402
-
403
- for (const item of Object.values(value)) collect(item)
404
- }
405
- collect(schema)
406
- return registry
407
- }
408
-
409
- function normalizeZodJsonSchema(value: unknown): unknown {
410
- if (Array.isArray(value)) return value.map((item) => normalizeZodJsonSchema(item))
411
- if (typeof value !== "object" || value === null) return value
412
- return Object.fromEntries(
413
- Object.entries(value)
414
- .filter((entry) =>
415
- (entry[0] === "exclusiveMaximum" || entry[0] === "exclusiveMinimum") && typeof entry[1] === "boolean"
416
- ? false
417
- : true,
418
- )
419
- .map(([key, item]) => [key, normalizeZodJsonSchema(item)]),
420
- )
421
- }
422
-
423
- function isJsonSchemaObject(value: unknown): value is Record<string, unknown> {
424
- return typeof value === "object" && value !== null && !Array.isArray(value)
425
- }
426
-
427
- export const node = LayerNode.make({
428
- service: Service,
429
- layer,
430
- deps: [
431
- Config.node,
432
- Plugin.node,
433
- Question.node,
434
- Todo.node,
435
- Agent.node,
436
- Skill.node,
437
- Session.node,
438
- BackgroundJob.node,
439
- Provider.node,
440
- LSP.node,
441
- Instruction.node,
442
- FSUtil.node,
443
- EventV2Bridge.node,
444
- httpClient,
445
- CrossSpawnSpawner.node,
446
- Format.node,
447
- Truncate.node,
448
- RuntimeFlags.node,
449
- MCP.node,
450
- Database.node,
451
- Ripgrep.node,
452
- ],
453
- })
454
-
455
- export * as ToolRegistry from "./registry"
@@ -1,14 +0,0 @@
1
- import { Schema } from "effect"
2
-
3
- import { Identifier } from "@/id/id"
4
- import { statics } from "@soraacode/core/schema"
5
-
6
- const toolIdSchema = Schema.String.check(Schema.isStartsWith("tool")).pipe(Schema.brand("ToolID"))
7
-
8
- export type ToolID = typeof toolIdSchema.Type
9
-
10
- export const ToolID = toolIdSchema.pipe(
11
- statics((schema: typeof toolIdSchema) => ({
12
- ascending: (id?: string) => schema.make(Identifier.ascending("tool", id)),
13
- })),
14
- )
@@ -1,19 +0,0 @@
1
- const kinds = ["bash", "pwsh", "powershell", "cmd"] as const
2
- export type Kind = (typeof kinds)[number]
3
-
4
- const shellKinds = new Set<string>(kinds)
5
-
6
- function isKind(value: string): value is Kind {
7
- return shellKinds.has(value)
8
- }
9
-
10
- export function toKind(value: string): Kind {
11
- return isKind(value) ? value : "bash"
12
- }
13
-
14
- // Keep the exposed tool ID and permission key as "bash" for compatibility with
15
- // existing plugins, users, and saved permissions. Rename with opencode 2.0.
16
- export const ToolID = "bash"
17
- export type ToolID = typeof ToolID
18
-
19
- export * as ShellID from "./id"