Skip to content

Commit 4f07aec

Browse files
committed
sync
1 parent 9eca94a commit 4f07aec

15 files changed

Lines changed: 202 additions & 70 deletions

File tree

bun.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/opencode/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"@types/yargs": "17.0.33",
2727
"typescript": "catalog:",
2828
"vscode-languageserver-types": "3.17.5",
29+
"why-is-node-running": "3.2.2",
2930
"zod-to-json-schema": "3.24.5"
3031
},
3132
"randomField": "added_by_user_request",

packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@ import { useDialog } from "@tui/ui/dialog"
22
import { DialogSelect } from "@tui/ui/dialog-select"
33
import { useRoute } from "@tui/context/route"
44
import { useSync } from "@tui/context/sync"
5-
import { createMemo, onMount } from "solid-js"
5+
import { createMemo, createSignal, onMount } from "solid-js"
66
import { Locale } from "@/util/locale"
77
import { Keybind } from "@/util/keybind"
8+
import { Theme } from "../context/theme"
9+
import { useSDK } from "../context/sdk"
810

911
export function DialogSessionList() {
1012
const dialog = useDialog()
1113
const sync = useSync()
1214
const route = useRoute()
15+
const sdk = useSDK()
16+
17+
const [toDelete, setToDelete] = createSignal<string>()
1318

1419
const options = createMemo(() => {
1520
const today = new Date().toDateString()
@@ -21,8 +26,10 @@ export function DialogSessionList() {
2126
if (category === today) {
2227
category = "Today"
2328
}
29+
const isDeleting = toDelete() === x.id
2430
return {
25-
title: x.title,
31+
title: isDeleting ? "Press delete again to confirm" : x.title,
32+
bg: isDeleting ? Theme.error : undefined,
2633
value: x.id,
2734
category,
2835
footer: Locale.time(x.time.updated),
@@ -39,6 +46,9 @@ export function DialogSessionList() {
3946
title="Sessions"
4047
options={options()}
4148
limit={50}
49+
onMove={() => {
50+
setToDelete(undefined)
51+
}}
4252
onSelect={(option) => {
4353
route.navigate({
4454
type: "session",
@@ -48,9 +58,20 @@ export function DialogSessionList() {
4858
}}
4959
keybind={[
5060
{
51-
keybind: Keybind.parse("del")[0],
61+
keybind: Keybind.parse("delete")[0],
5262
title: "delete",
53-
onTrigger: () => {},
63+
onTrigger: async (option) => {
64+
if (toDelete() === option.value) {
65+
sdk.session.delete({
66+
path: {
67+
id: option.value,
68+
},
69+
})
70+
setToDelete(undefined)
71+
return
72+
}
73+
setToDelete(option.value)
74+
},
5475
},
5576
]}
5677
/>

packages/opencode/src/cli/cmd/tui/context/sync.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
4444
case "todo.updated":
4545
setStore("todo", event.properties.sessionID, event.properties.todos)
4646
break
47+
case "session.deleted": {
48+
const result = Binary.search(store.session, event.properties.info.id, (s) => s.id)
49+
if (result.found) {
50+
setStore(
51+
"session",
52+
produce((draft) => {
53+
draft.splice(result.index, 1)
54+
}),
55+
)
56+
}
57+
break
58+
}
4759
case "session.updated":
4860
const result = Binary.search(store.session, event.properties.info.id, (s) => s.id)
4961
if (result.found) {

packages/opencode/src/cli/cmd/tui/ui/dialog-confirm.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useDialog, type DialogContext } from "./dialog"
44
import { createStore } from "solid-js/store"
55
import { For } from "solid-js"
66
import { useKeyboard } from "@opentui/solid"
7+
import { Locale } from "@/util/locale"
78

89
export type DialogConfirmProps = {
910
title: string
@@ -51,7 +52,7 @@ export function DialogConfirm(props: DialogConfirmProps) {
5152
dialog.clear()
5253
}}
5354
>
54-
<text fg={key === store.active ? Theme.background : Theme.textMuted}>{key}</text>
55+
<text fg={key === store.active ? Theme.background : Theme.textMuted}>{Locale.titlecase(key)}</text>
5556
</box>
5657
)}
5758
</For>

packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { Keybind } from "@/util/keybind"
1313
export interface DialogSelectProps<T> {
1414
title: string
1515
options: DialogSelectOption<T>[]
16+
onMove?: (option: DialogSelectOption<T>) => void
1617
onFilter?: (query: string) => void
1718
onSelect?: (option: DialogSelectOption<T>) => void
1819
keybind?: {
@@ -31,6 +32,7 @@ export interface DialogSelectOption<T = any> {
3132
footer?: string
3233
category?: string
3334
disabled?: boolean
35+
bg?: string
3436
onSelect?: (ctx: DialogContext) => void
3537
}
3638

@@ -87,6 +89,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
8789

8890
function moveTo(next: number) {
8991
setStore("selected", next)
92+
props.onMove?.(selected()!)
9093
const target = scroll.getChildren().find((child) => {
9194
return child.id === JSON.stringify(selected()?.value)
9295
})
@@ -117,7 +120,8 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
117120

118121
for (const item of props.keybind ?? []) {
119122
if (Keybind.match(item.keybind, keybind.parse(evt))) {
120-
item.onTrigger(selected())
123+
const s = selected()
124+
if (s) item.onTrigger(s)
121125
}
122126
}
123127
})
@@ -183,7 +187,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
183187
if (index === -1) return
184188
moveTo(index)
185189
}}
186-
backgroundColor={active() ? Theme.primary : RGBA.fromInts(0, 0, 0, 0)}
190+
backgroundColor={active() ? (option.bg ?? Theme.primary) : RGBA.fromInts(0, 0, 0, 0)}
187191
paddingLeft={1}
188192
paddingRight={1}
189193
>

packages/opencode/src/cli/cmd/tui/ui/dialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export function DialogProvider(props: ParentProps) {
124124
<box position="absolute">
125125
<For each={value.stack}>
126126
{(item, index) => (
127-
<Show when={index() === 0}>
127+
<Show when={index() === value.stack.length - 1}>
128128
<Dialog size={value.size}>{item.element}</Dialog>
129129
</Show>
130130
)}

packages/opencode/src/session/index.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,12 @@ export namespace Session {
242242
return result
243243
}
244244

245-
export async function remove(sessionID: string, emitEvent = true) {
245+
export async function remove(sessionID: string) {
246246
const project = Instance.project
247247
try {
248248
const session = await get(sessionID)
249249
for (const child of await children(sessionID)) {
250-
await remove(child.id, false)
250+
await remove(child.id)
251251
}
252252
await unshare(sessionID).catch(() => {})
253253
for (const msg of await Storage.list(["message", sessionID])) {
@@ -257,11 +257,9 @@ export namespace Session {
257257
await Storage.remove(msg)
258258
}
259259
await Storage.remove(["session", project.id, sessionID])
260-
if (emitEvent) {
261-
Bus.publish(Event.Deleted, {
262-
info: session,
263-
})
264-
}
260+
Bus.publish(Event.Deleted, {
261+
info: session,
262+
})
265263
} catch (e) {
266264
log.error(e)
267265
}

packages/sdk/js/src/gen/client/client.gen.ts

Lines changed: 68 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// This file is auto-generated by @hey-api/openapi-ts
22

33
import { createSseClient } from "../core/serverSentEvents.gen.js"
4+
import type { HttpMethod } from "../core/types.gen.js"
5+
import { getValidRequestBody } from "../core/utils.gen.js"
46
import type { Client, Config, RequestOptions, ResolvedRequestOptions } from "./types.gen.js"
57
import {
68
buildUrl,
@@ -49,12 +51,12 @@ export const createClient = (config: Config = {}): Client => {
4951
await opts.requestValidator(opts)
5052
}
5153

52-
if (opts.body && opts.bodySerializer) {
54+
if (opts.body !== undefined && opts.bodySerializer) {
5355
opts.serializedBody = opts.bodySerializer(opts.body)
5456
}
5557

5658
// remove Content-Type header if body is empty to avoid sending invalid requests
57-
if (opts.serializedBody === undefined || opts.serializedBody === "") {
59+
if (opts.body === undefined || opts.serializedBody === "") {
5860
opts.headers.delete("Content-Type")
5961
}
6062

@@ -69,7 +71,7 @@ export const createClient = (config: Config = {}): Client => {
6971
const requestInit: ReqInit = {
7072
redirect: "follow",
7173
...opts,
72-
body: opts.serializedBody,
74+
body: getValidRequestBody(opts),
7375
}
7476

7577
let request = new Request(url, requestInit)
@@ -97,18 +99,36 @@ export const createClient = (config: Config = {}): Client => {
9799
}
98100

99101
if (response.ok) {
102+
const parseAs =
103+
(opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json"
104+
100105
if (response.status === 204 || response.headers.get("Content-Length") === "0") {
106+
let emptyData: any
107+
switch (parseAs) {
108+
case "arrayBuffer":
109+
case "blob":
110+
case "text":
111+
emptyData = await response[parseAs]()
112+
break
113+
case "formData":
114+
emptyData = new FormData()
115+
break
116+
case "stream":
117+
emptyData = response.body
118+
break
119+
case "json":
120+
default:
121+
emptyData = {}
122+
break
123+
}
101124
return opts.responseStyle === "data"
102-
? {}
125+
? emptyData
103126
: {
104-
data: {},
127+
data: emptyData,
105128
...result,
106129
}
107130
}
108131

109-
const parseAs =
110-
(opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json"
111-
112132
let data: any
113133
switch (parseAs) {
114134
case "arrayBuffer":
@@ -178,35 +198,53 @@ export const createClient = (config: Config = {}): Client => {
178198
}
179199
}
180200

181-
const makeMethod = (method: Required<Config>["method"]) => {
182-
const fn = (options: RequestOptions) => request({ ...options, method })
183-
fn.sse = async (options: RequestOptions) => {
184-
const { opts, url } = await beforeRequest(options)
185-
return createSseClient({
186-
...opts,
187-
body: opts.body as BodyInit | null | undefined,
188-
headers: opts.headers as unknown as Record<string, string>,
189-
method,
190-
url,
191-
})
192-
}
193-
return fn
201+
const makeMethodFn = (method: Uppercase<HttpMethod>) => (options: RequestOptions) => request({ ...options, method })
202+
203+
const makeSseFn = (method: Uppercase<HttpMethod>) => async (options: RequestOptions) => {
204+
const { opts, url } = await beforeRequest(options)
205+
return createSseClient({
206+
...opts,
207+
body: opts.body as BodyInit | null | undefined,
208+
headers: opts.headers as unknown as Record<string, string>,
209+
method,
210+
onRequest: async (url, init) => {
211+
let request = new Request(url, init)
212+
for (const fn of interceptors.request._fns) {
213+
if (fn) {
214+
request = await fn(request, opts)
215+
}
216+
}
217+
return request
218+
},
219+
url,
220+
})
194221
}
195222

196223
return {
197224
buildUrl,
198-
connect: makeMethod("CONNECT"),
199-
delete: makeMethod("DELETE"),
200-
get: makeMethod("GET"),
225+
connect: makeMethodFn("CONNECT"),
226+
delete: makeMethodFn("DELETE"),
227+
get: makeMethodFn("GET"),
201228
getConfig,
202-
head: makeMethod("HEAD"),
229+
head: makeMethodFn("HEAD"),
203230
interceptors,
204-
options: makeMethod("OPTIONS"),
205-
patch: makeMethod("PATCH"),
206-
post: makeMethod("POST"),
207-
put: makeMethod("PUT"),
231+
options: makeMethodFn("OPTIONS"),
232+
patch: makeMethodFn("PATCH"),
233+
post: makeMethodFn("POST"),
234+
put: makeMethodFn("PUT"),
208235
request,
209236
setConfig,
210-
trace: makeMethod("TRACE"),
237+
sse: {
238+
connect: makeSseFn("CONNECT"),
239+
delete: makeSseFn("DELETE"),
240+
get: makeSseFn("GET"),
241+
head: makeSseFn("HEAD"),
242+
options: makeSseFn("OPTIONS"),
243+
patch: makeSseFn("PATCH"),
244+
post: makeSseFn("POST"),
245+
put: makeSseFn("PUT"),
246+
trace: makeSseFn("TRACE"),
247+
},
248+
trace: makeMethodFn("TRACE"),
211249
} as Client
212250
}

0 commit comments

Comments
 (0)