diff options
| author | Adam <[email protected]> | 2026-02-12 09:49:14 -0600 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-02-12 09:49:14 -0600 |
| commit | ff4414bb152acfddb5c0eb073c38bedc1df4ae14 (patch) | |
| tree | 78381c67d21ef6f089647f6b19e7aa2976840dbc /packages/app/src/context/prompt.tsx | |
| parent | 56ad2db02055955f926fda0e4a89055b22ead6f9 (diff) | |
| download | opencode-ff4414bb152acfddb5c0eb073c38bedc1df4ae14.tar.gz opencode-ff4414bb152acfddb5c0eb073c38bedc1df4ae14.zip | |
chore: refactor packages/app files (#13236)
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Frank <[email protected]>
Diffstat (limited to 'packages/app/src/context/prompt.tsx')
| -rw-r--r-- | packages/app/src/context/prompt.tsx | 109 |
1 files changed, 61 insertions, 48 deletions
diff --git a/packages/app/src/context/prompt.tsx b/packages/app/src/context/prompt.tsx index 99fab6c19..064892105 100644 --- a/packages/app/src/context/prompt.tsx +++ b/packages/app/src/context/prompt.tsx @@ -1,4 +1,4 @@ -import { createStore } from "solid-js/store" +import { createStore, type SetStoreFunction } from "solid-js/store" import { createSimpleContext } from "@opencode-ai/ui/context" import { batch, createMemo, createRoot, onCleanup } from "solid-js" import { useParams } from "@solidjs/router" @@ -60,27 +60,23 @@ function isSelectionEqual(a?: FileSelection, b?: FileSelection) { ) } +function isPartEqual(partA: ContentPart, partB: ContentPart) { + switch (partA.type) { + case "text": + return partB.type === "text" && partA.content === partB.content + case "file": + return partB.type === "file" && partA.path === partB.path && isSelectionEqual(partA.selection, partB.selection) + case "agent": + return partB.type === "agent" && partA.name === partB.name + case "image": + return partB.type === "image" && partA.id === partB.id + } +} + export function isPromptEqual(promptA: Prompt, promptB: Prompt): boolean { if (promptA.length !== promptB.length) return false for (let i = 0; i < promptA.length; i++) { - const partA = promptA[i] - const partB = promptB[i] - if (partA.type !== partB.type) return false - if (partA.type === "text" && partA.content !== (partB as TextPart).content) { - return false - } - if (partA.type === "file") { - const fileA = partA as FileAttachmentPart - const fileB = partB as FileAttachmentPart - if (fileA.path !== fileB.path) return false - if (!isSelectionEqual(fileA.selection, fileB.selection)) return false - } - if (partA.type === "agent" && partA.name !== (partB as AgentPart).name) { - return false - } - if (partA.type === "image" && partA.id !== (partB as ImageAttachmentPart).id) { - return false - } + if (!isPartEqual(promptA[i], promptB[i])) return false } return true } @@ -104,6 +100,48 @@ function clonePrompt(prompt: Prompt): Prompt { return prompt.map(clonePart) } +function contextItemKey(item: ContextItem) { + if (item.type !== "file") return item.type + const start = item.selection?.startLine + const end = item.selection?.endLine + const key = `${item.type}:${item.path}:${start}:${end}` + + if (item.commentID) { + return `${key}:c=${item.commentID}` + } + + const comment = item.comment?.trim() + if (!comment) return key + const digest = checksum(comment) ?? comment + return `${key}:c=${digest.slice(0, 8)}` +} + +function createPromptActions( + setStore: SetStoreFunction<{ + prompt: Prompt + cursor?: number + context: { + items: (ContextItem & { key: string })[] + } + }>, +) { + return { + set(prompt: Prompt, cursorPosition?: number) { + const next = clonePrompt(prompt) + batch(() => { + setStore("prompt", next) + if (cursorPosition !== undefined) setStore("cursor", cursorPosition) + }) + }, + reset() { + batch(() => { + setStore("prompt", clonePrompt(DEFAULT_PROMPT)) + setStore("cursor", 0) + }) + }, + } +} + const WORKSPACE_KEY = "__workspace__" const MAX_PROMPT_SESSIONS = 20 @@ -134,21 +172,7 @@ function createPromptSession(dir: string, id: string | undefined) { }), ) - function keyForItem(item: ContextItem) { - if (item.type !== "file") return item.type - const start = item.selection?.startLine - const end = item.selection?.endLine - const key = `${item.type}:${item.path}:${start}:${end}` - - if (item.commentID) { - return `${key}:c=${item.commentID}` - } - - const comment = item.comment?.trim() - if (!comment) return key - const digest = checksum(comment) ?? comment - return `${key}:c=${digest.slice(0, 8)}` - } + const actions = createPromptActions(setStore) return { ready, @@ -158,7 +182,7 @@ function createPromptSession(dir: string, id: string | undefined) { context: { items: createMemo(() => store.context.items), add(item: ContextItem) { - const key = keyForItem(item) + const key = contextItemKey(item) if (store.context.items.find((x) => x.key === key)) return setStore("context", "items", (items) => [...items, { key, ...item }]) }, @@ -166,19 +190,8 @@ function createPromptSession(dir: string, id: string | undefined) { setStore("context", "items", (items) => items.filter((x) => x.key !== key)) }, }, - set(prompt: Prompt, cursorPosition?: number) { - const next = clonePrompt(prompt) - batch(() => { - setStore("prompt", next) - if (cursorPosition !== undefined) setStore("cursor", cursorPosition) - }) - }, - reset() { - batch(() => { - setStore("prompt", clonePrompt(DEFAULT_PROMPT)) - setStore("cursor", 0) - }) - }, + set: actions.set, + reset: actions.reset, } } |
