summaryrefslogtreecommitdiffhomepage
path: root/packages/desktop/src/context
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-11-06 15:13:02 -0600
committerAdam <[email protected]>2025-11-06 15:13:06 -0600
commit96c57418f39bbf10e4538a6e0652baff7f0932fb (patch)
tree7709020729579f1ec84ce230726504a810d01421 /packages/desktop/src/context
parentb8c51e307f1e26c4cbc962fca742338fba3c9fe9 (diff)
downloadopencode-96c57418f39bbf10e4538a6e0652baff7f0932fb.tar.gz
opencode-96c57418f39bbf10e4538a6e0652baff7f0932fb.zip
feat(desktop): review flow
Diffstat (limited to 'packages/desktop/src/context')
-rw-r--r--packages/desktop/src/context/local.tsx17
-rw-r--r--packages/desktop/src/context/session.tsx8
-rw-r--r--packages/desktop/src/context/sync.tsx59
3 files changed, 66 insertions, 18 deletions
diff --git a/packages/desktop/src/context/local.tsx b/packages/desktop/src/context/local.tsx
index 9dacc7100..1785bdf0c 100644
--- a/packages/desktop/src/context/local.tsx
+++ b/packages/desktop/src/context/local.tsx
@@ -464,9 +464,12 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
opened: true,
width: 240,
},
+ review: {
+ state: "closed" as "open" | "closed" | "tab",
+ },
}),
{
- name: "layout",
+ name: "default-layout",
},
)
@@ -487,6 +490,18 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
setStore("sidebar", "width", width)
},
},
+ review: {
+ state: createMemo(() => store.review?.state ?? "closed"),
+ open() {
+ setStore("review", "state", "open")
+ },
+ close() {
+ setStore("review", "state", "closed")
+ },
+ tab() {
+ setStore("review", "state", "tab")
+ },
+ },
}
})()
diff --git a/packages/desktop/src/context/session.tsx b/packages/desktop/src/context/session.tsx
index 77ab3bc25..61fed945e 100644
--- a/packages/desktop/src/context/session.tsx
+++ b/packages/desktop/src/context/session.tsx
@@ -80,6 +80,7 @@ export const { use: useSession, provider: SessionProvider } = createSimpleContex
const model = createMemo(() =>
last() ? sync.data.provider.find((x) => x.id === last().providerID)?.models[last().modelID] : undefined,
)
+ const diffs = createMemo(() => (props.sessionId ? (sync.data.session_diff[props.sessionId] ?? []) : []))
const tokens = createMemo(() => {
if (!last()) return
@@ -98,6 +99,7 @@ export const { use: useSession, provider: SessionProvider } = createSimpleContex
id: props.sessionId,
info,
working,
+ diffs,
prompt: {
current: createMemo(() => store.prompt),
cursor: createMemo(() => store.cursorPosition),
@@ -139,8 +141,10 @@ export const { use: useSession, provider: SessionProvider } = createSimpleContex
if (tab.startsWith("file://")) {
await local.file.open(tab.replace("file://", ""))
}
- if (!store.tabs.opened.includes(tab)) {
- setStore("tabs", "opened", [...store.tabs.opened, tab])
+ if (tab !== "review") {
+ if (!store.tabs.opened.includes(tab)) {
+ setStore("tabs", "opened", [...store.tabs.opened, tab])
+ }
}
setStore("tabs", "active", tab)
},
diff --git a/packages/desktop/src/context/sync.tsx b/packages/desktop/src/context/sync.tsx
index 1e960397b..c5b169a38 100644
--- a/packages/desktop/src/context/sync.tsx
+++ b/packages/desktop/src/context/sync.tsx
@@ -1,4 +1,17 @@
-import type { Message, Agent, Provider, Session, Part, Config, Path, File, FileNode, Project } from "@opencode-ai/sdk"
+import type {
+ Message,
+ Agent,
+ Provider,
+ Session,
+ Part,
+ Config,
+ Path,
+ File,
+ FileNode,
+ Project,
+ FileDiff,
+ Todo,
+} from "@opencode-ai/sdk"
import { createStore, produce, reconcile } from "solid-js/store"
import { createMemo } from "solid-js"
import { Binary } from "@/utils/binary"
@@ -16,8 +29,13 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
config: Config
path: Path
session: Session[]
+ session_diff: {
+ [sessionID: string]: FileDiff[]
+ }
+ todo: {
+ [sessionID: string]: Todo[]
+ }
limit: number
- more: boolean
message: {
[sessionID: string]: Message[]
}
@@ -34,8 +52,9 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
agent: [],
provider: [],
session: [],
+ session_diff: {},
+ todo: {},
limit: 10,
- more: false,
message: {},
part: {},
node: [],
@@ -60,6 +79,12 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
)
break
}
+ case "session.diff":
+ setStore("session_diff", event.properties.sessionID, event.properties.diff)
+ break
+ case "todo.updated":
+ setStore("todo", event.properties.sessionID, event.properties.todos)
+ break
case "message.updated": {
const messages = store.message[event.properties.info.sessionID]
if (!messages) {
@@ -116,7 +141,6 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
.sort((a, b) => a.id.localeCompare(b.id))
.slice(0, store.limit)
setStore("session", sessions)
- setStore("more", sessions.length === store.limit)
}),
config: () => sdk.client.config.get().then((x) => setStore("config", x.data!)),
changes: () => sdk.client.file.status().then((x) => setStore("changes", x.data!)),
@@ -161,22 +185,19 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
if (match.found) return store.session[match.index]
return undefined
},
- async sync(sessionID: string, isRetry = false) {
- const [session, messages] = await Promise.all([
- sdk.client.session.get({ path: { id: sessionID } }),
+ async sync(sessionID: string, _isRetry = false) {
+ const [session, messages, todo, diff] = await Promise.all([
+ sdk.client.session.get({ path: { id: sessionID }, throwOnError: true }),
sdk.client.session.messages({ path: { id: sessionID } }),
+ sdk.client.session.todo({ path: { id: sessionID } }),
+ sdk.client.session.diff({ path: { id: sessionID } }),
])
-
- // If no messages and this might be a new session, retry after a delay
- if (!isRetry && messages.data!.length === 0) {
- setTimeout(() => this.sync(sessionID, true), 500)
- return
- }
-
setStore(
produce((draft) => {
const match = Binary.search(draft.session, sessionID, (s) => s.id)
- draft.session[match.index] = session.data!
+ if (match.found) draft.session[match.index] = session.data!
+ if (!match.found) draft.session.splice(match.index, 0, session.data!)
+ draft.todo[sessionID] = todo.data ?? []
draft.message[sessionID] = messages
.data!.map((x) => x.info)
.slice()
@@ -187,13 +208,21 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
.map(sanitizePart)
.sort((a, b) => a.id.localeCompare(b.id))
}
+ draft.session_diff[sessionID] = diff.data ?? []
}),
)
+
+ // If no messages and this might be a new session, retry after a delay
+ // if (!isRetry && messages.data!.length === 0) {
+ // setTimeout(() => this.sync(sessionID, true), 500)
+ // return
+ // }
},
fetch: async (count = 10) => {
setStore("limit", (x) => x + count)
await load.session()
},
+ more: createMemo(() => store.session.length === store.limit),
},
load,
absolute,