mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-20 09:14:22 +01:00
feat: /tui/show-toast api
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "bun run --conditions=development packages/opencode/src/index.ts",
|
"dev": "bun run --conditions=development packages/opencode/src/index.ts",
|
||||||
"typecheck": "bun run --filter='*' typecheck",
|
"typecheck": "bun run --filter='*' typecheck",
|
||||||
"stainless": "./scripts/stainless",
|
"generate": "(cd packages/sdk && ./js/script/generate.ts) && (cd packages/sdk/stainless && ./generate.ts)",
|
||||||
"postinstall": "./script/hooks"
|
"postinstall": "./script/hooks"
|
||||||
},
|
},
|
||||||
"workspaces": {
|
"workspaces": {
|
||||||
|
|||||||
@@ -1120,6 +1120,32 @@ export namespace Server {
|
|||||||
),
|
),
|
||||||
async (c) => c.json(await callTui(c)),
|
async (c) => c.json(await callTui(c)),
|
||||||
)
|
)
|
||||||
|
.post(
|
||||||
|
"/tui/show-toast",
|
||||||
|
describeRoute({
|
||||||
|
description: "Show a toast notification in the TUI",
|
||||||
|
operationId: "tui.showToast",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Toast notification shown successfully",
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: resolver(z.boolean()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator(
|
||||||
|
"json",
|
||||||
|
z.object({
|
||||||
|
title: z.string().optional(),
|
||||||
|
message: z.string(),
|
||||||
|
variant: z.enum(["info", "success", "warning", "error"]),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
async (c) => c.json(await callTui(c)),
|
||||||
|
)
|
||||||
.route("/tui/control", TuiRoute)
|
.route("/tui/control", TuiRoute)
|
||||||
.put(
|
.put(
|
||||||
"/auth/:id",
|
"/auth/:id",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
configured_endpoints: 36
|
configured_endpoints: 37
|
||||||
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-d0eaf92deaa53a25bbbc3181540ad73ed5a4aec6381ac08d8122e24318e5e455.yml
|
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-e438f89b86b573c957866c9b057efacc912e3946be03390e4027e8dfab5b83ba.yml
|
||||||
openapi_spec_hash: 22196d859c0711e564b9538d988abda6
|
openapi_spec_hash: 4e9d257b86172e266dc9d72fb04548bc
|
||||||
config_hash: 8d85a768523cff92b85ef06c443d49fa
|
config_hash: a78225c7474eb9ab8745e72a0cfe6f96
|
||||||
|
|||||||
@@ -147,4 +147,5 @@ Methods:
|
|||||||
- <code title="post /tui/open-models">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.OpenModels">OpenModels</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/open-models">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.OpenModels">OpenModels</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/open-sessions">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.OpenSessions">OpenSessions</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/open-sessions">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.OpenSessions">OpenSessions</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/open-themes">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.OpenThemes">OpenThemes</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/open-themes">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.OpenThemes">OpenThemes</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/show-toast">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.ShowToast">ShowToast</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#TuiShowToastParams">TuiShowToastParams</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/submit-prompt">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.SubmitPrompt">SubmitPrompt</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/submit-prompt">client.Tui.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#TuiService.SubmitPrompt">SubmitPrompt</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>
|
||||||
|
|||||||
@@ -87,6 +87,14 @@ func (r *TuiService) OpenThemes(ctx context.Context, opts ...option.RequestOptio
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show a toast notification in the TUI
|
||||||
|
func (r *TuiService) ShowToast(ctx context.Context, body TuiShowToastParams, opts ...option.RequestOption) (res *bool, err error) {
|
||||||
|
opts = append(r.Options[:], opts...)
|
||||||
|
path := "tui/show-toast"
|
||||||
|
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Submit the prompt
|
// Submit the prompt
|
||||||
func (r *TuiService) SubmitPrompt(ctx context.Context, opts ...option.RequestOption) (res *bool, err error) {
|
func (r *TuiService) SubmitPrompt(ctx context.Context, opts ...option.RequestOption) (res *bool, err error) {
|
||||||
opts = append(r.Options[:], opts...)
|
opts = append(r.Options[:], opts...)
|
||||||
@@ -110,3 +118,30 @@ type TuiExecuteCommandParams struct {
|
|||||||
func (r TuiExecuteCommandParams) MarshalJSON() (data []byte, err error) {
|
func (r TuiExecuteCommandParams) MarshalJSON() (data []byte, err error) {
|
||||||
return apijson.MarshalRoot(r)
|
return apijson.MarshalRoot(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TuiShowToastParams struct {
|
||||||
|
Message param.Field[string] `json:"message,required"`
|
||||||
|
Variant param.Field[TuiShowToastParamsVariant] `json:"variant,required"`
|
||||||
|
Title param.Field[string] `json:"title"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r TuiShowToastParams) MarshalJSON() (data []byte, err error) {
|
||||||
|
return apijson.MarshalRoot(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
type TuiShowToastParamsVariant string
|
||||||
|
|
||||||
|
const (
|
||||||
|
TuiShowToastParamsVariantInfo TuiShowToastParamsVariant = "info"
|
||||||
|
TuiShowToastParamsVariantSuccess TuiShowToastParamsVariant = "success"
|
||||||
|
TuiShowToastParamsVariantWarning TuiShowToastParamsVariant = "warning"
|
||||||
|
TuiShowToastParamsVariantError TuiShowToastParamsVariant = "error"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (r TuiShowToastParamsVariant) IsKnown() bool {
|
||||||
|
switch r {
|
||||||
|
case TuiShowToastParamsVariantInfo, TuiShowToastParamsVariantSuccess, TuiShowToastParamsVariantWarning, TuiShowToastParamsVariantError:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@@ -171,6 +171,32 @@ func TestTuiOpenThemes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTuiShowToastWithOptionalParams(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 {
|
||||||
|
baseURL = envURL
|
||||||
|
}
|
||||||
|
if !testutil.CheckTestServer(t, baseURL) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
client := opencode.NewClient(
|
||||||
|
option.WithBaseURL(baseURL),
|
||||||
|
)
|
||||||
|
_, err := client.Tui.ShowToast(context.TODO(), opencode.TuiShowToastParams{
|
||||||
|
Message: opencode.F("message"),
|
||||||
|
Variant: opencode.F(opencode.TuiShowToastParamsVariantInfo),
|
||||||
|
Title: opencode.F("title"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
var apierr *opencode.Error
|
||||||
|
if errors.As(err, &apierr) {
|
||||||
|
t.Log(string(apierr.DumpRequest(true)))
|
||||||
|
}
|
||||||
|
t.Fatalf("err should be nil: %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTuiSubmitPrompt(t *testing.T) {
|
func TestTuiSubmitPrompt(t *testing.T) {
|
||||||
t.Skip("skipped: tests are disabled for the time being")
|
t.Skip("skipped: tests are disabled for the time being")
|
||||||
baseURL := "http://localhost:4010"
|
baseURL := "http://localhost:4010"
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ import type {
|
|||||||
TuiClearPromptResponses,
|
TuiClearPromptResponses,
|
||||||
TuiExecuteCommandData,
|
TuiExecuteCommandData,
|
||||||
TuiExecuteCommandResponses,
|
TuiExecuteCommandResponses,
|
||||||
|
TuiShowToastData,
|
||||||
|
TuiShowToastResponses,
|
||||||
AuthSetData,
|
AuthSetData,
|
||||||
AuthSetResponses,
|
AuthSetResponses,
|
||||||
AuthSetErrors,
|
AuthSetErrors,
|
||||||
@@ -518,6 +520,20 @@ class Tui extends _HeyApiClient {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a toast notification in the TUI
|
||||||
|
*/
|
||||||
|
public showToast<ThrowOnError extends boolean = false>(options?: Options<TuiShowToastData, ThrowOnError>) {
|
||||||
|
return (options?.client ?? this._client).post<TuiShowToastResponses, unknown, ThrowOnError>({
|
||||||
|
url: "/tui/show-toast",
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
...options?.headers,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Auth extends _HeyApiClient {
|
class Auth extends _HeyApiClient {
|
||||||
|
|||||||
@@ -1911,6 +1911,26 @@ export type TuiExecuteCommandResponses = {
|
|||||||
|
|
||||||
export type TuiExecuteCommandResponse = TuiExecuteCommandResponses[keyof TuiExecuteCommandResponses]
|
export type TuiExecuteCommandResponse = TuiExecuteCommandResponses[keyof TuiExecuteCommandResponses]
|
||||||
|
|
||||||
|
export type TuiShowToastData = {
|
||||||
|
body?: {
|
||||||
|
title?: string
|
||||||
|
message: string
|
||||||
|
variant: "info" | "success" | "warning" | "error"
|
||||||
|
}
|
||||||
|
path?: never
|
||||||
|
query?: never
|
||||||
|
url: "/tui/show-toast"
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TuiShowToastResponses = {
|
||||||
|
/**
|
||||||
|
* Toast notification shown successfully
|
||||||
|
*/
|
||||||
|
200: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TuiShowToastResponse = TuiShowToastResponses[keyof TuiShowToastResponses]
|
||||||
|
|
||||||
export type AuthSetData = {
|
export type AuthSetData = {
|
||||||
body?: Auth
|
body?: Auth
|
||||||
path: {
|
path: {
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ resources:
|
|||||||
openThemes: post /tui/open-themes
|
openThemes: post /tui/open-themes
|
||||||
openModels: post /tui/open-models
|
openModels: post /tui/open-models
|
||||||
executeCommand: post /tui/execute-command
|
executeCommand: post /tui/execute-command
|
||||||
|
showToast: post /tui/show-toast
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
disable_mock_tests: true
|
disable_mock_tests: true
|
||||||
|
|||||||
@@ -705,6 +705,45 @@ func (a Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
updated, cmd := a.executeCommand(commands.Command(command))
|
updated, cmd := a.executeCommand(commands.Command(command))
|
||||||
a = updated.(Model)
|
a = updated.(Model)
|
||||||
cmds = append(cmds, cmd)
|
cmds = append(cmds, cmd)
|
||||||
|
case "/tui/show-toast":
|
||||||
|
var body struct {
|
||||||
|
Title string `json:"title,omitempty"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Variant string `json:"variant"`
|
||||||
|
}
|
||||||
|
json.Unmarshal((msg.Body), &body)
|
||||||
|
|
||||||
|
var toastCmd tea.Cmd
|
||||||
|
switch body.Variant {
|
||||||
|
case "info":
|
||||||
|
if body.Title != "" {
|
||||||
|
toastCmd = toast.NewInfoToast(body.Message, toast.WithTitle(body.Title))
|
||||||
|
} else {
|
||||||
|
toastCmd = toast.NewInfoToast(body.Message)
|
||||||
|
}
|
||||||
|
case "success":
|
||||||
|
if body.Title != "" {
|
||||||
|
toastCmd = toast.NewSuccessToast(body.Message, toast.WithTitle(body.Title))
|
||||||
|
} else {
|
||||||
|
toastCmd = toast.NewSuccessToast(body.Message)
|
||||||
|
}
|
||||||
|
case "warning":
|
||||||
|
if body.Title != "" {
|
||||||
|
toastCmd = toast.NewErrorToast(body.Message, toast.WithTitle(body.Title))
|
||||||
|
} else {
|
||||||
|
toastCmd = toast.NewErrorToast(body.Message)
|
||||||
|
}
|
||||||
|
case "error":
|
||||||
|
if body.Title != "" {
|
||||||
|
toastCmd = toast.NewErrorToast(body.Message, toast.WithTitle(body.Title))
|
||||||
|
} else {
|
||||||
|
toastCmd = toast.NewErrorToast(body.Message)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
slog.Error("Invalid toast variant", "variant", body.Variant)
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
cmds = append(cmds, toastCmd)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user