Dax Raad 7 miesięcy temu
rodzic
commit
5aafab118f

+ 1 - 2
packages/opencode/src/cli/cmd/generate.ts

@@ -1,6 +1,5 @@
 import { Server } from "../../server/server"
 import fs from "fs/promises"
-import path from "path"
 import type { CommandModule } from "yargs"
 
 export const GenerateCommand = {
@@ -10,6 +9,6 @@ export const GenerateCommand = {
     const dir = "gen"
     await fs.rmdir(dir, { recursive: true }).catch(() => {})
     await fs.mkdir(dir, { recursive: true })
-    await Bun.write(path.join(dir, "openapi.json"), JSON.stringify(specs, null, 2))
+    process.stdout.write(JSON.stringify(specs, null, 2))
   },
 } satisfies CommandModule

+ 2 - 3
packages/opencode/src/server/server.ts

@@ -705,9 +705,9 @@ export namespace Server {
         },
       )
       .post(
-        "/tui/prompt",
+        "/tui/append-prompt",
         describeRoute({
-          description: "Send a prompt to the TUI",
+          description: "Append prompt to the TUI",
           responses: {
             200: {
               description: "Prompt processed successfully",
@@ -723,7 +723,6 @@ export namespace Server {
           "json",
           z.object({
             text: z.string(),
-            parts: MessageV2.Part.array(),
           }),
         ),
         async (c) => c.json(await callTui(c)),

+ 3 - 1
packages/tui/internal/components/chat/editor.go

@@ -486,7 +486,9 @@ func (m *editorComponent) SetValueWithAttachments(value string) {
 
 			if end > start {
 				filePath := value[start:end]
-				if _, err := os.Stat(filePath); err == nil {
+				slog.Debug("test", "filePath", filePath)
+				if _, err := os.Stat(filepath.Join(m.app.Info.Path.Cwd, filePath)); err == nil {
+					slog.Debug("test", "found", true)
 					attachment := m.createAttachmentFromFile(filePath)
 					if attachment != nil {
 						m.textarea.InsertAttachment(attachment)

+ 2 - 2
packages/tui/internal/tui/tui.go

@@ -509,13 +509,13 @@ func (a Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 		case "/tui/open-help":
 			helpDialog := dialog.NewHelpDialog(a.app)
 			a.modal = helpDialog
-		case "/tui/prompt":
+		case "/tui/append-prompt":
 			var body struct {
 				Text  string          `json:"text"`
 				Parts []opencode.Part `json:"parts"`
 			}
 			json.Unmarshal((msg.Body), &body)
-			a.editor.SetValue(body.Text)
+			a.editor.SetValueWithAttachments(strings.TrimRight(a.editor.Value(), " ") + " " + body.Text + " ")
 		default:
 			break
 		}

+ 3 - 3
packages/tui/sdk/.stats.yml

@@ -1,4 +1,4 @@
 configured_endpoints: 24
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-d10809ab68e48a338167e5504d69db2a0a80739adf6ecd3f065644a4139bc374.yml
-openapi_spec_hash: 4875565ef8df3446dbab11f450e04c51
-config_hash: 0032a76356d31c6b4c218b39fff635bb
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-9574184bd9e916aa69eae8e26e0679556038d3fcfb4009a445c97c6cc3e4f3ee.yml
+openapi_spec_hash: 93ba1215ab0dc853a1691b049cc47d75
+config_hash: 6d92d798d44906c9e43c6dee06615360

+ 1 - 12
packages/tui/sdk/api.md

@@ -75,23 +75,12 @@ Methods:
 
 Params Types:
 
-- <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#FilePartParam">FilePartParam</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#FilePartInputParam">FilePartInputParam</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#FilePartSourceUnionParam">FilePartSourceUnionParam</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#FilePartSourceTextParam">FilePartSourceTextParam</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#FileSourceParam">FileSourceParam</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#PartUnionParam">PartUnionParam</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#SnapshotPartParam">SnapshotPartParam</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#StepFinishPartParam">StepFinishPartParam</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#StepStartPartParam">StepStartPartParam</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#SymbolSourceParam">SymbolSourceParam</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#TextPartParam">TextPartParam</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#TextPartInputParam">TextPartInputParam</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#ToolPartParam">ToolPartParam</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#ToolStateCompletedParam">ToolStateCompletedParam</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#ToolStateErrorParam">ToolStateErrorParam</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#ToolStatePendingParam">ToolStatePendingParam</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#ToolStateRunningParam">ToolStateRunningParam</a>
 
 Response Types:
 
@@ -133,5 +122,5 @@ Methods:
 
 Methods:
 
+- <code title="post /tui/append-prompt">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.AppendPrompt">AppendPrompt</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#TuiAppendPromptParams">TuiAppendPromptParams</a>) (<a href="https://pkg.go.dev/builtin#bool">bool</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
 - <code title="post /tui/open-help">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.OpenHelp">OpenHelp</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/builtin#bool">bool</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
-- <code title="post /tui/prompt">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.Prompt">Prompt</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#TuiPromptParams">TuiPromptParams</a>) (<a href="https://pkg.go.dev/builtin#bool">bool</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>

+ 73 - 74
packages/tui/sdk/event.go

@@ -52,7 +52,6 @@ type EventListResponse struct {
 	// [EventListResponseEventPermissionUpdatedProperties],
 	// [EventListResponseEventFileEditedProperties],
 	// [EventListResponseEventInstallationUpdatedProperties],
-	// [EventListResponseEventIdeInstalledProperties],
 	// [EventListResponseEventMessageUpdatedProperties],
 	// [EventListResponseEventMessageRemovedProperties],
 	// [EventListResponseEventMessagePartUpdatedProperties],
@@ -61,7 +60,8 @@ type EventListResponse struct {
 	// [EventListResponseEventSessionDeletedProperties],
 	// [EventListResponseEventSessionIdleProperties],
 	// [EventListResponseEventSessionErrorProperties],
-	// [EventListResponseEventFileWatcherUpdatedProperties].
+	// [EventListResponseEventFileWatcherUpdatedProperties],
+	// [EventListResponseEventIdeInstalledProperties].
 	Properties interface{}           `json:"properties,required"`
 	Type       EventListResponseType `json:"type,required"`
 	JSON       eventListResponseJSON `json:"-"`
@@ -97,13 +97,13 @@ func (r *EventListResponse) UnmarshalJSON(data []byte) (err error) {
 // [EventListResponseEventLspClientDiagnostics],
 // [EventListResponseEventPermissionUpdated], [EventListResponseEventFileEdited],
 // [EventListResponseEventInstallationUpdated],
-// [EventListResponseEventIdeInstalled],
 // [EventListResponseEventMessageUpdated], [EventListResponseEventMessageRemoved],
 // [EventListResponseEventMessagePartUpdated],
 // [EventListResponseEventStorageWrite], [EventListResponseEventSessionUpdated],
 // [EventListResponseEventSessionDeleted], [EventListResponseEventSessionIdle],
 // [EventListResponseEventSessionError],
-// [EventListResponseEventFileWatcherUpdated].
+// [EventListResponseEventFileWatcherUpdated],
+// [EventListResponseEventIdeInstalled].
 func (r EventListResponse) AsUnion() EventListResponseUnion {
 	return r.union
 }
@@ -111,13 +111,12 @@ func (r EventListResponse) AsUnion() EventListResponseUnion {
 // Union satisfied by [EventListResponseEventLspClientDiagnostics],
 // [EventListResponseEventPermissionUpdated], [EventListResponseEventFileEdited],
 // [EventListResponseEventInstallationUpdated],
-// [EventListResponseEventIdeInstalled],
 // [EventListResponseEventMessageUpdated], [EventListResponseEventMessageRemoved],
 // [EventListResponseEventMessagePartUpdated],
 // [EventListResponseEventStorageWrite], [EventListResponseEventSessionUpdated],
 // [EventListResponseEventSessionDeleted], [EventListResponseEventSessionIdle],
-// [EventListResponseEventSessionError] or
-// [EventListResponseEventFileWatcherUpdated].
+// [EventListResponseEventSessionError], [EventListResponseEventFileWatcherUpdated]
+// or [EventListResponseEventIdeInstalled].
 type EventListResponseUnion interface {
 	implementsEventListResponse()
 }
@@ -146,11 +145,6 @@ func init() {
 			Type:               reflect.TypeOf(EventListResponseEventInstallationUpdated{}),
 			DiscriminatorValue: "installation.updated",
 		},
-		apijson.UnionVariant{
-			TypeFilter:         gjson.JSON,
-			Type:               reflect.TypeOf(EventListResponseEventIdeInstalled{}),
-			DiscriminatorValue: "ide.installed",
-		},
 		apijson.UnionVariant{
 			TypeFilter:         gjson.JSON,
 			Type:               reflect.TypeOf(EventListResponseEventMessageUpdated{}),
@@ -196,6 +190,11 @@ func init() {
 			Type:               reflect.TypeOf(EventListResponseEventFileWatcherUpdated{}),
 			DiscriminatorValue: "file.watcher.updated",
 		},
+		apijson.UnionVariant{
+			TypeFilter:         gjson.JSON,
+			Type:               reflect.TypeOf(EventListResponseEventIdeInstalled{}),
+			DiscriminatorValue: "ide.installed",
+		},
 	)
 }
 
@@ -470,66 +469,6 @@ func (r EventListResponseEventInstallationUpdatedType) IsKnown() bool {
 	return false
 }
 
-type EventListResponseEventIdeInstalled struct {
-	Properties EventListResponseEventIdeInstalledProperties `json:"properties,required"`
-	Type       EventListResponseEventIdeInstalledType       `json:"type,required"`
-	JSON       eventListResponseEventIdeInstalledJSON       `json:"-"`
-}
-
-// eventListResponseEventIdeInstalledJSON contains the JSON metadata for the
-// struct [EventListResponseEventIdeInstalled]
-type eventListResponseEventIdeInstalledJSON struct {
-	Properties  apijson.Field
-	Type        apijson.Field
-	raw         string
-	ExtraFields map[string]apijson.Field
-}
-
-func (r *EventListResponseEventIdeInstalled) UnmarshalJSON(data []byte) (err error) {
-	return apijson.UnmarshalRoot(data, r)
-}
-
-func (r eventListResponseEventIdeInstalledJSON) RawJSON() string {
-	return r.raw
-}
-
-func (r EventListResponseEventIdeInstalled) implementsEventListResponse() {}
-
-type EventListResponseEventIdeInstalledProperties struct {
-	Ide  string                                           `json:"ide,required"`
-	JSON eventListResponseEventIdeInstalledPropertiesJSON `json:"-"`
-}
-
-// eventListResponseEventIdeInstalledPropertiesJSON contains the JSON
-// metadata for the struct [EventListResponseEventIdeInstalledProperties]
-type eventListResponseEventIdeInstalledPropertiesJSON struct {
-	Ide         apijson.Field
-	raw         string
-	ExtraFields map[string]apijson.Field
-}
-
-func (r *EventListResponseEventIdeInstalledProperties) UnmarshalJSON(data []byte) (err error) {
-	return apijson.UnmarshalRoot(data, r)
-}
-
-func (r eventListResponseEventIdeInstalledPropertiesJSON) RawJSON() string {
-	return r.raw
-}
-
-type EventListResponseEventIdeInstalledType string
-
-const (
-	EventListResponseEventIdeInstalledTypeIdeInstalled EventListResponseEventIdeInstalledType = "ide.installed"
-)
-
-func (r EventListResponseEventIdeInstalledType) IsKnown() bool {
-	switch r {
-	case EventListResponseEventIdeInstalledTypeIdeInstalled:
-		return true
-	}
-	return false
-}
-
 type EventListResponseEventMessageUpdated struct {
 	Properties EventListResponseEventMessageUpdatedProperties `json:"properties,required"`
 	Type       EventListResponseEventMessageUpdatedType       `json:"type,required"`
@@ -1227,6 +1166,66 @@ func (r EventListResponseEventFileWatcherUpdatedType) IsKnown() bool {
 	return false
 }
 
+type EventListResponseEventIdeInstalled struct {
+	Properties EventListResponseEventIdeInstalledProperties `json:"properties,required"`
+	Type       EventListResponseEventIdeInstalledType       `json:"type,required"`
+	JSON       eventListResponseEventIdeInstalledJSON       `json:"-"`
+}
+
+// eventListResponseEventIdeInstalledJSON contains the JSON metadata for the struct
+// [EventListResponseEventIdeInstalled]
+type eventListResponseEventIdeInstalledJSON struct {
+	Properties  apijson.Field
+	Type        apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *EventListResponseEventIdeInstalled) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r eventListResponseEventIdeInstalledJSON) RawJSON() string {
+	return r.raw
+}
+
+func (r EventListResponseEventIdeInstalled) implementsEventListResponse() {}
+
+type EventListResponseEventIdeInstalledProperties struct {
+	Ide  string                                           `json:"ide,required"`
+	JSON eventListResponseEventIdeInstalledPropertiesJSON `json:"-"`
+}
+
+// eventListResponseEventIdeInstalledPropertiesJSON contains the JSON metadata for
+// the struct [EventListResponseEventIdeInstalledProperties]
+type eventListResponseEventIdeInstalledPropertiesJSON struct {
+	Ide         apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *EventListResponseEventIdeInstalledProperties) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r eventListResponseEventIdeInstalledPropertiesJSON) RawJSON() string {
+	return r.raw
+}
+
+type EventListResponseEventIdeInstalledType string
+
+const (
+	EventListResponseEventIdeInstalledTypeIdeInstalled EventListResponseEventIdeInstalledType = "ide.installed"
+)
+
+func (r EventListResponseEventIdeInstalledType) IsKnown() bool {
+	switch r {
+	case EventListResponseEventIdeInstalledTypeIdeInstalled:
+		return true
+	}
+	return false
+}
+
 type EventListResponseType string
 
 const (
@@ -1234,7 +1233,6 @@ const (
 	EventListResponseTypePermissionUpdated    EventListResponseType = "permission.updated"
 	EventListResponseTypeFileEdited           EventListResponseType = "file.edited"
 	EventListResponseTypeInstallationUpdated  EventListResponseType = "installation.updated"
-	EventListResponseTypeIdeInstalled         EventListResponseType = "ide.installed"
 	EventListResponseTypeMessageUpdated       EventListResponseType = "message.updated"
 	EventListResponseTypeMessageRemoved       EventListResponseType = "message.removed"
 	EventListResponseTypeMessagePartUpdated   EventListResponseType = "message.part.updated"
@@ -1244,11 +1242,12 @@ const (
 	EventListResponseTypeSessionIdle          EventListResponseType = "session.idle"
 	EventListResponseTypeSessionError         EventListResponseType = "session.error"
 	EventListResponseTypeFileWatcherUpdated   EventListResponseType = "file.watcher.updated"
+	EventListResponseTypeIdeInstalled         EventListResponseType = "ide.installed"
 )
 
 func (r EventListResponseType) IsKnown() bool {
 	switch r {
-	case EventListResponseTypeLspClientDiagnostics, EventListResponseTypePermissionUpdated, EventListResponseTypeFileEdited, EventListResponseTypeInstallationUpdated, EventListResponseTypeIdeInstalled, EventListResponseTypeMessageUpdated, EventListResponseTypeMessageRemoved, EventListResponseTypeMessagePartUpdated, EventListResponseTypeStorageWrite, EventListResponseTypeSessionUpdated, EventListResponseTypeSessionDeleted, EventListResponseTypeSessionIdle, EventListResponseTypeSessionError, EventListResponseTypeFileWatcherUpdated:
+	case EventListResponseTypeLspClientDiagnostics, EventListResponseTypePermissionUpdated, EventListResponseTypeFileEdited, EventListResponseTypeInstallationUpdated, EventListResponseTypeMessageUpdated, EventListResponseTypeMessageRemoved, EventListResponseTypeMessagePartUpdated, EventListResponseTypeStorageWrite, EventListResponseTypeSessionUpdated, EventListResponseTypeSessionDeleted, EventListResponseTypeSessionIdle, EventListResponseTypeSessionError, EventListResponseTypeFileWatcherUpdated, EventListResponseTypeIdeInstalled:
 		return true
 	}
 	return false

+ 5 - 4
packages/tui/sdk/option/requestoption.go

@@ -27,14 +27,15 @@ type RequestOption = requestconfig.RequestOption
 // For security reasons, ensure that the base URL is trusted.
 func WithBaseURL(base string) RequestOption {
 	u, err := url.Parse(base)
+	if err == nil && u.Path != "" && !strings.HasSuffix(u.Path, "/") {
+		u.Path += "/"
+	}
+
 	return requestconfig.RequestOptionFunc(func(r *requestconfig.RequestConfig) error {
 		if err != nil {
-			return fmt.Errorf("requestoption: WithBaseURL failed to parse url %s\n", err)
+			return fmt.Errorf("requestoption: WithBaseURL failed to parse url %s", err)
 		}
 
-		if u.Path != "" && !strings.HasSuffix(u.Path, "/") {
-			u.Path += "/"
-		}
 		r.BaseURL = u
 		return nil
 	})

+ 0 - 252
packages/tui/sdk/session.go

@@ -483,23 +483,6 @@ func (r FilePartType) IsKnown() bool {
 	return false
 }
 
-type FilePartParam struct {
-	ID        param.Field[string]                   `json:"id,required"`
-	MessageID param.Field[string]                   `json:"messageID,required"`
-	Mime      param.Field[string]                   `json:"mime,required"`
-	SessionID param.Field[string]                   `json:"sessionID,required"`
-	Type      param.Field[FilePartType]             `json:"type,required"`
-	URL       param.Field[string]                   `json:"url,required"`
-	Filename  param.Field[string]                   `json:"filename"`
-	Source    param.Field[FilePartSourceUnionParam] `json:"source"`
-}
-
-func (r FilePartParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r FilePartParam) implementsPartUnionParam() {}
-
 type FilePartInputParam struct {
 	Mime     param.Field[string]                   `json:"mime,required"`
 	Type     param.Field[FilePartInputType]        `json:"type,required"`
@@ -949,38 +932,6 @@ func (r PartType) IsKnown() bool {
 	return false
 }
 
-type PartParam struct {
-	ID        param.Field[string]                   `json:"id,required"`
-	MessageID param.Field[string]                   `json:"messageID,required"`
-	SessionID param.Field[string]                   `json:"sessionID,required"`
-	Type      param.Field[PartType]                 `json:"type,required"`
-	CallID    param.Field[string]                   `json:"callID"`
-	Cost      param.Field[float64]                  `json:"cost"`
-	Filename  param.Field[string]                   `json:"filename"`
-	Mime      param.Field[string]                   `json:"mime"`
-	Snapshot  param.Field[string]                   `json:"snapshot"`
-	Source    param.Field[FilePartSourceUnionParam] `json:"source"`
-	State     param.Field[interface{}]              `json:"state"`
-	Synthetic param.Field[bool]                     `json:"synthetic"`
-	Text      param.Field[string]                   `json:"text"`
-	Time      param.Field[interface{}]              `json:"time"`
-	Tokens    param.Field[interface{}]              `json:"tokens"`
-	Tool      param.Field[string]                   `json:"tool"`
-	URL       param.Field[string]                   `json:"url"`
-}
-
-func (r PartParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r PartParam) implementsPartUnionParam() {}
-
-// Satisfied by [TextPartParam], [FilePartParam], [ToolPartParam],
-// [StepStartPartParam], [StepFinishPartParam], [SnapshotPartParam], [PartParam].
-type PartUnionParam interface {
-	implementsPartUnionParam()
-}
-
 type Session struct {
 	ID       string        `json:"id,required"`
 	Time     SessionTime   `json:"time,required"`
@@ -1123,20 +1074,6 @@ func (r SnapshotPartType) IsKnown() bool {
 	return false
 }
 
-type SnapshotPartParam struct {
-	ID        param.Field[string]           `json:"id,required"`
-	MessageID param.Field[string]           `json:"messageID,required"`
-	SessionID param.Field[string]           `json:"sessionID,required"`
-	Snapshot  param.Field[string]           `json:"snapshot,required"`
-	Type      param.Field[SnapshotPartType] `json:"type,required"`
-}
-
-func (r SnapshotPartParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r SnapshotPartParam) implementsPartUnionParam() {}
-
 type StepFinishPart struct {
 	ID        string               `json:"id,required"`
 	Cost      float64              `json:"cost,required"`
@@ -1233,41 +1170,6 @@ func (r StepFinishPartType) IsKnown() bool {
 	return false
 }
 
-type StepFinishPartParam struct {
-	ID        param.Field[string]                    `json:"id,required"`
-	Cost      param.Field[float64]                   `json:"cost,required"`
-	MessageID param.Field[string]                    `json:"messageID,required"`
-	SessionID param.Field[string]                    `json:"sessionID,required"`
-	Tokens    param.Field[StepFinishPartTokensParam] `json:"tokens,required"`
-	Type      param.Field[StepFinishPartType]        `json:"type,required"`
-}
-
-func (r StepFinishPartParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r StepFinishPartParam) implementsPartUnionParam() {}
-
-type StepFinishPartTokensParam struct {
-	Cache     param.Field[StepFinishPartTokensCacheParam] `json:"cache,required"`
-	Input     param.Field[float64]                        `json:"input,required"`
-	Output    param.Field[float64]                        `json:"output,required"`
-	Reasoning param.Field[float64]                        `json:"reasoning,required"`
-}
-
-func (r StepFinishPartTokensParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-type StepFinishPartTokensCacheParam struct {
-	Read  param.Field[float64] `json:"read,required"`
-	Write param.Field[float64] `json:"write,required"`
-}
-
-func (r StepFinishPartTokensCacheParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
 type StepStartPart struct {
 	ID        string            `json:"id,required"`
 	MessageID string            `json:"messageID,required"`
@@ -1310,19 +1212,6 @@ func (r StepStartPartType) IsKnown() bool {
 	return false
 }
 
-type StepStartPartParam struct {
-	ID        param.Field[string]            `json:"id,required"`
-	MessageID param.Field[string]            `json:"messageID,required"`
-	SessionID param.Field[string]            `json:"sessionID,required"`
-	Type      param.Field[StepStartPartType] `json:"type,required"`
-}
-
-func (r StepStartPartParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r StepStartPartParam) implementsPartUnionParam() {}
-
 type SymbolSource struct {
 	Kind  int64              `json:"kind,required"`
 	Name  string             `json:"name,required"`
@@ -1550,31 +1439,6 @@ func (r textPartTimeJSON) RawJSON() string {
 	return r.raw
 }
 
-type TextPartParam struct {
-	ID        param.Field[string]            `json:"id,required"`
-	MessageID param.Field[string]            `json:"messageID,required"`
-	SessionID param.Field[string]            `json:"sessionID,required"`
-	Text      param.Field[string]            `json:"text,required"`
-	Type      param.Field[TextPartType]      `json:"type,required"`
-	Synthetic param.Field[bool]              `json:"synthetic"`
-	Time      param.Field[TextPartTimeParam] `json:"time"`
-}
-
-func (r TextPartParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r TextPartParam) implementsPartUnionParam() {}
-
-type TextPartTimeParam struct {
-	Start param.Field[float64] `json:"start,required"`
-	End   param.Field[float64] `json:"end"`
-}
-
-func (r TextPartTimeParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
 type TextPartInputParam struct {
 	Text      param.Field[string]                 `json:"text,required"`
 	Type      param.Field[TextPartInputType]      `json:"type,required"`
@@ -1761,44 +1625,6 @@ func (r ToolPartType) IsKnown() bool {
 	return false
 }
 
-type ToolPartParam struct {
-	ID        param.Field[string]                  `json:"id,required"`
-	CallID    param.Field[string]                  `json:"callID,required"`
-	MessageID param.Field[string]                  `json:"messageID,required"`
-	SessionID param.Field[string]                  `json:"sessionID,required"`
-	State     param.Field[ToolPartStateUnionParam] `json:"state,required"`
-	Tool      param.Field[string]                  `json:"tool,required"`
-	Type      param.Field[ToolPartType]            `json:"type,required"`
-}
-
-func (r ToolPartParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r ToolPartParam) implementsPartUnionParam() {}
-
-type ToolPartStateParam struct {
-	Status   param.Field[ToolPartStateStatus] `json:"status,required"`
-	Error    param.Field[string]              `json:"error"`
-	Input    param.Field[interface{}]         `json:"input"`
-	Metadata param.Field[interface{}]         `json:"metadata"`
-	Output   param.Field[string]              `json:"output"`
-	Time     param.Field[interface{}]         `json:"time"`
-	Title    param.Field[string]              `json:"title"`
-}
-
-func (r ToolPartStateParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r ToolPartStateParam) implementsToolPartStateUnionParam() {}
-
-// Satisfied by [ToolStatePendingParam], [ToolStateRunningParam],
-// [ToolStateCompletedParam], [ToolStateErrorParam], [ToolPartStateParam].
-type ToolPartStateUnionParam interface {
-	implementsToolPartStateUnionParam()
-}
-
 type ToolStateCompleted struct {
 	Input    map[string]interface{}   `json:"input,required"`
 	Metadata map[string]interface{}   `json:"metadata,required"`
@@ -1869,30 +1695,6 @@ func (r toolStateCompletedTimeJSON) RawJSON() string {
 	return r.raw
 }
 
-type ToolStateCompletedParam struct {
-	Input    param.Field[map[string]interface{}]      `json:"input,required"`
-	Metadata param.Field[map[string]interface{}]      `json:"metadata,required"`
-	Output   param.Field[string]                      `json:"output,required"`
-	Status   param.Field[ToolStateCompletedStatus]    `json:"status,required"`
-	Time     param.Field[ToolStateCompletedTimeParam] `json:"time,required"`
-	Title    param.Field[string]                      `json:"title,required"`
-}
-
-func (r ToolStateCompletedParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r ToolStateCompletedParam) implementsToolPartStateUnionParam() {}
-
-type ToolStateCompletedTimeParam struct {
-	End   param.Field[float64] `json:"end,required"`
-	Start param.Field[float64] `json:"start,required"`
-}
-
-func (r ToolStateCompletedTimeParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
 type ToolStateError struct {
 	Error  string                 `json:"error,required"`
 	Input  map[string]interface{} `json:"input,required"`
@@ -1958,28 +1760,6 @@ func (r toolStateErrorTimeJSON) RawJSON() string {
 	return r.raw
 }
 
-type ToolStateErrorParam struct {
-	Error  param.Field[string]                  `json:"error,required"`
-	Input  param.Field[map[string]interface{}]  `json:"input,required"`
-	Status param.Field[ToolStateErrorStatus]    `json:"status,required"`
-	Time   param.Field[ToolStateErrorTimeParam] `json:"time,required"`
-}
-
-func (r ToolStateErrorParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r ToolStateErrorParam) implementsToolPartStateUnionParam() {}
-
-type ToolStateErrorTimeParam struct {
-	End   param.Field[float64] `json:"end,required"`
-	Start param.Field[float64] `json:"start,required"`
-}
-
-func (r ToolStateErrorTimeParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
 type ToolStatePending struct {
 	Status ToolStatePendingStatus `json:"status,required"`
 	JSON   toolStatePendingJSON   `json:"-"`
@@ -2017,16 +1797,6 @@ func (r ToolStatePendingStatus) IsKnown() bool {
 	return false
 }
 
-type ToolStatePendingParam struct {
-	Status param.Field[ToolStatePendingStatus] `json:"status,required"`
-}
-
-func (r ToolStatePendingParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r ToolStatePendingParam) implementsToolPartStateUnionParam() {}
-
 type ToolStateRunning struct {
 	Status   ToolStateRunningStatus `json:"status,required"`
 	Time     ToolStateRunningTime   `json:"time,required"`
@@ -2093,28 +1863,6 @@ func (r toolStateRunningTimeJSON) RawJSON() string {
 	return r.raw
 }
 
-type ToolStateRunningParam struct {
-	Status   param.Field[ToolStateRunningStatus]    `json:"status,required"`
-	Time     param.Field[ToolStateRunningTimeParam] `json:"time,required"`
-	Input    param.Field[interface{}]               `json:"input"`
-	Metadata param.Field[map[string]interface{}]    `json:"metadata"`
-	Title    param.Field[string]                    `json:"title"`
-}
-
-func (r ToolStateRunningParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
-func (r ToolStateRunningParam) implementsToolPartStateUnionParam() {}
-
-type ToolStateRunningTimeParam struct {
-	Start param.Field[float64] `json:"start,required"`
-}
-
-func (r ToolStateRunningTimeParam) MarshalJSON() (data []byte, err error) {
-	return apijson.MarshalRoot(r)
-}
-
 type UserMessage struct {
 	ID        string          `json:"id,required"`
 	Role      UserMessageRole `json:"role,required"`

+ 11 - 12
packages/tui/sdk/tui.go

@@ -31,27 +31,26 @@ func NewTuiService(opts ...option.RequestOption) (r *TuiService) {
 	return
 }
 
-// Open the help dialog
-func (r *TuiService) OpenHelp(ctx context.Context, opts ...option.RequestOption) (res *bool, err error) {
+// Append prompt to the TUI
+func (r *TuiService) AppendPrompt(ctx context.Context, body TuiAppendPromptParams, opts ...option.RequestOption) (res *bool, err error) {
 	opts = append(r.Options[:], opts...)
-	path := "tui/open-help"
-	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...)
+	path := "tui/append-prompt"
+	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
 	return
 }
 
-// Send a prompt to the TUI
-func (r *TuiService) Prompt(ctx context.Context, body TuiPromptParams, opts ...option.RequestOption) (res *bool, err error) {
+// Open the help dialog
+func (r *TuiService) OpenHelp(ctx context.Context, opts ...option.RequestOption) (res *bool, err error) {
 	opts = append(r.Options[:], opts...)
-	path := "tui/prompt"
-	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
+	path := "tui/open-help"
+	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...)
 	return
 }
 
-type TuiPromptParams struct {
-	Parts param.Field[[]PartUnionParam] `json:"parts,required"`
-	Text  param.Field[string]           `json:"text,required"`
+type TuiAppendPromptParams struct {
+	Text param.Field[string] `json:"text,required"`
 }
 
-func (r TuiPromptParams) MarshalJSON() (data []byte, err error) {
+func (r TuiAppendPromptParams) MarshalJSON() (data []byte, err error) {
 	return apijson.MarshalRoot(r)
 }

+ 6 - 18
packages/tui/sdk/tui_test.go

@@ -13,7 +13,7 @@ import (
 	"github.com/sst/opencode-sdk-go/option"
 )
 
-func TestTuiOpenHelp(t *testing.T) {
+func TestTuiAppendPrompt(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,9 @@ func TestTuiOpenHelp(t *testing.T) {
 	client := opencode.NewClient(
 		option.WithBaseURL(baseURL),
 	)
-	_, err := client.Tui.OpenHelp(context.TODO())
+	_, err := client.Tui.AppendPrompt(context.TODO(), opencode.TuiAppendPromptParams{
+		Text: opencode.F("text"),
+	})
 	if err != nil {
 		var apierr *opencode.Error
 		if errors.As(err, &apierr) {
@@ -35,7 +37,7 @@ func TestTuiOpenHelp(t *testing.T) {
 	}
 }
 
-func TestTuiPrompt(t *testing.T) {
+func TestTuiOpenHelp(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 {
@@ -47,21 +49,7 @@ func TestTuiPrompt(t *testing.T) {
 	client := opencode.NewClient(
 		option.WithBaseURL(baseURL),
 	)
-	_, err := client.Tui.Prompt(context.TODO(), opencode.TuiPromptParams{
-		Parts: opencode.F([]opencode.PartUnionParam{opencode.TextPartParam{
-			ID:        opencode.F("id"),
-			MessageID: opencode.F("messageID"),
-			SessionID: opencode.F("sessionID"),
-			Text:      opencode.F("text"),
-			Type:      opencode.F(opencode.TextPartTypeText),
-			Synthetic: opencode.F(true),
-			Time: opencode.F(opencode.TextPartTimeParam{
-				Start: opencode.F(0.000000),
-				End:   opencode.F(0.000000),
-			}),
-		}}),
-		Text: opencode.F("text"),
-	})
+	_, err := client.Tui.OpenHelp(context.TODO())
 	if err != nil {
 		var apierr *opencode.Error
 		if errors.As(err, &apierr) {

+ 1 - 12
scripts/stainless

@@ -10,18 +10,7 @@ for arg in "$@"; do
     fi
 done
 
-echo "Starting opencode server on port 4096..."
-bun run ./packages/opencode/src/index.ts serve --port 4096 &
-SERVER_PID=$!
-
-echo "Waiting for server to start..."
-sleep 3
-
-echo "Fetching OpenAPI spec from http://127.0.0.1:4096/doc..."
-curl -s http://127.0.0.1:4096/doc > openapi.json
-
-echo "Stopping server..."
-kill $SERVER_PID
+bun run ./packages/opencode/src/index.ts generate > openapi.json
 
 echo "Running stl builds create..."
 stl builds create --branch dev --pull --allow-empty --targets go 

+ 1 - 1
stainless.yml

@@ -123,7 +123,7 @@ resources:
 
   tui:
     methods:
-      prompt: post /tui/prompt
+      appendPrompt: post /tui/append-prompt
       openHelp: post /tui/open-help
 
 settings: