summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packages/opencode/src/server/server.ts8
-rw-r--r--packages/opencode/src/session/index.ts18
-rw-r--r--packages/sdk/go/.stats.yml6
-rw-r--r--packages/sdk/go/api.md2
-rw-r--r--packages/sdk/go/session.go42
-rw-r--r--packages/sdk/go/session_test.go58
-rwxr-xr-xpackages/sdk/stainless/generate.ts2
-rw-r--r--packages/sdk/stainless/stainless.yml2
-rw-r--r--packages/tui/internal/app/app.go4
9 files changed, 75 insertions, 67 deletions
diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts
index 48a9a25f3..b81b357a0 100644
--- a/packages/opencode/src/server/server.ts
+++ b/packages/opencode/src/server/server.ts
@@ -593,10 +593,10 @@ export namespace Server {
},
)
.post(
- "/session/:id/bash",
+ "/session/:id/shell",
describeRoute({
- description: "Run a bash command",
- operationId: "session.bash",
+ description: "Run a shell command",
+ operationId: "session.shell",
responses: {
200: {
description: "Created message",
@@ -618,7 +618,7 @@ export namespace Server {
async (c) => {
const sessionID = c.req.valid("param").id
const body = c.req.valid("json")
- const msg = await Session.bash({ ...body, sessionID })
+ const msg = await Session.shell({ ...body, sessionID })
return c.json(msg)
},
)
diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts
index a6c536b7d..ea51ce029 100644
--- a/packages/opencode/src/session/index.ts
+++ b/packages/opencode/src/session/index.ts
@@ -1,5 +1,5 @@
import path from "path"
-import { exec } from "child_process"
+import { spawn } from "child_process"
import { Decimal } from "decimal.js"
import { z, ZodSchema } from "zod"
import {
@@ -670,7 +670,7 @@ export namespace Session {
const lastSummary = msgs.findLast((msg) => msg.info.role === "assistant" && msg.info.summary === true)
if (lastSummary) msgs = msgs.filter((msg) => msg.info.id >= lastSummary.info.id)
- if (msgs.length === 1 && !session.parentID && isDefaultTitle(session.title)) {
+ if (msgs.filter((m) => m.info.role === "user").length === 1 && !session.parentID && isDefaultTitle(session.title)) {
const small = (await Provider.getSmallModel(input.providerID)) ?? model
generateText({
maxOutputTokens: small.info.reasoning ? 1024 : 20,
@@ -1005,7 +1005,7 @@ export namespace Session {
command: z.string(),
})
export type CommandInput = z.infer<typeof CommandInput>
- export async function bash(input: CommandInput) {
+ export async function shell(input: CommandInput) {
using abort = lock(input.sessionID)
const msg: MessageV2.Assistant = {
id: Identifier.ascending("message"),
@@ -1050,10 +1050,18 @@ export namespace Session {
}
await updatePart(part)
const app = App.info()
- const proc = exec(input.command, {
+ const script = `
+ [[ -f ~/.zshrc ]] && source ~/.zshrc 2>/dev/null || true
+ [[ -f ~/.bashrc ]] && source ~/.bashrc 2>/dev/null || true
+ eval "${input.command}"
+ `
+ const proc = spawn(process.env["SHELL"] ?? "bash", ["-c", "-l", script], {
cwd: app.path.cwd,
signal: abort.signal,
- shell: process.env["SHELL"],
+ env: {
+ ...process.env,
+ TERM: "dumb",
+ },
})
let output = ""
diff --git a/packages/sdk/go/.stats.yml b/packages/sdk/go/.stats.yml
index d9ba9daf4..9f1e13803 100644
--- a/packages/sdk/go/.stats.yml
+++ b/packages/sdk/go/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-9031231386199b2baadcaaed5b8df17899f8bc82efef4a74d7a0646fc035268a.yml
-openapi_spec_hash: 8ef902a2a7039a4a6fde44ee7c26c87d
-config_hash: 2b388a88fa9da825b43cbc25c2b349b5
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-a881262c7de4ab59bdfbfc6e30a23c47dee465d7270ffb867b760b0103aff8ed.yml
+openapi_spec_hash: 7dbb6f96f5c26a25c849e50298f58586
+config_hash: 8d85a768523cff92b85ef06c443d49fa
diff --git a/packages/sdk/go/api.md b/packages/sdk/go/api.md
index 5f2bc310d..79a67e42d 100644
--- a/packages/sdk/go/api.md
+++ b/packages/sdk/go/api.md
@@ -115,13 +115,13 @@ Methods:
- <code title="get /session">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>) ([]<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Session">Session</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="delete /session/{id}">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Delete">Delete</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/builtin#bool">bool</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /session/{id}/abort">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Abort">Abort</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/builtin#bool">bool</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
-- <code title="post /session/{id}/bash">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Bash">Bash</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionBashParams">SessionBashParams</a>) (<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#AssistantMessage">AssistantMessage</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /session/{id}/message">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Chat">Chat</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionChatParams">SessionChatParams</a>) (<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#AssistantMessage">AssistantMessage</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /session/{id}/init">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Init">Init</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionInitParams">SessionInitParams</a>) (<a href="https://pkg.go.dev/builtin#bool">bool</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /session/{id}/message/{messageID}">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Message">Message</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, messageID <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionMessageResponse">SessionMessageResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /session/{id}/message">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Messages">Messages</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) ([]<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionMessagesResponse">SessionMessagesResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /session/{id}/revert">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Revert">Revert</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionRevertParams">SessionRevertParams</a>) (<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Session">Session</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /session/{id}/share">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Share">Share</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Session">Session</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
+- <code title="post /session/{id}/shell">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Shell">Shell</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionShellParams">SessionShellParams</a>) (<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#AssistantMessage">AssistantMessage</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /session/{id}/summarize">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Summarize">Summarize</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionSummarizeParams">SessionSummarizeParams</a>) (<a href="https://pkg.go.dev/builtin#bool">bool</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /session/{id}/unrevert">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Unrevert">Unrevert</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Session">Session</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="delete /session/{id}/share">client.Session.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SessionService.Unshare">Unshare</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Session">Session</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
diff --git a/packages/sdk/go/session.go b/packages/sdk/go/session.go
index b8c156b6b..76a9d46fb 100644
--- a/packages/sdk/go/session.go
+++ b/packages/sdk/go/session.go
@@ -90,18 +90,6 @@ func (r *SessionService) Abort(ctx context.Context, id string, opts ...option.Re
return
}
-// Run a bash command
-func (r *SessionService) Bash(ctx context.Context, id string, body SessionBashParams, 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/bash", id)
- 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 *AssistantMessage, err error) {
opts = append(r.Options[:], opts...)
@@ -178,6 +166,18 @@ func (r *SessionService) Share(ctx context.Context, id string, opts ...option.Re
return
}
+// Run a shell command
+func (r *SessionService) Shell(ctx context.Context, id string, body 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...)
+ return
+}
+
// Summarize the session
func (r *SessionService) Summarize(ctx context.Context, id string, body SessionSummarizeParams, opts ...option.RequestOption) (res *bool, err error) {
opts = append(r.Options[:], opts...)
@@ -2306,15 +2306,6 @@ func (r SessionUpdateParams) MarshalJSON() (data []byte, err error) {
return apijson.MarshalRoot(r)
}
-type SessionBashParams struct {
- Agent param.Field[string] `json:"agent,required"`
- Command param.Field[string] `json:"command,required"`
-}
-
-func (r SessionBashParams) MarshalJSON() (data []byte, err error) {
- return apijson.MarshalRoot(r)
-}
-
type SessionChatParams struct {
ModelID param.Field[string] `json:"modelID,required"`
Parts param.Field[[]SessionChatParamsPartUnion] `json:"parts,required"`
@@ -2389,6 +2380,15 @@ func (r SessionRevertParams) MarshalJSON() (data []byte, err error) {
return apijson.MarshalRoot(r)
}
+type SessionShellParams struct {
+ Agent param.Field[string] `json:"agent,required"`
+ Command param.Field[string] `json:"command,required"`
+}
+
+func (r SessionShellParams) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
type SessionSummarizeParams struct {
ModelID param.Field[string] `json:"modelID,required"`
ProviderID param.Field[string] `json:"providerID,required"`
diff --git a/packages/sdk/go/session_test.go b/packages/sdk/go/session_test.go
index 61a340e12..cf4a851c3 100644
--- a/packages/sdk/go/session_test.go
+++ b/packages/sdk/go/session_test.go
@@ -129,35 +129,6 @@ func TestSessionAbort(t *testing.T) {
}
}
-func TestSessionBash(t *testing.T) {
- t.Skip("skipped: tests are disabled for the time being")
- baseURL := "http://localhost:4010"
- if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
- baseURL = envURL
- }
- if !testutil.CheckTestServer(t, baseURL) {
- return
- }
- client := opencode.NewClient(
- option.WithBaseURL(baseURL),
- )
- _, err := client.Session.Bash(
- context.TODO(),
- "id",
- opencode.SessionBashParams{
- Agent: opencode.F("agent"),
- Command: opencode.F("command"),
- },
- )
- 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 TestSessionChatWithOptionalParams(t *testing.T) {
t.Skip("skipped: tests are disabled for the time being")
baseURL := "http://localhost:4010"
@@ -332,6 +303,35 @@ func TestSessionShare(t *testing.T) {
}
}
+func TestSessionShell(t *testing.T) {
+ t.Skip("skipped: tests are disabled for the time being")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := opencode.NewClient(
+ option.WithBaseURL(baseURL),
+ )
+ _, err := client.Session.Shell(
+ context.TODO(),
+ "id",
+ opencode.SessionShellParams{
+ Agent: opencode.F("agent"),
+ Command: opencode.F("command"),
+ },
+ )
+ 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 TestSessionSummarize(t *testing.T) {
t.Skip("skipped: tests are disabled for the time being")
baseURL := "http://localhost:4010"
diff --git a/packages/sdk/stainless/generate.ts b/packages/sdk/stainless/generate.ts
index 0a766d0d7..6b1877f6b 100755
--- a/packages/sdk/stainless/generate.ts
+++ b/packages/sdk/stainless/generate.ts
@@ -7,7 +7,7 @@ console.log("=== Generating Stainless SDK ===")
console.log(process.cwd())
await $`rm -rf go`
-await $`bun run ../../opencode/src/index.ts generate > openapi.json`
+await $`bun run --conditions=development ../../opencode/src/index.ts generate > openapi.json`
await $`stl builds create --branch dev --pull --allow-empty --+target go`
await $`rm -rf ../go`
diff --git a/packages/sdk/stainless/stainless.yml b/packages/sdk/stainless/stainless.yml
index eb0f633f5..db4afd8da 100644
--- a/packages/sdk/stainless/stainless.yml
+++ b/packages/sdk/stainless/stainless.yml
@@ -124,7 +124,7 @@ resources:
message: get /session/{id}/message/{messageID}
messages: get /session/{id}/message
chat: post /session/{id}/message
- bash: post /session/{id}/bash
+ shell: post /session/{id}/shell
update: patch /session/{id}
revert: post /session/{id}/revert
unrevert: post /session/{id}/unrevert
diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go
index 08a79e310..5e9a5a37f 100644
--- a/packages/tui/internal/app/app.go
+++ b/packages/tui/internal/app/app.go
@@ -767,10 +767,10 @@ func (a *App) SendBash(ctx context.Context, command string) (*App, tea.Cmd) {
}
cmds = append(cmds, func() tea.Msg {
- _, err := a.Client.Session.Bash(
+ _, err := a.Client.Session.Shell(
context.Background(),
a.Session.ID,
- opencode.SessionBashParams{
+ opencode.SessionShellParams{
Agent: opencode.F(a.Agent().Name),
Command: opencode.F(command),
},