onlycode 1.18.0 → 1.20.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.
- package/bin/{opencode.cjs → onlycode.cjs} +8 -42
- package/package.json +12 -147
- package/src/account/account.ts +0 -463
- package/src/account/repo.ts +0 -173
- package/src/account/schema.ts +0 -99
- package/src/account/url.ts +0 -8
- package/src/acp/agent.ts +0 -95
- package/src/acp/config-option.ts +0 -203
- package/src/acp/content.ts +0 -250
- package/src/acp/directory.ts +0 -210
- package/src/acp/error.ts +0 -90
- package/src/acp/event.ts +0 -342
- package/src/acp/permission.ts +0 -124
- package/src/acp/profile.ts +0 -42
- package/src/acp/service.ts +0 -1048
- package/src/acp/session.ts +0 -231
- package/src/acp/tool.ts +0 -367
- package/src/acp/usage.ts +0 -232
- package/src/agent/agent.ts +0 -459
- package/src/agent/generate.txt +0 -75
- package/src/agent/prompt/compaction.txt +0 -9
- package/src/agent/prompt/explore.txt +0 -18
- package/src/agent/prompt/summary.txt +0 -11
- package/src/agent/prompt/title.txt +0 -44
- package/src/agent/subagent-permissions.ts +0 -27
- package/src/audio.d.ts +0 -14
- package/src/auth/index.ts +0 -99
- package/src/background/job.ts +0 -39
- package/src/bus/global.ts +0 -22
- package/src/cli/bootstrap.ts +0 -11
- package/src/cli/cmd/account.ts +0 -264
- package/src/cli/cmd/acp.ts +0 -73
- package/src/cli/cmd/agent.ts +0 -259
- package/src/cli/cmd/attach.ts +0 -97
- package/src/cli/cmd/cmd.ts +0 -7
- package/src/cli/cmd/db.ts +0 -62
- package/src/cli/cmd/debug/agent.handler.ts +0 -193
- package/src/cli/cmd/debug/agent.ts +0 -27
- package/src/cli/cmd/debug/config.ts +0 -14
- package/src/cli/cmd/debug/file.ts +0 -73
- package/src/cli/cmd/debug/index.ts +0 -87
- package/src/cli/cmd/debug/lsp.ts +0 -50
- package/src/cli/cmd/debug/ripgrep.ts +0 -79
- package/src/cli/cmd/debug/scrap.ts +0 -15
- package/src/cli/cmd/debug/skill.ts +0 -15
- package/src/cli/cmd/debug/snapshot.ts +0 -50
- package/src/cli/cmd/debug/startup.ts +0 -11
- package/src/cli/cmd/debug/v2.ts +0 -44
- package/src/cli/cmd/export.ts +0 -292
- package/src/cli/cmd/generate.ts +0 -54
- package/src/cli/cmd/github.handler.ts +0 -1593
- package/src/cli/cmd/github.shared.ts +0 -30
- package/src/cli/cmd/github.ts +0 -42
- package/src/cli/cmd/import.ts +0 -224
- package/src/cli/cmd/mcp.ts +0 -849
- package/src/cli/cmd/models.ts +0 -66
- package/src/cli/cmd/plug.ts +0 -230
- package/src/cli/cmd/pr.ts +0 -115
- package/src/cli/cmd/prompt-display.ts +0 -1
- package/src/cli/cmd/providers.ts +0 -534
- package/src/cli/cmd/run/demo.ts +0 -1274
- package/src/cli/cmd/run/entry.body.ts +0 -205
- package/src/cli/cmd/run/footer.command.tsx +0 -1064
- package/src/cli/cmd/run/footer.menu.tsx +0 -351
- package/src/cli/cmd/run/footer.permission.tsx +0 -472
- package/src/cli/cmd/run/footer.prompt.tsx +0 -1306
- package/src/cli/cmd/run/footer.question.tsx +0 -573
- package/src/cli/cmd/run/footer.subagent.tsx +0 -173
- package/src/cli/cmd/run/footer.ts +0 -1129
- package/src/cli/cmd/run/footer.view.tsx +0 -943
- package/src/cli/cmd/run/footer.width.ts +0 -27
- package/src/cli/cmd/run/permission.shared.ts +0 -256
- package/src/cli/cmd/run/prompt.editor.ts +0 -157
- package/src/cli/cmd/run/prompt.shared.ts +0 -153
- package/src/cli/cmd/run/question.shared.ts +0 -340
- package/src/cli/cmd/run/runtime.boot.ts +0 -202
- package/src/cli/cmd/run/runtime.lifecycle.ts +0 -406
- package/src/cli/cmd/run/runtime.queue.ts +0 -349
- package/src/cli/cmd/run/runtime.shared.ts +0 -17
- package/src/cli/cmd/run/runtime.stdin.ts +0 -37
- package/src/cli/cmd/run/runtime.ts +0 -814
- package/src/cli/cmd/run/scrollback.shared.ts +0 -92
- package/src/cli/cmd/run/scrollback.surface.ts +0 -431
- package/src/cli/cmd/run/scrollback.writer.tsx +0 -352
- package/src/cli/cmd/run/session-data.ts +0 -1113
- package/src/cli/cmd/run/session-replay.ts +0 -374
- package/src/cli/cmd/run/session.shared.ts +0 -196
- package/src/cli/cmd/run/splash.ts +0 -275
- package/src/cli/cmd/run/stream.transport.ts +0 -1462
- package/src/cli/cmd/run/stream.ts +0 -175
- package/src/cli/cmd/run/subagent-data.ts +0 -876
- package/src/cli/cmd/run/theme.ts +0 -690
- package/src/cli/cmd/run/tool.ts +0 -1489
- package/src/cli/cmd/run/trace.ts +0 -94
- package/src/cli/cmd/run/turn-summary.ts +0 -47
- package/src/cli/cmd/run/types.ts +0 -350
- package/src/cli/cmd/run/variant.shared.ts +0 -215
- package/src/cli/cmd/run.ts +0 -894
- package/src/cli/cmd/serve.ts +0 -24
- package/src/cli/cmd/session.ts +0 -147
- package/src/cli/cmd/stats.ts +0 -393
- package/src/cli/cmd/tui.ts +0 -224
- package/src/cli/cmd/uninstall.ts +0 -353
- package/src/cli/cmd/upgrade.ts +0 -74
- package/src/cli/cmd/web.ts +0 -84
- package/src/cli/effect/prompt.ts +0 -37
- package/src/cli/effect-cmd.ts +0 -96
- package/src/cli/error.ts +0 -130
- package/src/cli/heap.ts +0 -45
- package/src/cli/logo-pixel.ts +0 -35
- package/src/cli/logo.ts +0 -1
- package/src/cli/network.ts +0 -64
- package/src/cli/tui/layer.ts +0 -7
- package/src/cli/tui/validate-session.ts +0 -29
- package/src/cli/tui/worker.ts +0 -71
- package/src/cli/ui.ts +0 -148
- package/src/cli/upgrade.ts +0 -53
- package/src/command/index.ts +0 -184
- package/src/command/template/initialize.txt +0 -66
- package/src/command/template/review.txt +0 -101
- package/src/config/agent.ts +0 -59
- package/src/config/command.ts +0 -39
- package/src/config/config.ts +0 -686
- package/src/config/entry-name.ts +0 -19
- package/src/config/managed.ts +0 -69
- package/src/config/markdown.ts +0 -36
- package/src/config/parse.ts +0 -79
- package/src/config/paths.ts +0 -45
- package/src/config/plugin.ts +0 -79
- package/src/config/tui-cwd.ts +0 -5
- package/src/config/tui-host-attention.ts +0 -21
- package/src/config/tui-migrate.ts +0 -132
- package/src/config/tui.ts +0 -274
- package/src/config/variable.ts +0 -91
- package/src/control-plane/adapters/index.ts +0 -41
- package/src/control-plane/adapters/worktree.ts +0 -96
- package/src/control-plane/dev/README.md +0 -19
- package/src/control-plane/dev/debug-workspace-plugin.ts +0 -73
- package/src/control-plane/types.ts +0 -59
- package/src/control-plane/util.ts +0 -39
- package/src/control-plane/workspace-adapter-runtime.ts +0 -51
- package/src/control-plane/workspace-context.ts +0 -26
- package/src/control-plane/workspace.ts +0 -989
- package/src/effect/app-runtime.ts +0 -132
- package/src/effect/bootstrap-runtime.ts +0 -23
- package/src/effect/bridge.ts +0 -84
- package/src/effect/config-service.ts +0 -67
- package/src/effect/instance-ref.ts +0 -11
- package/src/effect/instance-registry.ts +0 -12
- package/src/effect/instance-state.ts +0 -69
- package/src/effect/promise.ts +0 -17
- package/src/effect/run-service.ts +0 -47
- package/src/effect/runner.ts +0 -217
- package/src/effect/runtime-flags.ts +0 -79
- package/src/env/index.ts +0 -43
- package/src/event-v2-bridge.ts +0 -79
- package/src/format/formatter.ts +0 -404
- package/src/format/index.ts +0 -205
- package/src/git/index.ts +0 -350
- package/src/id/id.ts +0 -80
- package/src/ide/index.ts +0 -61
- package/src/image/image.ts +0 -174
- package/src/index.ts +0 -142
- package/src/installation/index.ts +0 -350
- package/src/lsp/client.ts +0 -650
- package/src/lsp/diagnostic.ts +0 -29
- package/src/lsp/language.ts +0 -121
- package/src/lsp/launch.ts +0 -21
- package/src/lsp/lsp.ts +0 -511
- package/src/lsp/server.ts +0 -1983
- package/src/markdown.d.ts +0 -4
- package/src/mcp/auth.ts +0 -174
- package/src/mcp/catalog.ts +0 -153
- package/src/mcp/index.ts +0 -953
- package/src/mcp/oauth-callback.ts +0 -233
- package/src/mcp/oauth-provider.ts +0 -206
- package/src/node.ts +0 -4
- package/src/patch/index.ts +0 -686
- package/src/permission/arity.ts +0 -163
- package/src/permission/evaluate.ts +0 -1
- package/src/permission/index.ts +0 -230
- package/src/plugin/azure.ts +0 -26
- package/src/plugin/cloudflare.ts +0 -76
- package/src/plugin/digitalocean.ts +0 -383
- package/src/plugin/github-copilot/copilot.ts +0 -414
- package/src/plugin/github-copilot/models.ts +0 -246
- package/src/plugin/index.ts +0 -316
- package/src/plugin/install.ts +0 -439
- package/src/plugin/loader.ts +0 -237
- package/src/plugin/meta.ts +0 -188
- package/src/plugin/openai/README.md +0 -31
- package/src/plugin/openai/codex.ts +0 -641
- package/src/plugin/openai/ws-pool.ts +0 -270
- package/src/plugin/openai/ws.ts +0 -381
- package/src/plugin/pty-environment.ts +0 -24
- package/src/plugin/shared.ts +0 -323
- package/src/plugin/snowflake-cortex.ts +0 -529
- package/src/plugin/tui/internal.ts +0 -10
- package/src/plugin/tui/runtime.ts +0 -1130
- package/src/plugin/xai.ts +0 -716
- package/src/project/bootstrap-service.ts +0 -9
- package/src/project/bootstrap.ts +0 -76
- package/src/project/instance-context.ts +0 -24
- package/src/project/instance-layer.ts +0 -11
- package/src/project/instance-runtime.ts +0 -16
- package/src/project/instance-store.ts +0 -209
- package/src/project/project.ts +0 -519
- package/src/project/vcs.ts +0 -431
- package/src/provider/auth.ts +0 -233
- package/src/provider/error.ts +0 -188
- package/src/provider/model-status.ts +0 -8
- package/src/provider/provider.ts +0 -1975
- package/src/provider/transform.ts +0 -1543
- package/src/question/index.ts +0 -229
- package/src/question/schema.ts +0 -10
- package/src/server/auth.ts +0 -48
- package/src/server/event.ts +0 -13
- package/src/server/global-lifecycle.ts +0 -28
- package/src/server/init-projectors.ts +0 -3
- package/src/server/mdns.ts +0 -47
- package/src/server/projectors.ts +0 -1
- package/src/server/proxy-util.ts +0 -48
- package/src/server/routes/instance/httpapi/AGENTS.md +0 -39
- package/src/server/routes/instance/httpapi/api.ts +0 -78
- package/src/server/routes/instance/httpapi/errors.ts +0 -193
- package/src/server/routes/instance/httpapi/groups/config.ts +0 -65
- package/src/server/routes/instance/httpapi/groups/control-plane.ts +0 -35
- package/src/server/routes/instance/httpapi/groups/control.ts +0 -76
- package/src/server/routes/instance/httpapi/groups/event.ts +0 -29
- package/src/server/routes/instance/httpapi/groups/experimental.ts +0 -275
- package/src/server/routes/instance/httpapi/groups/file.ts +0 -185
- package/src/server/routes/instance/httpapi/groups/global.ts +0 -138
- package/src/server/routes/instance/httpapi/groups/instance.ts +0 -206
- package/src/server/routes/instance/httpapi/groups/mcp.ts +0 -156
- package/src/server/routes/instance/httpapi/groups/metadata.ts +0 -18
- package/src/server/routes/instance/httpapi/groups/permission.ts +0 -61
- package/src/server/routes/instance/httpapi/groups/project-copy.ts +0 -32
- package/src/server/routes/instance/httpapi/groups/project.ts +0 -93
- package/src/server/routes/instance/httpapi/groups/provider.ts +0 -101
- package/src/server/routes/instance/httpapi/groups/pty.ts +0 -172
- package/src/server/routes/instance/httpapi/groups/query.ts +0 -12
- package/src/server/routes/instance/httpapi/groups/question.ts +0 -74
- package/src/server/routes/instance/httpapi/groups/session.ts +0 -462
- package/src/server/routes/instance/httpapi/groups/sync.ts +0 -113
- package/src/server/routes/instance/httpapi/groups/tui.ts +0 -208
- package/src/server/routes/instance/httpapi/groups/workspace.ts +0 -141
- package/src/server/routes/instance/httpapi/handlers/config.ts +0 -34
- package/src/server/routes/instance/httpapi/handlers/control-plane.ts +0 -37
- package/src/server/routes/instance/httpapi/handlers/control.ts +0 -43
- package/src/server/routes/instance/httpapi/handlers/event.ts +0 -99
- package/src/server/routes/instance/httpapi/handlers/experimental.ts +0 -192
- package/src/server/routes/instance/httpapi/handlers/file.ts +0 -139
- package/src/server/routes/instance/httpapi/handlers/global.ts +0 -156
- package/src/server/routes/instance/httpapi/handlers/instance.ts +0 -110
- package/src/server/routes/instance/httpapi/handlers/mcp.ts +0 -111
- package/src/server/routes/instance/httpapi/handlers/permission.ts +0 -41
- package/src/server/routes/instance/httpapi/handlers/project-copy.ts +0 -83
- package/src/server/routes/instance/httpapi/handlers/project.ts +0 -63
- package/src/server/routes/instance/httpapi/handlers/provider.ts +0 -113
- package/src/server/routes/instance/httpapi/handlers/pty.ts +0 -273
- package/src/server/routes/instance/httpapi/handlers/question.ts +0 -54
- package/src/server/routes/instance/httpapi/handlers/session-errors.ts +0 -21
- package/src/server/routes/instance/httpapi/handlers/session.ts +0 -440
- package/src/server/routes/instance/httpapi/handlers/sync.ts +0 -89
- package/src/server/routes/instance/httpapi/handlers/tui.ts +0 -131
- package/src/server/routes/instance/httpapi/handlers/workspace.ts +0 -102
- package/src/server/routes/instance/httpapi/lifecycle.ts +0 -54
- package/src/server/routes/instance/httpapi/middleware/authorization.ts +0 -150
- package/src/server/routes/instance/httpapi/middleware/compression.ts +0 -64
- package/src/server/routes/instance/httpapi/middleware/cors-vary.ts +0 -29
- package/src/server/routes/instance/httpapi/middleware/error.ts +0 -43
- package/src/server/routes/instance/httpapi/middleware/fence.ts +0 -25
- package/src/server/routes/instance/httpapi/middleware/instance-context.ts +0 -43
- package/src/server/routes/instance/httpapi/middleware/proxy.ts +0 -108
- package/src/server/routes/instance/httpapi/middleware/schema-error.ts +0 -41
- package/src/server/routes/instance/httpapi/middleware/workspace-routing.ts +0 -250
- package/src/server/routes/instance/httpapi/public.ts +0 -535
- package/src/server/routes/instance/httpapi/server.ts +0 -298
- package/src/server/routes/instance/httpapi/websocket-tracker.ts +0 -57
- package/src/server/server.ts +0 -225
- package/src/server/shared/fence.ts +0 -60
- package/src/server/shared/pty-ticket.ts +0 -15
- package/src/server/shared/public-ui.ts +0 -12
- package/src/server/shared/tui-control.ts +0 -28
- package/src/server/shared/ui.ts +0 -108
- package/src/server/shared/workspace-routing.ts +0 -38
- package/src/server/tui-event.ts +0 -53
- package/src/session/compaction.ts +0 -620
- package/src/session/instruction.ts +0 -241
- package/src/session/llm/AGENTS.md +0 -90
- package/src/session/llm/ai-sdk.ts +0 -288
- package/src/session/llm/native-request.ts +0 -196
- package/src/session/llm/native-runtime.ts +0 -195
- package/src/session/llm/request.ts +0 -216
- package/src/session/llm.ts +0 -415
- package/src/session/message-error.ts +0 -14
- package/src/session/message-v2.ts +0 -747
- package/src/session/message.ts +0 -148
- package/src/session/overflow.ts +0 -34
- package/src/session/processor.ts +0 -1084
- package/src/session/prompt/anthropic.txt +0 -109
- package/src/session/prompt/beast.txt +0 -151
- package/src/session/prompt/build-switch.txt +0 -9
- package/src/session/prompt/codex.txt +0 -83
- package/src/session/prompt/copilot-gpt-5.txt +0 -147
- package/src/session/prompt/default.txt +0 -99
- package/src/session/prompt/gemini.txt +0 -159
- package/src/session/prompt/gpt.txt +0 -111
- package/src/session/prompt/kimi.txt +0 -99
- package/src/session/prompt/plan-mode.txt +0 -74
- package/src/session/prompt/plan-reminder-anthropic.txt +0 -71
- package/src/session/prompt/plan.txt +0 -30
- package/src/session/prompt/trinity.txt +0 -101
- package/src/session/prompt.ts +0 -1707
- package/src/session/reminders.ts +0 -92
- package/src/session/retry.ts +0 -201
- package/src/session/revert.ts +0 -160
- package/src/session/run-state.ts +0 -156
- package/src/session/schema.ts +0 -26
- package/src/session/session.ts +0 -1119
- package/src/session/status.ts +0 -97
- package/src/session/summary.ts +0 -165
- package/src/session/system.ts +0 -117
- package/src/session/todo.ts +0 -90
- package/src/session/tools.ts +0 -207
- package/src/share/session.ts +0 -61
- package/src/share/share-next.ts +0 -385
- package/src/skill/discovery.ts +0 -109
- package/src/skill/index.ts +0 -366
- package/src/snapshot/index.ts +0 -808
- package/src/sql.d.ts +0 -4
- package/src/storage/schema.ts +0 -5
- package/src/storage/storage.ts +0 -329
- package/src/sync/README.md +0 -179
- package/src/sync/schema.ts +0 -11
- package/src/temporary.ts +0 -31
- package/src/tool/apply_patch.ts +0 -315
- package/src/tool/apply_patch.txt +0 -33
- package/src/tool/apply_patch.zh.txt +0 -33
- package/src/tool/description.ts +0 -100
- package/src/tool/edit.ts +0 -739
- package/src/tool/edit.txt +0 -10
- package/src/tool/edit.zh.txt +0 -10
- package/src/tool/external-directory.ts +0 -49
- package/src/tool/glob.ts +0 -78
- package/src/tool/glob.txt +0 -6
- package/src/tool/glob.zh.txt +0 -6
- package/src/tool/grep.ts +0 -114
- package/src/tool/grep.txt +0 -8
- package/src/tool/grep.zh.txt +0 -8
- package/src/tool/invalid.ts +0 -21
- package/src/tool/json-schema.ts +0 -164
- package/src/tool/lsp.ts +0 -115
- package/src/tool/lsp.txt +0 -24
- package/src/tool/lsp.zh.txt +0 -24
- package/src/tool/mcp-websearch.ts +0 -96
- package/src/tool/plan-enter.txt +0 -14
- package/src/tool/plan-enter.zh.txt +0 -14
- package/src/tool/plan-exit.txt +0 -13
- package/src/tool/plan-exit.zh.txt +0 -13
- package/src/tool/plan.ts +0 -81
- package/src/tool/question.ts +0 -46
- package/src/tool/question.txt +0 -10
- package/src/tool/question.zh.txt +0 -10
- package/src/tool/read.ts +0 -388
- package/src/tool/read.txt +0 -14
- package/src/tool/read.zh.txt +0 -14
- package/src/tool/registry.ts +0 -440
- package/src/tool/schema.ts +0 -14
- package/src/tool/shell/id.ts +0 -19
- package/src/tool/shell/prompt.ts +0 -307
- package/src/tool/shell/shell.txt +0 -21
- package/src/tool/shell.ts +0 -657
- package/src/tool/skill.ts +0 -73
- package/src/tool/skill.txt +0 -5
- package/src/tool/skill.zh.txt +0 -5
- package/src/tool/task.ts +0 -348
- package/src/tool/task.txt +0 -19
- package/src/tool/task.zh.txt +0 -19
- package/src/tool/todo.ts +0 -59
- package/src/tool/todowrite.txt +0 -44
- package/src/tool/todowrite.zh.txt +0 -44
- package/src/tool/tool.ts +0 -183
- package/src/tool/truncate.ts +0 -158
- package/src/tool/truncation-dir.ts +0 -4
- package/src/tool/webfetch.ts +0 -194
- package/src/tool/webfetch.txt +0 -13
- package/src/tool/webfetch.zh.txt +0 -13
- package/src/tool/websearch.ts +0 -145
- package/src/tool/websearch.txt +0 -14
- package/src/tool/websearch.zh.txt +0 -14
- package/src/tool/write.ts +0 -106
- package/src/tool/write.txt +0 -8
- package/src/tool/write.zh.txt +0 -8
- package/src/util/archive.ts +0 -17
- package/src/util/bom.ts +0 -27
- package/src/util/data-url.ts +0 -9
- package/src/util/defer.ts +0 -10
- package/src/util/effect-http-client.ts +0 -11
- package/src/util/error.ts +0 -1
- package/src/util/filesystem.ts +0 -251
- package/src/util/html.ts +0 -8
- package/src/util/iife.ts +0 -3
- package/src/util/lazy.ts +0 -20
- package/src/util/local-context.ts +0 -25
- package/src/util/locale.ts +0 -2
- package/src/util/media.ts +0 -26
- package/src/util/process.ts +0 -177
- package/src/util/proxy-env.ts +0 -72
- package/src/util/queue.ts +0 -32
- package/src/util/record.ts +0 -1
- package/src/util/repository.ts +0 -232
- package/src/util/rpc.ts +0 -66
- package/src/util/signal.ts +0 -12
- package/src/util/timeout.ts +0 -13
- package/src/util/token.ts +0 -1
- package/src/util/wildcard.ts +0 -59
- package/src/worktree/index.ts +0 -654
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { ProxyUtil } from "@/server/proxy-util"
|
|
2
|
-
import { Effect, Stream } from "effect"
|
|
3
|
-
import { HttpBody, HttpClient, HttpClientRequest, HttpServerRequest, HttpServerResponse } from "effect/unstable/http"
|
|
4
|
-
import * as Socket from "effect/unstable/socket/Socket"
|
|
5
|
-
import { WebSocketTracker } from "../websocket-tracker"
|
|
6
|
-
|
|
7
|
-
function requestBody(request: HttpServerRequest.HttpServerRequest) {
|
|
8
|
-
if (request.method === "GET" || request.method === "HEAD") return HttpBody.empty
|
|
9
|
-
if (request.source instanceof Request && request.source.body === null) return HttpBody.empty
|
|
10
|
-
const len = request.headers["content-length"]
|
|
11
|
-
return HttpBody.stream(request.stream, request.headers["content-type"], len ? Number(len) : undefined)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function websocket(
|
|
15
|
-
request: HttpServerRequest.HttpServerRequest,
|
|
16
|
-
target: string | URL,
|
|
17
|
-
): Effect.Effect<HttpServerResponse.HttpServerResponse, never, Socket.WebSocketConstructor> {
|
|
18
|
-
return Effect.scoped(
|
|
19
|
-
Effect.gen(function* () {
|
|
20
|
-
const inbound = yield* Effect.orDie(request.upgrade)
|
|
21
|
-
const outbound = yield* Socket.makeWebSocket(ProxyUtil.websocketTargetURL(target), {
|
|
22
|
-
protocols: ProxyUtil.websocketProtocols(request.headers),
|
|
23
|
-
})
|
|
24
|
-
const writeInbound = yield* inbound.writer
|
|
25
|
-
const writeOutbound = yield* outbound.writer
|
|
26
|
-
const closeSocket = (socket: Socket.Socket, write: (event: Socket.CloseEvent) => Effect.Effect<void, unknown>) =>
|
|
27
|
-
socket
|
|
28
|
-
.runRaw(() => Effect.void, {
|
|
29
|
-
onOpen: write(WebSocketTracker.SERVER_CLOSING_EVENT()).pipe(Effect.catch(() => Effect.void)),
|
|
30
|
-
})
|
|
31
|
-
.pipe(
|
|
32
|
-
Effect.timeout("1 second"),
|
|
33
|
-
Effect.catchReason("SocketError", "SocketCloseError", () => Effect.void),
|
|
34
|
-
Effect.catch(() => Effect.void),
|
|
35
|
-
)
|
|
36
|
-
const closeAccepted = Effect.all([closeSocket(inbound, writeInbound), closeSocket(outbound, writeOutbound)], {
|
|
37
|
-
concurrency: "unbounded",
|
|
38
|
-
discard: true,
|
|
39
|
-
})
|
|
40
|
-
const registered = yield* WebSocketTracker.register(
|
|
41
|
-
Effect.all(
|
|
42
|
-
[
|
|
43
|
-
writeInbound(WebSocketTracker.SERVER_CLOSING_EVENT()),
|
|
44
|
-
writeOutbound(WebSocketTracker.SERVER_CLOSING_EVENT()),
|
|
45
|
-
],
|
|
46
|
-
{ concurrency: "unbounded", discard: true },
|
|
47
|
-
),
|
|
48
|
-
)
|
|
49
|
-
if (!registered) {
|
|
50
|
-
yield* closeAccepted
|
|
51
|
-
return HttpServerResponse.empty()
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
yield* outbound
|
|
55
|
-
.runRaw((message) => writeInbound(message))
|
|
56
|
-
.pipe(
|
|
57
|
-
Effect.catchReason("SocketError", "SocketCloseError", (reason) =>
|
|
58
|
-
writeInbound(new Socket.CloseEvent(reason.code, reason.closeReason)).pipe(Effect.catch(() => Effect.void)),
|
|
59
|
-
),
|
|
60
|
-
Effect.catch(() =>
|
|
61
|
-
writeInbound(new Socket.CloseEvent(1011, "proxy error")).pipe(Effect.catch(() => Effect.void)),
|
|
62
|
-
),
|
|
63
|
-
Effect.forkScoped,
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
yield* inbound
|
|
67
|
-
.runRaw((message) => {
|
|
68
|
-
return writeOutbound(typeof message === "string" ? message : message.slice())
|
|
69
|
-
})
|
|
70
|
-
.pipe(
|
|
71
|
-
Effect.catch(() => Effect.void),
|
|
72
|
-
Effect.ensuring(writeOutbound(new Socket.CloseEvent()).pipe(Effect.catch(() => Effect.void))),
|
|
73
|
-
)
|
|
74
|
-
return HttpServerResponse.empty()
|
|
75
|
-
}).pipe(Effect.orDie),
|
|
76
|
-
)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function statusText(response: unknown) {
|
|
80
|
-
return (response as { source?: Response }).source?.statusText
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function http(
|
|
84
|
-
client: HttpClient.HttpClient,
|
|
85
|
-
url: string | URL,
|
|
86
|
-
extra: HeadersInit | undefined,
|
|
87
|
-
request: HttpServerRequest.HttpServerRequest,
|
|
88
|
-
): Effect.Effect<HttpServerResponse.HttpServerResponse> {
|
|
89
|
-
return Effect.gen(function* () {
|
|
90
|
-
const response = yield* client.execute(
|
|
91
|
-
HttpClientRequest.make(request.method as never)(url, {
|
|
92
|
-
headers: ProxyUtil.headers(request.headers as HeadersInit, extra),
|
|
93
|
-
body: requestBody(request),
|
|
94
|
-
}),
|
|
95
|
-
)
|
|
96
|
-
const headers = new Headers(response.headers as HeadersInit)
|
|
97
|
-
headers.delete("content-encoding")
|
|
98
|
-
headers.delete("content-length")
|
|
99
|
-
|
|
100
|
-
return HttpServerResponse.stream(response.stream.pipe(Stream.catchCause(() => Stream.empty)), {
|
|
101
|
-
status: response.status,
|
|
102
|
-
statusText: statusText(response),
|
|
103
|
-
headers,
|
|
104
|
-
})
|
|
105
|
-
}).pipe(Effect.catch(() => Effect.succeed(HttpServerResponse.empty({ status: 500 }))))
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export * as HttpApiProxy from "./proxy"
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect"
|
|
2
|
-
import { HttpServerResponse } from "effect/unstable/http"
|
|
3
|
-
import { HttpApiMiddleware } from "effect/unstable/httpapi"
|
|
4
|
-
import { InvalidRequestError } from "../errors"
|
|
5
|
-
|
|
6
|
-
// Effect's Issue formatter recursively dumps the rejected `actual` value with
|
|
7
|
-
// no truncation, so a 5KB invalid array produces a ~360KB string. Cap to keep
|
|
8
|
-
// 4xx responses small and avoid mirroring entire request payloads (which may
|
|
9
|
-
// contain secrets) into the response body and log file.
|
|
10
|
-
const REASON_LIMIT = 1024
|
|
11
|
-
function truncateReason(reason: string) {
|
|
12
|
-
if (reason.length <= REASON_LIMIT) return reason
|
|
13
|
-
return reason.slice(0, REASON_LIMIT) + `… (${reason.length - REASON_LIMIT} more chars)`
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Default Respondable returns an empty 400 body. Match the NamedError shape
|
|
17
|
-
// used by other 4xx/5xx so the SDK's `wrapClientError` extracts `.data.message`.
|
|
18
|
-
export class SchemaErrorMiddleware extends HttpApiMiddleware.Service<SchemaErrorMiddleware>()(
|
|
19
|
-
"@opencode/HttpApiSchemaError",
|
|
20
|
-
{
|
|
21
|
-
error: InvalidRequestError,
|
|
22
|
-
},
|
|
23
|
-
) {}
|
|
24
|
-
|
|
25
|
-
export const schemaErrorLayer = HttpApiMiddleware.layerSchemaErrorTransform(SchemaErrorMiddleware, (error, context) => {
|
|
26
|
-
const reason = truncateReason(error.cause.message)
|
|
27
|
-
const response = context.endpoint.path.startsWith("/api/")
|
|
28
|
-
? Effect.fail(
|
|
29
|
-
new InvalidRequestError({
|
|
30
|
-
message: reason,
|
|
31
|
-
kind: error.kind,
|
|
32
|
-
}),
|
|
33
|
-
)
|
|
34
|
-
: Effect.succeed(
|
|
35
|
-
HttpServerResponse.jsonUnsafe(
|
|
36
|
-
{ name: "BadRequest", data: { message: reason, kind: error.kind } },
|
|
37
|
-
{ status: 400 },
|
|
38
|
-
),
|
|
39
|
-
)
|
|
40
|
-
return Effect.logWarning("schema rejection", { kind: error.kind, reason }).pipe(Effect.andThen(response))
|
|
41
|
-
})
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
import { WorkspaceV2 } from "@opencode-ai/core/workspace"
|
|
2
|
-
import type { Target } from "@/control-plane/types"
|
|
3
|
-
import { Workspace } from "@/control-plane/workspace"
|
|
4
|
-
import { WorkspaceAdapterRuntime } from "@/control-plane/workspace-adapter-runtime"
|
|
5
|
-
import { Session } from "@/session/session"
|
|
6
|
-
import { HttpApiProxy } from "./proxy"
|
|
7
|
-
import * as Fence from "@/server/shared/fence"
|
|
8
|
-
import { getWorkspaceRouteSessionID, isLocalWorkspaceRoute, workspaceProxyURL } from "@/server/shared/workspace-routing"
|
|
9
|
-
import { NotFoundError } from "@/storage/storage"
|
|
10
|
-
import { Flag } from "@opencode-ai/core/flag/flag"
|
|
11
|
-
import { Context, Data, Effect, Layer, Option, Schema } from "effect"
|
|
12
|
-
import { HttpClient, HttpServerRequest, HttpServerResponse } from "effect/unstable/http"
|
|
13
|
-
import { HttpApiMiddleware } from "effect/unstable/httpapi"
|
|
14
|
-
import * as Socket from "effect/unstable/socket/Socket"
|
|
15
|
-
import { InvalidRequestError } from "../errors"
|
|
16
|
-
|
|
17
|
-
// Query fields this middleware reads from the URL. Spread into every
|
|
18
|
-
// endpoint query schema in groups that apply WorkspaceRoutingMiddleware,
|
|
19
|
-
// otherwise HttpApi rejects requests carrying these params with 400.
|
|
20
|
-
// HttpApiMiddleware in effect-smol cannot declare query params today —
|
|
21
|
-
// remove this once upstream supports middleware-declared query schemas.
|
|
22
|
-
export const WorkspaceRoutingQueryFields = {
|
|
23
|
-
directory: Schema.optional(Schema.String),
|
|
24
|
-
workspace: Schema.optional(Schema.String),
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const WorkspaceRoutingQuery = Schema.Struct(WorkspaceRoutingQueryFields)
|
|
28
|
-
|
|
29
|
-
type RemoteTarget = Extract<Target, { type: "remote" }>
|
|
30
|
-
|
|
31
|
-
type RequestPlan = Data.TaggedEnum<{
|
|
32
|
-
InvalidWorkspace: {}
|
|
33
|
-
MissingWorkspace: { readonly workspaceID: WorkspaceV2.ID }
|
|
34
|
-
Local: { readonly directory: string; readonly workspaceID?: WorkspaceV2.ID }
|
|
35
|
-
Remote: {
|
|
36
|
-
readonly request: HttpServerRequest.HttpServerRequest
|
|
37
|
-
readonly workspace: Workspace.Info
|
|
38
|
-
readonly target: RemoteTarget
|
|
39
|
-
readonly url: URL
|
|
40
|
-
}
|
|
41
|
-
}>
|
|
42
|
-
const RequestPlan = Data.taggedEnum<RequestPlan>()
|
|
43
|
-
const InvalidWorkspaceID = Symbol("InvalidWorkspaceID")
|
|
44
|
-
|
|
45
|
-
export class WorkspaceRouteContext extends Context.Service<
|
|
46
|
-
WorkspaceRouteContext,
|
|
47
|
-
{
|
|
48
|
-
readonly directory: string
|
|
49
|
-
readonly workspaceID?: WorkspaceV2.ID
|
|
50
|
-
}
|
|
51
|
-
>()("@opencode/ExperimentalHttpApiWorkspaceRouteContext") {}
|
|
52
|
-
|
|
53
|
-
export class WorkspaceRoutingMiddleware extends HttpApiMiddleware.Service<
|
|
54
|
-
WorkspaceRoutingMiddleware,
|
|
55
|
-
{
|
|
56
|
-
provides: WorkspaceRouteContext
|
|
57
|
-
requires: Session.Service
|
|
58
|
-
}
|
|
59
|
-
>()("@opencode/ExperimentalHttpApiWorkspaceRouting") {}
|
|
60
|
-
|
|
61
|
-
function requestURL(request: HttpServerRequest.HttpServerRequest): URL {
|
|
62
|
-
return new URL(request.url, "http://localhost")
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function configuredWorkspaceID(): WorkspaceV2.ID | undefined {
|
|
66
|
-
return Flag.OPENCODE_WORKSPACE_ID ? WorkspaceV2.ID.make(Flag.OPENCODE_WORKSPACE_ID) : undefined
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function selectedWorkspaceID(url: URL, sessionWorkspaceID?: WorkspaceV2.ID): WorkspaceV2.ID | undefined {
|
|
70
|
-
const workspaceParam = url.searchParams.get("workspace")
|
|
71
|
-
return sessionWorkspaceID ?? (workspaceParam ? WorkspaceV2.ID.make(workspaceParam) : undefined)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function selectedV2WorkspaceID(
|
|
75
|
-
url: URL,
|
|
76
|
-
sessionWorkspaceID?: WorkspaceV2.ID,
|
|
77
|
-
): WorkspaceV2.ID | typeof InvalidWorkspaceID | undefined {
|
|
78
|
-
if (sessionWorkspaceID) return sessionWorkspaceID
|
|
79
|
-
const workspaceParam = url.searchParams.get("workspace")
|
|
80
|
-
if (!workspaceParam) return undefined
|
|
81
|
-
const workspaceID = Schema.decodeUnknownOption(WorkspaceV2.ID)(workspaceParam)
|
|
82
|
-
if (Option.isNone(workspaceID)) return InvalidWorkspaceID
|
|
83
|
-
return workspaceID.value
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function defaultDirectory(request: HttpServerRequest.HttpServerRequest, url: URL): string {
|
|
87
|
-
return url.searchParams.get("directory") || request.headers["x-opencode-directory"] || process.cwd()
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function shouldStayOnControlPlane(request: HttpServerRequest.HttpServerRequest, url: URL): boolean {
|
|
91
|
-
return isLocalWorkspaceRoute(request.method, url.pathname) || url.pathname.startsWith("/console")
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function resolveWorkspace(
|
|
95
|
-
id: WorkspaceV2.ID | undefined,
|
|
96
|
-
envWorkspaceID: WorkspaceV2.ID | undefined,
|
|
97
|
-
): Effect.Effect<Workspace.Info | void, never, Workspace.Service> {
|
|
98
|
-
if (!id || envWorkspaceID) return Effect.void
|
|
99
|
-
return Workspace.Service.use((workspace) => workspace.get(id))
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function missingWorkspaceResponse(id: WorkspaceV2.ID): HttpServerResponse.HttpServerResponse {
|
|
103
|
-
return HttpServerResponse.text(`Workspace not found: ${id}`, {
|
|
104
|
-
status: 500,
|
|
105
|
-
contentType: "text/plain; charset=utf-8",
|
|
106
|
-
})
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function resolveTarget(workspace: Workspace.Info): Effect.Effect<Target> {
|
|
110
|
-
return WorkspaceAdapterRuntime.target(workspace)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function proxyRemote(
|
|
114
|
-
client: HttpClient.HttpClient,
|
|
115
|
-
request: HttpServerRequest.HttpServerRequest,
|
|
116
|
-
workspace: Workspace.Info,
|
|
117
|
-
target: RemoteTarget,
|
|
118
|
-
url: URL,
|
|
119
|
-
): Effect.Effect<HttpServerResponse.HttpServerResponse, never, Socket.WebSocketConstructor | Workspace.Service> {
|
|
120
|
-
return Effect.gen(function* () {
|
|
121
|
-
const syncing = yield* Workspace.Service.use((svc) => svc.isSyncing(workspace.id))
|
|
122
|
-
if (!syncing) {
|
|
123
|
-
return HttpServerResponse.text(`broken sync connection for workspace: ${workspace.id}`, {
|
|
124
|
-
status: 503,
|
|
125
|
-
contentType: "text/plain; charset=utf-8",
|
|
126
|
-
})
|
|
127
|
-
}
|
|
128
|
-
const proxyURL = workspaceProxyURL(target.url, url)
|
|
129
|
-
const headers = request.headers as Record<string, string>
|
|
130
|
-
if (headers["upgrade"]?.toLowerCase() === "websocket") return yield* HttpApiProxy.websocket(request, proxyURL)
|
|
131
|
-
const response = yield* HttpApiProxy.http(client, proxyURL, target.headers, request)
|
|
132
|
-
const sync = Fence.parse(new Headers(response.headers))
|
|
133
|
-
if (sync) {
|
|
134
|
-
const syncFailure = yield* Fence.wait(
|
|
135
|
-
workspace.id,
|
|
136
|
-
sync,
|
|
137
|
-
request.source instanceof Request ? request.source.signal : undefined,
|
|
138
|
-
).pipe(
|
|
139
|
-
Effect.as(undefined),
|
|
140
|
-
Effect.catch((error) => Effect.succeed(HttpServerResponse.text(error.message, { status: 503 }))),
|
|
141
|
-
)
|
|
142
|
-
if (syncFailure) return syncFailure
|
|
143
|
-
}
|
|
144
|
-
return response
|
|
145
|
-
})
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function planWorkspaceRequest(
|
|
149
|
-
request: HttpServerRequest.HttpServerRequest,
|
|
150
|
-
url: URL,
|
|
151
|
-
workspace: Workspace.Info,
|
|
152
|
-
): Effect.Effect<RequestPlan, never, Workspace.Service> {
|
|
153
|
-
return Effect.gen(function* () {
|
|
154
|
-
const target = yield* resolveTarget(workspace)
|
|
155
|
-
if (target.type === "remote") return RequestPlan.Remote({ request, workspace, target, url })
|
|
156
|
-
return RequestPlan.Local({ directory: target.directory, workspaceID: workspace.id })
|
|
157
|
-
})
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function planRequest(
|
|
161
|
-
request: HttpServerRequest.HttpServerRequest,
|
|
162
|
-
session?: Session.Info,
|
|
163
|
-
): Effect.Effect<RequestPlan, never, Workspace.Service> {
|
|
164
|
-
return Effect.gen(function* () {
|
|
165
|
-
const url = requestURL(request)
|
|
166
|
-
const envWorkspaceID = configuredWorkspaceID()
|
|
167
|
-
const workspaceID = url.pathname.startsWith("/api/")
|
|
168
|
-
? selectedV2WorkspaceID(url, session?.workspaceID)
|
|
169
|
-
: selectedWorkspaceID(url, session?.workspaceID)
|
|
170
|
-
if (workspaceID === InvalidWorkspaceID) return RequestPlan.InvalidWorkspace()
|
|
171
|
-
const workspace = yield* resolveWorkspace(workspaceID, envWorkspaceID)
|
|
172
|
-
|
|
173
|
-
if (workspaceID && workspace === undefined && !envWorkspaceID) {
|
|
174
|
-
return RequestPlan.MissingWorkspace({ workspaceID })
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if (workspace !== undefined && !envWorkspaceID && !shouldStayOnControlPlane(request, url)) {
|
|
178
|
-
return yield* planWorkspaceRequest(request, url, workspace)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return RequestPlan.Local({
|
|
182
|
-
directory: session?.directory || defaultDirectory(request, url),
|
|
183
|
-
workspaceID: envWorkspaceID ?? workspaceID,
|
|
184
|
-
})
|
|
185
|
-
})
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function routeWorkspace<E>(
|
|
189
|
-
client: HttpClient.HttpClient,
|
|
190
|
-
effect: Effect.Effect<HttpServerResponse.HttpServerResponse, E, WorkspaceRouteContext>,
|
|
191
|
-
plan: RequestPlan,
|
|
192
|
-
): Effect.Effect<HttpServerResponse.HttpServerResponse, E, Socket.WebSocketConstructor | Workspace.Service> {
|
|
193
|
-
return RequestPlan.$match(plan, {
|
|
194
|
-
InvalidWorkspace: () =>
|
|
195
|
-
Effect.succeed(
|
|
196
|
-
HttpServerResponse.jsonUnsafe(
|
|
197
|
-
new InvalidRequestError({
|
|
198
|
-
message: "Invalid workspace query parameter",
|
|
199
|
-
kind: "Query",
|
|
200
|
-
field: "workspace",
|
|
201
|
-
}),
|
|
202
|
-
{ status: 400 },
|
|
203
|
-
),
|
|
204
|
-
),
|
|
205
|
-
MissingWorkspace: ({ workspaceID }) => Effect.succeed(missingWorkspaceResponse(workspaceID)),
|
|
206
|
-
Remote: ({ request, workspace, target, url }) => proxyRemote(client, request, workspace, target, url),
|
|
207
|
-
Local: ({ directory, workspaceID }) =>
|
|
208
|
-
effect.pipe(Effect.provideService(WorkspaceRouteContext, WorkspaceRouteContext.of({ directory, workspaceID }))),
|
|
209
|
-
})
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function routeHttpApiWorkspace<E>(
|
|
213
|
-
client: HttpClient.HttpClient,
|
|
214
|
-
effect: Effect.Effect<HttpServerResponse.HttpServerResponse, E, WorkspaceRouteContext>,
|
|
215
|
-
): Effect.Effect<
|
|
216
|
-
HttpServerResponse.HttpServerResponse,
|
|
217
|
-
E,
|
|
218
|
-
Session.Service | Workspace.Service | HttpServerRequest.HttpServerRequest | Socket.WebSocketConstructor
|
|
219
|
-
> {
|
|
220
|
-
return Effect.gen(function* () {
|
|
221
|
-
const request = yield* HttpServerRequest.HttpServerRequest
|
|
222
|
-
const sessionID = getWorkspaceRouteSessionID(requestURL(request))
|
|
223
|
-
const session = sessionID
|
|
224
|
-
? yield* Session.Service.use((svc) => svc.get(sessionID)).pipe(
|
|
225
|
-
Effect.catchIf(
|
|
226
|
-
(error): error is NotFoundError => NotFoundError.isInstance(error),
|
|
227
|
-
() => Effect.succeed(undefined),
|
|
228
|
-
),
|
|
229
|
-
Effect.catchDefect(() => Effect.succeed(undefined)),
|
|
230
|
-
)
|
|
231
|
-
: undefined
|
|
232
|
-
const plan = yield* planRequest(request, session)
|
|
233
|
-
return yield* routeWorkspace(client, effect, plan)
|
|
234
|
-
})
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
export const workspaceRoutingLayer = Layer.effect(
|
|
238
|
-
WorkspaceRoutingMiddleware,
|
|
239
|
-
Effect.gen(function* () {
|
|
240
|
-
const makeWebSocket = yield* Socket.WebSocketConstructor
|
|
241
|
-
const workspace = yield* Workspace.Service
|
|
242
|
-
const client = yield* HttpClient.HttpClient
|
|
243
|
-
return WorkspaceRoutingMiddleware.of((effect) =>
|
|
244
|
-
routeHttpApiWorkspace(client, effect).pipe(
|
|
245
|
-
Effect.provideService(Socket.WebSocketConstructor, makeWebSocket),
|
|
246
|
-
Effect.provideService(Workspace.Service, workspace),
|
|
247
|
-
),
|
|
248
|
-
)
|
|
249
|
-
}),
|
|
250
|
-
)
|