mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-17 12:56:41 +02:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 23c30521d8 | |||
| e681d610de | |||
| a1fdeded3e | |||
| 2051312d12 | |||
| 20cb7a76af | |||
| a493aec174 | |||
| 3ce3ac8e61 | |||
| 91ad64feda | |||
| 60b55f9d92 | |||
| 3c6c2bf13b | |||
| d4f9375548 | |||
| 28b39f547e | |||
| 7520f5efa8 | |||
| eb4cdf4b20 | |||
| 9f6fc1c3c5 | |||
| dfede9ae6e | |||
| fc45c0c944 | |||
| 9d869f784c | |||
| bd244f73af |
@@ -1,20 +1,21 @@
|
||||
# Download Stats
|
||||
|
||||
| Date | GitHub Downloads | npm Downloads | Total |
|
||||
| ---------- | ---------------- | --------------- | ----------------- |
|
||||
| 2025-06-29 | 18,789 (+0) | 39,420 (+0) | 58,209 (+0) |
|
||||
| 2025-06-30 | 20,127 (+1,338) | 41,059 (+1,639) | 61,186 (+2,977) |
|
||||
| 2025-07-01 | 22,108 (+1,981) | 43,745 (+2,686) | 65,853 (+4,667) |
|
||||
| 2025-07-02 | 24,814 (+2,706) | 46,168 (+2,423) | 70,982 (+5,129) |
|
||||
| 2025-07-03 | 27,834 (+3,020) | 49,955 (+3,787) | 77,789 (+6,807) |
|
||||
| 2025-07-04 | 30,608 (+2,774) | 54,758 (+4,803) | 85,366 (+7,577) |
|
||||
| 2025-07-05 | 32,524 (+1,916) | 58,371 (+3,613) | 90,895 (+5,529) |
|
||||
| 2025-07-06 | 33,766 (+1,242) | 59,694 (+1,323) | 93,460 (+2,565) |
|
||||
| 2025-07-08 | 38,052 (+4,286) | 64,468 (+4,774) | 102,520 (+9,060) |
|
||||
| 2025-07-10 | 43,796 (+5,744) | 71,402 (+6,934) | 115,198 (+12,678) |
|
||||
| 2025-07-11 | 46,982 (+3,186) | 77,462 (+6,060) | 124,444 (+9,246) |
|
||||
| 2025-07-12 | 49,302 (+2,320) | 82,177 (+4,715) | 131,479 (+7,035) |
|
||||
| 2025-07-13 | 50,803 (+1,501) | 86,394 (+4,217) | 137,197 (+5,718) |
|
||||
| 2025-07-14 | 53,283 (+2,480) | 87,860 (+1,466) | 141,143 (+3,946) |
|
||||
| 2025-07-15 | 57,590 (+4,307) | 91,036 (+3,176) | 148,626 (+7,483) |
|
||||
| 2025-07-16 | 62,313 (+4,723) | 95,258 (+4,222) | 157,571 (+8,945) |
|
||||
| Date | GitHub Downloads | npm Downloads | Total |
|
||||
| ---------- | ---------------- | ---------------- | ----------------- |
|
||||
| 2025-06-29 | 18,789 (+0) | 39,420 (+0) | 58,209 (+0) |
|
||||
| 2025-06-30 | 20,127 (+1,338) | 41,059 (+1,639) | 61,186 (+2,977) |
|
||||
| 2025-07-01 | 22,108 (+1,981) | 43,745 (+2,686) | 65,853 (+4,667) |
|
||||
| 2025-07-02 | 24,814 (+2,706) | 46,168 (+2,423) | 70,982 (+5,129) |
|
||||
| 2025-07-03 | 27,834 (+3,020) | 49,955 (+3,787) | 77,789 (+6,807) |
|
||||
| 2025-07-04 | 30,608 (+2,774) | 54,758 (+4,803) | 85,366 (+7,577) |
|
||||
| 2025-07-05 | 32,524 (+1,916) | 58,371 (+3,613) | 90,895 (+5,529) |
|
||||
| 2025-07-06 | 33,766 (+1,242) | 59,694 (+1,323) | 93,460 (+2,565) |
|
||||
| 2025-07-08 | 38,052 (+4,286) | 64,468 (+4,774) | 102,520 (+9,060) |
|
||||
| 2025-07-10 | 43,796 (+5,744) | 71,402 (+6,934) | 115,198 (+12,678) |
|
||||
| 2025-07-11 | 46,982 (+3,186) | 77,462 (+6,060) | 124,444 (+9,246) |
|
||||
| 2025-07-12 | 49,302 (+2,320) | 82,177 (+4,715) | 131,479 (+7,035) |
|
||||
| 2025-07-13 | 50,803 (+1,501) | 86,394 (+4,217) | 137,197 (+5,718) |
|
||||
| 2025-07-14 | 53,283 (+2,480) | 87,860 (+1,466) | 141,143 (+3,946) |
|
||||
| 2025-07-15 | 57,590 (+4,307) | 91,036 (+3,176) | 148,626 (+7,483) |
|
||||
| 2025-07-16 | 62,313 (+4,723) | 95,258 (+4,222) | 157,571 (+8,945) |
|
||||
| 2025-07-17 | 66,684 (+4,371) | 100,048 (+4,790) | 166,732 (+9,161) |
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
],
|
||||
"catalog": {
|
||||
"@types/node": "22.13.9",
|
||||
"ai": "5.0.0-beta.18",
|
||||
"ai": "5.0.0-beta.21",
|
||||
"typescript": "5.8.2",
|
||||
"zod": "3.25.49",
|
||||
},
|
||||
@@ -109,11 +109,11 @@
|
||||
|
||||
"@ai-sdk/anthropic": ["@ai-sdk/anthropic@1.2.12", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-YSzjlko7JvuiyQFmI9RN1tNZdEiZxc+6xld/0tq/VkJaHpEzGAb1yiNxxvmYVcjvfu/PcvCxAAYXmTYQQ63IHQ=="],
|
||||
|
||||
"@ai-sdk/gateway": ["@ai-sdk/gateway@1.0.0-beta.7", "", { "dependencies": { "@ai-sdk/provider": "2.0.0-beta.1", "@ai-sdk/provider-utils": "3.0.0-beta.2" }, "peerDependencies": { "zod": "^3.25.49" } }, "sha512-0TOWFetxYximugqdmA/uxk+NRkz51Lyo+anntc3hPzm2OnsbE/Q2wWkKJ14YzoCAfWZ9ZhvxsJRp8xzvvQREsA=="],
|
||||
"@ai-sdk/gateway": ["@ai-sdk/gateway@1.0.0-beta.8", "", { "dependencies": { "@ai-sdk/provider": "2.0.0-beta.1", "@ai-sdk/provider-utils": "3.0.0-beta.3" }, "peerDependencies": { "zod": "^3.25.49 || ^4" } }, "sha512-D2SqYRT/42JTiRxUuiWtn5cYQFscpb9Z14UNvJx7lnurBUXx57zy7TbLH0h7O+WbCluTQN5G6146JpUZ/SRyzw=="],
|
||||
|
||||
"@ai-sdk/provider": ["@ai-sdk/provider@2.0.0-beta.1", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Z8SPncMtS3RsoXITmT7NVwrAq6M44dmw0DoUOYJqNNtCu8iMWuxB8Nxsoqpa0uEEy9R1V1ZThJAXTYgjTUxl3w=="],
|
||||
|
||||
"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.0-beta.2", "", { "dependencies": { "@ai-sdk/provider": "2.0.0-beta.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.3", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.25.49" } }, "sha512-H4K+4weOVgWqrDDeAbQWoA4U5mN4WrQPHQFdH7ynQYcnhj/pzctU9Q6mGlR5ESMWxaXxazxlOblSITlXo9bahA=="],
|
||||
"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.0-beta.3", "", { "dependencies": { "@ai-sdk/provider": "2.0.0-beta.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.3", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.25.49 || ^4" } }, "sha512-4gZ392GxjzMF7TnReF2eTKhOSyiSS3ydRVq4I7jxkeV5sdEuMoH3gzfItmlctsqGxlMU1/+zKPwl5yYz9O2dzg=="],
|
||||
|
||||
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
||||
|
||||
@@ -543,7 +543,7 @@
|
||||
|
||||
"acorn-walk": ["acorn-walk@8.3.2", "", {}, "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A=="],
|
||||
|
||||
"ai": ["ai@5.0.0-beta.18", "", { "dependencies": { "@ai-sdk/gateway": "1.0.0-beta.7", "@ai-sdk/provider": "2.0.0-beta.1", "@ai-sdk/provider-utils": "3.0.0-beta.2", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.49" } }, "sha512-gUkO9WF315aT6Al7FxBpY41z3aOVE11BdQUIdIekP1sebys4dElMmKjs9AoaNeYPcf+PklwQ6ZofztiT0egd4A=="],
|
||||
"ai": ["ai@5.0.0-beta.21", "", { "dependencies": { "@ai-sdk/gateway": "1.0.0-beta.8", "@ai-sdk/provider": "2.0.0-beta.1", "@ai-sdk/provider-utils": "3.0.0-beta.3", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.49 || ^4" }, "bin": { "ai": "dist/bin/ai.min.js" } }, "sha512-ZmgUoEIXb2G2HLtK1U3UB+hSDa3qrVIeAfgXf3SIE9r5Vqj6xHG1pN/7fHIZDSgb1TCaypG0ANVB0O9WmnMfiw=="],
|
||||
|
||||
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
"typescript": "5.8.2",
|
||||
"@types/node": "22.13.9",
|
||||
"zod": "3.25.49",
|
||||
"ai": "5.0.0-beta.18"
|
||||
"ai": "5.0.0-beta.21"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -120,7 +120,7 @@ export const AuthLoginCommand = cmd({
|
||||
|
||||
if (provider === "amazon-bedrock") {
|
||||
prompts.log.info(
|
||||
"Amazon bedrock can be configured with standard AWS environment variables like AWS_PROFILE or AWS_ACCESS_KEY_ID",
|
||||
"Amazon bedrock can be configured with standard AWS environment variables like AWS_BEARER_TOKEN_BEDROCK, AWS_PROFILE or AWS_ACCESS_KEY_ID",
|
||||
)
|
||||
prompts.outro("Done")
|
||||
return
|
||||
|
||||
@@ -31,6 +31,9 @@ export namespace Config {
|
||||
const os = await import("os")
|
||||
result.username = os.userInfo().username
|
||||
}
|
||||
if (!result.layout) {
|
||||
result.layout = "auto"
|
||||
}
|
||||
|
||||
log.info("loaded", result)
|
||||
|
||||
@@ -57,6 +60,7 @@ export namespace Config {
|
||||
type: z.literal("remote").describe("Type of MCP server connection"),
|
||||
url: z.string().describe("URL of the remote MCP server"),
|
||||
enabled: z.boolean().optional().describe("Enable or disable the MCP server on startup"),
|
||||
headers: z.record(z.string(), z.string()).optional().describe("Headers to send with the request"),
|
||||
})
|
||||
.strict()
|
||||
.openapi({
|
||||
@@ -136,9 +140,11 @@ export namespace Config {
|
||||
theme: z.string().optional().describe("Theme name to use for the interface"),
|
||||
keybinds: Keybinds.optional().describe("Custom keybind configurations"),
|
||||
share: z
|
||||
.enum(["auto", "disabled"])
|
||||
.enum(["manual", "auto", "disabled"])
|
||||
.optional()
|
||||
.describe("Control sharing behavior: 'auto' enables automatic sharing, 'disabled' disables all sharing"),
|
||||
.describe(
|
||||
"Control sharing behavior:'manual' allows manual sharing via commands, 'auto' enables automatic sharing, 'disabled' disables all sharing",
|
||||
),
|
||||
autoshare: z
|
||||
.boolean()
|
||||
.optional()
|
||||
|
||||
@@ -105,7 +105,29 @@ export const ruff: Info = {
|
||||
command: ["ruff", "format", "$FILE"],
|
||||
extensions: [".py", ".pyi"],
|
||||
async enabled() {
|
||||
return Bun.which("ruff") !== null
|
||||
if (!Bun.which("ruff")) return false
|
||||
const app = App.info()
|
||||
const configs = ["pyproject.toml", "ruff.toml", ".ruff.toml"]
|
||||
for (const config of configs) {
|
||||
const found = await Filesystem.findUp(config, app.path.cwd, app.path.root)
|
||||
if (found.length > 0) {
|
||||
if (config === "pyproject.toml") {
|
||||
const content = await Bun.file(found[0]).text()
|
||||
if (content.includes("[tool.ruff]")) return true
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
const deps = ["requirements.txt", "pyproject.toml", "Pipfile"]
|
||||
for (const dep of deps) {
|
||||
const found = await Filesystem.findUp(dep, app.path.cwd, app.path.root)
|
||||
if (found.length > 0) {
|
||||
const content = await Bun.file(found[0]).text()
|
||||
if (content.includes("ruff")) return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ export namespace MCP {
|
||||
transport: {
|
||||
type: "sse",
|
||||
url: mcp.url,
|
||||
headers: mcp.headers,
|
||||
},
|
||||
}).catch(() => {})
|
||||
if (!client) {
|
||||
|
||||
@@ -139,7 +139,8 @@ export namespace Provider {
|
||||
}
|
||||
},
|
||||
"amazon-bedrock": async () => {
|
||||
if (!process.env["AWS_PROFILE"] && !process.env["AWS_ACCESS_KEY_ID"]) return { autoload: false }
|
||||
if (!process.env["AWS_PROFILE"] && !process.env["AWS_ACCESS_KEY_ID"] && !process.env["AWS_BEARER_TOKEN_BEDROCK"])
|
||||
return { autoload: false }
|
||||
|
||||
const region = process.env["AWS_REGION"] ?? "us-east-1"
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
opencode-test
|
||||
cmd/opencode/opencode
|
||||
|
||||
Binary file not shown.
@@ -344,6 +344,10 @@ func LoadFromConfig(config *opencode.Config) CommandRegistry {
|
||||
marshalled, _ := json.Marshal(config.Keybinds)
|
||||
json.Unmarshal(marshalled, &keybinds)
|
||||
for _, command := range defaults {
|
||||
// Remove share/unshare commands if sharing is disabled
|
||||
if config.Share == opencode.ConfigShareDisabled && (command.Name == SessionShareCommand || command.Name == SessionUnshareCommand) {
|
||||
continue
|
||||
}
|
||||
if keybind, ok := keybinds[string(command.Name)]; ok && keybind != "" {
|
||||
command.Keybindings = parseBindings(keybind)
|
||||
}
|
||||
|
||||
@@ -380,6 +380,12 @@ func (m *messagesComponent) renderView() {
|
||||
width,
|
||||
WithBorderColor(t.Error()),
|
||||
)
|
||||
error = lipgloss.PlaceHorizontal(
|
||||
m.width,
|
||||
lipgloss.Center,
|
||||
error,
|
||||
styles.WhitespaceStyle(t.Background()),
|
||||
)
|
||||
blocks = append(blocks, error)
|
||||
m.lineCount += lipgloss.Height(error) + 1
|
||||
}
|
||||
@@ -448,23 +454,30 @@ func (m *messagesComponent) renderHeader() string {
|
||||
Render(formatTokensAndCost(tokens, contextWindow, cost, isSubscriptionModel))
|
||||
|
||||
background := t.Background()
|
||||
share = layout.Render(
|
||||
|
||||
var items []layout.FlexItem
|
||||
justify := layout.JustifyEnd
|
||||
|
||||
if m.app.Config.Share != opencode.ConfigShareDisabled {
|
||||
items = append(items, layout.FlexItem{View: share})
|
||||
justify = layout.JustifySpaceBetween
|
||||
}
|
||||
|
||||
items = append(items, layout.FlexItem{View: sessionInfo})
|
||||
|
||||
headerRow := layout.Render(
|
||||
layout.FlexOptions{
|
||||
Background: &background,
|
||||
Direction: layout.Row,
|
||||
Justify: layout.JustifySpaceBetween,
|
||||
Justify: justify,
|
||||
Align: layout.AlignStretch,
|
||||
Width: headerWidth - 6,
|
||||
},
|
||||
layout.FlexItem{
|
||||
View: share,
|
||||
},
|
||||
layout.FlexItem{
|
||||
View: sessionInfo,
|
||||
},
|
||||
items...,
|
||||
)
|
||||
|
||||
headerLines = append(headerLines, share)
|
||||
headerLines = append(headerLines, headerRow)
|
||||
|
||||
header := strings.Join(headerLines, "\n")
|
||||
header = styles.NewStyle().
|
||||
Background(t.Background()).
|
||||
@@ -616,6 +629,7 @@ func (m *messagesComponent) CopyLastMessage() (tea.Model, tea.Cmd) {
|
||||
func NewMessagesComponent(app *app.App) MessagesComponent {
|
||||
vp := viewport.New()
|
||||
vp.KeyMap = viewport.KeyMap{}
|
||||
vp.MouseWheelDelta = 4
|
||||
|
||||
return &messagesComponent{
|
||||
app: app,
|
||||
|
||||
@@ -28,6 +28,7 @@ type SessionDialog interface {
|
||||
type sessionItem struct {
|
||||
title string
|
||||
isDeleteConfirming bool
|
||||
isCurrentSession bool
|
||||
}
|
||||
|
||||
func (s sessionItem) Render(
|
||||
@@ -42,7 +43,11 @@ func (s sessionItem) Render(
|
||||
if s.isDeleteConfirming {
|
||||
text = "Press again to confirm delete"
|
||||
} else {
|
||||
text = s.title
|
||||
if s.isCurrentSession {
|
||||
text = "● " + s.title
|
||||
} else {
|
||||
text = s.title
|
||||
}
|
||||
}
|
||||
|
||||
truncatedStr := truncate.StringWithTail(text, uint(width-1), "...")
|
||||
@@ -56,6 +61,14 @@ func (s sessionItem) Render(
|
||||
Foreground(t.BackgroundElement()).
|
||||
Width(width).
|
||||
PaddingLeft(1)
|
||||
} else if s.isCurrentSession {
|
||||
// Different style for current session when selected
|
||||
itemStyle = baseStyle.
|
||||
Background(t.Primary()).
|
||||
Foreground(t.BackgroundElement()).
|
||||
Width(width).
|
||||
PaddingLeft(1).
|
||||
Bold(true)
|
||||
} else {
|
||||
// Normal selection
|
||||
itemStyle = baseStyle.
|
||||
@@ -70,6 +83,12 @@ func (s sessionItem) Render(
|
||||
itemStyle = baseStyle.
|
||||
Foreground(t.Error()).
|
||||
PaddingLeft(1)
|
||||
} else if s.isCurrentSession {
|
||||
// Highlight current session when not selected
|
||||
itemStyle = baseStyle.
|
||||
Foreground(t.Primary()).
|
||||
PaddingLeft(1).
|
||||
Bold(true)
|
||||
} else {
|
||||
itemStyle = baseStyle.
|
||||
PaddingLeft(1)
|
||||
@@ -194,6 +213,7 @@ func (s *sessionDialog) updateListItems() {
|
||||
item := sessionItem{
|
||||
title: sess.Title,
|
||||
isDeleteConfirming: s.deleteConfirmation == i,
|
||||
isCurrentSession: s.app.Session != nil && s.app.Session.ID == sess.ID,
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
@@ -229,6 +249,7 @@ func NewSessionDialog(app *app.App) SessionDialog {
|
||||
items = append(items, sessionItem{
|
||||
title: sess.Title,
|
||||
isDeleteConfirming: false,
|
||||
isCurrentSession: app.Session != nil && app.Session.ID == sess.ID,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -110,11 +110,6 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
case tea.KeyPressMsg:
|
||||
keyString := msg.String()
|
||||
|
||||
// Handle Ctrl+Z for suspend
|
||||
if keyString == "ctrl+z" {
|
||||
return a, tea.Suspend
|
||||
}
|
||||
|
||||
// 1. Handle active modal
|
||||
if a.modal != nil {
|
||||
switch keyString {
|
||||
@@ -277,6 +272,11 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return a, util.CmdHandler(commands.ExecuteCommandsMsg(matches))
|
||||
}
|
||||
|
||||
// Fallback: suspend if ctrl+z is pressed and no user keybind matched
|
||||
if keyString == "ctrl+z" {
|
||||
return a, tea.Suspend
|
||||
}
|
||||
|
||||
// 10. Fallback to editor. This is for other characters like backspace, tab, etc.
|
||||
updatedEditor, cmd := a.editor.Update(msg)
|
||||
a.editor = updatedEditor.(chat.EditorComponent)
|
||||
|
||||
@@ -10,7 +10,6 @@ You can configure opencode using a JSON config file.
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"theme": "opencode",
|
||||
"model": "anthropic/claude-sonnet-4-20250514",
|
||||
"autoshare": false,
|
||||
"autoupdate": true
|
||||
}
|
||||
```
|
||||
@@ -93,6 +92,24 @@ You can configure the theme you want to use in your opencode config through the
|
||||
|
||||
---
|
||||
|
||||
### Layout
|
||||
|
||||
You can configure the layout of the TUI with the `layout` option.
|
||||
|
||||
```json title="opencode.json"
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"layout": "stretch"
|
||||
}
|
||||
```
|
||||
|
||||
This takes:
|
||||
|
||||
- `"auto"`: Centers content with padding. This is the default.
|
||||
- `"stretch"`: Uses full terminal width.
|
||||
|
||||
---
|
||||
|
||||
### Logging
|
||||
|
||||
Logs are written to:
|
||||
@@ -118,8 +135,28 @@ With the following options:
|
||||
| `WARN` | Warnings and errors only |
|
||||
| `ERROR` | Errors only |
|
||||
|
||||
The **default** log level is `INFO`. If you are running opencode locally in
|
||||
development mode it's set to `DEBUG`.
|
||||
The **default** log level is `INFO`. If you are running opencode locally in development mode it's set to `DEBUG`.
|
||||
|
||||
---
|
||||
|
||||
### Sharing
|
||||
|
||||
You can configure the [share](/docs/share) feature through the `share` option.
|
||||
|
||||
```json title="opencode.json"
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"share": "manual"
|
||||
}
|
||||
```
|
||||
|
||||
This takes:
|
||||
|
||||
- `"manual"` - Allow manual sharing via commands (default)
|
||||
- `"auto"` - Automatically share new conversations
|
||||
- `"disabled"` - Disable sharing entirely
|
||||
|
||||
By default, sharing is set to manual mode where you need to explicitly share conversations using the `/share` command.
|
||||
|
||||
---
|
||||
|
||||
@@ -138,6 +175,19 @@ You can customize your keybinds through the `keybinds` option.
|
||||
|
||||
---
|
||||
|
||||
### Autoupdate
|
||||
|
||||
opencode will automatically download any new updates when it starts up. You can disable this with the `autoupdate` option.
|
||||
|
||||
```json title="opencode.json"
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"autoupdate": false
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### MCP servers
|
||||
|
||||
You can configure MCP servers you want to use through the `mcp` option.
|
||||
@@ -153,6 +203,22 @@ You can configure MCP servers you want to use through the `mcp` option.
|
||||
|
||||
---
|
||||
|
||||
### Instructions
|
||||
|
||||
You can configure the instructions for the model you're using through the `instructions` option.
|
||||
|
||||
```json title="opencode.json"
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"instructions": ["CONTRIBUTING.md", "docs/guidelines.md", ".cursor/rules/*.md"]
|
||||
}
|
||||
```
|
||||
|
||||
This takes an array of paths and glob patterns to instruction files. [Learn more
|
||||
about rules here](/docs/rules).
|
||||
|
||||
---
|
||||
|
||||
### Disabled providers
|
||||
|
||||
You can disable providers that are loaded automatically through the `disabled_providers` option. This is useful when you want to prevent certain providers from being loaded even if their credentials are available.
|
||||
@@ -190,7 +256,7 @@ Use `{env:VARIABLE_NAME}` to substitute environment variables:
|
||||
"anthropic": {
|
||||
"options": {
|
||||
"apiKey": "{env:ANTHROPIC_API_KEY}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ Since opencode is open source and does not store any of your code or context dat
|
||||
|
||||
**opencode does not store your code or context data.** All processing happens locally or through direct API calls to your AI provider.
|
||||
|
||||
The only caveat here is the optional `/share` feature that must be manually enabled.
|
||||
The only caveat here is the optional `/share` feature.
|
||||
|
||||
---
|
||||
|
||||
@@ -33,6 +33,17 @@ If a user enables the `/share` feature, the conversation and the data associated
|
||||
|
||||
The data is currently served through our CDN's edge network, and is cached on the edge near your users.
|
||||
|
||||
We recommend you disable this for your trial.
|
||||
|
||||
```json title="opencode.json"
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"share": "disabled"
|
||||
}
|
||||
```
|
||||
|
||||
[Learn more about sharing](/docs/share).
|
||||
|
||||
---
|
||||
|
||||
### Code ownership
|
||||
@@ -51,9 +62,37 @@ pricing and implementation options.
|
||||
|
||||
### SSO
|
||||
|
||||
SSO integration can be implemented for enterprise deployments after your trial. Currently users manage and configure individual API keys locally.
|
||||
SSO integration can be implemented for enterprise deployments after your trial.
|
||||
This will allow your team's session data and shared conversations to be protected
|
||||
by your enterprise's authentication system.
|
||||
|
||||
This can be switched to a centralized authentication system that your organization uses.
|
||||
---
|
||||
|
||||
### Private NPM
|
||||
|
||||
opencode supports private npm registries through Bun's native `.npmrc` file support. If your organization uses a private registry, such as JFrog Artifactory, Nexus, or similar, ensure developers are authenticated before running opencode.
|
||||
|
||||
To set up authentication with your private registry:
|
||||
|
||||
```bash
|
||||
npm login --registry=https://your-company.jfrog.io/api/npm/npm-virtual/
|
||||
```
|
||||
|
||||
This creates `~/.npmrc` with authentication details. opencode will automatically
|
||||
pick this up.
|
||||
|
||||
:::caution
|
||||
You must be logged into the private registry before running opencode.
|
||||
:::
|
||||
|
||||
Alternatively, you can manually configure a `.npmrc` file:
|
||||
|
||||
```bash title="~/.npmrc"
|
||||
registry=https://your-company.jfrog.io/api/npm/npm-virtual/
|
||||
//your-company.jfrog.io/api/npm/npm-virtual/:_authToken=${NPM_AUTH_TOKEN}
|
||||
```
|
||||
|
||||
Developers must be logged into the private registry before running opencode to ensure packages can be installed from your enterprise registry.
|
||||
|
||||
---
|
||||
|
||||
@@ -61,30 +100,3 @@ This can be switched to a centralized authentication system that your organizati
|
||||
|
||||
The share feature can be self-hosted and the share pages can be made accessible
|
||||
only after the user has been authenticated.
|
||||
|
||||
---
|
||||
|
||||
### Private NPM registries
|
||||
|
||||
opencode supports private npm registries through Bun's native `.npmrc` file support. If your organization uses a private registry (such as JFrog Artifactory, Nexus, or similar), ensure developers are authenticated before running opencode.
|
||||
|
||||
To set up authentication with your private registry:
|
||||
|
||||
```bash
|
||||
# Authenticate with your enterprise registry
|
||||
npm login --registry=https://your-company.jfrog.io/api/npm/npm-virtual/
|
||||
|
||||
# This creates ~/.npmrc with authentication
|
||||
# opencode will automatically use it through Bun's native support
|
||||
```
|
||||
|
||||
Alternatively, you can manually configure a `.npmrc` file:
|
||||
|
||||
```bash
|
||||
# ~/.npmrc
|
||||
registry=https://your-company.jfrog.io/api/npm/npm-virtual/
|
||||
//your-company.jfrog.io/api/npm/npm-virtual/:_authToken=${NPM_AUTH_TOKEN}
|
||||
```
|
||||
|
||||
**Important**: Developers must be logged into the private registry before running opencode
|
||||
to ensure packages can be installed from your enterprise registry.
|
||||
|
||||
@@ -9,32 +9,45 @@ opencode has a list of keybinds that you can customize through the opencode conf
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"keybinds": {
|
||||
|
||||
"leader": "ctrl+x",
|
||||
"help": "<leader>h",
|
||||
"app_help": "<leader>h",
|
||||
"switch_mode": "tab",
|
||||
|
||||
"editor_open": "<leader>e",
|
||||
|
||||
"session_new": "<leader>n",
|
||||
"session_list": "<leader>l",
|
||||
"session_share": "<leader>s",
|
||||
"session_unshare": "<leader>u",
|
||||
"session_interrupt": "esc",
|
||||
"session_compact": "<leader>c",
|
||||
|
||||
"tool_details": "<leader>d",
|
||||
"model_list": "<leader>m",
|
||||
"theme_list": "<leader>t",
|
||||
"project_init": "<leader>i",
|
||||
|
||||
"file_list": "<leader>f",
|
||||
"file_close": "esc",
|
||||
"file_diff_toggle": "<leader>v",
|
||||
|
||||
"input_clear": "ctrl+c",
|
||||
"input_paste": "ctrl+v",
|
||||
"input_submit": "enter",
|
||||
"input_newline": "shift+enter,ctrl+j",
|
||||
"history_previous": "up",
|
||||
"history_next": "down",
|
||||
|
||||
"messages_page_up": "pgup",
|
||||
"messages_page_down": "pgdown",
|
||||
"messages_half_page_up": "ctrl+alt+u",
|
||||
"messages_half_page_down": "ctrl+alt+d",
|
||||
"messages_previous": "ctrl+alt+k",
|
||||
"messages_next": "ctrl+alt+j",
|
||||
"messages_previous": "ctrl+up",
|
||||
"messages_next": "ctrl+down",
|
||||
"messages_first": "ctrl+g",
|
||||
"messages_last": "ctrl+alt+g",
|
||||
"messages_layout_toggle": "<leader>p",
|
||||
"messages_copy": "<leader>y",
|
||||
"messages_revert": "<leader>r",
|
||||
"app_exit": "ctrl+c,<leader>q"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,10 @@ Add a remote MCP servers under `mcp.remotemcp`.
|
||||
"remotemcp": {
|
||||
"type": "remote",
|
||||
"url": "https://my-mcp-server.com",
|
||||
"enabled": true
|
||||
"enabled": true,
|
||||
"headers": {
|
||||
"Authorization": "Bearer MY_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,14 +46,14 @@ You can add custom providers by specifying the npm package for the provider and
|
||||
|
||||
You can customize the base URL for any provider by setting the `baseURL` option. This is useful when using proxy services or custom endpoints.
|
||||
|
||||
```json title="opencode.json" {6-7}
|
||||
```json title="opencode.json" {6}
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"provider": {
|
||||
"anthropic": {
|
||||
"options": {
|
||||
"baseURL": "https://api.anthropic.com/v1"
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,13 +23,13 @@ When you share a conversation, opencode:
|
||||
|
||||
## Sharing
|
||||
|
||||
You can manually share a conversation or enable automatic sharing for all new conversations.
|
||||
opencode supports three sharing modes that control how conversations are shared:
|
||||
|
||||
---
|
||||
|
||||
### Manual
|
||||
### Manual (default)
|
||||
|
||||
Use the `/share` command in any conversation to create a shareable link:
|
||||
By default, opencode uses manual sharing mode. Sessions are not shared automatically, but you can manually share them using the `/share` command:
|
||||
|
||||
```
|
||||
/share
|
||||
@@ -37,24 +37,48 @@ Use the `/share` command in any conversation to create a shareable link:
|
||||
|
||||
This will generate a unique URL that'll be copied to your clipboard.
|
||||
|
||||
---
|
||||
|
||||
### Autoshare
|
||||
|
||||
You can enable automatic sharing for all new conversations through the `autoshare` option in your [config file](/docs/config).
|
||||
To explicitly set manual mode in your [config file](/docs/config):
|
||||
|
||||
```json title="opencode.json"
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"autoshare": true
|
||||
"share": "manual"
|
||||
}
|
||||
```
|
||||
|
||||
By default, `autoshare` is disabled.
|
||||
---
|
||||
|
||||
### Auto-share
|
||||
|
||||
You can enable automatic sharing for all new conversations by setting the `share` option to `"auto"` in your [config file](/docs/config):
|
||||
|
||||
```json title="opencode.json"
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"share": "auto"
|
||||
}
|
||||
```
|
||||
|
||||
With auto-share enabled, every new conversation will automatically be shared and a link will be generated.
|
||||
|
||||
---
|
||||
|
||||
## Unsharing
|
||||
### Disabled
|
||||
|
||||
You can disable sharing entirely by setting the `share` option to `"disabled"` in your [config file](/docs/config):
|
||||
|
||||
```json title="opencode.json"
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"share": "disabled"
|
||||
}
|
||||
```
|
||||
|
||||
To enforce this across your team for a given project, add it to the `opencode.json` in your project and check into Git.
|
||||
|
||||
---
|
||||
|
||||
## Un-sharing
|
||||
|
||||
To stop sharing a conversation and remove it from public access:
|
||||
|
||||
@@ -85,10 +109,11 @@ includes:
|
||||
|
||||
### Recommendations
|
||||
|
||||
- Only share conversations that don't contain sensitive information
|
||||
- Review conversation content before sharing
|
||||
- Unshare conversations when collaboration is complete
|
||||
- Avoid sharing conversations with proprietary code or confidential data
|
||||
- Only share conversations that don't contain sensitive information.
|
||||
- Review conversation content before sharing.
|
||||
- Unshare conversations when collaboration is complete.
|
||||
- Avoid sharing conversations with proprietary code or confidential data.
|
||||
- For sensitive projects, disable sharing entirely.
|
||||
|
||||
---
|
||||
|
||||
@@ -96,8 +121,8 @@ includes:
|
||||
|
||||
For enterprise deployments, the share feature can be:
|
||||
|
||||
- **Self-hosted** on your own infrastructure
|
||||
- **Restricted** to authenticated users only
|
||||
- **Disabled** entirely for security compliance
|
||||
- **Restricted** to users authenticated through SSO only
|
||||
- **Self-hosted** on your own infrastructure
|
||||
|
||||
[Learn more](/docs/enterprise) about using opencode in your organization.
|
||||
|
||||
@@ -134,13 +134,10 @@ We're working on adding click & drag text selection in a future update.
|
||||
|
||||
By default, opencode's TUI uses an "auto" layout that centers content with padding. If you want the TUI to use the full width of your terminal, you can configure the layout setting:
|
||||
|
||||
```json
|
||||
```json title="opencode.json"
|
||||
{
|
||||
"layout": "stretch"
|
||||
}
|
||||
```
|
||||
|
||||
Add this to your `opencode.json` configuration file. The available layout options are:
|
||||
|
||||
- `"auto"` (default) - Centers content with padding
|
||||
- `"stretch"` - Uses full terminal width
|
||||
Read more about this in the [config docs](/docs/config#layout).
|
||||
|
||||
Reference in New Issue
Block a user