cerebras-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +27 -0
- package/Dockerfile +10 -0
- package/README.md +15 -0
- package/bin/opencode +84 -0
- package/bunfig.toml +4 -0
- package/package.json +128 -0
- package/parsers-config.ts +239 -0
- package/script/build.ts +151 -0
- package/script/postinstall.mjs +122 -0
- package/script/publish.ts +256 -0
- package/script/schema.ts +47 -0
- package/src/acp/README.md +164 -0
- package/src/acp/agent.ts +812 -0
- package/src/acp/session.ts +70 -0
- package/src/acp/types.ts +22 -0
- package/src/agent/agent.ts +310 -0
- package/src/agent/generate.txt +75 -0
- package/src/auth/index.ts +70 -0
- package/src/bun/index.ts +152 -0
- package/src/bus/global.ts +10 -0
- package/src/bus/index.ts +142 -0
- package/src/cli/bootstrap.ts +17 -0
- package/src/cli/cmd/acp.ts +88 -0
- package/src/cli/cmd/agent.ts +165 -0
- package/src/cli/cmd/auth.ts +369 -0
- package/src/cli/cmd/cmd.ts +7 -0
- package/src/cli/cmd/debug/config.ts +15 -0
- package/src/cli/cmd/debug/file.ts +91 -0
- package/src/cli/cmd/debug/index.ts +41 -0
- package/src/cli/cmd/debug/lsp.ts +47 -0
- package/src/cli/cmd/debug/ripgrep.ts +83 -0
- package/src/cli/cmd/debug/scrap.ts +15 -0
- package/src/cli/cmd/debug/snapshot.ts +48 -0
- package/src/cli/cmd/export.ts +88 -0
- package/src/cli/cmd/generate.ts +38 -0
- package/src/cli/cmd/github.ts +1200 -0
- package/src/cli/cmd/import.ts +98 -0
- package/src/cli/cmd/mcp.ts +400 -0
- package/src/cli/cmd/models.ts +77 -0
- package/src/cli/cmd/pr.ts +112 -0
- package/src/cli/cmd/run.ts +342 -0
- package/src/cli/cmd/serve.ts +31 -0
- package/src/cli/cmd/session.ts +106 -0
- package/src/cli/cmd/stats.ts +298 -0
- package/src/cli/cmd/tui/app.tsx +732 -0
- package/src/cli/cmd/tui/attach.ts +25 -0
- package/src/cli/cmd/tui/component/border.tsx +21 -0
- package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
- package/src/cli/cmd/tui/component/dialog-command.tsx +124 -0
- package/src/cli/cmd/tui/component/dialog-feedback.tsx +160 -0
- package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
- package/src/cli/cmd/tui/component/dialog-model.tsx +223 -0
- package/src/cli/cmd/tui/component/dialog-notification.tsx +78 -0
- package/src/cli/cmd/tui/component/dialog-provider.tsx +222 -0
- package/src/cli/cmd/tui/component/dialog-session-list.tsx +97 -0
- package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
- package/src/cli/cmd/tui/component/dialog-status.tsx +114 -0
- package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
- package/src/cli/cmd/tui/component/dialog-theme-list.tsx +50 -0
- package/src/cli/cmd/tui/component/logo.tsx +37 -0
- package/src/cli/cmd/tui/component/notification-banner.tsx +58 -0
- package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +530 -0
- package/src/cli/cmd/tui/component/prompt/history.tsx +107 -0
- package/src/cli/cmd/tui/component/prompt/index.tsx +931 -0
- package/src/cli/cmd/tui/context/args.tsx +14 -0
- package/src/cli/cmd/tui/context/directory.ts +12 -0
- package/src/cli/cmd/tui/context/exit.tsx +23 -0
- package/src/cli/cmd/tui/context/helper.tsx +25 -0
- package/src/cli/cmd/tui/context/keybind.tsx +111 -0
- package/src/cli/cmd/tui/context/kv.tsx +49 -0
- package/src/cli/cmd/tui/context/local.tsx +339 -0
- package/src/cli/cmd/tui/context/prompt.tsx +18 -0
- package/src/cli/cmd/tui/context/route.tsx +45 -0
- package/src/cli/cmd/tui/context/sdk.tsx +75 -0
- package/src/cli/cmd/tui/context/sync.tsx +374 -0
- package/src/cli/cmd/tui/context/theme/aura.json +69 -0
- package/src/cli/cmd/tui/context/theme/ayu.json +80 -0
- package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +233 -0
- package/src/cli/cmd/tui/context/theme/catppuccin.json +112 -0
- package/src/cli/cmd/tui/context/theme/cobalt2.json +228 -0
- package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
- package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
- package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
- package/src/cli/cmd/tui/context/theme/github.json +233 -0
- package/src/cli/cmd/tui/context/theme/gruvbox.json +95 -0
- package/src/cli/cmd/tui/context/theme/kanagawa.json +77 -0
- package/src/cli/cmd/tui/context/theme/material.json +235 -0
- package/src/cli/cmd/tui/context/theme/matrix.json +77 -0
- package/src/cli/cmd/tui/context/theme/mercury.json +252 -0
- package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
- package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
- package/src/cli/cmd/tui/context/theme/nord.json +223 -0
- package/src/cli/cmd/tui/context/theme/one-dark.json +84 -0
- package/src/cli/cmd/tui/context/theme/orng.json +245 -0
- package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
- package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
- package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
- package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
- package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
- package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
- package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
- package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
- package/src/cli/cmd/tui/context/theme.tsx +1077 -0
- package/src/cli/cmd/tui/event.ts +39 -0
- package/src/cli/cmd/tui/routes/home.tsx +104 -0
- package/src/cli/cmd/tui/routes/session/dialog-message.tsx +93 -0
- package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +37 -0
- package/src/cli/cmd/tui/routes/session/footer.tsx +76 -0
- package/src/cli/cmd/tui/routes/session/header.tsx +183 -0
- package/src/cli/cmd/tui/routes/session/index.tsx +1703 -0
- package/src/cli/cmd/tui/routes/session/sidebar.tsx +586 -0
- package/src/cli/cmd/tui/spawn.ts +60 -0
- package/src/cli/cmd/tui/thread.ts +120 -0
- package/src/cli/cmd/tui/ui/dialog-alert.tsx +55 -0
- package/src/cli/cmd/tui/ui/dialog-confirm.tsx +81 -0
- package/src/cli/cmd/tui/ui/dialog-help.tsx +36 -0
- package/src/cli/cmd/tui/ui/dialog-prompt.tsx +75 -0
- package/src/cli/cmd/tui/ui/dialog-select.tsx +317 -0
- package/src/cli/cmd/tui/ui/dialog.tsx +170 -0
- package/src/cli/cmd/tui/ui/spinner.ts +368 -0
- package/src/cli/cmd/tui/ui/toast.tsx +100 -0
- package/src/cli/cmd/tui/util/clipboard.ts +127 -0
- package/src/cli/cmd/tui/util/editor.ts +32 -0
- package/src/cli/cmd/tui/util/terminal.ts +114 -0
- package/src/cli/cmd/tui/worker.ts +63 -0
- package/src/cli/cmd/uninstall.ts +344 -0
- package/src/cli/cmd/upgrade.ts +67 -0
- package/src/cli/cmd/web.ts +84 -0
- package/src/cli/error.ts +55 -0
- package/src/cli/ui.ts +84 -0
- package/src/cli/upgrade.ts +25 -0
- package/src/command/index.ts +79 -0
- package/src/command/template/initialize.txt +10 -0
- package/src/command/template/review.txt +73 -0
- package/src/config/config.ts +886 -0
- package/src/config/markdown.ts +41 -0
- package/src/env/index.ts +26 -0
- package/src/file/fzf.ts +124 -0
- package/src/file/ignore.ts +83 -0
- package/src/file/index.ts +326 -0
- package/src/file/ripgrep.ts +391 -0
- package/src/file/time.ts +38 -0
- package/src/file/watcher.ts +89 -0
- package/src/flag/flag.ts +28 -0
- package/src/format/formatter.ts +277 -0
- package/src/format/index.ts +137 -0
- package/src/global/index.ts +52 -0
- package/src/id/id.ts +73 -0
- package/src/ide/index.ts +75 -0
- package/src/index.ts +158 -0
- package/src/installation/index.ts +194 -0
- package/src/lsp/client.ts +215 -0
- package/src/lsp/index.ts +370 -0
- package/src/lsp/language.ts +111 -0
- package/src/lsp/server.ts +1327 -0
- package/src/mcp/auth.ts +82 -0
- package/src/mcp/index.ts +576 -0
- package/src/mcp/oauth-callback.ts +203 -0
- package/src/mcp/oauth-provider.ts +132 -0
- package/src/notification/index.ts +101 -0
- package/src/patch/index.ts +622 -0
- package/src/permission/index.ts +198 -0
- package/src/plugin/index.ts +95 -0
- package/src/project/bootstrap.ts +31 -0
- package/src/project/instance.ts +68 -0
- package/src/project/project.ts +133 -0
- package/src/project/state.ts +65 -0
- package/src/project/vcs.ts +77 -0
- package/src/provider/auth.ts +143 -0
- package/src/provider/models-macro.ts +11 -0
- package/src/provider/models.ts +93 -0
- package/src/provider/provider.ts +996 -0
- package/src/provider/sdk/openai-compatible/src/README.md +5 -0
- package/src/provider/sdk/openai-compatible/src/index.ts +2 -0
- package/src/provider/sdk/openai-compatible/src/openai-compatible-provider.ts +100 -0
- package/src/provider/sdk/openai-compatible/src/responses/convert-to-openai-responses-input.ts +303 -0
- package/src/provider/sdk/openai-compatible/src/responses/map-openai-responses-finish-reason.ts +27 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-config.ts +18 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-error.ts +22 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-api-types.ts +207 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-language-model.ts +1713 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-prepare-tools.ts +177 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-settings.ts +1 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/code-interpreter.ts +88 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/file-search.ts +128 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/image-generation.ts +115 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/local-shell.ts +65 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/web-search-preview.ts +104 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/web-search.ts +103 -0
- package/src/provider/transform.ts +406 -0
- package/src/pty/index.ts +226 -0
- package/src/ratelimit/index.ts +185 -0
- package/src/server/error.ts +36 -0
- package/src/server/project.ts +50 -0
- package/src/server/server.ts +2463 -0
- package/src/server/tui.ts +71 -0
- package/src/session/compaction.ts +257 -0
- package/src/session/index.ts +470 -0
- package/src/session/message-v2.ts +641 -0
- package/src/session/message.ts +189 -0
- package/src/session/processor.ts +443 -0
- package/src/session/prompt/anthropic-20250930.txt +166 -0
- package/src/session/prompt/anthropic.txt +105 -0
- package/src/session/prompt/anthropic_spoof.txt +1 -0
- package/src/session/prompt/beast.txt +147 -0
- package/src/session/prompt/build-switch.txt +5 -0
- package/src/session/prompt/codex.txt +318 -0
- package/src/session/prompt/compaction.txt +12 -0
- package/src/session/prompt/copilot-gpt-5.txt +143 -0
- package/src/session/prompt/gemini.txt +155 -0
- package/src/session/prompt/max-steps.txt +16 -0
- package/src/session/prompt/plan-reminder-anthropic.txt +67 -0
- package/src/session/prompt/plan.txt +26 -0
- package/src/session/prompt/polaris.txt +107 -0
- package/src/session/prompt/qwen.txt +109 -0
- package/src/session/prompt/summarize.txt +4 -0
- package/src/session/prompt/title.txt +36 -0
- package/src/session/prompt.ts +1541 -0
- package/src/session/retry.ts +82 -0
- package/src/session/revert.ts +108 -0
- package/src/session/status.ts +75 -0
- package/src/session/summary.ts +203 -0
- package/src/session/system.ts +148 -0
- package/src/session/todo.ts +36 -0
- package/src/share/share-next.ts +195 -0
- package/src/share/share.ts +87 -0
- package/src/snapshot/index.ts +197 -0
- package/src/storage/storage.ts +226 -0
- package/src/telemetry/index.ts +232 -0
- package/src/tool/bash.ts +365 -0
- package/src/tool/bash.txt +128 -0
- package/src/tool/batch.ts +173 -0
- package/src/tool/batch.txt +28 -0
- package/src/tool/codesearch.ts +138 -0
- package/src/tool/codesearch.txt +12 -0
- package/src/tool/edit.ts +674 -0
- package/src/tool/edit.txt +10 -0
- package/src/tool/glob.ts +65 -0
- package/src/tool/glob.txt +6 -0
- package/src/tool/grep.ts +120 -0
- package/src/tool/grep.txt +8 -0
- package/src/tool/invalid.ts +17 -0
- package/src/tool/ls.ts +110 -0
- package/src/tool/ls.txt +1 -0
- package/src/tool/lsp-diagnostics.ts +26 -0
- package/src/tool/lsp-diagnostics.txt +1 -0
- package/src/tool/lsp-hover.ts +31 -0
- package/src/tool/lsp-hover.txt +1 -0
- package/src/tool/multiedit.ts +46 -0
- package/src/tool/multiedit.txt +41 -0
- package/src/tool/patch.ts +233 -0
- package/src/tool/patch.txt +1 -0
- package/src/tool/read.ts +217 -0
- package/src/tool/read.txt +12 -0
- package/src/tool/registry.ts +148 -0
- package/src/tool/task.ts +135 -0
- package/src/tool/task.txt +60 -0
- package/src/tool/todo.ts +39 -0
- package/src/tool/todoread.txt +14 -0
- package/src/tool/todowrite.txt +167 -0
- package/src/tool/tool.ts +66 -0
- package/src/tool/webfetch.ts +187 -0
- package/src/tool/webfetch.txt +14 -0
- package/src/tool/websearch.ts +150 -0
- package/src/tool/websearch.txt +11 -0
- package/src/tool/write.ts +99 -0
- package/src/tool/write.txt +8 -0
- package/src/types/shims.d.ts +3 -0
- package/src/util/color.ts +19 -0
- package/src/util/context.ts +25 -0
- package/src/util/defer.ts +12 -0
- package/src/util/eventloop.ts +20 -0
- package/src/util/filesystem.ts +69 -0
- package/src/util/fn.ts +11 -0
- package/src/util/iife.ts +3 -0
- package/src/util/keybind.ts +79 -0
- package/src/util/lazy.ts +11 -0
- package/src/util/locale.ts +81 -0
- package/src/util/lock.ts +98 -0
- package/src/util/log.ts +177 -0
- package/src/util/queue.ts +32 -0
- package/src/util/rpc.ts +42 -0
- package/src/util/scrap.ts +10 -0
- package/src/util/signal.ts +12 -0
- package/src/util/timeout.ts +14 -0
- package/src/util/token.ts +7 -0
- package/src/util/wildcard.ts +54 -0
- package/sst-env.d.ts +9 -0
- package/test/bun.test.ts +53 -0
- package/test/config/agent-color.test.ts +66 -0
- package/test/config/config.test.ts +503 -0
- package/test/config/markdown.test.ts +89 -0
- package/test/file/ignore.test.ts +10 -0
- package/test/fixture/fixture.ts +28 -0
- package/test/fixture/lsp/fake-lsp-server.js +77 -0
- package/test/ide/ide.test.ts +82 -0
- package/test/keybind.test.ts +317 -0
- package/test/lsp/client.test.ts +95 -0
- package/test/patch/patch.test.ts +348 -0
- package/test/preload.ts +38 -0
- package/test/project/project.test.ts +42 -0
- package/test/provider/provider.test.ts +1809 -0
- package/test/provider/transform.test.ts +305 -0
- package/test/session/retry.test.ts +61 -0
- package/test/session/session.test.ts +71 -0
- package/test/snapshot/snapshot.test.ts +939 -0
- package/test/tool/__snapshots__/tool.test.ts.snap +9 -0
- package/test/tool/bash.test.ts +55 -0
- package/test/tool/patch.test.ts +259 -0
- package/test/util/iife.test.ts +36 -0
- package/test/util/lazy.test.ts +50 -0
- package/test/util/timeout.test.ts +21 -0
- package/test/util/wildcard.test.ts +55 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "fs"
|
|
4
|
+
import path from "path"
|
|
5
|
+
import os from "os"
|
|
6
|
+
import { fileURLToPath } from "url"
|
|
7
|
+
import { createRequire } from "module"
|
|
8
|
+
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
10
|
+
const require = createRequire(import.meta.url)
|
|
11
|
+
|
|
12
|
+
function detectPlatformAndArch() {
|
|
13
|
+
// Map platform names
|
|
14
|
+
let platform
|
|
15
|
+
switch (os.platform()) {
|
|
16
|
+
case "darwin":
|
|
17
|
+
platform = "darwin"
|
|
18
|
+
break
|
|
19
|
+
case "linux":
|
|
20
|
+
platform = "linux"
|
|
21
|
+
break
|
|
22
|
+
case "win32":
|
|
23
|
+
platform = "windows"
|
|
24
|
+
break
|
|
25
|
+
default:
|
|
26
|
+
platform = os.platform()
|
|
27
|
+
break
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Map architecture names
|
|
31
|
+
let arch
|
|
32
|
+
switch (os.arch()) {
|
|
33
|
+
case "x64":
|
|
34
|
+
arch = "x64"
|
|
35
|
+
break
|
|
36
|
+
case "arm64":
|
|
37
|
+
arch = "arm64"
|
|
38
|
+
break
|
|
39
|
+
case "arm":
|
|
40
|
+
arch = "arm"
|
|
41
|
+
break
|
|
42
|
+
default:
|
|
43
|
+
arch = os.arch()
|
|
44
|
+
break
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return { platform, arch }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function findBinary() {
|
|
51
|
+
const { platform, arch } = detectPlatformAndArch()
|
|
52
|
+
const packageName = `opencode-${platform}-${arch}`
|
|
53
|
+
const binaryName = platform === "windows" ? "opencode.exe" : "opencode"
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
// Use require.resolve to find the package
|
|
57
|
+
const packageJsonPath = require.resolve(`${packageName}/package.json`)
|
|
58
|
+
const packageDir = path.dirname(packageJsonPath)
|
|
59
|
+
const binaryPath = path.join(packageDir, "bin", binaryName)
|
|
60
|
+
|
|
61
|
+
if (!fs.existsSync(binaryPath)) {
|
|
62
|
+
throw new Error(`Binary not found at ${binaryPath}`)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return { binaryPath, binaryName }
|
|
66
|
+
} catch (error) {
|
|
67
|
+
throw new Error(`Could not find package ${packageName}: ${error.message}`)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function prepareBinDirectory(binaryName) {
|
|
72
|
+
const binDir = path.join(__dirname, "bin")
|
|
73
|
+
const targetPath = path.join(binDir, binaryName)
|
|
74
|
+
|
|
75
|
+
// Ensure bin directory exists
|
|
76
|
+
if (!fs.existsSync(binDir)) {
|
|
77
|
+
fs.mkdirSync(binDir, { recursive: true })
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Remove existing binary/symlink if it exists
|
|
81
|
+
if (fs.existsSync(targetPath)) {
|
|
82
|
+
fs.unlinkSync(targetPath)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return { binDir, targetPath }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function symlinkBinary(sourcePath, binaryName) {
|
|
89
|
+
const { targetPath } = prepareBinDirectory(binaryName)
|
|
90
|
+
|
|
91
|
+
fs.symlinkSync(sourcePath, targetPath)
|
|
92
|
+
console.log(`opencode binary symlinked: ${targetPath} -> ${sourcePath}`)
|
|
93
|
+
|
|
94
|
+
// Verify the file exists after operation
|
|
95
|
+
if (!fs.existsSync(targetPath)) {
|
|
96
|
+
throw new Error(`Failed to symlink binary to ${targetPath}`)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function main() {
|
|
101
|
+
try {
|
|
102
|
+
if (os.platform() === "win32") {
|
|
103
|
+
// On Windows, the .exe is already included in the package and bin field points to it
|
|
104
|
+
// No postinstall setup needed
|
|
105
|
+
console.log("Windows detected: binary setup not needed (using packaged .exe)")
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const { binaryPath, binaryName } = findBinary()
|
|
110
|
+
symlinkBinary(binaryPath, binaryName)
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.error("Failed to setup opencode binary:", error.message)
|
|
113
|
+
process.exit(1)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
main()
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error("Postinstall script error:", error.message)
|
|
121
|
+
process.exit(0)
|
|
122
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { $ } from "bun"
|
|
3
|
+
import pkg from "../package.json"
|
|
4
|
+
import { Script } from "@opencode-ai/script"
|
|
5
|
+
import { fileURLToPath } from "url"
|
|
6
|
+
|
|
7
|
+
const dir = fileURLToPath(new URL("..", import.meta.url))
|
|
8
|
+
process.chdir(dir)
|
|
9
|
+
|
|
10
|
+
const { binaries } = await import("./build.ts")
|
|
11
|
+
{
|
|
12
|
+
const name = `${pkg.name}-${process.platform}-${process.arch}`
|
|
13
|
+
console.log(`smoke test: running dist/${name}/bin/opencode --version`)
|
|
14
|
+
await $`./dist/${name}/bin/opencode --version`
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
await $`mkdir -p ./dist/${pkg.name}`
|
|
18
|
+
await $`cp -r ./bin ./dist/${pkg.name}/bin`
|
|
19
|
+
await $`cp ./script/postinstall.mjs ./dist/${pkg.name}/postinstall.mjs`
|
|
20
|
+
|
|
21
|
+
await Bun.file(`./dist/${pkg.name}/package.json`).write(
|
|
22
|
+
JSON.stringify(
|
|
23
|
+
{
|
|
24
|
+
name: pkg.name + "-ai",
|
|
25
|
+
bin: {
|
|
26
|
+
[pkg.name]: `./bin/${pkg.name}`,
|
|
27
|
+
},
|
|
28
|
+
scripts: {
|
|
29
|
+
postinstall: "bun ./postinstall.mjs || node ./postinstall.mjs",
|
|
30
|
+
},
|
|
31
|
+
version: Script.version,
|
|
32
|
+
optionalDependencies: binaries,
|
|
33
|
+
},
|
|
34
|
+
null,
|
|
35
|
+
2,
|
|
36
|
+
),
|
|
37
|
+
)
|
|
38
|
+
for (const [name] of Object.entries(binaries)) {
|
|
39
|
+
try {
|
|
40
|
+
process.chdir(`./dist/${name}`)
|
|
41
|
+
if (process.platform !== "win32") {
|
|
42
|
+
await $`chmod 755 -R .`
|
|
43
|
+
}
|
|
44
|
+
await $`bun publish --access public --tag ${Script.channel}`
|
|
45
|
+
} finally {
|
|
46
|
+
process.chdir(dir)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
await $`cd ./dist/${pkg.name} && bun publish --access public --tag ${Script.channel}`
|
|
50
|
+
|
|
51
|
+
if (!Script.preview) {
|
|
52
|
+
const major = Script.version.split(".")[0]
|
|
53
|
+
const majorTag = `latest-${major}`
|
|
54
|
+
for (const [name] of Object.entries(binaries)) {
|
|
55
|
+
await $`cd dist/${name} && npm dist-tag add ${name}@${Script.version} ${majorTag}`
|
|
56
|
+
}
|
|
57
|
+
await $`cd ./dist/${pkg.name} && npm dist-tag add ${pkg.name}-ai@${Script.version} ${majorTag}`
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!Script.preview) {
|
|
61
|
+
for (const key of Object.keys(binaries)) {
|
|
62
|
+
if (key.includes("linux")) {
|
|
63
|
+
await $`cd dist/${key}/bin && tar -czf ../../${key}.tar.gz *`
|
|
64
|
+
} else {
|
|
65
|
+
await $`cd dist/${key}/bin && zip -r ../../${key}.zip *`
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Calculate SHA values
|
|
70
|
+
const arm64Sha = await $`sha256sum ./dist/opencode-linux-arm64.tar.gz | cut -d' ' -f1`.text().then((x) => x.trim())
|
|
71
|
+
const x64Sha = await $`sha256sum ./dist/opencode-linux-x64.tar.gz | cut -d' ' -f1`.text().then((x) => x.trim())
|
|
72
|
+
const macX64Sha = await $`sha256sum ./dist/opencode-darwin-x64.zip | cut -d' ' -f1`.text().then((x) => x.trim())
|
|
73
|
+
const macArm64Sha = await $`sha256sum ./dist/opencode-darwin-arm64.zip | cut -d' ' -f1`.text().then((x) => x.trim())
|
|
74
|
+
|
|
75
|
+
const [pkgver, _subver = ""] = Script.version.split(/(-.*)/, 2)
|
|
76
|
+
|
|
77
|
+
// arch
|
|
78
|
+
const binaryPkgbuild = [
|
|
79
|
+
"# Maintainer: dax",
|
|
80
|
+
"# Maintainer: adam",
|
|
81
|
+
"",
|
|
82
|
+
"pkgname='opencode-bin'",
|
|
83
|
+
`pkgver=${pkgver}`,
|
|
84
|
+
`_subver=${_subver}`,
|
|
85
|
+
"options=('!debug' '!strip')",
|
|
86
|
+
"pkgrel=1",
|
|
87
|
+
"pkgdesc='The AI coding agent built for the terminal.'",
|
|
88
|
+
"url='https://github.com/sst/opencode'",
|
|
89
|
+
"arch=('aarch64' 'x86_64')",
|
|
90
|
+
"license=('MIT')",
|
|
91
|
+
"provides=('opencode')",
|
|
92
|
+
"conflicts=('opencode')",
|
|
93
|
+
"depends=('fzf' 'ripgrep')",
|
|
94
|
+
"",
|
|
95
|
+
`source_aarch64=("\${pkgname}_\${pkgver}_aarch64.tar.gz::https://github.com/sst/opencode/releases/download/v\${pkgver}\${_subver}/opencode-linux-arm64.tar.gz")`,
|
|
96
|
+
`sha256sums_aarch64=('${arm64Sha}')`,
|
|
97
|
+
|
|
98
|
+
`source_x86_64=("\${pkgname}_\${pkgver}_x86_64.tar.gz::https://github.com/sst/opencode/releases/download/v\${pkgver}\${_subver}/opencode-linux-x64.tar.gz")`,
|
|
99
|
+
`sha256sums_x86_64=('${x64Sha}')`,
|
|
100
|
+
"",
|
|
101
|
+
"package() {",
|
|
102
|
+
' install -Dm755 ./opencode "${pkgdir}/usr/bin/opencode"',
|
|
103
|
+
"}",
|
|
104
|
+
"",
|
|
105
|
+
].join("\n")
|
|
106
|
+
|
|
107
|
+
// Source-based PKGBUILD for opencode
|
|
108
|
+
const sourcePkgbuild = [
|
|
109
|
+
"# Maintainer: dax",
|
|
110
|
+
"# Maintainer: adam",
|
|
111
|
+
"",
|
|
112
|
+
"pkgname='opencode'",
|
|
113
|
+
`pkgver=${pkgver}`,
|
|
114
|
+
`_subver=${_subver}`,
|
|
115
|
+
"options=('!debug' '!strip')",
|
|
116
|
+
"pkgrel=1",
|
|
117
|
+
"pkgdesc='The AI coding agent built for the terminal.'",
|
|
118
|
+
"url='https://github.com/sst/opencode'",
|
|
119
|
+
"arch=('aarch64' 'x86_64')",
|
|
120
|
+
"license=('MIT')",
|
|
121
|
+
"provides=('opencode')",
|
|
122
|
+
"conflicts=('opencode-bin')",
|
|
123
|
+
"depends=('fzf' 'ripgrep')",
|
|
124
|
+
"makedepends=('git' 'bun-bin' 'go')",
|
|
125
|
+
"",
|
|
126
|
+
`source=("opencode-\${pkgver}.tar.gz::https://github.com/sst/opencode/archive/v\${pkgver}\${_subver}.tar.gz")`,
|
|
127
|
+
`sha256sums=('SKIP')`,
|
|
128
|
+
"",
|
|
129
|
+
"build() {",
|
|
130
|
+
` cd "opencode-\${pkgver}"`,
|
|
131
|
+
` bun install`,
|
|
132
|
+
" cd ./packages/opencode",
|
|
133
|
+
` OPENCODE_CHANNEL=latest OPENCODE_VERSION=${pkgver} bun run ./script/build.ts --single`,
|
|
134
|
+
"}",
|
|
135
|
+
"",
|
|
136
|
+
"package() {",
|
|
137
|
+
` cd "opencode-\${pkgver}/packages/opencode"`,
|
|
138
|
+
' mkdir -p "${pkgdir}/usr/bin"',
|
|
139
|
+
' target_arch="x64"',
|
|
140
|
+
' case "$CARCH" in',
|
|
141
|
+
' x86_64) target_arch="x64" ;;',
|
|
142
|
+
' aarch64) target_arch="arm64" ;;',
|
|
143
|
+
' *) printf "unsupported architecture: %s\\n" "$CARCH" >&2 ; return 1 ;;',
|
|
144
|
+
" esac",
|
|
145
|
+
' libc=""',
|
|
146
|
+
" if command -v ldd >/dev/null 2>&1; then",
|
|
147
|
+
" if ldd --version 2>&1 | grep -qi musl; then",
|
|
148
|
+
' libc="-musl"',
|
|
149
|
+
" fi",
|
|
150
|
+
" fi",
|
|
151
|
+
' if [ -z "$libc" ] && ls /lib/ld-musl-* >/dev/null 2>&1; then',
|
|
152
|
+
' libc="-musl"',
|
|
153
|
+
" fi",
|
|
154
|
+
' base=""',
|
|
155
|
+
' if [ "$target_arch" = "x64" ]; then',
|
|
156
|
+
" if ! grep -qi avx2 /proc/cpuinfo 2>/dev/null; then",
|
|
157
|
+
' base="-baseline"',
|
|
158
|
+
" fi",
|
|
159
|
+
" fi",
|
|
160
|
+
' bin="dist/opencode-linux-${target_arch}${base}${libc}/bin/opencode"',
|
|
161
|
+
' if [ ! -f "$bin" ]; then',
|
|
162
|
+
' printf "unable to find binary for %s%s%s\\n" "$target_arch" "$base" "$libc" >&2',
|
|
163
|
+
" return 1",
|
|
164
|
+
" fi",
|
|
165
|
+
' install -Dm755 "$bin" "${pkgdir}/usr/bin/opencode"',
|
|
166
|
+
"}",
|
|
167
|
+
"",
|
|
168
|
+
].join("\n")
|
|
169
|
+
|
|
170
|
+
for (const [pkg, pkgbuild] of [
|
|
171
|
+
["opencode-bin", binaryPkgbuild],
|
|
172
|
+
["opencode", sourcePkgbuild],
|
|
173
|
+
]) {
|
|
174
|
+
for (let i = 0; i < 30; i++) {
|
|
175
|
+
try {
|
|
176
|
+
await $`rm -rf ./dist/aur-${pkg}`
|
|
177
|
+
await $`git clone ssh://aur@aur.archlinux.org/${pkg}.git ./dist/aur-${pkg}`
|
|
178
|
+
await $`cd ./dist/aur-${pkg} && git checkout master`
|
|
179
|
+
await Bun.file(`./dist/aur-${pkg}/PKGBUILD`).write(pkgbuild)
|
|
180
|
+
await $`cd ./dist/aur-${pkg} && makepkg --printsrcinfo > .SRCINFO`
|
|
181
|
+
await $`cd ./dist/aur-${pkg} && git add PKGBUILD .SRCINFO`
|
|
182
|
+
await $`cd ./dist/aur-${pkg} && git commit -m "Update to v${Script.version}"`
|
|
183
|
+
await $`cd ./dist/aur-${pkg} && git push`
|
|
184
|
+
break
|
|
185
|
+
} catch (e) {
|
|
186
|
+
continue
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Homebrew formula
|
|
192
|
+
const homebrewFormula = [
|
|
193
|
+
"# typed: false",
|
|
194
|
+
"# frozen_string_literal: true",
|
|
195
|
+
"",
|
|
196
|
+
"# This file was generated by GoReleaser. DO NOT EDIT.",
|
|
197
|
+
"class Opencode < Formula",
|
|
198
|
+
` desc "The AI coding agent built for the terminal."`,
|
|
199
|
+
` homepage "https://github.com/sst/opencode"`,
|
|
200
|
+
` version "${Script.version.split("-")[0]}"`,
|
|
201
|
+
"",
|
|
202
|
+
` depends_on "ripgrep"`,
|
|
203
|
+
"",
|
|
204
|
+
" on_macos do",
|
|
205
|
+
" if Hardware::CPU.intel?",
|
|
206
|
+
` url "https://github.com/sst/opencode/releases/download/v${Script.version}/opencode-darwin-x64.zip"`,
|
|
207
|
+
` sha256 "${macX64Sha}"`,
|
|
208
|
+
"",
|
|
209
|
+
" def install",
|
|
210
|
+
' bin.install "opencode"',
|
|
211
|
+
" end",
|
|
212
|
+
" end",
|
|
213
|
+
" if Hardware::CPU.arm?",
|
|
214
|
+
` url "https://github.com/sst/opencode/releases/download/v${Script.version}/opencode-darwin-arm64.zip"`,
|
|
215
|
+
` sha256 "${macArm64Sha}"`,
|
|
216
|
+
"",
|
|
217
|
+
" def install",
|
|
218
|
+
' bin.install "opencode"',
|
|
219
|
+
" end",
|
|
220
|
+
" end",
|
|
221
|
+
" end",
|
|
222
|
+
"",
|
|
223
|
+
" on_linux do",
|
|
224
|
+
" if Hardware::CPU.intel? and Hardware::CPU.is_64_bit?",
|
|
225
|
+
` url "https://github.com/sst/opencode/releases/download/v${Script.version}/opencode-linux-x64.tar.gz"`,
|
|
226
|
+
` sha256 "${x64Sha}"`,
|
|
227
|
+
" def install",
|
|
228
|
+
' bin.install "opencode"',
|
|
229
|
+
" end",
|
|
230
|
+
" end",
|
|
231
|
+
" if Hardware::CPU.arm? and Hardware::CPU.is_64_bit?",
|
|
232
|
+
` url "https://github.com/sst/opencode/releases/download/v${Script.version}/opencode-linux-arm64.tar.gz"`,
|
|
233
|
+
` sha256 "${arm64Sha}"`,
|
|
234
|
+
" def install",
|
|
235
|
+
' bin.install "opencode"',
|
|
236
|
+
" end",
|
|
237
|
+
" end",
|
|
238
|
+
" end",
|
|
239
|
+
"end",
|
|
240
|
+
"",
|
|
241
|
+
"",
|
|
242
|
+
].join("\n")
|
|
243
|
+
|
|
244
|
+
await $`rm -rf ./dist/homebrew-tap`
|
|
245
|
+
await $`git clone https://${process.env["GITHUB_TOKEN"]}@github.com/sst/homebrew-tap.git ./dist/homebrew-tap`
|
|
246
|
+
await Bun.file("./dist/homebrew-tap/opencode.rb").write(homebrewFormula)
|
|
247
|
+
await $`cd ./dist/homebrew-tap && git add opencode.rb`
|
|
248
|
+
await $`cd ./dist/homebrew-tap && git commit -m "Update to v${Script.version}"`
|
|
249
|
+
await $`cd ./dist/homebrew-tap && git push`
|
|
250
|
+
|
|
251
|
+
const image = "ghcr.io/sst/opencode"
|
|
252
|
+
await $`docker build -t ${image}:${Script.version} .`
|
|
253
|
+
await $`docker push ${image}:${Script.version}`
|
|
254
|
+
await $`docker tag ${image}:${Script.version} ${image}:latest`
|
|
255
|
+
await $`docker push ${image}:latest`
|
|
256
|
+
}
|
package/script/schema.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { z } from "zod"
|
|
4
|
+
import { Config } from "../src/config/config"
|
|
5
|
+
|
|
6
|
+
const file = process.argv[2]
|
|
7
|
+
console.log(file)
|
|
8
|
+
|
|
9
|
+
const result = z.toJSONSchema(Config.Info, {
|
|
10
|
+
io: "input", // Generate input shape (treats optional().default() as not required)
|
|
11
|
+
/**
|
|
12
|
+
* We'll use the `default` values of the field as the only value in `examples`.
|
|
13
|
+
* This will ensure no docs are needed to be read, as the configuration is
|
|
14
|
+
* self-documenting.
|
|
15
|
+
*
|
|
16
|
+
* See https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.9.5
|
|
17
|
+
*/
|
|
18
|
+
override(ctx) {
|
|
19
|
+
const schema = ctx.jsonSchema
|
|
20
|
+
|
|
21
|
+
// Preserve strictness: set additionalProperties: false for objects
|
|
22
|
+
if (schema && typeof schema === "object" && schema.type === "object" && schema.additionalProperties === undefined) {
|
|
23
|
+
schema.additionalProperties = false
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Add examples and default descriptions for string fields with defaults
|
|
27
|
+
if (schema && typeof schema === "object" && "type" in schema && schema.type === "string" && schema?.default) {
|
|
28
|
+
if (!schema.examples) {
|
|
29
|
+
schema.examples = [schema.default]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
schema.description = [schema.description || "", `default: \`${schema.default}\``]
|
|
33
|
+
.filter(Boolean)
|
|
34
|
+
.join("\n\n")
|
|
35
|
+
.trim()
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
}) as Record<string, unknown> & {
|
|
39
|
+
allowComments?: boolean
|
|
40
|
+
allowTrailingCommas?: boolean
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// used for json lsps since config supports jsonc
|
|
44
|
+
result.allowComments = true
|
|
45
|
+
result.allowTrailingCommas = true
|
|
46
|
+
|
|
47
|
+
await Bun.write(file, JSON.stringify(result, null, 2))
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# ACP (Agent Client Protocol) Implementation
|
|
2
|
+
|
|
3
|
+
This directory contains a clean, protocol-compliant implementation of the [Agent Client Protocol](https://agentclientprotocol.com/) for opencode.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
The implementation follows a clean separation of concerns:
|
|
8
|
+
|
|
9
|
+
### Core Components
|
|
10
|
+
|
|
11
|
+
- **`agent.ts`** - Implements the `Agent` interface from `@agentclientprotocol/sdk`
|
|
12
|
+
- Handles initialization and capability negotiation
|
|
13
|
+
- Manages session lifecycle (`session/new`, `session/load`)
|
|
14
|
+
- Processes prompts and returns responses
|
|
15
|
+
- Properly implements ACP protocol v1
|
|
16
|
+
|
|
17
|
+
- **`client.ts`** - Implements the `Client` interface for client-side capabilities
|
|
18
|
+
- File operations (`readTextFile`, `writeTextFile`)
|
|
19
|
+
- Permission requests (auto-approves for now)
|
|
20
|
+
- Terminal support (stub implementation)
|
|
21
|
+
|
|
22
|
+
- **`session.ts`** - Session state management
|
|
23
|
+
- Creates and tracks ACP sessions
|
|
24
|
+
- Maps ACP sessions to internal opencode sessions
|
|
25
|
+
- Maintains working directory context
|
|
26
|
+
- Handles MCP server configurations
|
|
27
|
+
|
|
28
|
+
- **`server.ts`** - ACP server startup and lifecycle
|
|
29
|
+
- Sets up JSON-RPC over stdio using the official library
|
|
30
|
+
- Manages graceful shutdown on SIGTERM/SIGINT
|
|
31
|
+
- Provides Instance context for the agent
|
|
32
|
+
|
|
33
|
+
- **`types.ts`** - Type definitions for internal use
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Command Line
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Start the ACP server in the current directory
|
|
41
|
+
opencode acp
|
|
42
|
+
|
|
43
|
+
# Start in a specific directory
|
|
44
|
+
opencode acp --cwd /path/to/project
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Programmatic
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { ACPServer } from "./acp/server"
|
|
51
|
+
|
|
52
|
+
await ACPServer.start()
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Integration with Zed
|
|
56
|
+
|
|
57
|
+
Add to your Zed configuration (`~/.config/zed/settings.json`):
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"agent_servers": {
|
|
62
|
+
"OpenCode": {
|
|
63
|
+
"command": "opencode",
|
|
64
|
+
"args": ["acp"]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Protocol Compliance
|
|
71
|
+
|
|
72
|
+
This implementation follows the ACP specification v1:
|
|
73
|
+
|
|
74
|
+
✅ **Initialization**
|
|
75
|
+
|
|
76
|
+
- Proper `initialize` request/response with protocol version negotiation
|
|
77
|
+
- Capability advertisement (`agentCapabilities`)
|
|
78
|
+
- Authentication support (stub)
|
|
79
|
+
|
|
80
|
+
✅ **Session Management**
|
|
81
|
+
|
|
82
|
+
- `session/new` - Create new conversation sessions
|
|
83
|
+
- `session/load` - Resume existing sessions (basic support)
|
|
84
|
+
- Working directory context (`cwd`)
|
|
85
|
+
- MCP server configuration support
|
|
86
|
+
|
|
87
|
+
✅ **Prompting**
|
|
88
|
+
|
|
89
|
+
- `session/prompt` - Process user messages
|
|
90
|
+
- Content block handling (text, resources)
|
|
91
|
+
- Response with stop reasons
|
|
92
|
+
|
|
93
|
+
✅ **Client Capabilities**
|
|
94
|
+
|
|
95
|
+
- File read/write operations
|
|
96
|
+
- Permission requests
|
|
97
|
+
- Terminal support (stub for future)
|
|
98
|
+
|
|
99
|
+
## Current Limitations
|
|
100
|
+
|
|
101
|
+
### Not Yet Implemented
|
|
102
|
+
|
|
103
|
+
1. **Streaming Responses** - Currently returns complete responses instead of streaming via `session/update` notifications
|
|
104
|
+
2. **Tool Call Reporting** - Doesn't report tool execution progress
|
|
105
|
+
3. **Session Modes** - No mode switching support yet
|
|
106
|
+
4. **Authentication** - No actual auth implementation
|
|
107
|
+
5. **Terminal Support** - Placeholder only
|
|
108
|
+
6. **Session Persistence** - `session/load` doesn't restore actual conversation history
|
|
109
|
+
|
|
110
|
+
### Future Enhancements
|
|
111
|
+
|
|
112
|
+
- **Real-time Streaming**: Implement `session/update` notifications for progressive responses
|
|
113
|
+
- **Tool Call Visibility**: Report tool executions as they happen
|
|
114
|
+
- **Session Persistence**: Save and restore full conversation history
|
|
115
|
+
- **Mode Support**: Implement different operational modes (ask, code, etc.)
|
|
116
|
+
- **Enhanced Permissions**: More sophisticated permission handling
|
|
117
|
+
- **Terminal Integration**: Full terminal support via opencode's bash tool
|
|
118
|
+
|
|
119
|
+
## Testing
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Run ACP tests
|
|
123
|
+
bun test test/acp.test.ts
|
|
124
|
+
|
|
125
|
+
# Test manually with stdio
|
|
126
|
+
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1}}' | opencode acp
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Design Decisions
|
|
130
|
+
|
|
131
|
+
### Why the Official Library?
|
|
132
|
+
|
|
133
|
+
We use `@agentclientprotocol/sdk` instead of implementing JSON-RPC ourselves because:
|
|
134
|
+
|
|
135
|
+
- Ensures protocol compliance
|
|
136
|
+
- Handles edge cases and future protocol versions
|
|
137
|
+
- Reduces maintenance burden
|
|
138
|
+
- Works with other ACP clients automatically
|
|
139
|
+
|
|
140
|
+
### Clean Architecture
|
|
141
|
+
|
|
142
|
+
Each component has a single responsibility:
|
|
143
|
+
|
|
144
|
+
- **Agent** = Protocol interface
|
|
145
|
+
- **Client** = Client-side operations
|
|
146
|
+
- **Session** = State management
|
|
147
|
+
- **Server** = Lifecycle and I/O
|
|
148
|
+
|
|
149
|
+
This makes the codebase maintainable and testable.
|
|
150
|
+
|
|
151
|
+
### Mapping to OpenCode
|
|
152
|
+
|
|
153
|
+
ACP sessions map cleanly to opencode's internal session model:
|
|
154
|
+
|
|
155
|
+
- ACP `session/new` → creates internal Session
|
|
156
|
+
- ACP `session/prompt` → uses SessionPrompt.prompt()
|
|
157
|
+
- Working directory context preserved per-session
|
|
158
|
+
- Tool execution uses existing ToolRegistry
|
|
159
|
+
|
|
160
|
+
## References
|
|
161
|
+
|
|
162
|
+
- [ACP Specification](https://agentclientprotocol.com/)
|
|
163
|
+
- [TypeScript Library](https://github.com/agentclientprotocol/typescript-sdk)
|
|
164
|
+
- [Protocol Examples](https://github.com/agentclientprotocol/typescript-sdk/tree/main/src/examples)
|