Просмотр исходного кода

feat: add scroll speed to config (#1968)

Aiden Cline 6 месяцев назад
Родитель
Сommit
dc01071498

+ 5 - 0
packages/opencode/src/config/config.ts

@@ -274,6 +274,10 @@ export namespace Config {
       ref: "KeybindsConfig",
     })
 
+  export const TUI = z.object({
+    scroll_speed: z.number().min(1).optional().default(2).describe("TUI scroll speed"),
+  })
+
   export const Layout = z.enum(["auto", "stretch"]).openapi({
     ref: "LayoutConfig",
   })
@@ -284,6 +288,7 @@ 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"),
+      tui: TUI.optional().describe("TUI specific settings"),
       plugin: z.string().array().optional(),
       snapshot: z.boolean().optional(),
       share: z

+ 2 - 2
packages/sdk/go/.stats.yml

@@ -1,4 +1,4 @@
 configured_endpoints: 39
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-b751e5c3cd3ab7fc61b18fbbfd6092b7264ea2ee305858aa538b884e7c492090.yml
-openapi_spec_hash: a61f8b1d9b834cf321f0cb7805cc8522
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-e4b6496e5f2c68fa8b3ea1b88e40041eaf5ce2652001344df80bf130675d1766.yml
+openapi_spec_hash: df474311dc9e4a89cd483bd8b8d971d8
 config_hash: eab3723c4c2232a6ba1821151259d6da

+ 1 - 1
packages/sdk/go/api.md

@@ -110,7 +110,7 @@ Response Types:
 
 Methods:
 
-- <code title="post /session">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.New">New</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>) (<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Session">Session</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
+- <code title="post /session">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.New">New</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, body <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionNewParams">SessionNewParams</a>) (<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Session">Session</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
 - <code title="patch /session/{id}">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Update">Update</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionUpdateParams">SessionUpdateParams</a>) (<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Session">Session</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
 - <code title="get /session">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>) ([]<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Session">Session</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
 - <code title="delete /session/{id}">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Delete">Delete</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/builtin#bool">bool</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>

+ 79 - 48
packages/sdk/go/config.go

@@ -80,6 +80,8 @@ type Config struct {
 	Snapshot   bool   `json:"snapshot"`
 	// Theme name to use for the interface
 	Theme string `json:"theme"`
+	// TUI specific settings
+	Tui ConfigTui `json:"tui"`
 	// Custom username to display in conversations instead of system username
 	Username string     `json:"username"`
 	JSON     configJSON `json:"-"`
@@ -108,6 +110,7 @@ type configJSON struct {
 	SmallModel        apijson.Field
 	Snapshot          apijson.Field
 	Theme             apijson.Field
+	Tui               apijson.Field
 	Username          apijson.Field
 	raw               string
 	ExtraFields       map[string]apijson.Field
@@ -1654,6 +1657,28 @@ func (r ConfigShare) IsKnown() bool {
 	return false
 }
 
+// TUI specific settings
+type ConfigTui struct {
+	// TUI scroll speed
+	ScrollSpeed float64       `json:"scroll_speed,required"`
+	JSON        configTuiJSON `json:"-"`
+}
+
+// configTuiJSON contains the JSON metadata for the struct [ConfigTui]
+type configTuiJSON struct {
+	ScrollSpeed apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *ConfigTui) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r configTuiJSON) RawJSON() string {
+	return r.raw
+}
+
 type KeybindsConfig struct {
 	// Next agent
 	AgentCycle string `json:"agent_cycle,required"`
@@ -1719,6 +1744,10 @@ type KeybindsConfig struct {
 	ModelList string `json:"model_list,required"`
 	// Create/update AGENTS.md
 	ProjectInit string `json:"project_init,required"`
+	// Cycle to next child session
+	SessionChildCycle string `json:"session_child_cycle,required"`
+	// Cycle to previous child session
+	SessionChildCycleReverse string `json:"session_child_cycle_reverse,required"`
 	// Compact the session
 	SessionCompact string `json:"session_compact,required"`
 	// Export session to editor
@@ -1752,54 +1781,56 @@ type KeybindsConfig struct {
 
 // keybindsConfigJSON contains the JSON metadata for the struct [KeybindsConfig]
 type keybindsConfigJSON struct {
-	AgentCycle              apijson.Field
-	AgentCycleReverse       apijson.Field
-	AgentList               apijson.Field
-	AppExit                 apijson.Field
-	AppHelp                 apijson.Field
-	EditorOpen              apijson.Field
-	FileClose               apijson.Field
-	FileDiffToggle          apijson.Field
-	FileList                apijson.Field
-	FileSearch              apijson.Field
-	InputClear              apijson.Field
-	InputNewline            apijson.Field
-	InputPaste              apijson.Field
-	InputSubmit             apijson.Field
-	Leader                  apijson.Field
-	MessagesCopy            apijson.Field
-	MessagesFirst           apijson.Field
-	MessagesHalfPageDown    apijson.Field
-	MessagesHalfPageUp      apijson.Field
-	MessagesLast            apijson.Field
-	MessagesLayoutToggle    apijson.Field
-	MessagesNext            apijson.Field
-	MessagesPageDown        apijson.Field
-	MessagesPageUp          apijson.Field
-	MessagesPrevious        apijson.Field
-	MessagesRedo            apijson.Field
-	MessagesRevert          apijson.Field
-	MessagesUndo            apijson.Field
-	ModelCycleRecent        apijson.Field
-	ModelCycleRecentReverse apijson.Field
-	ModelList               apijson.Field
-	ProjectInit             apijson.Field
-	SessionCompact          apijson.Field
-	SessionExport           apijson.Field
-	SessionInterrupt        apijson.Field
-	SessionList             apijson.Field
-	SessionNew              apijson.Field
-	SessionShare            apijson.Field
-	SessionUnshare          apijson.Field
-	SwitchAgent             apijson.Field
-	SwitchAgentReverse      apijson.Field
-	SwitchMode              apijson.Field
-	SwitchModeReverse       apijson.Field
-	ThemeList               apijson.Field
-	ThinkingBlocks          apijson.Field
-	ToolDetails             apijson.Field
-	raw                     string
-	ExtraFields             map[string]apijson.Field
+	AgentCycle               apijson.Field
+	AgentCycleReverse        apijson.Field
+	AgentList                apijson.Field
+	AppExit                  apijson.Field
+	AppHelp                  apijson.Field
+	EditorOpen               apijson.Field
+	FileClose                apijson.Field
+	FileDiffToggle           apijson.Field
+	FileList                 apijson.Field
+	FileSearch               apijson.Field
+	InputClear               apijson.Field
+	InputNewline             apijson.Field
+	InputPaste               apijson.Field
+	InputSubmit              apijson.Field
+	Leader                   apijson.Field
+	MessagesCopy             apijson.Field
+	MessagesFirst            apijson.Field
+	MessagesHalfPageDown     apijson.Field
+	MessagesHalfPageUp       apijson.Field
+	MessagesLast             apijson.Field
+	MessagesLayoutToggle     apijson.Field
+	MessagesNext             apijson.Field
+	MessagesPageDown         apijson.Field
+	MessagesPageUp           apijson.Field
+	MessagesPrevious         apijson.Field
+	MessagesRedo             apijson.Field
+	MessagesRevert           apijson.Field
+	MessagesUndo             apijson.Field
+	ModelCycleRecent         apijson.Field
+	ModelCycleRecentReverse  apijson.Field
+	ModelList                apijson.Field
+	ProjectInit              apijson.Field
+	SessionChildCycle        apijson.Field
+	SessionChildCycleReverse apijson.Field
+	SessionCompact           apijson.Field
+	SessionExport            apijson.Field
+	SessionInterrupt         apijson.Field
+	SessionList              apijson.Field
+	SessionNew               apijson.Field
+	SessionShare             apijson.Field
+	SessionUnshare           apijson.Field
+	SwitchAgent              apijson.Field
+	SwitchAgentReverse       apijson.Field
+	SwitchMode               apijson.Field
+	SwitchModeReverse        apijson.Field
+	ThemeList                apijson.Field
+	ThinkingBlocks           apijson.Field
+	ToolDetails              apijson.Field
+	raw                      string
+	ExtraFields              map[string]apijson.Field
 }
 
 func (r *KeybindsConfig) UnmarshalJSON(data []byte) (err error) {

+ 11 - 2
packages/sdk/go/session.go

@@ -39,10 +39,10 @@ func NewSessionService(opts ...option.RequestOption) (r *SessionService) {
 }
 
 // Create a new session
-func (r *SessionService) New(ctx context.Context, opts ...option.RequestOption) (res *Session, err error) {
+func (r *SessionService) New(ctx context.Context, body SessionNewParams, opts ...option.RequestOption) (res *Session, err error) {
 	opts = append(r.Options[:], opts...)
 	path := "session"
-	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...)
+	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
 	return
 }
 
@@ -2324,6 +2324,15 @@ func (r sessionMessagesResponseJSON) RawJSON() string {
 	return r.raw
 }
 
+type SessionNewParams struct {
+	ParentID param.Field[string] `json:"parentID"`
+	Title    param.Field[string] `json:"title"`
+}
+
+func (r SessionNewParams) MarshalJSON() (data []byte, err error) {
+	return apijson.MarshalRoot(r)
+}
+
 type SessionUpdateParams struct {
 	Title param.Field[string] `json:"title"`
 }

+ 5 - 2
packages/sdk/go/session_test.go

@@ -13,7 +13,7 @@ import (
 	"github.com/sst/opencode-sdk-go/option"
 )
 
-func TestSessionNew(t *testing.T) {
+func TestSessionNewWithOptionalParams(t *testing.T) {
 	t.Skip("skipped: tests are disabled for the time being")
 	baseURL := "http://localhost:4010"
 	if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
@@ -25,7 +25,10 @@ func TestSessionNew(t *testing.T) {
 	client := opencode.NewClient(
 		option.WithBaseURL(baseURL),
 	)
-	_, err := client.Session.New(context.TODO())
+	_, err := client.Session.New(context.TODO(), opencode.SessionNewParams{
+		ParentID: opencode.F("parentID"),
+		Title:    opencode.F("title"),
+	})
 	if err != nil {
 		var apierr *opencode.Error
 		if errors.As(err, &apierr) {

+ 9 - 0
packages/sdk/js/src/gen/types.gen.ts

@@ -576,6 +576,15 @@ export type Config = {
    * Custom keybind configurations
    */
   keybinds?: KeybindsConfig
+  /**
+   * TUI specific settings
+   */
+  tui?: {
+    /**
+     * TUI scroll speed
+     */
+    scroll_speed: number
+  }
   plugin?: Array<string>
   snapshot?: boolean
   /**

+ 3 - 1
packages/tui/internal/app/app.go

@@ -50,6 +50,7 @@ type App struct {
 	compactCancel     context.CancelFunc
 	IsLeaderSequence  bool
 	IsBashMode        bool
+	ScrollSpeed       int
 }
 
 func (a *App) Agent() *opencode.Agent {
@@ -198,6 +199,7 @@ func New(
 		InitialPrompt:  initialPrompt,
 		InitialAgent:   initialAgent,
 		InitialSession: initialSession,
+		ScrollSpeed:    int(configInfo.Tui.ScrollSpeed),
 	}
 
 	return app, nil
@@ -725,7 +727,7 @@ func (a *App) MarkProjectInitialized(ctx context.Context) error {
 }
 
 func (a *App) CreateSession(ctx context.Context) (*opencode.Session, error) {
-	session, err := a.Client.Session.New(ctx)
+	session, err := a.Client.Session.New(ctx, opencode.SessionNewParams{})
 	if err != nil {
 		return nil, err
 	}

+ 0 - 1
packages/tui/internal/app/state.go

@@ -28,7 +28,6 @@ type AgentModel struct {
 
 type State struct {
 	Theme              string                `toml:"theme"`
-	ScrollSpeed        *int                  `toml:"scroll_speed"`
 	AgentModel         map[string]AgentModel `toml:"agent_model"`
 	Provider           string                `toml:"provider"`
 	Model              string                `toml:"model"`

+ 1 - 5
packages/tui/internal/components/chat/messages.go

@@ -1194,11 +1194,7 @@ func NewMessagesComponent(app *app.App) MessagesComponent {
 	vp := viewport.New()
 	vp.KeyMap = viewport.KeyMap{}
 
-	if app.State.ScrollSpeed != nil && *app.State.ScrollSpeed > 0 {
-		vp.MouseWheelDelta = *app.State.ScrollSpeed
-	} else {
-		vp.MouseWheelDelta = 2
-	}
+	vp.MouseWheelDelta = app.ScrollSpeed
 
 	// Default to showing tool details, hidden thinking blocks
 	showToolDetails := true