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
package/src/cli/cmd/acp.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect"
|
|
2
|
-
import { effectCmd } from "../effect-cmd"
|
|
3
|
-
import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk"
|
|
4
|
-
import { ServerAuth } from "@/server/auth"
|
|
5
|
-
import { createOpencodeClient } from "@opencode-ai/sdk/v2"
|
|
6
|
-
import { withNetworkOptions, resolveNetworkOptions } from "../network"
|
|
7
|
-
import { ACPProfile } from "@/acp/profile"
|
|
8
|
-
|
|
9
|
-
export const AcpCommand = effectCmd({
|
|
10
|
-
command: "acp",
|
|
11
|
-
describe: "start ACP (Agent Client Protocol) server",
|
|
12
|
-
builder: (yargs) => {
|
|
13
|
-
return withNetworkOptions(yargs).option("cwd", {
|
|
14
|
-
describe: "working directory",
|
|
15
|
-
type: "string",
|
|
16
|
-
default: process.cwd(),
|
|
17
|
-
})
|
|
18
|
-
},
|
|
19
|
-
handler: Effect.fn("Cli.acp")(function* (args) {
|
|
20
|
-
const { Server } = yield* Effect.promise(() => import("@/server/server"))
|
|
21
|
-
const { ACP } = yield* Effect.promise(() => import("@/acp/agent"))
|
|
22
|
-
ACPProfile.mark("cli.acp.handler")
|
|
23
|
-
process.env.OPENCODE_CLIENT = "acp"
|
|
24
|
-
const opts = yield* resolveNetworkOptions(args)
|
|
25
|
-
const server = yield* Effect.promise(() => ACPProfile.measure("cli.acp.server.listen", () => Server.listen(opts)))
|
|
26
|
-
|
|
27
|
-
const sdk = createOpencodeClient({
|
|
28
|
-
baseUrl: `http://${server.hostname}:${server.port}`,
|
|
29
|
-
headers: ServerAuth.headers(),
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
const input = new WritableStream<Uint8Array>({
|
|
33
|
-
write(chunk) {
|
|
34
|
-
return new Promise<void>((resolve, reject) => {
|
|
35
|
-
process.stdout.write(chunk, (err) => {
|
|
36
|
-
if (err) {
|
|
37
|
-
reject(err)
|
|
38
|
-
} else {
|
|
39
|
-
resolve()
|
|
40
|
-
}
|
|
41
|
-
})
|
|
42
|
-
})
|
|
43
|
-
},
|
|
44
|
-
})
|
|
45
|
-
const output = new ReadableStream<Uint8Array>({
|
|
46
|
-
start(controller) {
|
|
47
|
-
process.stdin.on("data", (chunk: Buffer) => {
|
|
48
|
-
controller.enqueue(new Uint8Array(chunk))
|
|
49
|
-
})
|
|
50
|
-
process.stdin.on("end", () => controller.close())
|
|
51
|
-
process.stdin.on("error", (err) => controller.error(err))
|
|
52
|
-
},
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
const stream = ndJsonStream(input, output)
|
|
56
|
-
const agent = ACP.init({ sdk })
|
|
57
|
-
|
|
58
|
-
new AgentSideConnection((conn) => {
|
|
59
|
-
ACPProfile.mark("cli.acp.connection.create")
|
|
60
|
-
return agent.create(conn)
|
|
61
|
-
}, stream)
|
|
62
|
-
|
|
63
|
-
yield* Effect.logInfo("setup connection")
|
|
64
|
-
process.stdin.resume()
|
|
65
|
-
yield* Effect.promise(
|
|
66
|
-
() =>
|
|
67
|
-
new Promise<void>((resolve, reject) => {
|
|
68
|
-
process.stdin.on("end", () => resolve())
|
|
69
|
-
process.stdin.on("error", reject)
|
|
70
|
-
}),
|
|
71
|
-
)
|
|
72
|
-
}),
|
|
73
|
-
})
|
package/src/cli/cmd/agent.ts
DELETED
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import { cmd } from "./cmd"
|
|
2
|
-
import * as prompts from "@clack/prompts"
|
|
3
|
-
import { UI } from "../ui"
|
|
4
|
-
import { Global } from "@opencode-ai/core/global"
|
|
5
|
-
import path from "path"
|
|
6
|
-
import fs from "fs/promises"
|
|
7
|
-
import { Filesystem } from "@/util/filesystem"
|
|
8
|
-
import matter from "gray-matter"
|
|
9
|
-
import { EOL } from "os"
|
|
10
|
-
import type { Argv } from "yargs"
|
|
11
|
-
import { Effect } from "effect"
|
|
12
|
-
import { effectCmd } from "../effect-cmd"
|
|
13
|
-
|
|
14
|
-
type AgentMode = "all" | "primary" | "subagent"
|
|
15
|
-
|
|
16
|
-
// Permission keys (not raw tool names). Multiple tools can map to a single
|
|
17
|
-
// permission — e.g. write/edit/apply_patch all gate on `edit` — so we configure
|
|
18
|
-
// agents at the permission level to match how the runtime actually enforces it.
|
|
19
|
-
const AVAILABLE_PERMISSIONS = [
|
|
20
|
-
"bash",
|
|
21
|
-
"read",
|
|
22
|
-
"edit",
|
|
23
|
-
"glob",
|
|
24
|
-
"grep",
|
|
25
|
-
"webfetch",
|
|
26
|
-
"task",
|
|
27
|
-
"todowrite",
|
|
28
|
-
"websearch",
|
|
29
|
-
"lsp",
|
|
30
|
-
"skill",
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
const AgentCreateCommand = effectCmd({
|
|
34
|
-
command: "create",
|
|
35
|
-
describe: "create a new agent",
|
|
36
|
-
builder: (yargs: Argv) =>
|
|
37
|
-
yargs
|
|
38
|
-
.option("path", {
|
|
39
|
-
type: "string",
|
|
40
|
-
describe: "directory path to generate the agent file",
|
|
41
|
-
})
|
|
42
|
-
.option("description", {
|
|
43
|
-
type: "string",
|
|
44
|
-
describe: "what the agent should do",
|
|
45
|
-
})
|
|
46
|
-
.option("mode", {
|
|
47
|
-
type: "string",
|
|
48
|
-
describe: "agent mode",
|
|
49
|
-
choices: ["all", "primary", "subagent"] as const,
|
|
50
|
-
})
|
|
51
|
-
.option("permissions", {
|
|
52
|
-
type: "string",
|
|
53
|
-
alias: ["tools"],
|
|
54
|
-
describe: `comma-separated list of permissions to allow (default: all). Available: "${AVAILABLE_PERMISSIONS.join(", ")}"`,
|
|
55
|
-
})
|
|
56
|
-
.option("model", {
|
|
57
|
-
type: "string",
|
|
58
|
-
alias: ["m"],
|
|
59
|
-
describe: "model to use in the format of provider/model",
|
|
60
|
-
}),
|
|
61
|
-
handler: Effect.fn("Cli.agent.create")(function* (args) {
|
|
62
|
-
const { InstanceRef } = yield* Effect.promise(() => import("@/effect/instance-ref"))
|
|
63
|
-
const { Agent } = yield* Effect.promise(() => import("../../agent/agent"))
|
|
64
|
-
const { Provider } = yield* Effect.promise(() => import("@/provider/provider"))
|
|
65
|
-
const maybeCtx = yield* InstanceRef
|
|
66
|
-
if (!maybeCtx) return yield* Effect.die("InstanceRef not provided")
|
|
67
|
-
const ctx = maybeCtx
|
|
68
|
-
const agentSvc = yield* Agent.Service
|
|
69
|
-
const runLocalEffect = <A, E>(effect: Effect.Effect<A, E>) =>
|
|
70
|
-
Effect.runPromise(effect.pipe(Effect.provideService(InstanceRef, ctx)))
|
|
71
|
-
yield* Effect.promise(async () => {
|
|
72
|
-
const cliPath = args.path
|
|
73
|
-
const cliDescription = args.description
|
|
74
|
-
const cliMode = args.mode as AgentMode | undefined
|
|
75
|
-
const perms = args.permissions
|
|
76
|
-
|
|
77
|
-
const isFullyNonInteractive = cliPath && cliDescription && cliMode && perms !== undefined
|
|
78
|
-
|
|
79
|
-
if (!isFullyNonInteractive) {
|
|
80
|
-
UI.empty()
|
|
81
|
-
prompts.intro("Create agent")
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const project = ctx.project
|
|
85
|
-
|
|
86
|
-
// Determine scope/path
|
|
87
|
-
let targetPath: string
|
|
88
|
-
if (cliPath) {
|
|
89
|
-
targetPath = path.join(cliPath, "agents")
|
|
90
|
-
} else {
|
|
91
|
-
let scope: "global" | "project" = "global"
|
|
92
|
-
if (project.vcs === "git") {
|
|
93
|
-
const scopeResult = await prompts.select({
|
|
94
|
-
message: "Location",
|
|
95
|
-
options: [
|
|
96
|
-
{
|
|
97
|
-
label: "Current project",
|
|
98
|
-
value: "project" as const,
|
|
99
|
-
hint: ctx.worktree,
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
label: "Global",
|
|
103
|
-
value: "global" as const,
|
|
104
|
-
hint: Global.Path.config,
|
|
105
|
-
},
|
|
106
|
-
],
|
|
107
|
-
})
|
|
108
|
-
if (prompts.isCancel(scopeResult)) throw new UI.CancelledError()
|
|
109
|
-
scope = scopeResult
|
|
110
|
-
}
|
|
111
|
-
targetPath = path.join(scope === "global" ? Global.Path.config : path.join(ctx.worktree, ".opencode"), "agents")
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Get description
|
|
115
|
-
let description: string
|
|
116
|
-
if (cliDescription) {
|
|
117
|
-
description = cliDescription
|
|
118
|
-
} else {
|
|
119
|
-
const query = await prompts.text({
|
|
120
|
-
message: "Description",
|
|
121
|
-
placeholder: "What should this agent do?",
|
|
122
|
-
validate: (x) => (x && x.length > 0 ? undefined : "Required"),
|
|
123
|
-
})
|
|
124
|
-
if (prompts.isCancel(query)) throw new UI.CancelledError()
|
|
125
|
-
description = query
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Generate agent
|
|
129
|
-
const spinner = prompts.spinner()
|
|
130
|
-
spinner.start("Generating agent configuration...")
|
|
131
|
-
const model = args.model ? Provider.parseModel(args.model) : undefined
|
|
132
|
-
const generated = await runLocalEffect(agentSvc.generate({ description, model })).catch((error) => {
|
|
133
|
-
spinner.stop(`LLM failed to generate agent: ${error.message}`, 1)
|
|
134
|
-
if (isFullyNonInteractive) process.exit(1)
|
|
135
|
-
throw new UI.CancelledError()
|
|
136
|
-
})
|
|
137
|
-
spinner.stop(`Agent ${generated.identifier} generated`)
|
|
138
|
-
|
|
139
|
-
// Select permissions to allow
|
|
140
|
-
let selected: string[]
|
|
141
|
-
if (perms !== undefined) {
|
|
142
|
-
selected = perms ? perms.split(",").map((t) => t.trim()) : AVAILABLE_PERMISSIONS
|
|
143
|
-
} else {
|
|
144
|
-
const result = await prompts.multiselect({
|
|
145
|
-
message: "Select permissions to allow (Space to toggle)",
|
|
146
|
-
options: AVAILABLE_PERMISSIONS.map((permission) => ({
|
|
147
|
-
label: permission,
|
|
148
|
-
value: permission,
|
|
149
|
-
})),
|
|
150
|
-
initialValues: AVAILABLE_PERMISSIONS,
|
|
151
|
-
})
|
|
152
|
-
if (prompts.isCancel(result)) throw new UI.CancelledError()
|
|
153
|
-
selected = result
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Get mode
|
|
157
|
-
let mode: AgentMode
|
|
158
|
-
if (cliMode) {
|
|
159
|
-
mode = cliMode
|
|
160
|
-
} else {
|
|
161
|
-
const modeResult = await prompts.select({
|
|
162
|
-
message: "Agent mode",
|
|
163
|
-
options: [
|
|
164
|
-
{
|
|
165
|
-
label: "All",
|
|
166
|
-
value: "all" as const,
|
|
167
|
-
hint: "Can function in both primary and subagent roles",
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
label: "Primary",
|
|
171
|
-
value: "primary" as const,
|
|
172
|
-
hint: "Acts as a primary/main agent",
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
label: "Subagent",
|
|
176
|
-
value: "subagent" as const,
|
|
177
|
-
hint: "Can be used as a subagent by other agents",
|
|
178
|
-
},
|
|
179
|
-
],
|
|
180
|
-
initialValue: "all" as const,
|
|
181
|
-
})
|
|
182
|
-
if (prompts.isCancel(modeResult)) throw new UI.CancelledError()
|
|
183
|
-
mode = modeResult
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// Build permissions config — deny anything not explicitly selected.
|
|
187
|
-
const permissions: Record<string, "deny"> = {}
|
|
188
|
-
for (const permission of AVAILABLE_PERMISSIONS) {
|
|
189
|
-
if (!selected.includes(permission)) {
|
|
190
|
-
permissions[permission] = "deny"
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Build frontmatter
|
|
195
|
-
const frontmatter: {
|
|
196
|
-
description: string
|
|
197
|
-
mode: AgentMode
|
|
198
|
-
permission?: Record<string, "deny">
|
|
199
|
-
} = {
|
|
200
|
-
description: generated.whenToUse,
|
|
201
|
-
mode,
|
|
202
|
-
}
|
|
203
|
-
if (Object.keys(permissions).length > 0) {
|
|
204
|
-
frontmatter.permission = permissions
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Write file
|
|
208
|
-
const content = matter.stringify(generated.systemPrompt, frontmatter)
|
|
209
|
-
const filePath = path.join(targetPath, `${generated.identifier}.md`)
|
|
210
|
-
|
|
211
|
-
await fs.mkdir(targetPath, { recursive: true })
|
|
212
|
-
|
|
213
|
-
if (await Filesystem.exists(filePath)) {
|
|
214
|
-
if (isFullyNonInteractive) {
|
|
215
|
-
console.error(`Error: Agent file already exists: ${filePath}`)
|
|
216
|
-
process.exit(1)
|
|
217
|
-
}
|
|
218
|
-
prompts.log.error(`Agent file already exists: ${filePath}`)
|
|
219
|
-
throw new UI.CancelledError()
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
await Filesystem.write(filePath, content)
|
|
223
|
-
|
|
224
|
-
if (isFullyNonInteractive) {
|
|
225
|
-
console.log(filePath)
|
|
226
|
-
} else {
|
|
227
|
-
prompts.log.success(`Agent created: ${filePath}`)
|
|
228
|
-
prompts.outro("Done")
|
|
229
|
-
}
|
|
230
|
-
})
|
|
231
|
-
}),
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
const AgentListCommand = effectCmd({
|
|
235
|
-
command: "list",
|
|
236
|
-
describe: "list all available agents",
|
|
237
|
-
handler: Effect.fn("Cli.agent.list")(function* () {
|
|
238
|
-
const { Agent } = yield* Effect.promise(() => import("../../agent/agent"))
|
|
239
|
-
const agents = yield* Agent.Service.use((svc) => svc.list())
|
|
240
|
-
const sortedAgents = agents.sort((a, b) => {
|
|
241
|
-
if (a.native !== b.native) {
|
|
242
|
-
return a.native ? -1 : 1
|
|
243
|
-
}
|
|
244
|
-
return a.name.localeCompare(b.name)
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
for (const agent of sortedAgents) {
|
|
248
|
-
process.stdout.write(`${agent.name} (${agent.mode})` + EOL)
|
|
249
|
-
process.stdout.write(` ${JSON.stringify(agent.permission, null, 2)}` + EOL)
|
|
250
|
-
}
|
|
251
|
-
}),
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
export const AgentCommand = cmd({
|
|
255
|
-
command: "agent",
|
|
256
|
-
describe: "manage agents",
|
|
257
|
-
builder: (yargs) => yargs.command(AgentCreateCommand).command(AgentListCommand).demandCommand(),
|
|
258
|
-
async handler() {},
|
|
259
|
-
})
|
package/src/cli/cmd/attach.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { cmd } from "./cmd"
|
|
2
|
-
import { UI } from "@/cli/ui"
|
|
3
|
-
import { errorMessage } from "@opencode-ai/tui/util/error"
|
|
4
|
-
import { validateSession } from "../tui/validate-session"
|
|
5
|
-
import { ServerAuth } from "@/server/auth"
|
|
6
|
-
|
|
7
|
-
export const AttachCommand = cmd({
|
|
8
|
-
command: "attach <url>",
|
|
9
|
-
describe: "attach to a running opencode server",
|
|
10
|
-
builder: (yargs) =>
|
|
11
|
-
yargs
|
|
12
|
-
.positional("url", {
|
|
13
|
-
type: "string",
|
|
14
|
-
describe: "http://localhost:4096",
|
|
15
|
-
demandOption: true,
|
|
16
|
-
})
|
|
17
|
-
.option("dir", {
|
|
18
|
-
type: "string",
|
|
19
|
-
description: "directory to run in",
|
|
20
|
-
})
|
|
21
|
-
.option("continue", {
|
|
22
|
-
alias: ["c"],
|
|
23
|
-
describe: "continue the last session",
|
|
24
|
-
type: "boolean",
|
|
25
|
-
})
|
|
26
|
-
.option("session", {
|
|
27
|
-
alias: ["s"],
|
|
28
|
-
type: "string",
|
|
29
|
-
describe: "session id to continue",
|
|
30
|
-
})
|
|
31
|
-
.option("fork", {
|
|
32
|
-
type: "boolean",
|
|
33
|
-
describe: "fork the session when continuing (use with --continue or --session)",
|
|
34
|
-
})
|
|
35
|
-
.option("password", {
|
|
36
|
-
alias: ["p"],
|
|
37
|
-
type: "string",
|
|
38
|
-
describe: "basic auth password (defaults to OPENCODE_SERVER_PASSWORD)",
|
|
39
|
-
})
|
|
40
|
-
.option("username", {
|
|
41
|
-
alias: ["u"],
|
|
42
|
-
type: "string",
|
|
43
|
-
describe: "basic auth username (defaults to OPENCODE_SERVER_USERNAME or 'opencode')",
|
|
44
|
-
}),
|
|
45
|
-
handler: async (args) => {
|
|
46
|
-
const { TuiConfig } = await import("@/config/tui")
|
|
47
|
-
if (args.fork && !args.continue && !args.session) {
|
|
48
|
-
UI.error("--fork requires --continue or --session")
|
|
49
|
-
process.exitCode = 1
|
|
50
|
-
return
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const directory = (() => {
|
|
54
|
-
if (!args.dir) return undefined
|
|
55
|
-
try {
|
|
56
|
-
process.chdir(args.dir)
|
|
57
|
-
return process.cwd()
|
|
58
|
-
} catch {
|
|
59
|
-
// If the directory doesn't exist locally (remote attach), pass it through.
|
|
60
|
-
return args.dir
|
|
61
|
-
}
|
|
62
|
-
})()
|
|
63
|
-
const headers = ServerAuth.headers({ password: args.password, username: args.username })
|
|
64
|
-
const config = await TuiConfig.get()
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
await validateSession({
|
|
68
|
-
url: args.url,
|
|
69
|
-
sessionID: args.session,
|
|
70
|
-
directory,
|
|
71
|
-
headers,
|
|
72
|
-
})
|
|
73
|
-
} catch (error) {
|
|
74
|
-
UI.error(errorMessage(error))
|
|
75
|
-
process.exitCode = 1
|
|
76
|
-
return
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const { Effect } = await import("effect")
|
|
80
|
-
const { run } = await import("../tui/layer")
|
|
81
|
-
const { createLegacyTuiPluginHost } = await import("@/plugin/tui/runtime")
|
|
82
|
-
await Effect.runPromise(
|
|
83
|
-
run({
|
|
84
|
-
url: args.url,
|
|
85
|
-
config,
|
|
86
|
-
pluginHost: createLegacyTuiPluginHost(),
|
|
87
|
-
args: {
|
|
88
|
-
continue: args.continue,
|
|
89
|
-
sessionID: args.session,
|
|
90
|
-
fork: args.fork,
|
|
91
|
-
},
|
|
92
|
-
directory,
|
|
93
|
-
headers,
|
|
94
|
-
}),
|
|
95
|
-
)
|
|
96
|
-
},
|
|
97
|
-
})
|
package/src/cli/cmd/cmd.ts
DELETED
package/src/cli/cmd/db.ts
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import type { Argv } from "yargs"
|
|
2
|
-
import { spawn } from "child_process"
|
|
3
|
-
import { Database } from "@opencode-ai/core/database/database"
|
|
4
|
-
import { Effect } from "effect"
|
|
5
|
-
import { sql } from "drizzle-orm"
|
|
6
|
-
import { effectCmd } from "../effect-cmd"
|
|
7
|
-
|
|
8
|
-
const QueryCommand = effectCmd({
|
|
9
|
-
command: "$0 [query]",
|
|
10
|
-
describe: "open an interactive sqlite3 shell or run a query",
|
|
11
|
-
instance: false,
|
|
12
|
-
builder: (yargs: Argv) => {
|
|
13
|
-
return yargs
|
|
14
|
-
.positional("query", {
|
|
15
|
-
type: "string",
|
|
16
|
-
describe: "SQL query to execute",
|
|
17
|
-
})
|
|
18
|
-
.option("format", {
|
|
19
|
-
type: "string",
|
|
20
|
-
choices: ["json", "tsv"],
|
|
21
|
-
default: "tsv",
|
|
22
|
-
describe: "Output format",
|
|
23
|
-
})
|
|
24
|
-
},
|
|
25
|
-
handler: Effect.fn("Cli.db.query")(function* (args: { query?: string; format: string }) {
|
|
26
|
-
const query = args.query as string | undefined
|
|
27
|
-
if (query) {
|
|
28
|
-
const { db } = yield* Database.Service
|
|
29
|
-
const result = yield* db.all<Record<string, unknown>>(sql.raw(query)).pipe(Effect.orDie)
|
|
30
|
-
if (args.format === "json") console.log(JSON.stringify(result, null, 2))
|
|
31
|
-
else if (result.length > 0) {
|
|
32
|
-
const keys = Object.keys(result[0])
|
|
33
|
-
console.log(keys.join("\t"))
|
|
34
|
-
for (const row of result) console.log(keys.map((key) => row[key]).join("\t"))
|
|
35
|
-
}
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
const child = spawn("sqlite3", [Database.path()], {
|
|
39
|
-
stdio: "inherit",
|
|
40
|
-
})
|
|
41
|
-
yield* Effect.promise(() => new Promise((resolve) => child.on("close", resolve)))
|
|
42
|
-
}),
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
const PathCommand = effectCmd({
|
|
46
|
-
command: "path",
|
|
47
|
-
describe: "print the database path",
|
|
48
|
-
instance: false,
|
|
49
|
-
handler: Effect.fn("Cli.db.path")(function* () {
|
|
50
|
-
console.log(Database.path())
|
|
51
|
-
}),
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
export const DbCommand = effectCmd({
|
|
55
|
-
command: "db",
|
|
56
|
-
describe: "database tools",
|
|
57
|
-
instance: false,
|
|
58
|
-
builder: (yargs: Argv) => {
|
|
59
|
-
return yargs.command(QueryCommand).command(PathCommand).demandCommand()
|
|
60
|
-
},
|
|
61
|
-
handler: Effect.fn("Cli.db")(function* () {}),
|
|
62
|
-
})
|
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
|
2
|
-
import { EOL } from "os"
|
|
3
|
-
import { SessionV1 } from "@opencode-ai/core/v1/session"
|
|
4
|
-
import { basename } from "path"
|
|
5
|
-
import { Cause, Effect } from "effect"
|
|
6
|
-
import { Agent } from "../../../agent/agent"
|
|
7
|
-
import { Provider } from "@/provider/provider"
|
|
8
|
-
import { Session } from "@/session/session"
|
|
9
|
-
import type { MessageV2 } from "../../../session/message-v2"
|
|
10
|
-
import { MessageID, PartID } from "../../../session/schema"
|
|
11
|
-
import { ToolRegistry } from "@/tool/registry"
|
|
12
|
-
import { Permission } from "../../../permission"
|
|
13
|
-
import { iife } from "../../../util/iife"
|
|
14
|
-
import { fail } from "../../effect-cmd"
|
|
15
|
-
import { InstanceRef } from "@/effect/instance-ref"
|
|
16
|
-
import type { InstanceContext } from "@/project/instance-context"
|
|
17
|
-
|
|
18
|
-
export const debugAgent = Effect.fn("Cli.debug.agent")(function* (args: {
|
|
19
|
-
name: string
|
|
20
|
-
tool?: string
|
|
21
|
-
params?: string
|
|
22
|
-
}) {
|
|
23
|
-
const ctx = yield* InstanceRef
|
|
24
|
-
if (!ctx) return
|
|
25
|
-
return yield* run(args, ctx)
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
const run = Effect.fn("Cli.debug.agent.body")(function* (
|
|
29
|
-
args: { name: string; tool?: string; params?: string },
|
|
30
|
-
ctx: InstanceContext,
|
|
31
|
-
) {
|
|
32
|
-
const agentName = args.name
|
|
33
|
-
const agent = yield* Agent.Service.use((svc) => svc.get(agentName))
|
|
34
|
-
if (!agent) {
|
|
35
|
-
process.stderr.write(
|
|
36
|
-
`Agent ${agentName} not found, run '${basename(process.execPath)} agent list' to get an agent list` + EOL,
|
|
37
|
-
)
|
|
38
|
-
return yield* fail("", 1)
|
|
39
|
-
}
|
|
40
|
-
const availableTools = yield* getAvailableTools(agent)
|
|
41
|
-
const resolvedTools = resolveTools(agent, availableTools)
|
|
42
|
-
const toolID = args.tool
|
|
43
|
-
if (toolID) {
|
|
44
|
-
const tool = availableTools.find((item) => item.id === toolID)
|
|
45
|
-
if (!tool) {
|
|
46
|
-
process.stderr.write(`Tool ${toolID} not found for agent ${agentName}` + EOL)
|
|
47
|
-
return yield* fail("", 1)
|
|
48
|
-
}
|
|
49
|
-
if (resolvedTools[toolID] === false) {
|
|
50
|
-
process.stderr.write(`Tool ${toolID} is disabled for agent ${agentName}` + EOL)
|
|
51
|
-
return yield* fail("", 1)
|
|
52
|
-
}
|
|
53
|
-
const params = parseToolParams(args.params)
|
|
54
|
-
const toolCtx = yield* createToolContext(agent, ctx)
|
|
55
|
-
const result = yield* tool.execute(params, toolCtx)
|
|
56
|
-
process.stdout.write(JSON.stringify({ tool: toolID, input: params, result }, null, 2) + EOL)
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const output = {
|
|
61
|
-
...agent,
|
|
62
|
-
tools: resolvedTools,
|
|
63
|
-
}
|
|
64
|
-
process.stdout.write(JSON.stringify(output, null, 2) + EOL)
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
const getAvailableTools = Effect.fn("Cli.debug.agent.getAvailableTools")(function* (agent: Agent.Info) {
|
|
68
|
-
const provider = yield* Provider.Service
|
|
69
|
-
const registry = yield* ToolRegistry.Service
|
|
70
|
-
const model =
|
|
71
|
-
agent.model ??
|
|
72
|
-
(yield* provider.defaultModel().pipe(
|
|
73
|
-
Effect.matchCauseEffect({
|
|
74
|
-
onSuccess: Effect.succeed,
|
|
75
|
-
onFailure: (cause) => {
|
|
76
|
-
const error = Cause.squash(cause) as Provider.DefaultModelError
|
|
77
|
-
if (error instanceof Provider.ModelNotFoundError) {
|
|
78
|
-
return fail(`Model not found: ${error.providerID}/${error.modelID}`)
|
|
79
|
-
}
|
|
80
|
-
if (error instanceof Provider.NoModelsError) return fail(`No models found for provider ${error.providerID}`)
|
|
81
|
-
return fail("No providers found")
|
|
82
|
-
},
|
|
83
|
-
}),
|
|
84
|
-
))
|
|
85
|
-
return yield* registry.tools({ ...model, agent })
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
function resolveTools(agent: Agent.Info, availableTools: { id: string }[]) {
|
|
89
|
-
const disabled = Permission.disabled(
|
|
90
|
-
availableTools.map((tool) => tool.id),
|
|
91
|
-
agent.permission,
|
|
92
|
-
)
|
|
93
|
-
const resolved: Record<string, boolean> = {}
|
|
94
|
-
for (const tool of availableTools) {
|
|
95
|
-
resolved[tool.id] = !disabled.has(tool.id)
|
|
96
|
-
}
|
|
97
|
-
return resolved
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function parseToolParams(input?: string) {
|
|
101
|
-
if (!input) return {}
|
|
102
|
-
const trimmed = input.trim()
|
|
103
|
-
if (trimmed.length === 0) return {}
|
|
104
|
-
|
|
105
|
-
const parsed = iife(() => {
|
|
106
|
-
try {
|
|
107
|
-
return JSON.parse(trimmed)
|
|
108
|
-
} catch (jsonError) {
|
|
109
|
-
try {
|
|
110
|
-
return new Function(`return (${trimmed})`)()
|
|
111
|
-
} catch (evalError) {
|
|
112
|
-
throw new Error(
|
|
113
|
-
`Failed to parse --params. Use JSON or a JS object literal. JSON error: ${jsonError}. Eval error: ${evalError}.`,
|
|
114
|
-
{ cause: evalError },
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
121
|
-
throw new Error("Tool params must be an object.")
|
|
122
|
-
}
|
|
123
|
-
return parsed as Record<string, unknown>
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const createToolContext = Effect.fn("Cli.debug.agent.createToolContext")(function* (
|
|
127
|
-
agent: Agent.Info,
|
|
128
|
-
ctx: InstanceContext,
|
|
129
|
-
) {
|
|
130
|
-
const sessionSvc = yield* Session.Service
|
|
131
|
-
const session = yield* sessionSvc.create({ title: `Debug tool run (${agent.name})` })
|
|
132
|
-
const messageID = MessageID.ascending()
|
|
133
|
-
const model = agent.model
|
|
134
|
-
? agent.model
|
|
135
|
-
: yield* Effect.gen(function* () {
|
|
136
|
-
const provider = yield* Provider.Service
|
|
137
|
-
return yield* provider.defaultModel().pipe(
|
|
138
|
-
Effect.matchCauseEffect({
|
|
139
|
-
onSuccess: Effect.succeed,
|
|
140
|
-
onFailure: (cause) => {
|
|
141
|
-
const error = Cause.squash(cause) as Provider.DefaultModelError
|
|
142
|
-
if (error instanceof Provider.ModelNotFoundError) {
|
|
143
|
-
return fail(`Model not found: ${error.providerID}/${error.modelID}`)
|
|
144
|
-
}
|
|
145
|
-
if (error instanceof Provider.NoModelsError)
|
|
146
|
-
return fail(`No models found for provider ${error.providerID}`)
|
|
147
|
-
return fail("No providers found")
|
|
148
|
-
},
|
|
149
|
-
}),
|
|
150
|
-
)
|
|
151
|
-
})
|
|
152
|
-
const now = Date.now()
|
|
153
|
-
const message: SessionV1.Assistant = {
|
|
154
|
-
id: messageID,
|
|
155
|
-
sessionID: session.id,
|
|
156
|
-
role: "assistant",
|
|
157
|
-
time: { created: now },
|
|
158
|
-
parentID: messageID,
|
|
159
|
-
modelID: model.modelID,
|
|
160
|
-
providerID: model.providerID,
|
|
161
|
-
mode: "debug",
|
|
162
|
-
agent: agent.name,
|
|
163
|
-
path: {
|
|
164
|
-
cwd: ctx.directory,
|
|
165
|
-
root: ctx.worktree,
|
|
166
|
-
},
|
|
167
|
-
cost: 0,
|
|
168
|
-
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
169
|
-
}
|
|
170
|
-
yield* sessionSvc.updateMessage(message)
|
|
171
|
-
|
|
172
|
-
const ruleset = Permission.merge(agent.permission, session.permission ?? [])
|
|
173
|
-
|
|
174
|
-
return {
|
|
175
|
-
sessionID: session.id,
|
|
176
|
-
messageID,
|
|
177
|
-
callID: PartID.ascending(),
|
|
178
|
-
agent: agent.name,
|
|
179
|
-
abort: new AbortController().signal,
|
|
180
|
-
messages: [],
|
|
181
|
-
metadata: () => Effect.void,
|
|
182
|
-
ask(req: Omit<PermissionV1.Request, "id" | "sessionID" | "tool">) {
|
|
183
|
-
return Effect.sync(() => {
|
|
184
|
-
for (const pattern of req.patterns) {
|
|
185
|
-
const rule = Permission.evaluate(req.permission, pattern, ruleset)
|
|
186
|
-
if (rule.action === "deny") {
|
|
187
|
-
throw new PermissionV1.DeniedError({ ruleset })
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
})
|
|
191
|
-
},
|
|
192
|
-
}
|
|
193
|
-
})
|