Skip to content
Merged
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
31 changes: 19 additions & 12 deletions packages/app/src/context/prompt.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createSimpleContext } from "@opencode-ai/ui/context"
import { checksum } from "@opencode-ai/core/util/encode"
import { useParams } from "@solidjs/router"
import { useParams, useSearchParams } from "@solidjs/router"
import { batch, createMemo, createRoot, getOwner, onCleanup } from "solid-js"
import { createStore, type SetStoreFunction } from "solid-js/store"
import type { FileSelection } from "@/context/file"
Expand Down Expand Up @@ -153,21 +153,27 @@ const MAX_PROMPT_SESSIONS = 20

type PromptSession = ReturnType<typeof createPromptSession>

type Scope = {
dir: string
id?: string
type Scope = { draftID: string } | { dir: string; id?: string }

function scopeKey(scope: Scope) {
if ("draftID" in scope) return `draft:${scope.draftID}`
return `${scope.dir}:${scope.id ?? WORKSPACE_KEY}`
}

type PromptCacheEntry = {
value: PromptSession
dispose: VoidFunction
}

function createPromptSession(scope: ServerScope, dir: string, id: string | undefined) {
const legacy = `${dir}/prompt${id ? "/" + id : ""}.v2`
function promptTarget(serverScope: ServerScope, scope: Scope) {
if ("draftID" in scope) return Persist.draft(scope.draftID, "prompt")
const legacy = `${scope.dir}/prompt${scope.id ? "/" + scope.id : ""}.v2`
return Persist.serverScoped(serverScope, scope.dir, scope.id, "prompt", [legacy])
}

function createPromptSession(serverScope: ServerScope, scope: Scope) {
const [store, setStore, _, ready] = persisted(
Persist.serverScoped(scope, dir, id, "prompt", [legacy]),
promptTarget(serverScope, scope),
createStore<{
prompt: Prompt
cursor?: number
Expand Down Expand Up @@ -231,6 +237,7 @@ export const { use: usePrompt, provider: PromptProvider } = createSimpleContext(
gate: false,
init: () => {
const params = useParams()
const [search] = useSearchParams<{ draftId?: string }>()
const serverSDK = useServerSDK()
const cache = new Map<string, PromptCacheEntry>()

Expand All @@ -254,8 +261,8 @@ export const { use: usePrompt, provider: PromptProvider } = createSimpleContext(
}

const owner = getOwner()
const load = (dir: string, id: string | undefined) => {
const key = `${dir}:${id ?? WORKSPACE_KEY}`
const load = (scope: Scope) => {
const key = scopeKey(scope)
const existing = cache.get(key)
if (existing) {
cache.delete(key)
Expand All @@ -265,7 +272,7 @@ export const { use: usePrompt, provider: PromptProvider } = createSimpleContext(

const entry = createRoot(
(dispose) => ({
value: createPromptSession(serverSDK.scope, dir, id),
value: createPromptSession(serverSDK.scope, scope),
dispose,
}),
owner,
Expand All @@ -276,8 +283,8 @@ export const { use: usePrompt, provider: PromptProvider } = createSimpleContext(
return entry.value
}

const session = createMemo(() => load(params.dir!, params.id))
const pick = (scope?: Scope) => (scope ? load(scope.dir, scope.id) : session())
const session = createMemo(() => load(search.draftId ? { draftID: search.draftId } : { dir: params.dir!, id: params.id }))
const pick = (scope?: Scope) => (scope ? load(scope) : session())

return {
ready: () => session().ready,
Expand Down
Loading