refactor(schema): apply session review decisions (#35793)

This commit is contained in:
Kit Langton 2026-07-07 22:10:11 -04:00 committed by GitHub
commit ed6ad272ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
142 changed files with 4239 additions and 3174 deletions

View file

@ -1,6 +1,6 @@
import { createMemo, createResource, createSignal, onMount } from "solid-js"
import path from "path"
import type { SessionV2Info } from "@opencode-ai/sdk/v2"
import type { SessionInfo } from "@opencode-ai/sdk/v2"
import { useDialog } from "../ui/dialog"
import { DialogSelect } from "../ui/dialog-select"
import { useRoute } from "../context/route"
@ -44,7 +44,7 @@ export function DialogSessionList() {
workspace: location.workspaceID,
})
// oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- generated client output is readonly; session list UI reuses legacy mutable session types.
return { query, sessions: structuredClone(response.data) as SessionV2Info[] }
return { query, sessions: structuredClone(response.data) as SessionInfo[] }
})
const currentSessionID = createMemo(() => (route.data.type === "session" ? route.data.sessionID : undefined))
@ -77,7 +77,7 @@ export function DialogSessionList() {
const pinnedSet = new Set(pinned)
const slotByID = new Map(local.session.slots().map((sessionID, index) => [sessionID, index + 1]))
const option = (session: SessionV2Info, category: string) => {
const option = (session: SessionInfo, category: string) => {
const directory = session.location.directory
const footer = directory !== project.data.project.mainDir ? Locale.truncate(path.basename(directory), 20) : ""
const slot = slotByID.get(session.id)
@ -88,12 +88,11 @@ export function DialogSessionList() {
category,
footer,
bg: deleting ? theme.error : undefined,
gutter:
data.session.family(session.id).some((id) => data.session.status(id) === "running")
? () => <Spinner />
: slot === undefined
? undefined
: () => <text fg={theme.accent}>{slot}</text>,
gutter: data.session.family(session.id).some((id) => data.session.status(id) === "running")
? () => <Spinner />
: slot === undefined
? undefined
: () => <text fg={theme.accent}>{slot}</text>,
}
}
@ -135,16 +134,14 @@ export function DialogSessionList() {
setToDelete(option.value)
return
}
void sdk.client.v2.session
.remove({ sessionID: option.value }, { throwOnError: true })
.catch((error) => {
setToDelete(undefined)
toast.show({
message: `Failed to delete session: ${errorMessage(error)}`,
variant: "error",
duration: 5000,
})
void sdk.client.v2.session.remove({ sessionID: option.value }, { throwOnError: true }).catch((error) => {
setToDelete(undefined)
toast.show({
message: `Failed to delete session: ${errorMessage(error)}`,
variant: "error",
duration: 5000,
})
})
},
},
{

View file

@ -45,10 +45,10 @@ export function DialogSkill(props: DialogSkillProps) {
return list.map((skill) => ({
title: skill.name.padEnd(maxWidth),
description: skill.description?.replace(/\s+/g, " ").trim(),
value: skill.name,
value: skill.id,
category: "Skills",
onSelect: () => {
props.onSelect(skill.name)
props.onSelect(skill.id)
dialog.clear()
},
}))

View file

@ -448,12 +448,12 @@ export function Autocomplete(props: {
for (const skill of data.location.skill
.list(location())
?.filter((skill) => skill.slash === true && !commandNames.has(skill.name)) ?? []) {
?.filter((skill) => skill.slash === true && !commandNames.has(skill.id)) ?? []) {
results.push({
display: "/" + skill.name,
display: "/" + skill.id,
description: skill.description,
onSelect: () => {
const newText = "/" + skill.name + " "
const newText = "/" + skill.id + " "
const cursor = props.input().logicalCursor
props.input().deleteRange(0, 0, cursor.row, cursor.col)
props.input().insertText(newText)

View file

@ -37,7 +37,7 @@ import { usePromptStash } from "../../prompt/stash"
import { DialogStash } from "../dialog-stash"
import { type AutocompleteRef, Autocomplete } from "./autocomplete"
import { useRenderer, useTerminalDimensions, type JSX } from "@opentui/solid"
import type { SessionV2Info, UserMessage } from "@opencode-ai/sdk/v2"
import type { SessionInfo, UserMessage } from "@opencode-ai/sdk/v2"
import { Locale } from "../../util/locale"
import { errorMessage } from "../../util/error"
import { createColors, createFrames } from "../../ui/spinner"
@ -165,9 +165,9 @@ export function Prompt(props: PromptProps) {
const status = createMemo(() => data.session.status(props.sessionID ?? ""))
const activeSubagents = createMemo(() => {
if (!props.sessionID) return 0
return data.session.family(props.sessionID).filter(
(id) => id !== props.sessionID && data.session.status(id) === "running",
).length
return data.session
.family(props.sessionID)
.filter((id) => id !== props.sessionID && data.session.status(id) === "running").length
})
const runningShells = createMemo(
() => data.shell.list(currentLocation()).filter((shell) => shell.metadata.sessionID === props.sessionID).length,
@ -1028,7 +1028,7 @@ export function Prompt(props: PromptProps) {
sessionID = created.id
// oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- generated client output is readonly; prompt state still uses legacy mutable session types.
session = structuredClone(created) as SessionV2Info
session = structuredClone(created) as SessionInfo
}
const inputText = expandTrackedPastedText(
@ -1099,7 +1099,7 @@ export function Prompt(props: PromptProps) {
} else if (
inputText.startsWith("/") &&
(data.location.skill.list(currentLocation()) ?? []).some(
(skill) => skill.slash === true && skill.name === inputText.split("\n")[0].split(" ")[0].slice(1),
(skill) => skill.slash === true && skill.id === inputText.split("\n")[0].split(" ")[0].slice(1),
)
) {
move.startSubmit()