summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--opencode.json1
-rw-r--r--packages/opencode/src/app/app.ts6
-rw-r--r--packages/opencode/src/config/config.ts33
-rw-r--r--packages/tui/AGENTS.md28
-rw-r--r--packages/tui/internal/components/chat/messages.go2
-rw-r--r--packages/tui/sdk/.stats.yml4
-rw-r--r--packages/tui/sdk/app.go2
-rw-r--r--packages/tui/sdk/config.go31
8 files changed, 62 insertions, 45 deletions
diff --git a/opencode.json b/opencode.json
index 07f3581af..2fa644079 100644
--- a/opencode.json
+++ b/opencode.json
@@ -1,6 +1,5 @@
{
"$schema": "https://opencode.ai/config.json",
- "username": "testuser",
"mcp": {
"weather": {
"type": "local",
diff --git a/packages/opencode/src/app/app.ts b/packages/opencode/src/app/app.ts
index ce417e6b9..fc7f49cb9 100644
--- a/packages/opencode/src/app/app.ts
+++ b/packages/opencode/src/app/app.ts
@@ -12,7 +12,6 @@ export namespace App {
export const Info = z
.object({
- user: z.string(),
hostname: z.string(),
git: z.boolean(),
path: z.object({
@@ -69,12 +68,7 @@ export namespace App {
const root = git ?? input.cwd
- // Load config to get custom username if set
- const { Config } = await import("../config/config")
- const config = await Config.global()
-
const info: Info = {
- user: config.username || os.userInfo().username,
hostname: os.hostname(),
time: {
initialized: state.initialized,
diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts
index 53ada8a73..ebcf065a1 100644
--- a/packages/opencode/src/config/config.ts
+++ b/packages/opencode/src/config/config.ts
@@ -21,6 +21,17 @@ export namespace Config {
result = mergeDeep(result, await load(resolved))
}
}
+
+ // Handle migration from autoshare to share field
+ if (result.autoshare === true && !result.share) {
+ result.share = "auto"
+ }
+
+ if (!result.username) {
+ const os = await import("os")
+ result.username = os.userInfo().username
+ }
+
log.info("loaded", result)
return result
@@ -117,12 +128,21 @@ export namespace Config {
$schema: z.string().optional().describe("JSON schema reference for configuration validation"),
theme: z.string().optional().describe("Theme name to use for the interface"),
keybinds: Keybinds.optional().describe("Custom keybind configurations"),
- share: z.enum(["auto", "disabled"]).optional().describe("Control sharing behavior: 'auto' enables automatic sharing, 'disabled' disables all sharing"),
- autoshare: z.boolean().optional().describe("@deprecated Use 'share' field instead. Share newly created sessions automatically"),
+ share: z
+ .enum(["auto", "disabled"])
+ .optional()
+ .describe("Control sharing behavior: 'auto' enables automatic sharing, 'disabled' disables all sharing"),
+ autoshare: z
+ .boolean()
+ .optional()
+ .describe("@deprecated Use 'share' field instead. Share newly created sessions automatically"),
autoupdate: z.boolean().optional().describe("Automatically update to the latest version"),
disabled_providers: z.array(z.string()).optional().describe("Disable providers that are loaded automatically"),
model: z.string().describe("Model to use in the format of provider/model, eg anthropic/claude-2").optional(),
- username: z.string().optional().describe("Custom username to display in conversations instead of system username"),
+ username: z
+ .string()
+ .optional()
+ .describe("Custom username to display in conversations instead of system username"),
mode: z
.object({
build: Mode.optional(),
@@ -234,11 +254,6 @@ export namespace Config {
const parsed = Info.safeParse(data)
if (parsed.success) {
- // Handle migration from autoshare to share field
- if (parsed.data.autoshare === true && !parsed.data.share) {
- parsed.data.share = "auto"
- }
-
if (!parsed.data.$schema) {
parsed.data.$schema = "https://opencode.ai/config.json"
await Bun.write(configPath, JSON.stringify(parsed.data, null, 2))
@@ -265,6 +280,4 @@ export namespace Config {
export function get() {
return state()
}
-
-
}
diff --git a/packages/tui/AGENTS.md b/packages/tui/AGENTS.md
index 753374f92..51babefb3 100644
--- a/packages/tui/AGENTS.md
+++ b/packages/tui/AGENTS.md
@@ -1,25 +1,13 @@
# TUI Agent Guidelines
-## Build/Test Commands
+## Style
-- **Build**: `go build ./cmd/opencode` (builds main binary)
-- **Test**: `go test ./...` (runs all tests)
-- **Single test**: `go test ./internal/theme -run TestLoadThemesFromJSON` (specific test)
-- **Release build**: Uses `.goreleaser.yml` configuration
+- prefer single word variable names
+- avoid try catch where possible - prefer to let exceptions bubble up
+- avoid else statements where possible
+- prefer Bun apis
-## Code Style
+## Workflow
-- **Language**: Go 1.24+ with standard formatting (`gofmt`)
-- **Imports**: Group standard, third-party, local packages with blank lines
-- **Naming**: Go conventions - PascalCase exports, camelCase private, ALL_CAPS constants
-- **Error handling**: Return errors explicitly, use `fmt.Errorf` for wrapping
-- **Structs**: Define clear interfaces, embed when appropriate
-- **Testing**: Use table-driven tests, `t.TempDir()` for file operations
-
-## Architecture
-
-- **TUI Framework**: Bubble Tea v2 with Lipgloss v2 for styling
-- **Client**: Generated OpenAPI client communicates with TypeScript server
-- **Components**: Reusable UI components in `internal/components/`
-- **Themes**: JSON-based theming system with override hierarchy
-- **State**: Centralized app state with message passing
+- you can regenerate the golang sdk by calling ./scripts/stainless.ts
+- we use bun for everything
diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go
index 191432cc3..938ef683e 100644
--- a/packages/tui/internal/components/chat/messages.go
+++ b/packages/tui/internal/components/chat/messages.go
@@ -190,7 +190,7 @@ func (m *messagesComponent) renderView(width int) {
m.app,
message.Info,
part.Text,
- m.app.Info.User,
+ m.app.Config.Username,
m.showToolDetails,
m.partCount == m.selectedPart,
width,
diff --git a/packages/tui/sdk/.stats.yml b/packages/tui/sdk/.stats.yml
index 61d2fa3b7..c2069e9c5 100644
--- a/packages/tui/sdk/.stats.yml
+++ b/packages/tui/sdk/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 22
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-352994eb17f76d9472b0f0176efacf77a200a6fab2db28d1cfcd29451b211d7a.yml
-openapi_spec_hash: f01cd3de8c7cf0c9fd513896e81986de
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-9bdc593eab163d2165321716af6a4c13253792ad409420790ed6196da4178d3a.yml
+openapi_spec_hash: c687f53ada739d315e2e7056df93d999
config_hash: 3695cfc829cfaae14490850b4a1ed282
diff --git a/packages/tui/sdk/app.go b/packages/tui/sdk/app.go
index 09d8cbf39..69414f20b 100644
--- a/packages/tui/sdk/app.go
+++ b/packages/tui/sdk/app.go
@@ -68,7 +68,6 @@ type App struct {
Hostname string `json:"hostname,required"`
Path AppPath `json:"path,required"`
Time AppTime `json:"time,required"`
- User string `json:"user,required"`
JSON appJSON `json:"-"`
}
@@ -78,7 +77,6 @@ type appJSON struct {
Hostname apijson.Field
Path apijson.Field
Time apijson.Field
- User apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
diff --git a/packages/tui/sdk/config.go b/packages/tui/sdk/config.go
index 59c4e62cf..7c04cd14b 100644
--- a/packages/tui/sdk/config.go
+++ b/packages/tui/sdk/config.go
@@ -51,7 +51,8 @@ func (r *ConfigService) Providers(ctx context.Context, opts ...option.RequestOpt
type Config struct {
// JSON schema reference for configuration validation
Schema string `json:"$schema"`
- // Share newly created sessions automatically
+ // @deprecated Use 'share' field instead. Share newly created sessions
+ // automatically
Autoshare bool `json:"autoshare"`
// Automatically update to the latest version
Autoupdate bool `json:"autoupdate"`
@@ -71,9 +72,14 @@ type Config struct {
Model string `json:"model"`
// Custom provider configurations and model overrides
Provider map[string]ConfigProvider `json:"provider"`
+ // Control sharing behavior: 'auto' enables automatic sharing, 'disabled' disables
+ // all sharing
+ Share ConfigShare `json:"share"`
// Theme name to use for the interface
- Theme string `json:"theme"`
- JSON configJSON `json:"-"`
+ Theme string `json:"theme"`
+ // Custom username to display in conversations instead of system username
+ Username string `json:"username"`
+ JSON configJSON `json:"-"`
}
// configJSON contains the JSON metadata for the struct [Config]
@@ -90,7 +96,9 @@ type configJSON struct {
Mode apijson.Field
Model apijson.Field
Provider apijson.Field
+ Share apijson.Field
Theme apijson.Field
+ Username apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
@@ -470,6 +478,23 @@ func (r configProviderModelsLimitJSON) RawJSON() string {
return r.raw
}
+// Control sharing behavior: 'auto' enables automatic sharing, 'disabled' disables
+// all sharing
+type ConfigShare string
+
+const (
+ ConfigShareAuto ConfigShare = "auto"
+ ConfigShareDisabled ConfigShare = "disabled"
+)
+
+func (r ConfigShare) IsKnown() bool {
+ switch r {
+ case ConfigShareAuto, ConfigShareDisabled:
+ return true
+ }
+ return false
+}
+
type Keybinds struct {
// Exit the application
AppExit string `json:"app_exit,required"`