Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions packages/opencode/src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,17 +323,28 @@ export namespace Server {
"json",
z.object({
title: z.string().optional(),
pinned: z.boolean().optional(),
}),
),
async (c) => {
const sessionID = c.req.valid("param").id
const updates = c.req.valid("json")

const updatedSession = await Session.update(sessionID, (session) => {
if (updates.title !== undefined) {
session.title = updates.title
}
})
// Check if only pinned field is being updated
const onlyPinnedUpdate = updates.title === undefined && updates.pinned !== undefined

const updatedSession = await Session.update(
sessionID,
(session) => {
if (updates.title !== undefined) {
session.title = updates.title
}
if (updates.pinned !== undefined) {
session.pinned = updates.pinned
}
},
{ skipTimeUpdate: onlyPinnedUpdate },
)

return c.json(updatedSession)
},
Expand Down
11 changes: 9 additions & 2 deletions packages/opencode/src/session/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export namespace Session {
diff: z.string().optional(),
})
.optional(),
pinned: z.boolean().optional(),
})
.openapi({
ref: "Session",
Expand Down Expand Up @@ -243,12 +244,18 @@ export namespace Session {
await Share.remove(id, share.secret)
}

export async function update(id: string, editor: (session: Info) => void) {
export async function update(
id: string,
editor: (session: Info) => void,
options: { skipTimeUpdate?: boolean } = {},
) {
const { sessions } = state()
const session = await get(id)
if (!session) return
editor(session)
session.time.updated = Date.now()
if (!options.skipTimeUpdate) {
session.time.updated = Date.now()
}
sessions.set(id, session)
await Storage.writeJSON("session/info/" + id, session)
Bus.publish(Event.Updated, {
Expand Down
13 changes: 9 additions & 4 deletions packages/sdk/go/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,7 @@ type Session struct {
Title string `json:"title,required"`
Version string `json:"version,required"`
ParentID string `json:"parentID"`
Pinned bool `json:"pinned"`
Revert SessionRevert `json:"revert"`
Share SessionShare `json:"share"`
JSON sessionJSON `json:"-"`
Expand All @@ -1275,6 +1276,7 @@ type sessionJSON struct {
Title apijson.Field
Version apijson.Field
ParentID apijson.Field
Pinned apijson.Field
Revert apijson.Field
Share apijson.Field
raw string
Expand Down Expand Up @@ -2298,10 +2300,6 @@ func (r sessionMessagesResponseJSON) RawJSON() string {
return r.raw
}

type SessionUpdateParams struct {
Title param.Field[string] `json:"title"`
}

func (r SessionUpdateParams) MarshalJSON() (data []byte, err error) {
return apijson.MarshalRoot(r)
}
Expand Down Expand Up @@ -2397,3 +2395,10 @@ type SessionSummarizeParams struct {
func (r SessionSummarizeParams) MarshalJSON() (data []byte, err error) {
return apijson.MarshalRoot(r)
}

type SessionUpdateParams struct {
Title param.Field[string] `json:"title"`
Pinned param.Field[bool] `json:"pinned"`
}


21 changes: 21 additions & 0 deletions packages/tui/internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,27 @@ func (a *App) UpdateSession(ctx context.Context, sessionID string, title string)
return nil
}

func (a *App) PinSession(ctx context.Context, sessionID string, pinned bool) error {
_, err := a.Client.Session.Update(ctx, sessionID, opencode.SessionUpdateParams{
Pinned: opencode.F(pinned),
})
if err != nil {
slog.Error("Failed to pin/unpin session", "error", err)
return err
}
return nil
}

func (a *App) TouchSession(ctx context.Context, sessionID string) error {
// Update session without changing any fields - this will update the timestamp
_, err := a.Client.Session.Update(ctx, sessionID, opencode.SessionUpdateParams{})
if err != nil {
slog.Error("Failed to touch session", "error", err)
return err
}
return nil
}

func (a *App) ListMessages(ctx context.Context, sessionId string) ([]Message, error) {
response, err := a.Client.Session.Messages(ctx, sessionId)
if err != nil {
Expand Down
Loading
Loading