mirror of
https://github.com/sst/opencode.git
synced 2025-12-23 10:11:41 +00:00
tui: refactor command system and add session management commands
This commit is contained in:
parent
127241d53f
commit
3d80e36549
5 changed files with 51 additions and 45 deletions
|
|
@ -16,16 +16,25 @@ const ctx = createContext<Context>()
|
|||
|
||||
function init() {
|
||||
const [registrations, setRegistrations] = createSignal<Accessor<DialogSelectOption[]>[]>([])
|
||||
const dialog = useDialog()
|
||||
const options = createMemo(() => {
|
||||
return registrations().flatMap((x) => x())
|
||||
})
|
||||
|
||||
return {
|
||||
trigger(name: string) {
|
||||
for (const option of options()) {
|
||||
if (option.value === name) {
|
||||
option.onSelect?.(dialog)
|
||||
return
|
||||
}
|
||||
}
|
||||
},
|
||||
register(cb: () => DialogSelectOption[]) {
|
||||
const results = createMemo(cb)
|
||||
setRegistrations((x) => [...x, results])
|
||||
setRegistrations((arr) => [results, ...arr])
|
||||
onCleanup(() => {
|
||||
setRegistrations((x) => x.filter((x) => x !== results))
|
||||
setRegistrations((arr) => arr.filter((x) => x !== results))
|
||||
})
|
||||
},
|
||||
get options() {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import type { FilePart } from "@opencode-ai/sdk"
|
|||
import fuzzysort from "fuzzysort"
|
||||
import { DialogModel } from "./dialog-model"
|
||||
import { DialogAgent } from "./dialog-agent"
|
||||
import { useCommandDialog } from "./dialog-command"
|
||||
|
||||
export type PromptProps = {
|
||||
sessionID?: string
|
||||
|
|
@ -254,6 +255,7 @@ function Autocomplete(props: {
|
|||
const sdk = useSDK()
|
||||
const local = useLocal()
|
||||
const sync = useSync()
|
||||
const command = useCommandDialog()
|
||||
|
||||
const [store, setStore] = createStore({
|
||||
index: 0,
|
||||
|
|
@ -310,12 +312,10 @@ function Autocomplete(props: {
|
|||
},
|
||||
)
|
||||
|
||||
const route = useRoute()
|
||||
const session = createMemo(() => (props.sessionID ? sync.session.get(props.sessionID) : undefined))
|
||||
const commands = createMemo((): AutocompleteOption[] => {
|
||||
const results: AutocompleteOption[] = []
|
||||
const s = session()
|
||||
const dialog = useDialog()
|
||||
for (const command of sync.data.command) {
|
||||
results.push({
|
||||
display: "/" + command.name,
|
||||
|
|
@ -341,41 +341,19 @@ function Autocomplete(props: {
|
|||
{
|
||||
display: "/compact",
|
||||
description: "compact the session",
|
||||
onSelect: () => {
|
||||
sdk.session.summarize({
|
||||
path: {
|
||||
id: s.id,
|
||||
},
|
||||
body: {
|
||||
modelID: local.model.current().modelID,
|
||||
providerID: local.model.current().providerID,
|
||||
},
|
||||
})
|
||||
},
|
||||
onSelect: () => command.trigger("session.compact"),
|
||||
},
|
||||
{
|
||||
display: "/share",
|
||||
disabled: !!s.share?.url,
|
||||
description: "share a session",
|
||||
onSelect: () => {
|
||||
sdk.session.share({
|
||||
path: {
|
||||
id: s.id,
|
||||
},
|
||||
})
|
||||
},
|
||||
onSelect: () => command.trigger("session.share"),
|
||||
},
|
||||
{
|
||||
display: "/unshare",
|
||||
disabled: !s.share,
|
||||
description: "unshare a session",
|
||||
onSelect: () => {
|
||||
sdk.session.unshare({
|
||||
path: {
|
||||
id: s.id,
|
||||
},
|
||||
})
|
||||
},
|
||||
onSelect: () => command.trigger("session.unshare"),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -383,25 +361,17 @@ function Autocomplete(props: {
|
|||
{
|
||||
display: "/new",
|
||||
description: "create a new session",
|
||||
onSelect: () => {
|
||||
route.navigate({
|
||||
type: "home",
|
||||
})
|
||||
},
|
||||
onSelect: () => command.trigger("session.new"),
|
||||
},
|
||||
{
|
||||
display: "/models",
|
||||
description: "list models",
|
||||
onSelect: () => {
|
||||
dialog.replace(() => <DialogModel />)
|
||||
},
|
||||
onSelect: () => command.trigger("model.list"),
|
||||
},
|
||||
{
|
||||
display: "/agents",
|
||||
description: "list agents",
|
||||
onSelect: () => {
|
||||
dialog.replace(() => <DialogAgent />)
|
||||
},
|
||||
onSelect: () => command.trigger("agent.list"),
|
||||
},
|
||||
)
|
||||
const max = firstBy(results, [(x) => x.display.length, "desc"])?.display.length
|
||||
|
|
|
|||
|
|
@ -49,8 +49,27 @@ export function Session() {
|
|||
})
|
||||
})
|
||||
|
||||
const local = useLocal()
|
||||
|
||||
const command = useCommandDialog()
|
||||
command.register(() => [
|
||||
{
|
||||
title: "Compact session",
|
||||
value: "session.compact",
|
||||
category: "Session",
|
||||
onSelect: (dialog) => {
|
||||
sdk.session.summarize({
|
||||
path: {
|
||||
id: route.sessionID,
|
||||
},
|
||||
body: {
|
||||
modelID: local.model.current().modelID,
|
||||
providerID: local.model.current().providerID,
|
||||
},
|
||||
})
|
||||
dialog.clear()
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Share session",
|
||||
value: "session.share",
|
||||
|
|
@ -79,6 +98,12 @@ export function Session() {
|
|||
dialog.clear()
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Rename session",
|
||||
value: "session.rename",
|
||||
category: "Session",
|
||||
onSelect: () => {},
|
||||
},
|
||||
])
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ function App() {
|
|||
command.register(() => [
|
||||
{
|
||||
title: "Switch session",
|
||||
value: "switch-session",
|
||||
value: "session.list",
|
||||
category: "Session",
|
||||
onSelect: () => {
|
||||
dialog.replace(() => <DialogSessionList />)
|
||||
|
|
@ -145,7 +145,7 @@ function App() {
|
|||
},
|
||||
{
|
||||
title: "New session",
|
||||
value: "new-session",
|
||||
value: "session.new",
|
||||
category: "Session",
|
||||
onSelect: () => {
|
||||
route.navigate({
|
||||
|
|
@ -156,7 +156,7 @@ function App() {
|
|||
},
|
||||
{
|
||||
title: "Switch model",
|
||||
value: "switch-model",
|
||||
value: "model.list",
|
||||
category: "Agent",
|
||||
onSelect: () => {
|
||||
dialog.replace(() => <DialogModel />)
|
||||
|
|
@ -164,7 +164,7 @@ function App() {
|
|||
},
|
||||
{
|
||||
title: "Switch agent",
|
||||
value: "switch-agent",
|
||||
value: "agent.list",
|
||||
category: "Agent",
|
||||
onSelect: () => {
|
||||
dialog.replace(() => <DialogAgent />)
|
||||
|
|
|
|||
|
|
@ -155,7 +155,8 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|||
)}
|
||||
</For>
|
||||
</scrollbox>
|
||||
<box paddingRight={2} paddingLeft={3} paddingBottom={1} flexDirection="row">
|
||||
<box paddingRight={2} paddingLeft={3} flexDirection="row">
|
||||
{/*
|
||||
<text fg={Theme.text} attributes={TextAttributes.BOLD}>
|
||||
n
|
||||
</text>
|
||||
|
|
@ -164,6 +165,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|||
{" "}r
|
||||
</text>
|
||||
<text fg={Theme.textMuted}> rename</text>
|
||||
*/}
|
||||
</box>
|
||||
</box>
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue