From 55cfacc6f4ebe7c42cae7d1628af22d26aeb352d Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Sun, 31 Aug 2025 20:19:30 -0400 Subject: [PATCH] core: sync updates across opencode, sdk, tui, and plugin components --- packages/opencode/src/file/index.ts | 1 - packages/opencode/src/server/project.ts | 58 ++-- packages/opencode/src/server/server.ts | 28 +- packages/opencode/src/session/index.ts | 4 +- packages/opencode/src/session/system.ts | 2 +- packages/plugin/src/example.ts | 2 +- packages/sdk/go/.release-please-manifest.json | 2 +- packages/sdk/go/.stats.yml | 8 +- packages/sdk/go/CHANGELOG.md | 8 + packages/sdk/go/README.md | 19 +- packages/sdk/go/agent.go | 19 +- packages/sdk/go/agent_test.go | 6 +- packages/sdk/go/api.md | 75 ++--- packages/sdk/go/app.go | 33 ++- packages/sdk/go/app_test.go | 13 +- packages/sdk/go/client_test.go | 24 +- packages/sdk/go/command.go | 19 +- packages/sdk/go/command_test.go | 6 +- packages/sdk/go/config.go | 19 +- packages/sdk/go/config_test.go | 6 +- packages/sdk/go/event.go | 19 +- packages/sdk/go/file.go | 22 +- packages/sdk/go/file_test.go | 16 +- packages/sdk/go/find.go | 9 +- packages/sdk/go/find_test.go | 15 +- packages/sdk/go/internal/version.go | 2 +- packages/sdk/go/path.go | 19 +- packages/sdk/go/path_test.go | 6 +- packages/sdk/go/project.go | 39 ++- packages/sdk/go/project_test.go | 30 +- packages/sdk/go/session.go | 276 +++++++++++++++--- packages/sdk/go/session_test.go | 115 ++++++-- packages/sdk/go/sessionpermission.go | 18 +- packages/sdk/go/sessionpermission_test.go | 5 +- packages/sdk/go/tui.go | 194 +++++++++--- packages/sdk/go/tui_test.go | 53 ++-- packages/sdk/go/usage_test.go | 2 +- packages/sdk/js/src/gen/types.gen.ts | 5 - packages/sdk/stainless/stainless.yml | 1 + packages/tui/cmd/opencode/main.go | 58 ++-- packages/tui/internal/app/app.go | 20 +- packages/tui/internal/completions/agents.go | 1 + packages/tui/internal/completions/files.go | 2 +- .../tui/internal/components/chat/messages.go | 2 + packages/tui/internal/tui/tui.go | 20 +- 45 files changed, 960 insertions(+), 341 deletions(-) diff --git a/packages/opencode/src/file/index.ts b/packages/opencode/src/file/index.ts index 85b7a6ac9..a6dd08a80 100644 --- a/packages/opencode/src/file/index.ts +++ b/packages/opencode/src/file/index.ts @@ -7,7 +7,6 @@ import fs from "fs" import ignore from "ignore" import { Log } from "../util/log" import { Instance } from "../project/instance" -import { Project } from "../project/project" export namespace File { const log = Log.create({ service: "file" }) diff --git a/packages/opencode/src/server/project.ts b/packages/opencode/src/server/project.ts index 9c266306c..dba9bcfa3 100644 --- a/packages/opencode/src/server/project.ts +++ b/packages/opencode/src/server/project.ts @@ -1,26 +1,48 @@ import { Hono } from "hono" import { describeRoute } from "hono-openapi" -import { resolver, validator as zValidator } from "hono-openapi/zod" +import { resolver } from "hono-openapi/zod" +import { Instance } from "../project/instance" import { Project } from "../project/project" -export const ProjectRoute = new Hono().get( - "/", - describeRoute({ - description: "List all projects", - operationId: "project.list", - responses: { - 200: { - description: "List of projects", - content: { - "application/json": { - schema: resolver(Project.Info.array()), +export const ProjectRoute = new Hono() + .get( + "/", + describeRoute({ + description: "List all projects", + operationId: "project.list", + responses: { + 200: { + description: "List of projects", + content: { + "application/json": { + schema: resolver(Project.Info.array()), + }, }, }, }, + }), + async (c) => { + const projects = await Project.list() + return c.json(projects) }, - }), - async (c) => { - const projects = await Project.list() - return c.json(projects) - }, -) + ) + .get( + "/current", + describeRoute({ + description: "Get the current project", + operationId: "butt.current", + responses: { + 200: { + description: "Current project", + content: { + "application/json": { + schema: resolver(Project.Info), + }, + }, + }, + }, + }), + async (c) => { + return c.json(Instance.project) + }, + ) diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts index eb05ef4e7..15afccf49 100644 --- a/packages/opencode/src/server/server.ts +++ b/packages/opencode/src/server/server.ts @@ -21,8 +21,8 @@ import { Instance } from "../project/instance" import { Agent } from "../agent/agent" import { Auth } from "../auth" import { Command } from "../command" -import { Project } from "../project/project" import { Global } from "../global" +import { ProjectRoute } from "./project" const ERRORS = { 400: { @@ -85,27 +85,6 @@ export namespace Server { }) }) .use(zValidator("query", z.object({ directory: z.string().optional() }))) - .get( - "/project", - describeRoute({ - description: "List all projects", - operationId: "project.list", - responses: { - 200: { - description: "List of projects", - content: { - "application/json": { - schema: resolver(Project.Info.array()), - }, - }, - }, - }, - }), - async (c) => { - const projects = await Project.list() - return c.json(projects) - }, - ) .get( "/doc", openAPISpecs(app, { @@ -119,6 +98,7 @@ export namespace Server { }, }), ) + .route("/project", ProjectRoute) .get( "/event", describeRoute({ @@ -198,6 +178,8 @@ export namespace Server { .object({ state: z.string(), config: z.string(), + worktree: z.string(), + directory: z.string(), }) .openapi({ ref: "Path", @@ -212,6 +194,8 @@ export namespace Server { return c.json({ state: Global.Path.state, config: Global.Path.config, + worktree: Instance.worktree, + directory: Instance.directory, }) }, ) diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts index 4d3a4d2d0..0894adbc6 100644 --- a/packages/opencode/src/session/index.ts +++ b/packages/opencode/src/session/index.ts @@ -1257,7 +1257,7 @@ export namespace Session { const filename = match[1] const filepath = filename.startsWith("~/") ? path.join(os.homedir(), filename.slice(2)) - : path.join(app.path.cwd, filename) + : path.join(Instance.worktree, filename) parts.push({ type: "file", @@ -1777,6 +1777,6 @@ export namespace Session { }, ], }) - await Project.setInitialized() + await Project.setInitialized(Instance.project.id) } } diff --git a/packages/opencode/src/session/system.ts b/packages/opencode/src/session/system.ts index 72d762b0f..41119c4fc 100644 --- a/packages/opencode/src/session/system.ts +++ b/packages/opencode/src/session/system.ts @@ -2,7 +2,7 @@ import { Ripgrep } from "../file/ripgrep" import { Global } from "../global" import { Filesystem } from "../util/filesystem" import { Config } from "../config/config" -import { Project } from "../project/project" + import { Instance } from "../project/instance" import path from "path" import os from "os" diff --git a/packages/plugin/src/example.ts b/packages/plugin/src/example.ts index 998108f0a..a13c0fbac 100644 --- a/packages/plugin/src/example.ts +++ b/packages/plugin/src/example.ts @@ -1,6 +1,6 @@ import { Plugin } from "./index" -export const ExamplePlugin: Plugin = async ({ app, client, $ }) => { +export const ExamplePlugin: Plugin = async ({ client, $ }) => { return { permission: {}, async "chat.params"(input, output) { diff --git a/packages/sdk/go/.release-please-manifest.json b/packages/sdk/go/.release-please-manifest.json index da59f99ea..2aca35ae2 100644 --- a/packages/sdk/go/.release-please-manifest.json +++ b/packages/sdk/go/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.4.0" + ".": "0.5.0" } \ No newline at end of file diff --git a/packages/sdk/go/.stats.yml b/packages/sdk/go/.stats.yml index f5603766f..024d6225d 100644 --- a/packages/sdk/go/.stats.yml +++ b/packages/sdk/go/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 42 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-4abd0b72d011cf0a07c5a91c28ca4d16e8b9fe005ca771dac6498ed97bd25874.yml -openapi_spec_hash: 3b1da51d6059a2eae5ef70726352dda5 -config_hash: 438a9bbaa02ccffea52d3463ca2122eb +configured_endpoints: 43 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-24d6bfcc66bba2e3a826fdad7e48a474c5aa9193a6bb89dc8ab1feb1f3d9bf72.yml +openapi_spec_hash: db8b553192d9027e1f9254096406cfc2 +config_hash: 1b0d220e033fe9f683abf7048e7ad076 diff --git a/packages/sdk/go/CHANGELOG.md b/packages/sdk/go/CHANGELOG.md index 69bf339ac..2a92cdf76 100644 --- a/packages/sdk/go/CHANGELOG.md +++ b/packages/sdk/go/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.5.0 (2025-08-31) + +Full Changelog: [v0.4.0...v0.5.0](https://github.com/sst/opencode-sdk-go/compare/v0.4.0...v0.5.0) + +### Features + +* **api:** api update ([44b281d](https://github.com/sst/opencode-sdk-go/commit/44b281d0bb39c5022a984ac9d0fca1529ccc0604)) + ## 0.4.0 (2025-08-31) Full Changelog: [v0.3.0...v0.4.0](https://github.com/sst/opencode-sdk-go/compare/v0.3.0...v0.4.0) diff --git a/packages/sdk/go/README.md b/packages/sdk/go/README.md index f57904860..880886bd9 100644 --- a/packages/sdk/go/README.md +++ b/packages/sdk/go/README.md @@ -24,7 +24,7 @@ Or to pin the version: ```sh -go get -u 'github.com/sst/opencode-sdk-go@v0.4.0' +go get -u 'github.com/sst/opencode-sdk-go@v0.5.0' ``` @@ -49,7 +49,7 @@ import ( func main() { client := opencode.NewClient() - sessions, err := client.Session.List(context.TODO()) + sessions, err := client.Session.List(context.TODO(), opencode.SessionListParams{}) if err != nil { panic(err.Error()) } @@ -171,7 +171,7 @@ When the API returns a non-success status code, we return an error with type To handle errors, we recommend that you use the `errors.As` pattern: ```go -_, err := client.Session.List(context.TODO()) +_, err := client.Session.List(context.TODO(), opencode.SessionListParams{}) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -198,6 +198,7 @@ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() client.Session.List( ctx, + opencode.SessionListParams{}, // This sets the per-retry timeout option.WithRequestTimeout(20*time.Second), ) @@ -231,7 +232,11 @@ client := opencode.NewClient( ) // Override per-request: -client.Session.List(context.TODO(), option.WithMaxRetries(5)) +client.Session.List( + context.TODO(), + opencode.SessionListParams{}, + option.WithMaxRetries(5), +) ``` ### Accessing raw response data (e.g. response headers) @@ -242,7 +247,11 @@ you need to examine response headers, status codes, or other details. ```go // Create a variable to store the HTTP response var response *http.Response -sessions, err := client.Session.List(context.TODO(), option.WithResponseInto(&response)) +sessions, err := client.Session.List( + context.TODO(), + opencode.SessionListParams{}, + option.WithResponseInto(&response), +) if err != nil { // handle error } diff --git a/packages/sdk/go/agent.go b/packages/sdk/go/agent.go index fe8b31860..5e8f4957c 100644 --- a/packages/sdk/go/agent.go +++ b/packages/sdk/go/agent.go @@ -5,8 +5,11 @@ package opencode import ( "context" "net/http" + "net/url" "github.com/sst/opencode-sdk-go/internal/apijson" + "github.com/sst/opencode-sdk-go/internal/apiquery" + "github.com/sst/opencode-sdk-go/internal/param" "github.com/sst/opencode-sdk-go/internal/requestconfig" "github.com/sst/opencode-sdk-go/option" ) @@ -31,10 +34,10 @@ func NewAgentService(opts ...option.RequestOption) (r *AgentService) { } // List all agents -func (r *AgentService) List(ctx context.Context, opts ...option.RequestOption) (res *[]Agent, err error) { +func (r *AgentService) List(ctx context.Context, query AgentListParams, opts ...option.RequestOption) (res *[]Agent, err error) { opts = append(r.Options[:], opts...) path := "agent" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } @@ -187,3 +190,15 @@ func (r *AgentModel) UnmarshalJSON(data []byte) (err error) { func (r agentModelJSON) RawJSON() string { return r.raw } + +type AgentListParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [AgentListParams]'s query parameters as `url.Values`. +func (r AgentListParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} diff --git a/packages/sdk/go/agent_test.go b/packages/sdk/go/agent_test.go index c3984b539..0827df5fd 100644 --- a/packages/sdk/go/agent_test.go +++ b/packages/sdk/go/agent_test.go @@ -13,7 +13,7 @@ import ( "github.com/sst/opencode-sdk-go/option" ) -func TestAgentList(t *testing.T) { +func TestAgentListWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -25,7 +25,9 @@ func TestAgentList(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Agent.List(context.TODO()) + _, err := client.Agent.List(context.TODO(), opencode.AgentListParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { diff --git a/packages/sdk/go/api.md b/packages/sdk/go/api.md index f5b2d9f36..ba2a388b8 100644 --- a/packages/sdk/go/api.md +++ b/packages/sdk/go/api.md @@ -12,7 +12,7 @@ Response Types: Methods: -- client.Event.List(ctx context.Context) (opencode.EventListResponse, error) +- client.Event.List(ctx context.Context, query opencode.EventListParams) (opencode.EventListResponse, error) # Path @@ -22,7 +22,7 @@ Response Types: Methods: -- client.Path.Get(ctx context.Context) (opencode.Path, error) +- client.Path.Get(ctx context.Context, query opencode.PathGetParams) (opencode.Path, error) # App @@ -34,8 +34,8 @@ Response Types: Methods: -- client.App.Log(ctx context.Context, body opencode.AppLogParams) (bool, error) -- client.App.Providers(ctx context.Context) (opencode.AppProvidersResponse, error) +- client.App.Log(ctx context.Context, params opencode.AppLogParams) (bool, error) +- client.App.Providers(ctx context.Context, query opencode.AppProvidersParams) (opencode.AppProvidersResponse, error) # Agent @@ -45,7 +45,7 @@ Response Types: Methods: -- client.Agent.List(ctx context.Context) ([]opencode.Agent, error) +- client.Agent.List(ctx context.Context, query opencode.AgentListParams) ([]opencode.Agent, error) # Find @@ -72,7 +72,7 @@ Methods: - client.File.List(ctx context.Context, query opencode.FileListParams) ([]opencode.FileNode, error) - client.File.Read(ctx context.Context, query opencode.FileReadParams) (opencode.FileReadResponse, error) -- client.File.Status(ctx context.Context) ([]opencode.File, error) +- client.File.Status(ctx context.Context, query opencode.FileStatusParams) ([]opencode.File, error) # Config @@ -85,7 +85,7 @@ Response Types: Methods: -- client.Config.Get(ctx context.Context) (opencode.Config, error) +- client.Config.Get(ctx context.Context, query opencode.ConfigGetParams) (opencode.Config, error) # Command @@ -95,7 +95,7 @@ Response Types: Methods: -- client.Command.List(ctx context.Context) ([]opencode.Command, error) +- client.Command.List(ctx context.Context, query opencode.CommandListParams) ([]opencode.Command, error) # Project @@ -105,7 +105,8 @@ Response Types: Methods: -- client.Project.List(ctx context.Context) ([]opencode.Project, error) +- client.Project.List(ctx context.Context, query opencode.ProjectListParams) ([]opencode.Project, error) +- client.Project.Current(ctx context.Context, query opencode.ProjectCurrentParams) (opencode.Project, error) # Session @@ -149,24 +150,24 @@ Response Types: Methods: -- client.Session.New(ctx context.Context, body opencode.SessionNewParams) (opencode.Session, error) -- client.Session.Update(ctx context.Context, id string, body opencode.SessionUpdateParams) (opencode.Session, error) -- client.Session.List(ctx context.Context) ([]opencode.Session, error) -- client.Session.Delete(ctx context.Context, id string) (bool, error) -- client.Session.Abort(ctx context.Context, id string) (bool, error) -- client.Session.Chat(ctx context.Context, id string, body opencode.SessionChatParams) (opencode.SessionChatResponse, error) -- client.Session.Children(ctx context.Context, id string) ([]opencode.Session, error) -- client.Session.Command(ctx context.Context, id string, body opencode.SessionCommandParams) (opencode.SessionCommandResponse, error) -- client.Session.Get(ctx context.Context, id string) (opencode.Session, error) -- client.Session.Init(ctx context.Context, id string, body opencode.SessionInitParams) (bool, error) -- client.Session.Message(ctx context.Context, id string, messageID string) (opencode.SessionMessageResponse, error) -- client.Session.Messages(ctx context.Context, id string) ([]opencode.SessionMessagesResponse, error) -- client.Session.Revert(ctx context.Context, id string, body opencode.SessionRevertParams) (opencode.Session, error) -- client.Session.Share(ctx context.Context, id string) (opencode.Session, error) -- client.Session.Shell(ctx context.Context, id string, body opencode.SessionShellParams) (opencode.AssistantMessage, error) -- client.Session.Summarize(ctx context.Context, id string, body opencode.SessionSummarizeParams) (bool, error) -- client.Session.Unrevert(ctx context.Context, id string) (opencode.Session, error) -- client.Session.Unshare(ctx context.Context, id string) (opencode.Session, error) +- client.Session.New(ctx context.Context, params opencode.SessionNewParams) (opencode.Session, error) +- client.Session.Update(ctx context.Context, id string, params opencode.SessionUpdateParams) (opencode.Session, error) +- client.Session.List(ctx context.Context, query opencode.SessionListParams) ([]opencode.Session, error) +- client.Session.Delete(ctx context.Context, id string, body opencode.SessionDeleteParams) (bool, error) +- client.Session.Abort(ctx context.Context, id string, body opencode.SessionAbortParams) (bool, error) +- client.Session.Chat(ctx context.Context, id string, params opencode.SessionChatParams) (opencode.SessionChatResponse, error) +- client.Session.Children(ctx context.Context, id string, query opencode.SessionChildrenParams) ([]opencode.Session, error) +- client.Session.Command(ctx context.Context, id string, params opencode.SessionCommandParams) (opencode.SessionCommandResponse, error) +- client.Session.Get(ctx context.Context, id string, query opencode.SessionGetParams) (opencode.Session, error) +- client.Session.Init(ctx context.Context, id string, params opencode.SessionInitParams) (bool, error) +- client.Session.Message(ctx context.Context, id string, messageID string, query opencode.SessionMessageParams) (opencode.SessionMessageResponse, error) +- client.Session.Messages(ctx context.Context, id string, query opencode.SessionMessagesParams) ([]opencode.SessionMessagesResponse, error) +- client.Session.Revert(ctx context.Context, id string, params opencode.SessionRevertParams) (opencode.Session, error) +- client.Session.Share(ctx context.Context, id string, body opencode.SessionShareParams) (opencode.Session, error) +- client.Session.Shell(ctx context.Context, id string, params opencode.SessionShellParams) (opencode.AssistantMessage, error) +- client.Session.Summarize(ctx context.Context, id string, params opencode.SessionSummarizeParams) (bool, error) +- client.Session.Unrevert(ctx context.Context, id string, body opencode.SessionUnrevertParams) (opencode.Session, error) +- client.Session.Unshare(ctx context.Context, id string, body opencode.SessionUnshareParams) (opencode.Session, error) ## Permissions @@ -176,18 +177,18 @@ Response Types: Methods: -- client.Session.Permissions.Respond(ctx context.Context, id string, permissionID string, body opencode.SessionPermissionRespondParams) (bool, error) +- client.Session.Permissions.Respond(ctx context.Context, id string, permissionID string, params opencode.SessionPermissionRespondParams) (bool, error) # Tui Methods: -- client.Tui.AppendPrompt(ctx context.Context, body opencode.TuiAppendPromptParams) (bool, error) -- client.Tui.ClearPrompt(ctx context.Context) (bool, error) -- client.Tui.ExecuteCommand(ctx context.Context, body opencode.TuiExecuteCommandParams) (bool, error) -- client.Tui.OpenHelp(ctx context.Context) (bool, error) -- client.Tui.OpenModels(ctx context.Context) (bool, error) -- client.Tui.OpenSessions(ctx context.Context) (bool, error) -- client.Tui.OpenThemes(ctx context.Context) (bool, error) -- client.Tui.ShowToast(ctx context.Context, body opencode.TuiShowToastParams) (bool, error) -- client.Tui.SubmitPrompt(ctx context.Context) (bool, error) +- client.Tui.AppendPrompt(ctx context.Context, params opencode.TuiAppendPromptParams) (bool, error) +- client.Tui.ClearPrompt(ctx context.Context, body opencode.TuiClearPromptParams) (bool, error) +- client.Tui.ExecuteCommand(ctx context.Context, params opencode.TuiExecuteCommandParams) (bool, error) +- client.Tui.OpenHelp(ctx context.Context, body opencode.TuiOpenHelpParams) (bool, error) +- client.Tui.OpenModels(ctx context.Context, body opencode.TuiOpenModelsParams) (bool, error) +- client.Tui.OpenSessions(ctx context.Context, body opencode.TuiOpenSessionsParams) (bool, error) +- client.Tui.OpenThemes(ctx context.Context, body opencode.TuiOpenThemesParams) (bool, error) +- client.Tui.ShowToast(ctx context.Context, params opencode.TuiShowToastParams) (bool, error) +- client.Tui.SubmitPrompt(ctx context.Context, body opencode.TuiSubmitPromptParams) (bool, error) diff --git a/packages/sdk/go/app.go b/packages/sdk/go/app.go index 8e4891162..53a8aeb4a 100644 --- a/packages/sdk/go/app.go +++ b/packages/sdk/go/app.go @@ -5,8 +5,10 @@ package opencode import ( "context" "net/http" + "net/url" "github.com/sst/opencode-sdk-go/internal/apijson" + "github.com/sst/opencode-sdk-go/internal/apiquery" "github.com/sst/opencode-sdk-go/internal/param" "github.com/sst/opencode-sdk-go/internal/requestconfig" "github.com/sst/opencode-sdk-go/option" @@ -32,18 +34,18 @@ func NewAppService(opts ...option.RequestOption) (r *AppService) { } // Write a log entry to the server logs -func (r *AppService) Log(ctx context.Context, body AppLogParams, opts ...option.RequestOption) (res *bool, err error) { +func (r *AppService) Log(ctx context.Context, params AppLogParams, opts ...option.RequestOption) (res *bool, err error) { opts = append(r.Options[:], opts...) path := "log" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } // List all providers -func (r *AppService) Providers(ctx context.Context, opts ...option.RequestOption) (res *AppProvidersResponse, err error) { +func (r *AppService) Providers(ctx context.Context, query AppProvidersParams, opts ...option.RequestOption) (res *AppProvidersResponse, err error) { opts = append(r.Options[:], opts...) path := "config/providers" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } @@ -192,7 +194,8 @@ type AppLogParams struct { // Log message Message param.Field[string] `json:"message,required"` // Service name for the log entry - Service param.Field[string] `json:"service,required"` + Service param.Field[string] `json:"service,required"` + Directory param.Field[string] `query:"directory"` // Additional metadata for the log entry Extra param.Field[map[string]interface{}] `json:"extra"` } @@ -201,6 +204,14 @@ func (r AppLogParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [AppLogParams]'s query parameters as `url.Values`. +func (r AppLogParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + // Log level type AppLogParamsLevel string @@ -218,3 +229,15 @@ func (r AppLogParamsLevel) IsKnown() bool { } return false } + +type AppProvidersParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [AppProvidersParams]'s query parameters as `url.Values`. +func (r AppProvidersParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} diff --git a/packages/sdk/go/app_test.go b/packages/sdk/go/app_test.go index 847ec5caf..eb2fc92e5 100644 --- a/packages/sdk/go/app_test.go +++ b/packages/sdk/go/app_test.go @@ -26,9 +26,10 @@ func TestAppLogWithOptionalParams(t *testing.T) { option.WithBaseURL(baseURL), ) _, err := client.App.Log(context.TODO(), opencode.AppLogParams{ - Level: opencode.F(opencode.AppLogParamsLevelDebug), - Message: opencode.F("message"), - Service: opencode.F("service"), + Level: opencode.F(opencode.AppLogParamsLevelDebug), + Message: opencode.F("message"), + Service: opencode.F("service"), + Directory: opencode.F("directory"), Extra: opencode.F(map[string]interface{}{ "foo": "bar", }), @@ -42,7 +43,7 @@ func TestAppLogWithOptionalParams(t *testing.T) { } } -func TestAppProviders(t *testing.T) { +func TestAppProvidersWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -54,7 +55,9 @@ func TestAppProviders(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.App.Providers(context.TODO()) + _, err := client.App.Providers(context.TODO(), opencode.AppProvidersParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { diff --git a/packages/sdk/go/client_test.go b/packages/sdk/go/client_test.go index 0f5b8205d..d620da8ed 100644 --- a/packages/sdk/go/client_test.go +++ b/packages/sdk/go/client_test.go @@ -38,7 +38,7 @@ func TestUserAgentHeader(t *testing.T) { }, }), ) - client.Session.List(context.Background()) + client.Session.List(context.Background(), opencode.SessionListParams{}) if userAgent != fmt.Sprintf("Opencode/Go %s", internal.PackageVersion) { t.Errorf("Expected User-Agent to be correct, but got: %#v", userAgent) } @@ -61,7 +61,7 @@ func TestRetryAfter(t *testing.T) { }, }), ) - _, err := client.Session.List(context.Background()) + _, err := client.Session.List(context.Background(), opencode.SessionListParams{}) if err == nil { t.Error("Expected there to be a cancel error") } @@ -95,7 +95,7 @@ func TestDeleteRetryCountHeader(t *testing.T) { }), option.WithHeaderDel("X-Stainless-Retry-Count"), ) - _, err := client.Session.List(context.Background()) + _, err := client.Session.List(context.Background(), opencode.SessionListParams{}) if err == nil { t.Error("Expected there to be a cancel error") } @@ -124,7 +124,7 @@ func TestOverwriteRetryCountHeader(t *testing.T) { }), option.WithHeader("X-Stainless-Retry-Count", "42"), ) - _, err := client.Session.List(context.Background()) + _, err := client.Session.List(context.Background(), opencode.SessionListParams{}) if err == nil { t.Error("Expected there to be a cancel error") } @@ -152,7 +152,7 @@ func TestRetryAfterMs(t *testing.T) { }, }), ) - _, err := client.Session.List(context.Background()) + _, err := client.Session.List(context.Background(), opencode.SessionListParams{}) if err == nil { t.Error("Expected there to be a cancel error") } @@ -174,7 +174,7 @@ func TestContextCancel(t *testing.T) { ) cancelCtx, cancel := context.WithCancel(context.Background()) cancel() - _, err := client.Session.List(cancelCtx) + _, err := client.Session.List(cancelCtx, opencode.SessionListParams{}) if err == nil { t.Error("Expected there to be a cancel error") } @@ -193,7 +193,7 @@ func TestContextCancelDelay(t *testing.T) { ) cancelCtx, cancel := context.WithTimeout(context.Background(), 2*time.Millisecond) defer cancel() - _, err := client.Session.List(cancelCtx) + _, err := client.Session.List(cancelCtx, opencode.SessionListParams{}) if err == nil { t.Error("expected there to be a cancel error") } @@ -218,7 +218,7 @@ func TestContextDeadline(t *testing.T) { }, }), ) - _, err := client.Session.List(deadlineCtx) + _, err := client.Session.List(deadlineCtx, opencode.SessionListParams{}) if err == nil { t.Error("expected there to be a deadline error") } @@ -262,7 +262,7 @@ func TestContextDeadlineStreaming(t *testing.T) { }, }), ) - stream := client.Event.ListStreaming(deadlineCtx) + stream := client.Event.ListStreaming(deadlineCtx, opencode.EventListParams{}) for stream.Next() { _ = stream.Current() } @@ -306,7 +306,11 @@ func TestContextDeadlineStreamingWithRequestTimeout(t *testing.T) { }, }), ) - stream := client.Event.ListStreaming(context.Background(), option.WithRequestTimeout((100 * time.Millisecond))) + stream := client.Event.ListStreaming( + context.Background(), + opencode.EventListParams{}, + option.WithRequestTimeout((100 * time.Millisecond)), + ) for stream.Next() { _ = stream.Current() } diff --git a/packages/sdk/go/command.go b/packages/sdk/go/command.go index 9ca70c3ac..2638fc607 100644 --- a/packages/sdk/go/command.go +++ b/packages/sdk/go/command.go @@ -5,8 +5,11 @@ package opencode import ( "context" "net/http" + "net/url" "github.com/sst/opencode-sdk-go/internal/apijson" + "github.com/sst/opencode-sdk-go/internal/apiquery" + "github.com/sst/opencode-sdk-go/internal/param" "github.com/sst/opencode-sdk-go/internal/requestconfig" "github.com/sst/opencode-sdk-go/option" ) @@ -31,10 +34,10 @@ func NewCommandService(opts ...option.RequestOption) (r *CommandService) { } // List all commands -func (r *CommandService) List(ctx context.Context, opts ...option.RequestOption) (res *[]Command, err error) { +func (r *CommandService) List(ctx context.Context, query CommandListParams, opts ...option.RequestOption) (res *[]Command, err error) { opts = append(r.Options[:], opts...) path := "command" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } @@ -65,3 +68,15 @@ func (r *Command) UnmarshalJSON(data []byte) (err error) { func (r commandJSON) RawJSON() string { return r.raw } + +type CommandListParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [CommandListParams]'s query parameters as `url.Values`. +func (r CommandListParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} diff --git a/packages/sdk/go/command_test.go b/packages/sdk/go/command_test.go index 5e62ffb12..781498b27 100644 --- a/packages/sdk/go/command_test.go +++ b/packages/sdk/go/command_test.go @@ -13,7 +13,7 @@ import ( "github.com/sst/opencode-sdk-go/option" ) -func TestCommandList(t *testing.T) { +func TestCommandListWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -25,7 +25,9 @@ func TestCommandList(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Command.List(context.TODO()) + _, err := client.Command.List(context.TODO(), opencode.CommandListParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { diff --git a/packages/sdk/go/config.go b/packages/sdk/go/config.go index cf2f78cbe..4c92b0ea1 100644 --- a/packages/sdk/go/config.go +++ b/packages/sdk/go/config.go @@ -5,9 +5,12 @@ package opencode import ( "context" "net/http" + "net/url" "reflect" "github.com/sst/opencode-sdk-go/internal/apijson" + "github.com/sst/opencode-sdk-go/internal/apiquery" + "github.com/sst/opencode-sdk-go/internal/param" "github.com/sst/opencode-sdk-go/internal/requestconfig" "github.com/sst/opencode-sdk-go/option" "github.com/tidwall/gjson" @@ -33,10 +36,10 @@ func NewConfigService(opts ...option.RequestOption) (r *ConfigService) { } // Get config info -func (r *ConfigService) Get(ctx context.Context, opts ...option.RequestOption) (res *Config, err error) { +func (r *ConfigService) Get(ctx context.Context, query ConfigGetParams, opts ...option.RequestOption) (res *Config, err error) { opts = append(r.Options[:], opts...) path := "config" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } @@ -1968,3 +1971,15 @@ func (r McpRemoteConfigType) IsKnown() bool { } return false } + +type ConfigGetParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [ConfigGetParams]'s query parameters as `url.Values`. +func (r ConfigGetParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} diff --git a/packages/sdk/go/config_test.go b/packages/sdk/go/config_test.go index 9a2676b18..f188d7e8d 100644 --- a/packages/sdk/go/config_test.go +++ b/packages/sdk/go/config_test.go @@ -13,7 +13,7 @@ import ( "github.com/sst/opencode-sdk-go/option" ) -func TestConfigGet(t *testing.T) { +func TestConfigGetWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -25,7 +25,9 @@ func TestConfigGet(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Config.Get(context.TODO()) + _, err := client.Config.Get(context.TODO(), opencode.ConfigGetParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { diff --git a/packages/sdk/go/event.go b/packages/sdk/go/event.go index dd6afc443..2f44f907e 100644 --- a/packages/sdk/go/event.go +++ b/packages/sdk/go/event.go @@ -5,9 +5,12 @@ package opencode import ( "context" "net/http" + "net/url" "reflect" "github.com/sst/opencode-sdk-go/internal/apijson" + "github.com/sst/opencode-sdk-go/internal/apiquery" + "github.com/sst/opencode-sdk-go/internal/param" "github.com/sst/opencode-sdk-go/internal/requestconfig" "github.com/sst/opencode-sdk-go/option" "github.com/sst/opencode-sdk-go/packages/ssestream" @@ -35,7 +38,7 @@ func NewEventService(opts ...option.RequestOption) (r *EventService) { } // Get events -func (r *EventService) ListStreaming(ctx context.Context, opts ...option.RequestOption) (stream *ssestream.Stream[EventListResponse]) { +func (r *EventService) ListStreaming(ctx context.Context, query EventListParams, opts ...option.RequestOption) (stream *ssestream.Stream[EventListResponse]) { var ( raw *http.Response err error @@ -43,7 +46,7 @@ func (r *EventService) ListStreaming(ctx context.Context, opts ...option.Request opts = append(r.Options[:], opts...) opts = append([]option.RequestOption{option.WithHeader("Accept", "text/event-stream")}, opts...) path := "event" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &raw, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &raw, opts...) return ssestream.NewStream[EventListResponse](ssestream.NewDecoder(raw), err) } @@ -1170,3 +1173,15 @@ func (r EventListResponseType) IsKnown() bool { } return false } + +type EventListParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [EventListParams]'s query parameters as `url.Values`. +func (r EventListParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} diff --git a/packages/sdk/go/file.go b/packages/sdk/go/file.go index 9af7f5384..3e1b2f42f 100644 --- a/packages/sdk/go/file.go +++ b/packages/sdk/go/file.go @@ -50,10 +50,10 @@ func (r *FileService) Read(ctx context.Context, query FileReadParams, opts ...op } // Get file status -func (r *FileService) Status(ctx context.Context, opts ...option.RequestOption) (res *[]File, err error) { +func (r *FileService) Status(ctx context.Context, query FileStatusParams, opts ...option.RequestOption) (res *[]File, err error) { opts = append(r.Options[:], opts...) path := "file/status" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } @@ -179,7 +179,8 @@ func (r FileReadResponseType) IsKnown() bool { } type FileListParams struct { - Path param.Field[string] `query:"path,required"` + Path param.Field[string] `query:"path,required"` + Directory param.Field[string] `query:"directory"` } // URLQuery serializes [FileListParams]'s query parameters as `url.Values`. @@ -191,7 +192,8 @@ func (r FileListParams) URLQuery() (v url.Values) { } type FileReadParams struct { - Path param.Field[string] `query:"path,required"` + Path param.Field[string] `query:"path,required"` + Directory param.Field[string] `query:"directory"` } // URLQuery serializes [FileReadParams]'s query parameters as `url.Values`. @@ -201,3 +203,15 @@ func (r FileReadParams) URLQuery() (v url.Values) { NestedFormat: apiquery.NestedQueryFormatBrackets, }) } + +type FileStatusParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [FileStatusParams]'s query parameters as `url.Values`. +func (r FileStatusParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} diff --git a/packages/sdk/go/file_test.go b/packages/sdk/go/file_test.go index 273f6e84e..2790fff96 100644 --- a/packages/sdk/go/file_test.go +++ b/packages/sdk/go/file_test.go @@ -13,7 +13,7 @@ import ( "github.com/sst/opencode-sdk-go/option" ) -func TestFileList(t *testing.T) { +func TestFileListWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -26,7 +26,8 @@ func TestFileList(t *testing.T) { option.WithBaseURL(baseURL), ) _, err := client.File.List(context.TODO(), opencode.FileListParams{ - Path: opencode.F("path"), + Path: opencode.F("path"), + Directory: opencode.F("directory"), }) if err != nil { var apierr *opencode.Error @@ -37,7 +38,7 @@ func TestFileList(t *testing.T) { } } -func TestFileRead(t *testing.T) { +func TestFileReadWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -50,7 +51,8 @@ func TestFileRead(t *testing.T) { option.WithBaseURL(baseURL), ) _, err := client.File.Read(context.TODO(), opencode.FileReadParams{ - Path: opencode.F("path"), + Path: opencode.F("path"), + Directory: opencode.F("directory"), }) if err != nil { var apierr *opencode.Error @@ -61,7 +63,7 @@ func TestFileRead(t *testing.T) { } } -func TestFileStatus(t *testing.T) { +func TestFileStatusWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -73,7 +75,9 @@ func TestFileStatus(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.File.Status(context.TODO()) + _, err := client.File.Status(context.TODO(), opencode.FileStatusParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { diff --git a/packages/sdk/go/find.go b/packages/sdk/go/find.go index a993a353f..e869116b4 100644 --- a/packages/sdk/go/find.go +++ b/packages/sdk/go/find.go @@ -290,7 +290,8 @@ func (r findTextResponseSubmatchesMatchJSON) RawJSON() string { } type FindFilesParams struct { - Query param.Field[string] `query:"query,required"` + Query param.Field[string] `query:"query,required"` + Directory param.Field[string] `query:"directory"` } // URLQuery serializes [FindFilesParams]'s query parameters as `url.Values`. @@ -302,7 +303,8 @@ func (r FindFilesParams) URLQuery() (v url.Values) { } type FindSymbolsParams struct { - Query param.Field[string] `query:"query,required"` + Query param.Field[string] `query:"query,required"` + Directory param.Field[string] `query:"directory"` } // URLQuery serializes [FindSymbolsParams]'s query parameters as `url.Values`. @@ -314,7 +316,8 @@ func (r FindSymbolsParams) URLQuery() (v url.Values) { } type FindTextParams struct { - Pattern param.Field[string] `query:"pattern,required"` + Pattern param.Field[string] `query:"pattern,required"` + Directory param.Field[string] `query:"directory"` } // URLQuery serializes [FindTextParams]'s query parameters as `url.Values`. diff --git a/packages/sdk/go/find_test.go b/packages/sdk/go/find_test.go index 22b5b9568..901a895b2 100644 --- a/packages/sdk/go/find_test.go +++ b/packages/sdk/go/find_test.go @@ -13,7 +13,7 @@ import ( "github.com/sst/opencode-sdk-go/option" ) -func TestFindFiles(t *testing.T) { +func TestFindFilesWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -26,7 +26,8 @@ func TestFindFiles(t *testing.T) { option.WithBaseURL(baseURL), ) _, err := client.Find.Files(context.TODO(), opencode.FindFilesParams{ - Query: opencode.F("query"), + Query: opencode.F("query"), + Directory: opencode.F("directory"), }) if err != nil { var apierr *opencode.Error @@ -37,7 +38,7 @@ func TestFindFiles(t *testing.T) { } } -func TestFindSymbols(t *testing.T) { +func TestFindSymbolsWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -50,7 +51,8 @@ func TestFindSymbols(t *testing.T) { option.WithBaseURL(baseURL), ) _, err := client.Find.Symbols(context.TODO(), opencode.FindSymbolsParams{ - Query: opencode.F("query"), + Query: opencode.F("query"), + Directory: opencode.F("directory"), }) if err != nil { var apierr *opencode.Error @@ -61,7 +63,7 @@ func TestFindSymbols(t *testing.T) { } } -func TestFindText(t *testing.T) { +func TestFindTextWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -74,7 +76,8 @@ func TestFindText(t *testing.T) { option.WithBaseURL(baseURL), ) _, err := client.Find.Text(context.TODO(), opencode.FindTextParams{ - Pattern: opencode.F("pattern"), + Pattern: opencode.F("pattern"), + Directory: opencode.F("directory"), }) if err != nil { var apierr *opencode.Error diff --git a/packages/sdk/go/internal/version.go b/packages/sdk/go/internal/version.go index 5c62cacd5..67c4d4094 100644 --- a/packages/sdk/go/internal/version.go +++ b/packages/sdk/go/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.4.0" // x-release-please-version +const PackageVersion = "0.5.0" // x-release-please-version diff --git a/packages/sdk/go/path.go b/packages/sdk/go/path.go index da5528b32..6d80e85fe 100644 --- a/packages/sdk/go/path.go +++ b/packages/sdk/go/path.go @@ -5,8 +5,11 @@ package opencode import ( "context" "net/http" + "net/url" "github.com/sst/opencode-sdk-go/internal/apijson" + "github.com/sst/opencode-sdk-go/internal/apiquery" + "github.com/sst/opencode-sdk-go/internal/param" "github.com/sst/opencode-sdk-go/internal/requestconfig" "github.com/sst/opencode-sdk-go/option" ) @@ -31,10 +34,10 @@ func NewPathService(opts ...option.RequestOption) (r *PathService) { } // Get the current path -func (r *PathService) Get(ctx context.Context, opts ...option.RequestOption) (res *Path, err error) { +func (r *PathService) Get(ctx context.Context, query PathGetParams, opts ...option.RequestOption) (res *Path, err error) { opts = append(r.Options[:], opts...) path := "path" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } @@ -59,3 +62,15 @@ func (r *Path) UnmarshalJSON(data []byte) (err error) { func (r pathJSON) RawJSON() string { return r.raw } + +type PathGetParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [PathGetParams]'s query parameters as `url.Values`. +func (r PathGetParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} diff --git a/packages/sdk/go/path_test.go b/packages/sdk/go/path_test.go index e8b274a4e..08273ce32 100644 --- a/packages/sdk/go/path_test.go +++ b/packages/sdk/go/path_test.go @@ -13,7 +13,7 @@ import ( "github.com/sst/opencode-sdk-go/option" ) -func TestPathGet(t *testing.T) { +func TestPathGetWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -25,7 +25,9 @@ func TestPathGet(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Path.Get(context.TODO()) + _, err := client.Path.Get(context.TODO(), opencode.PathGetParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { diff --git a/packages/sdk/go/project.go b/packages/sdk/go/project.go index 00c6ce840..3b349dadd 100644 --- a/packages/sdk/go/project.go +++ b/packages/sdk/go/project.go @@ -5,8 +5,11 @@ package opencode import ( "context" "net/http" + "net/url" "github.com/sst/opencode-sdk-go/internal/apijson" + "github.com/sst/opencode-sdk-go/internal/apiquery" + "github.com/sst/opencode-sdk-go/internal/param" "github.com/sst/opencode-sdk-go/internal/requestconfig" "github.com/sst/opencode-sdk-go/option" ) @@ -31,10 +34,18 @@ func NewProjectService(opts ...option.RequestOption) (r *ProjectService) { } // List all projects -func (r *ProjectService) List(ctx context.Context, opts ...option.RequestOption) (res *[]Project, err error) { +func (r *ProjectService) List(ctx context.Context, query ProjectListParams, opts ...option.RequestOption) (res *[]Project, err error) { opts = append(r.Options[:], opts...) path := "project" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) + return +} + +// Get the current project +func (r *ProjectService) Current(ctx context.Context, query ProjectCurrentParams, opts ...option.RequestOption) (res *Project, err error) { + opts = append(r.Options[:], opts...) + path := "project/current" + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } @@ -99,3 +110,27 @@ func (r ProjectVcs) IsKnown() bool { } return false } + +type ProjectListParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [ProjectListParams]'s query parameters as `url.Values`. +func (r ProjectListParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type ProjectCurrentParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [ProjectCurrentParams]'s query parameters as `url.Values`. +func (r ProjectCurrentParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} diff --git a/packages/sdk/go/project_test.go b/packages/sdk/go/project_test.go index 4a09aaee7..adf3dbf10 100644 --- a/packages/sdk/go/project_test.go +++ b/packages/sdk/go/project_test.go @@ -13,7 +13,7 @@ import ( "github.com/sst/opencode-sdk-go/option" ) -func TestProjectList(t *testing.T) { +func TestProjectListWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -25,7 +25,33 @@ func TestProjectList(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Project.List(context.TODO()) + _, err := client.Project.List(context.TODO(), opencode.ProjectListParams{ + Directory: opencode.F("directory"), + }) + 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 TestProjectCurrentWithOptionalParams(t *testing.T) { + t.Skip("Prism tests are disabled") + 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.Project.Current(context.TODO(), opencode.ProjectCurrentParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { diff --git a/packages/sdk/go/session.go b/packages/sdk/go/session.go index d05640e7e..11b1338a1 100644 --- a/packages/sdk/go/session.go +++ b/packages/sdk/go/session.go @@ -7,9 +7,11 @@ import ( "errors" "fmt" "net/http" + "net/url" "reflect" "github.com/sst/opencode-sdk-go/internal/apijson" + "github.com/sst/opencode-sdk-go/internal/apiquery" "github.com/sst/opencode-sdk-go/internal/param" "github.com/sst/opencode-sdk-go/internal/requestconfig" "github.com/sst/opencode-sdk-go/option" @@ -39,119 +41,119 @@ func NewSessionService(opts ...option.RequestOption) (r *SessionService) { } // Create a new session -func (r *SessionService) New(ctx context.Context, body SessionNewParams, opts ...option.RequestOption) (res *Session, err error) { +func (r *SessionService) New(ctx context.Context, params SessionNewParams, opts ...option.RequestOption) (res *Session, err error) { opts = append(r.Options[:], opts...) path := "session" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } // Update session properties -func (r *SessionService) Update(ctx context.Context, id string, body SessionUpdateParams, opts ...option.RequestOption) (res *Session, err error) { +func (r *SessionService) Update(ctx context.Context, id string, params SessionUpdateParams, opts ...option.RequestOption) (res *Session, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, params, &res, opts...) return } // List all sessions -func (r *SessionService) List(ctx context.Context, opts ...option.RequestOption) (res *[]Session, err error) { +func (r *SessionService) List(ctx context.Context, query SessionListParams, opts ...option.RequestOption) (res *[]Session, err error) { opts = append(r.Options[:], opts...) path := "session" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } // Delete a session and all its data -func (r *SessionService) Delete(ctx context.Context, id string, opts ...option.RequestOption) (res *bool, err error) { +func (r *SessionService) Delete(ctx context.Context, id string, body SessionDeleteParams, opts ...option.RequestOption) (res *bool, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, body, &res, opts...) return } // Abort a session -func (r *SessionService) Abort(ctx context.Context, id string, opts ...option.RequestOption) (res *bool, err error) { +func (r *SessionService) Abort(ctx context.Context, id string, body SessionAbortParams, opts ...option.RequestOption) (res *bool, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/abort", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) return } // Create and send a new message to a session -func (r *SessionService) Chat(ctx context.Context, id string, body SessionChatParams, opts ...option.RequestOption) (res *SessionChatResponse, err error) { +func (r *SessionService) Chat(ctx context.Context, id string, params SessionChatParams, opts ...option.RequestOption) (res *SessionChatResponse, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/message", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } // Get a session's children -func (r *SessionService) Children(ctx context.Context, id string, opts ...option.RequestOption) (res *[]Session, err error) { +func (r *SessionService) Children(ctx context.Context, id string, query SessionChildrenParams, opts ...option.RequestOption) (res *[]Session, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/children", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } // Send a new command to a session -func (r *SessionService) Command(ctx context.Context, id string, body SessionCommandParams, opts ...option.RequestOption) (res *SessionCommandResponse, err error) { +func (r *SessionService) Command(ctx context.Context, id string, params SessionCommandParams, opts ...option.RequestOption) (res *SessionCommandResponse, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/command", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } // Get session -func (r *SessionService) Get(ctx context.Context, id string, opts ...option.RequestOption) (res *Session, err error) { +func (r *SessionService) Get(ctx context.Context, id string, query SessionGetParams, opts ...option.RequestOption) (res *Session, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } // Analyze the app and create an AGENTS.md file -func (r *SessionService) Init(ctx context.Context, id string, body SessionInitParams, opts ...option.RequestOption) (res *bool, err error) { +func (r *SessionService) Init(ctx context.Context, id string, params SessionInitParams, opts ...option.RequestOption) (res *bool, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/init", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } // Get a message from a session -func (r *SessionService) Message(ctx context.Context, id string, messageID string, opts ...option.RequestOption) (res *SessionMessageResponse, err error) { +func (r *SessionService) Message(ctx context.Context, id string, messageID string, query SessionMessageParams, opts ...option.RequestOption) (res *SessionMessageResponse, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") @@ -162,91 +164,91 @@ func (r *SessionService) Message(ctx context.Context, id string, messageID strin return } path := fmt.Sprintf("session/%s/message/%s", id, messageID) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } // List messages for a session -func (r *SessionService) Messages(ctx context.Context, id string, opts ...option.RequestOption) (res *[]SessionMessagesResponse, err error) { +func (r *SessionService) Messages(ctx context.Context, id string, query SessionMessagesParams, opts ...option.RequestOption) (res *[]SessionMessagesResponse, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/message", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...) return } // Revert a message -func (r *SessionService) Revert(ctx context.Context, id string, body SessionRevertParams, opts ...option.RequestOption) (res *Session, err error) { +func (r *SessionService) Revert(ctx context.Context, id string, params SessionRevertParams, opts ...option.RequestOption) (res *Session, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/revert", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } // Share a session -func (r *SessionService) Share(ctx context.Context, id string, opts ...option.RequestOption) (res *Session, err error) { +func (r *SessionService) Share(ctx context.Context, id string, body SessionShareParams, opts ...option.RequestOption) (res *Session, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/share", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) return } // Run a shell command -func (r *SessionService) Shell(ctx context.Context, id string, body SessionShellParams, opts ...option.RequestOption) (res *AssistantMessage, err error) { +func (r *SessionService) Shell(ctx context.Context, id string, params SessionShellParams, opts ...option.RequestOption) (res *AssistantMessage, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/shell", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } // Summarize the session -func (r *SessionService) Summarize(ctx context.Context, id string, body SessionSummarizeParams, opts ...option.RequestOption) (res *bool, err error) { +func (r *SessionService) Summarize(ctx context.Context, id string, params SessionSummarizeParams, opts ...option.RequestOption) (res *bool, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/summarize", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } // Restore all reverted messages -func (r *SessionService) Unrevert(ctx context.Context, id string, opts ...option.RequestOption) (res *Session, err error) { +func (r *SessionService) Unrevert(ctx context.Context, id string, body SessionUnrevertParams, opts ...option.RequestOption) (res *Session, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/unrevert", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) return } // Unshare the session -func (r *SessionService) Unshare(ctx context.Context, id string, opts ...option.RequestOption) (res *Session, err error) { +func (r *SessionService) Unshare(ctx context.Context, id string, body SessionUnshareParams, opts ...option.RequestOption) (res *Session, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") return } path := fmt.Sprintf("session/%s/share", id) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, body, &res, opts...) return } @@ -2387,26 +2389,81 @@ func (r sessionMessagesResponseJSON) RawJSON() string { } type SessionNewParams struct { - ParentID param.Field[string] `json:"parentID"` - Title param.Field[string] `json:"title"` + Directory param.Field[string] `query:"directory"` + ParentID param.Field[string] `json:"parentID"` + Title param.Field[string] `json:"title"` } func (r SessionNewParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [SessionNewParams]'s query parameters as `url.Values`. +func (r SessionNewParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type SessionUpdateParams struct { - Title param.Field[string] `json:"title"` + Directory param.Field[string] `query:"directory"` + Title param.Field[string] `json:"title"` } func (r SessionUpdateParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [SessionUpdateParams]'s query parameters as `url.Values`. +func (r SessionUpdateParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type SessionListParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [SessionListParams]'s query parameters as `url.Values`. +func (r SessionListParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type SessionDeleteParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [SessionDeleteParams]'s query parameters as `url.Values`. +func (r SessionDeleteParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type SessionAbortParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [SessionAbortParams]'s query parameters as `url.Values`. +func (r SessionAbortParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type SessionChatParams struct { ModelID param.Field[string] `json:"modelID,required"` Parts param.Field[[]SessionChatParamsPartUnion] `json:"parts,required"` ProviderID param.Field[string] `json:"providerID,required"` + Directory param.Field[string] `query:"directory"` Agent param.Field[string] `json:"agent"` MessageID param.Field[string] `json:"messageID"` System param.Field[string] `json:"system"` @@ -2417,6 +2474,14 @@ func (r SessionChatParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [SessionChatParams]'s query parameters as `url.Values`. +func (r SessionChatParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type SessionChatParamsPart struct { Type param.Field[SessionChatParamsPartsType] `json:"type,required"` ID param.Field[string] `json:"id"` @@ -2458,9 +2523,22 @@ func (r SessionChatParamsPartsType) IsKnown() bool { return false } +type SessionChildrenParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [SessionChildrenParams]'s query parameters as `url.Values`. +func (r SessionChildrenParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type SessionCommandParams struct { Arguments param.Field[string] `json:"arguments,required"` Command param.Field[string] `json:"command,required"` + Directory param.Field[string] `query:"directory"` Agent param.Field[string] `json:"agent"` MessageID param.Field[string] `json:"messageID"` Model param.Field[string] `json:"model"` @@ -2470,18 +2548,72 @@ func (r SessionCommandParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [SessionCommandParams]'s query parameters as `url.Values`. +func (r SessionCommandParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type SessionGetParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [SessionGetParams]'s query parameters as `url.Values`. +func (r SessionGetParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type SessionInitParams struct { MessageID param.Field[string] `json:"messageID,required"` ModelID param.Field[string] `json:"modelID,required"` ProviderID param.Field[string] `json:"providerID,required"` + Directory param.Field[string] `query:"directory"` } func (r SessionInitParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [SessionInitParams]'s query parameters as `url.Values`. +func (r SessionInitParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type SessionMessageParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [SessionMessageParams]'s query parameters as `url.Values`. +func (r SessionMessageParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type SessionMessagesParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [SessionMessagesParams]'s query parameters as `url.Values`. +func (r SessionMessagesParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type SessionRevertParams struct { MessageID param.Field[string] `json:"messageID,required"` + Directory param.Field[string] `query:"directory"` PartID param.Field[string] `json:"partID"` } @@ -2489,20 +2621,82 @@ func (r SessionRevertParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [SessionRevertParams]'s query parameters as `url.Values`. +func (r SessionRevertParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type SessionShareParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [SessionShareParams]'s query parameters as `url.Values`. +func (r SessionShareParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type SessionShellParams struct { - Agent param.Field[string] `json:"agent,required"` - Command param.Field[string] `json:"command,required"` + Agent param.Field[string] `json:"agent,required"` + Command param.Field[string] `json:"command,required"` + Directory param.Field[string] `query:"directory"` } func (r SessionShellParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [SessionShellParams]'s query parameters as `url.Values`. +func (r SessionShellParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type SessionSummarizeParams struct { ModelID param.Field[string] `json:"modelID,required"` ProviderID param.Field[string] `json:"providerID,required"` + Directory param.Field[string] `query:"directory"` } func (r SessionSummarizeParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } + +// URLQuery serializes [SessionSummarizeParams]'s query parameters as `url.Values`. +func (r SessionSummarizeParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type SessionUnrevertParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [SessionUnrevertParams]'s query parameters as `url.Values`. +func (r SessionUnrevertParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type SessionUnshareParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [SessionUnshareParams]'s query parameters as `url.Values`. +func (r SessionUnshareParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} diff --git a/packages/sdk/go/session_test.go b/packages/sdk/go/session_test.go index 9c4604144..13a7315b4 100644 --- a/packages/sdk/go/session_test.go +++ b/packages/sdk/go/session_test.go @@ -26,8 +26,9 @@ func TestSessionNewWithOptionalParams(t *testing.T) { option.WithBaseURL(baseURL), ) _, err := client.Session.New(context.TODO(), opencode.SessionNewParams{ - ParentID: opencode.F("parentID"), - Title: opencode.F("title"), + Directory: opencode.F("directory"), + ParentID: opencode.F("parentID"), + Title: opencode.F("title"), }) if err != nil { var apierr *opencode.Error @@ -54,7 +55,8 @@ func TestSessionUpdateWithOptionalParams(t *testing.T) { context.TODO(), "id", opencode.SessionUpdateParams{ - Title: opencode.F("title"), + Directory: opencode.F("directory"), + Title: opencode.F("title"), }, ) if err != nil { @@ -66,7 +68,7 @@ func TestSessionUpdateWithOptionalParams(t *testing.T) { } } -func TestSessionList(t *testing.T) { +func TestSessionListWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -78,7 +80,9 @@ func TestSessionList(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Session.List(context.TODO()) + _, err := client.Session.List(context.TODO(), opencode.SessionListParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -88,7 +92,7 @@ func TestSessionList(t *testing.T) { } } -func TestSessionDelete(t *testing.T) { +func TestSessionDeleteWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -100,7 +104,13 @@ func TestSessionDelete(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Session.Delete(context.TODO(), "id") + _, err := client.Session.Delete( + context.TODO(), + "id", + opencode.SessionDeleteParams{ + Directory: opencode.F("directory"), + }, + ) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -110,7 +120,7 @@ func TestSessionDelete(t *testing.T) { } } -func TestSessionAbort(t *testing.T) { +func TestSessionAbortWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -122,7 +132,13 @@ func TestSessionAbort(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Session.Abort(context.TODO(), "id") + _, err := client.Session.Abort( + context.TODO(), + "id", + opencode.SessionAbortParams{ + Directory: opencode.F("directory"), + }, + ) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -160,6 +176,7 @@ func TestSessionChatWithOptionalParams(t *testing.T) { }), }}), ProviderID: opencode.F("providerID"), + Directory: opencode.F("directory"), Agent: opencode.F("agent"), MessageID: opencode.F("msg"), System: opencode.F("system"), @@ -177,7 +194,7 @@ func TestSessionChatWithOptionalParams(t *testing.T) { } } -func TestSessionChildren(t *testing.T) { +func TestSessionChildrenWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -189,7 +206,13 @@ func TestSessionChildren(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Session.Children(context.TODO(), "id") + _, err := client.Session.Children( + context.TODO(), + "id", + opencode.SessionChildrenParams{ + Directory: opencode.F("directory"), + }, + ) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -217,6 +240,7 @@ func TestSessionCommandWithOptionalParams(t *testing.T) { opencode.SessionCommandParams{ Arguments: opencode.F("arguments"), Command: opencode.F("command"), + Directory: opencode.F("directory"), Agent: opencode.F("agent"), MessageID: opencode.F("msg"), Model: opencode.F("model"), @@ -231,7 +255,7 @@ func TestSessionCommandWithOptionalParams(t *testing.T) { } } -func TestSessionGet(t *testing.T) { +func TestSessionGetWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -243,7 +267,13 @@ func TestSessionGet(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Session.Get(context.TODO(), "id") + _, err := client.Session.Get( + context.TODO(), + "id", + opencode.SessionGetParams{ + Directory: opencode.F("directory"), + }, + ) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -253,7 +283,7 @@ func TestSessionGet(t *testing.T) { } } -func TestSessionInit(t *testing.T) { +func TestSessionInitWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -272,6 +302,7 @@ func TestSessionInit(t *testing.T) { MessageID: opencode.F("messageID"), ModelID: opencode.F("modelID"), ProviderID: opencode.F("providerID"), + Directory: opencode.F("directory"), }, ) if err != nil { @@ -283,7 +314,7 @@ func TestSessionInit(t *testing.T) { } } -func TestSessionMessage(t *testing.T) { +func TestSessionMessageWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -299,6 +330,9 @@ func TestSessionMessage(t *testing.T) { context.TODO(), "id", "messageID", + opencode.SessionMessageParams{ + Directory: opencode.F("directory"), + }, ) if err != nil { var apierr *opencode.Error @@ -309,7 +343,7 @@ func TestSessionMessage(t *testing.T) { } } -func TestSessionMessages(t *testing.T) { +func TestSessionMessagesWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -321,7 +355,13 @@ func TestSessionMessages(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Session.Messages(context.TODO(), "id") + _, err := client.Session.Messages( + context.TODO(), + "id", + opencode.SessionMessagesParams{ + Directory: opencode.F("directory"), + }, + ) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -348,6 +388,7 @@ func TestSessionRevertWithOptionalParams(t *testing.T) { "id", opencode.SessionRevertParams{ MessageID: opencode.F("msg"), + Directory: opencode.F("directory"), PartID: opencode.F("prt"), }, ) @@ -360,7 +401,7 @@ func TestSessionRevertWithOptionalParams(t *testing.T) { } } -func TestSessionShare(t *testing.T) { +func TestSessionShareWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -372,7 +413,13 @@ func TestSessionShare(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Session.Share(context.TODO(), "id") + _, err := client.Session.Share( + context.TODO(), + "id", + opencode.SessionShareParams{ + Directory: opencode.F("directory"), + }, + ) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -382,7 +429,7 @@ func TestSessionShare(t *testing.T) { } } -func TestSessionShell(t *testing.T) { +func TestSessionShellWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -398,8 +445,9 @@ func TestSessionShell(t *testing.T) { context.TODO(), "id", opencode.SessionShellParams{ - Agent: opencode.F("agent"), - Command: opencode.F("command"), + Agent: opencode.F("agent"), + Command: opencode.F("command"), + Directory: opencode.F("directory"), }, ) if err != nil { @@ -411,7 +459,7 @@ func TestSessionShell(t *testing.T) { } } -func TestSessionSummarize(t *testing.T) { +func TestSessionSummarizeWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -429,6 +477,7 @@ func TestSessionSummarize(t *testing.T) { opencode.SessionSummarizeParams{ ModelID: opencode.F("modelID"), ProviderID: opencode.F("providerID"), + Directory: opencode.F("directory"), }, ) if err != nil { @@ -440,7 +489,7 @@ func TestSessionSummarize(t *testing.T) { } } -func TestSessionUnrevert(t *testing.T) { +func TestSessionUnrevertWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -452,7 +501,13 @@ func TestSessionUnrevert(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Session.Unrevert(context.TODO(), "id") + _, err := client.Session.Unrevert( + context.TODO(), + "id", + opencode.SessionUnrevertParams{ + Directory: opencode.F("directory"), + }, + ) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -462,7 +517,7 @@ func TestSessionUnrevert(t *testing.T) { } } -func TestSessionUnshare(t *testing.T) { +func TestSessionUnshareWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -474,7 +529,13 @@ func TestSessionUnshare(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Session.Unshare(context.TODO(), "id") + _, err := client.Session.Unshare( + context.TODO(), + "id", + opencode.SessionUnshareParams{ + Directory: opencode.F("directory"), + }, + ) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { diff --git a/packages/sdk/go/sessionpermission.go b/packages/sdk/go/sessionpermission.go index 85e55bd5e..4d49bd87b 100644 --- a/packages/sdk/go/sessionpermission.go +++ b/packages/sdk/go/sessionpermission.go @@ -7,8 +7,10 @@ import ( "errors" "fmt" "net/http" + "net/url" "github.com/sst/opencode-sdk-go/internal/apijson" + "github.com/sst/opencode-sdk-go/internal/apiquery" "github.com/sst/opencode-sdk-go/internal/param" "github.com/sst/opencode-sdk-go/internal/requestconfig" "github.com/sst/opencode-sdk-go/option" @@ -34,7 +36,7 @@ func NewSessionPermissionService(opts ...option.RequestOption) (r *SessionPermis } // Respond to a permission request -func (r *SessionPermissionService) Respond(ctx context.Context, id string, permissionID string, body SessionPermissionRespondParams, opts ...option.RequestOption) (res *bool, err error) { +func (r *SessionPermissionService) Respond(ctx context.Context, id string, permissionID string, params SessionPermissionRespondParams, opts ...option.RequestOption) (res *bool, err error) { opts = append(r.Options[:], opts...) if id == "" { err = errors.New("missing required id parameter") @@ -45,7 +47,7 @@ func (r *SessionPermissionService) Respond(ctx context.Context, id string, permi return } path := fmt.Sprintf("session/%s/permissions/%s", id, permissionID) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } @@ -106,13 +108,23 @@ func (r permissionTimeJSON) RawJSON() string { } type SessionPermissionRespondParams struct { - Response param.Field[SessionPermissionRespondParamsResponse] `json:"response,required"` + Response param.Field[SessionPermissionRespondParamsResponse] `json:"response,required"` + Directory param.Field[string] `query:"directory"` } func (r SessionPermissionRespondParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [SessionPermissionRespondParams]'s query parameters as +// `url.Values`. +func (r SessionPermissionRespondParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type SessionPermissionRespondParamsResponse string const ( diff --git a/packages/sdk/go/sessionpermission_test.go b/packages/sdk/go/sessionpermission_test.go index 6a60f2f1e..ed396b50a 100644 --- a/packages/sdk/go/sessionpermission_test.go +++ b/packages/sdk/go/sessionpermission_test.go @@ -13,7 +13,7 @@ import ( "github.com/sst/opencode-sdk-go/option" ) -func TestSessionPermissionRespond(t *testing.T) { +func TestSessionPermissionRespondWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -30,7 +30,8 @@ func TestSessionPermissionRespond(t *testing.T) { "id", "permissionID", opencode.SessionPermissionRespondParams{ - Response: opencode.F(opencode.SessionPermissionRespondParamsResponseOnce), + Response: opencode.F(opencode.SessionPermissionRespondParamsResponseOnce), + Directory: opencode.F("directory"), }, ) if err != nil { diff --git a/packages/sdk/go/tui.go b/packages/sdk/go/tui.go index ab5ed6403..b7a8483f0 100644 --- a/packages/sdk/go/tui.go +++ b/packages/sdk/go/tui.go @@ -5,8 +5,10 @@ package opencode import ( "context" "net/http" + "net/url" "github.com/sst/opencode-sdk-go/internal/apijson" + "github.com/sst/opencode-sdk-go/internal/apiquery" "github.com/sst/opencode-sdk-go/internal/param" "github.com/sst/opencode-sdk-go/internal/requestconfig" "github.com/sst/opencode-sdk-go/option" @@ -32,103 +34,191 @@ func NewTuiService(opts ...option.RequestOption) (r *TuiService) { } // Append prompt to the TUI -func (r *TuiService) AppendPrompt(ctx context.Context, body TuiAppendPromptParams, opts ...option.RequestOption) (res *bool, err error) { +func (r *TuiService) AppendPrompt(ctx context.Context, params TuiAppendPromptParams, opts ...option.RequestOption) (res *bool, err error) { opts = append(r.Options[:], opts...) path := "tui/append-prompt" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } // Clear the prompt -func (r *TuiService) ClearPrompt(ctx context.Context, opts ...option.RequestOption) (res *bool, err error) { +func (r *TuiService) ClearPrompt(ctx context.Context, body TuiClearPromptParams, opts ...option.RequestOption) (res *bool, err error) { opts = append(r.Options[:], opts...) path := "tui/clear-prompt" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) return } // Execute a TUI command (e.g. agent_cycle) -func (r *TuiService) ExecuteCommand(ctx context.Context, body TuiExecuteCommandParams, opts ...option.RequestOption) (res *bool, err error) { +func (r *TuiService) ExecuteCommand(ctx context.Context, params TuiExecuteCommandParams, opts ...option.RequestOption) (res *bool, err error) { opts = append(r.Options[:], opts...) path := "tui/execute-command" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } // Open the help dialog -func (r *TuiService) OpenHelp(ctx context.Context, opts ...option.RequestOption) (res *bool, err error) { +func (r *TuiService) OpenHelp(ctx context.Context, body TuiOpenHelpParams, 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...) - return -} - -// Open the model dialog -func (r *TuiService) OpenModels(ctx context.Context, opts ...option.RequestOption) (res *bool, err error) { - opts = append(r.Options[:], opts...) - path := "tui/open-models" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...) - return -} - -// Open the session dialog -func (r *TuiService) OpenSessions(ctx context.Context, opts ...option.RequestOption) (res *bool, err error) { - opts = append(r.Options[:], opts...) - path := "tui/open-sessions" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...) - return -} - -// Open the theme dialog -func (r *TuiService) OpenThemes(ctx context.Context, opts ...option.RequestOption) (res *bool, err error) { - opts = append(r.Options[:], opts...) - path := "tui/open-themes" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...) - 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 } +// Open the model dialog +func (r *TuiService) OpenModels(ctx context.Context, body TuiOpenModelsParams, opts ...option.RequestOption) (res *bool, err error) { + opts = append(r.Options[:], opts...) + path := "tui/open-models" + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + return +} + +// Open the session dialog +func (r *TuiService) OpenSessions(ctx context.Context, body TuiOpenSessionsParams, opts ...option.RequestOption) (res *bool, err error) { + opts = append(r.Options[:], opts...) + path := "tui/open-sessions" + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + return +} + +// Open the theme dialog +func (r *TuiService) OpenThemes(ctx context.Context, body TuiOpenThemesParams, opts ...option.RequestOption) (res *bool, err error) { + opts = append(r.Options[:], opts...) + path := "tui/open-themes" + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + return +} + +// Show a toast notification in the TUI +func (r *TuiService) ShowToast(ctx context.Context, params TuiShowToastParams, opts ...option.RequestOption) (res *bool, err error) { + opts = append(r.Options[:], opts...) + path := "tui/show-toast" + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) + return +} + // Submit the prompt -func (r *TuiService) SubmitPrompt(ctx context.Context, opts ...option.RequestOption) (res *bool, err error) { +func (r *TuiService) SubmitPrompt(ctx context.Context, body TuiSubmitPromptParams, opts ...option.RequestOption) (res *bool, err error) { opts = append(r.Options[:], opts...) path := "tui/submit-prompt" - err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) return } type TuiAppendPromptParams struct { - Text param.Field[string] `json:"text,required"` + Text param.Field[string] `json:"text,required"` + Directory param.Field[string] `query:"directory"` } func (r TuiAppendPromptParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [TuiAppendPromptParams]'s query parameters as `url.Values`. +func (r TuiAppendPromptParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type TuiClearPromptParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [TuiClearPromptParams]'s query parameters as `url.Values`. +func (r TuiClearPromptParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type TuiExecuteCommandParams struct { - Command param.Field[string] `json:"command,required"` + Command param.Field[string] `json:"command,required"` + Directory param.Field[string] `query:"directory"` } func (r TuiExecuteCommandParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [TuiExecuteCommandParams]'s query parameters as +// `url.Values`. +func (r TuiExecuteCommandParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type TuiOpenHelpParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [TuiOpenHelpParams]'s query parameters as `url.Values`. +func (r TuiOpenHelpParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type TuiOpenModelsParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [TuiOpenModelsParams]'s query parameters as `url.Values`. +func (r TuiOpenModelsParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type TuiOpenSessionsParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [TuiOpenSessionsParams]'s query parameters as `url.Values`. +func (r TuiOpenSessionsParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type TuiOpenThemesParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [TuiOpenThemesParams]'s query parameters as `url.Values`. +func (r TuiOpenThemesParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type TuiShowToastParams struct { - Message param.Field[string] `json:"message,required"` - Variant param.Field[TuiShowToastParamsVariant] `json:"variant,required"` - Title param.Field[string] `json:"title"` + Message param.Field[string] `json:"message,required"` + Variant param.Field[TuiShowToastParamsVariant] `json:"variant,required"` + Directory param.Field[string] `query:"directory"` + Title param.Field[string] `json:"title"` } func (r TuiShowToastParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +// URLQuery serializes [TuiShowToastParams]'s query parameters as `url.Values`. +func (r TuiShowToastParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + type TuiShowToastParamsVariant string const ( @@ -145,3 +235,15 @@ func (r TuiShowToastParamsVariant) IsKnown() bool { } return false } + +type TuiSubmitPromptParams struct { + Directory param.Field[string] `query:"directory"` +} + +// URLQuery serializes [TuiSubmitPromptParams]'s query parameters as `url.Values`. +func (r TuiSubmitPromptParams) URLQuery() (v url.Values) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} diff --git a/packages/sdk/go/tui_test.go b/packages/sdk/go/tui_test.go index 55faee81b..635473ba6 100644 --- a/packages/sdk/go/tui_test.go +++ b/packages/sdk/go/tui_test.go @@ -13,7 +13,7 @@ import ( "github.com/sst/opencode-sdk-go/option" ) -func TestTuiAppendPrompt(t *testing.T) { +func TestTuiAppendPromptWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -26,7 +26,8 @@ func TestTuiAppendPrompt(t *testing.T) { option.WithBaseURL(baseURL), ) _, err := client.Tui.AppendPrompt(context.TODO(), opencode.TuiAppendPromptParams{ - Text: opencode.F("text"), + Text: opencode.F("text"), + Directory: opencode.F("directory"), }) if err != nil { var apierr *opencode.Error @@ -37,7 +38,7 @@ func TestTuiAppendPrompt(t *testing.T) { } } -func TestTuiClearPrompt(t *testing.T) { +func TestTuiClearPromptWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -49,7 +50,9 @@ func TestTuiClearPrompt(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Tui.ClearPrompt(context.TODO()) + _, err := client.Tui.ClearPrompt(context.TODO(), opencode.TuiClearPromptParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -59,7 +62,7 @@ func TestTuiClearPrompt(t *testing.T) { } } -func TestTuiExecuteCommand(t *testing.T) { +func TestTuiExecuteCommandWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -72,7 +75,8 @@ func TestTuiExecuteCommand(t *testing.T) { option.WithBaseURL(baseURL), ) _, err := client.Tui.ExecuteCommand(context.TODO(), opencode.TuiExecuteCommandParams{ - Command: opencode.F("command"), + Command: opencode.F("command"), + Directory: opencode.F("directory"), }) if err != nil { var apierr *opencode.Error @@ -83,7 +87,7 @@ func TestTuiExecuteCommand(t *testing.T) { } } -func TestTuiOpenHelp(t *testing.T) { +func TestTuiOpenHelpWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -95,7 +99,9 @@ func TestTuiOpenHelp(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Tui.OpenHelp(context.TODO()) + _, err := client.Tui.OpenHelp(context.TODO(), opencode.TuiOpenHelpParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -105,7 +111,7 @@ func TestTuiOpenHelp(t *testing.T) { } } -func TestTuiOpenModels(t *testing.T) { +func TestTuiOpenModelsWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -117,7 +123,9 @@ func TestTuiOpenModels(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Tui.OpenModels(context.TODO()) + _, err := client.Tui.OpenModels(context.TODO(), opencode.TuiOpenModelsParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -127,7 +135,7 @@ func TestTuiOpenModels(t *testing.T) { } } -func TestTuiOpenSessions(t *testing.T) { +func TestTuiOpenSessionsWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -139,7 +147,9 @@ func TestTuiOpenSessions(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Tui.OpenSessions(context.TODO()) + _, err := client.Tui.OpenSessions(context.TODO(), opencode.TuiOpenSessionsParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -149,7 +159,7 @@ func TestTuiOpenSessions(t *testing.T) { } } -func TestTuiOpenThemes(t *testing.T) { +func TestTuiOpenThemesWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -161,7 +171,9 @@ func TestTuiOpenThemes(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Tui.OpenThemes(context.TODO()) + _, err := client.Tui.OpenThemes(context.TODO(), opencode.TuiOpenThemesParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { @@ -184,9 +196,10 @@ func TestTuiShowToastWithOptionalParams(t *testing.T) { option.WithBaseURL(baseURL), ) _, err := client.Tui.ShowToast(context.TODO(), opencode.TuiShowToastParams{ - Message: opencode.F("message"), - Variant: opencode.F(opencode.TuiShowToastParamsVariantInfo), - Title: opencode.F("title"), + Message: opencode.F("message"), + Variant: opencode.F(opencode.TuiShowToastParamsVariantInfo), + Directory: opencode.F("directory"), + Title: opencode.F("title"), }) if err != nil { var apierr *opencode.Error @@ -197,7 +210,7 @@ func TestTuiShowToastWithOptionalParams(t *testing.T) { } } -func TestTuiSubmitPrompt(t *testing.T) { +func TestTuiSubmitPromptWithOptionalParams(t *testing.T) { t.Skip("Prism tests are disabled") baseURL := "http://localhost:4010" if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { @@ -209,7 +222,9 @@ func TestTuiSubmitPrompt(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - _, err := client.Tui.SubmitPrompt(context.TODO()) + _, err := client.Tui.SubmitPrompt(context.TODO(), opencode.TuiSubmitPromptParams{ + Directory: opencode.F("directory"), + }) if err != nil { var apierr *opencode.Error if errors.As(err, &apierr) { diff --git a/packages/sdk/go/usage_test.go b/packages/sdk/go/usage_test.go index ef7ce8bde..2652b5829 100644 --- a/packages/sdk/go/usage_test.go +++ b/packages/sdk/go/usage_test.go @@ -23,7 +23,7 @@ func TestUsage(t *testing.T) { client := opencode.NewClient( option.WithBaseURL(baseURL), ) - sessions, err := client.Session.List(context.TODO()) + sessions, err := client.Session.List(context.TODO(), opencode.SessionListParams{}) if err != nil { t.Error(err) return diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index b0e09d7a2..194b69fc6 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -1178,11 +1178,6 @@ export type WellKnownAuth = { token: string } -/** - * Working directory path (defaults to current working directory) - */ -export type Directory = string - export type ProjectListData = { body?: never path?: never diff --git a/packages/sdk/stainless/stainless.yml b/packages/sdk/stainless/stainless.yml index 17c5c4389..ac6da0468 100644 --- a/packages/sdk/stainless/stainless.yml +++ b/packages/sdk/stainless/stainless.yml @@ -105,6 +105,7 @@ resources: project: Project methods: list: get /project + current: get /project/current session: models: diff --git a/packages/tui/cmd/opencode/main.go b/packages/tui/cmd/opencode/main.go index ee371d8fd..22841fc89 100644 --- a/packages/tui/cmd/opencode/main.go +++ b/packages/tui/cmd/opencode/main.go @@ -2,7 +2,6 @@ package main import ( "context" - "encoding/json" "io" "log/slog" "os" @@ -19,6 +18,7 @@ import ( "github.com/sst/opencode/internal/clipboard" "github.com/sst/opencode/internal/tui" "github.com/sst/opencode/internal/util" + "golang.org/x/sync/errgroup" ) var Version = "dev" @@ -37,13 +37,6 @@ func main() { url := os.Getenv("OPENCODE_SERVER") - var project opencode.Project - err := json.Unmarshal([]byte(os.Getenv("OPENCODE_PROJECT")), &project) - if err != nil { - slog.Error("Failed to unmarshal app info", "error", err) - os.Exit(1) - } - stat, err := os.Stdin.Stat() if err != nil { slog.Error("Failed to stat stdin", "error", err) @@ -72,21 +65,42 @@ func main() { option.WithBaseURL(url), ) - // Fetch agents from the /agent endpoint - agentsPtr, err := httpClient.Agent.List(context.Background()) - if err != nil { - slog.Error("Failed to fetch agents", "error", err) - os.Exit(1) - } - if agentsPtr == nil { - slog.Error("No agents returned from server") - os.Exit(1) - } - agents := *agentsPtr + var agents []opencode.Agent + var path *opencode.Path + var project *opencode.Project - path, err := httpClient.Path.Get(context.Background()) + batch := errgroup.Group{} + + batch.Go(func() error { + result, err := httpClient.Project.Current(context.Background(), opencode.ProjectCurrentParams{}) + if err != nil { + return err + } + project = result + return nil + }) + + batch.Go(func() error { + result, err := httpClient.Agent.List(context.Background(), opencode.AgentListParams{}) + if err != nil { + return err + } + agents = *result + return nil + }) + + batch.Go(func() error { + result, err := httpClient.Path.Get(context.Background(), opencode.PathGetParams{}) + if err != nil { + return err + } + path = result + return nil + }) + + err = batch.Wait() if err != nil { - os.Exit(1) + panic(err) } ctx, cancel := context.WithCancel(context.Background()) @@ -122,7 +136,7 @@ func main() { signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT) go func() { - stream := httpClient.Event.ListStreaming(ctx) + stream := httpClient.Event.ListStreaming(ctx, opencode.EventListParams{}) for stream.Next() { evt := stream.Current().AsUnion() program.Send(evt) diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go index 29387c299..7defbc294 100644 --- a/packages/tui/internal/app/app.go +++ b/packages/tui/internal/app/app.go @@ -101,7 +101,7 @@ type PermissionRespondedToMsg struct { func New( ctx context.Context, version string, - project opencode.Project, + project *opencode.Project, path *opencode.Path, agents []opencode.Agent, httpClient *opencode.Client, @@ -113,7 +113,7 @@ func New( util.RootPath = project.Worktree util.CwdPath, _ = os.Getwd() - configInfo, err := httpClient.Config.Get(ctx) + configInfo, err := httpClient.Config.Get(ctx, opencode.ConfigGetParams{}) if err != nil { return nil, err } @@ -188,13 +188,13 @@ func New( slog.Debug("Loaded config", "config", configInfo) - customCommands, err := httpClient.Command.List(ctx) + customCommands, err := httpClient.Command.List(ctx, opencode.CommandListParams{}) if err != nil { return nil, err } app := &App{ - Project: project, + Project: *project, Agents: agents, Version: version, StatePath: appStatePath, @@ -460,7 +460,7 @@ func findProviderByID(providers []opencode.Provider, providerID string) *opencod } func (a *App) InitializeProvider() tea.Cmd { - providersResponse, err := a.Client.App.Providers(context.Background()) + providersResponse, err := a.Client.App.Providers(context.Background(), opencode.AppProvidersParams{}) if err != nil { slog.Error("Failed to list providers", "error", err) // TODO: notify user @@ -879,7 +879,7 @@ func (a *App) Cancel(ctx context.Context, sessionID string) error { a.compactCancel = nil } - _, err := a.Client.Session.Abort(ctx, sessionID) + _, err := a.Client.Session.Abort(ctx, sessionID, opencode.SessionAbortParams{}) if err != nil { slog.Error("Failed to cancel session", "error", err) return err @@ -888,7 +888,7 @@ func (a *App) Cancel(ctx context.Context, sessionID string) error { } func (a *App) ListSessions(ctx context.Context) ([]opencode.Session, error) { - response, err := a.Client.Session.List(ctx) + response, err := a.Client.Session.List(ctx, opencode.SessionListParams{}) if err != nil { return nil, err } @@ -900,7 +900,7 @@ func (a *App) ListSessions(ctx context.Context) ([]opencode.Session, error) { } func (a *App) DeleteSession(ctx context.Context, sessionID string) error { - _, err := a.Client.Session.Delete(ctx, sessionID) + _, err := a.Client.Session.Delete(ctx, sessionID, opencode.SessionDeleteParams{}) if err != nil { slog.Error("Failed to delete session", "error", err) return err @@ -920,7 +920,7 @@ func (a *App) UpdateSession(ctx context.Context, sessionID string, title string) } func (a *App) ListMessages(ctx context.Context, sessionId string) ([]Message, error) { - response, err := a.Client.Session.Messages(ctx, sessionId) + response, err := a.Client.Session.Messages(ctx, sessionId, opencode.SessionMessagesParams{}) if err != nil { return nil, err } @@ -942,7 +942,7 @@ func (a *App) ListMessages(ctx context.Context, sessionId string) ([]Message, er } func (a *App) ListProviders(ctx context.Context) ([]opencode.Provider, error) { - response, err := a.Client.App.Providers(ctx) + response, err := a.Client.App.Providers(ctx, opencode.AppProvidersParams{}) if err != nil { return nil, err } diff --git a/packages/tui/internal/completions/agents.go b/packages/tui/internal/completions/agents.go index 3744d38c4..d25c76d89 100644 --- a/packages/tui/internal/completions/agents.go +++ b/packages/tui/internal/completions/agents.go @@ -32,6 +32,7 @@ func (cg *agentsContextGroup) GetChildEntries( agents, err := cg.app.Client.Agent.List( context.Background(), + opencode.AgentListParams{}, ) if err != nil { slog.Error("Failed to get agent list", "error", err) diff --git a/packages/tui/internal/completions/files.go b/packages/tui/internal/completions/files.go index bece89a89..d00873656 100644 --- a/packages/tui/internal/completions/files.go +++ b/packages/tui/internal/completions/files.go @@ -29,7 +29,7 @@ func (cg *filesContextGroup) GetEmptyMessage() string { func (cg *filesContextGroup) getGitFiles() []CompletionSuggestion { items := make([]CompletionSuggestion, 0) - status, _ := cg.app.Client.File.Status(context.Background()) + status, _ := cg.app.Client.File.Status(context.Background(), opencode.FileStatusParams{}) if status != nil { files := *status sort.Slice(files, func(i, j int) bool { diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go index b3074bb54..053d538a4 100644 --- a/packages/tui/internal/components/chat/messages.go +++ b/packages/tui/internal/components/chat/messages.go @@ -769,6 +769,7 @@ func (m *messagesComponent) renderView() tea.Cmd { context.Background(), m.app.CurrentPermission.SessionID, m.app.CurrentPermission.MessageID, + opencode.SessionMessageParams{}, ) if err != nil || response == nil { slog.Error("Failed to get message from child session", "error", err) @@ -1238,6 +1239,7 @@ func (m *messagesComponent) RedoLastMessage() (tea.Model, tea.Cmd) { response, err := m.app.Client.Session.Unrevert( context.Background(), m.app.Session.ID, + opencode.SessionUnrevertParams{}, ) if err != nil { slog.Error("Failed to unrevert session", "error", err) diff --git a/packages/tui/internal/tui/tui.go b/packages/tui/internal/tui/tui.go index 6e0c7df47..62a647a14 100644 --- a/packages/tui/internal/tui/tui.go +++ b/packages/tui/internal/tui/tui.go @@ -393,7 +393,7 @@ func (a Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { a.showCompletionDialog = false // If we're in a child session, switch back to parent before sending prompt if a.app.Session.ParentID != "" { - parentSession, err := a.app.Client.Session.Get(context.Background(), a.app.Session.ParentID) + parentSession, err := a.app.Client.Session.Get(context.Background(), a.app.Session.ParentID, opencode.SessionGetParams{}) if err != nil { slog.Error("Failed to get parent session", "error", err) return a, toast.NewErrorToast("Failed to get parent session") @@ -411,7 +411,7 @@ func (a Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case app.SendCommand: // If we're in a child session, switch back to parent before sending prompt if a.app.Session.ParentID != "" { - parentSession, err := a.app.Client.Session.Get(context.Background(), a.app.Session.ParentID) + parentSession, err := a.app.Client.Session.Get(context.Background(), a.app.Session.ParentID, opencode.SessionGetParams{}) if err != nil { slog.Error("Failed to get parent session", "error", err) return a, toast.NewErrorToast("Failed to get parent session") @@ -429,7 +429,7 @@ func (a Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case app.SendShell: // If we're in a child session, switch back to parent before sending prompt if a.app.Session.ParentID != "" { - parentSession, err := a.app.Client.Session.Get(context.Background(), a.app.Session.ParentID) + parentSession, err := a.app.Client.Session.Get(context.Background(), a.app.Session.ParentID, opencode.SessionGetParams{}) if err != nil { slog.Error("Failed to get parent session", "error", err) return a, toast.NewErrorToast("Failed to get parent session") @@ -676,7 +676,7 @@ func (a Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if nextMessageID == "" { // Last message - use unrevert to restore full conversation - response, err = a.app.Client.Session.Unrevert(context.Background(), a.app.Session.ID) + response, err = a.app.Client.Session.Unrevert(context.Background(), a.app.Session.ID, opencode.SessionUnrevertParams{}) } else { // Revert to next message to make target the last visible response, err = a.app.Client.Session.Revert(context.Background(), a.app.Session.ID, @@ -1185,7 +1185,7 @@ func (a Model) executeCommand(command commands.Command) (tea.Model, tea.Cmd) { if a.app.Session.ID == "" { return a, nil } - response, err := a.app.Client.Session.Share(context.Background(), a.app.Session.ID) + response, err := a.app.Client.Session.Share(context.Background(), a.app.Session.ID, opencode.SessionShareParams{}) if err != nil { slog.Error("Failed to share session", "error", err) return a, toast.NewErrorToast("Failed to share session") @@ -1197,7 +1197,7 @@ func (a Model) executeCommand(command commands.Command) (tea.Model, tea.Cmd) { if a.app.Session.ID == "" { return a, nil } - _, err := a.app.Client.Session.Unshare(context.Background(), a.app.Session.ID) + _, err := a.app.Client.Session.Unshare(context.Background(), a.app.Session.ID, opencode.SessionUnshareParams{}) if err != nil { slog.Error("Failed to unshare session", "error", err) return a, toast.NewErrorToast("Failed to unshare session") @@ -1225,7 +1225,7 @@ func (a Model) executeCommand(command commands.Command) (tea.Model, tea.Cmd) { var parentSession *opencode.Session if a.app.Session.ParentID != "" { parentSessionID = a.app.Session.ParentID - session, err := a.app.Client.Session.Get(context.Background(), parentSessionID) + session, err := a.app.Client.Session.Get(context.Background(), parentSessionID, opencode.SessionGetParams{}) if err != nil { slog.Error("Failed to get parent session", "error", err) return toast.NewErrorToast("Failed to get parent session") @@ -1235,7 +1235,7 @@ func (a Model) executeCommand(command commands.Command) (tea.Model, tea.Cmd) { parentSession = a.app.Session } - children, err := a.app.Client.Session.Children(context.Background(), parentSessionID) + children, err := a.app.Client.Session.Children(context.Background(), parentSessionID, opencode.SessionChildrenParams{}) if err != nil { slog.Error("Failed to get session children", "error", err) return toast.NewErrorToast("Failed to get session children") @@ -1283,7 +1283,7 @@ func (a Model) executeCommand(command commands.Command) (tea.Model, tea.Cmd) { var parentSession *opencode.Session if a.app.Session.ParentID != "" { parentSessionID = a.app.Session.ParentID - session, err := a.app.Client.Session.Get(context.Background(), parentSessionID) + session, err := a.app.Client.Session.Get(context.Background(), parentSessionID, opencode.SessionGetParams{}) if err != nil { slog.Error("Failed to get parent session", "error", err) return toast.NewErrorToast("Failed to get parent session") @@ -1293,7 +1293,7 @@ func (a Model) executeCommand(command commands.Command) (tea.Model, tea.Cmd) { parentSession = a.app.Session } - children, err := a.app.Client.Session.Children(context.Background(), parentSessionID) + children, err := a.app.Client.Session.Children(context.Background(), parentSessionID, opencode.SessionChildrenParams{}) if err != nil { slog.Error("Failed to get session children", "error", err) return toast.NewErrorToast("Failed to get session children")