summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/testing
diff options
context:
space:
mode:
authorLuke Parker <[email protected]>2026-03-13 12:21:50 +1000
committerGitHub <[email protected]>2026-03-13 12:21:50 +1000
commit96b1d8f639991e896bc8d31afe64d6309bf3ccd2 (patch)
treed51a398a9e13046b634a5cbe517f5ecbe72db765 /packages/app/src/testing
parentdcb17c6a678918ce0786640729fcc8cd8adb1746 (diff)
downloadopencode-96b1d8f639991e896bc8d31afe64d6309bf3ccd2.tar.gz
opencode-96b1d8f639991e896bc8d31afe64d6309bf3ccd2.zip
fix(app): stabilize todo dock e2e with composer probe (#17267)
Diffstat (limited to 'packages/app/src/testing')
-rw-r--r--packages/app/src/testing/session-composer.ts84
1 files changed, 84 insertions, 0 deletions
diff --git a/packages/app/src/testing/session-composer.ts b/packages/app/src/testing/session-composer.ts
new file mode 100644
index 000000000..01c809e4c
--- /dev/null
+++ b/packages/app/src/testing/session-composer.ts
@@ -0,0 +1,84 @@
+import type { Todo } from "@opencode-ai/sdk/v2"
+
+export const composerEvent = "opencode:e2e:composer"
+
+export type ComposerDriverState = {
+ live?: boolean
+ todos?: Array<Pick<Todo, "content" | "status" | "priority">>
+}
+
+export type ComposerProbeState = {
+ mounted: boolean
+ collapsed: boolean
+ hidden: boolean
+ count: number
+ states: Todo["status"][]
+}
+
+type ComposerState = {
+ driver?: ComposerDriverState
+ probe?: ComposerProbeState
+}
+
+export type ComposerWindow = Window & {
+ __opencode_e2e?: {
+ composer?: {
+ enabled?: boolean
+ sessions?: Record<string, ComposerState>
+ }
+ }
+}
+
+const clone = (driver: ComposerDriverState) => ({
+ live: driver.live,
+ todos: driver.todos?.map((todo) => ({ ...todo })),
+})
+
+export const composerEnabled = () => {
+ if (typeof window === "undefined") return false
+ return (window as ComposerWindow).__opencode_e2e?.composer?.enabled === true
+}
+
+const root = () => {
+ if (!composerEnabled()) return
+ const state = (window as ComposerWindow).__opencode_e2e?.composer
+ if (!state) return
+ state.sessions ??= {}
+ return state.sessions
+}
+
+export const composerDriver = (sessionID?: string) => {
+ if (!sessionID) return
+ const state = root()?.[sessionID]?.driver
+ if (!state) return
+ return clone(state)
+}
+
+export const composerProbe = (sessionID?: string) => {
+ const set = (next: ComposerProbeState) => {
+ if (!sessionID) return
+ const sessions = root()
+ if (!sessions) return
+ const prev = sessions[sessionID] ?? {}
+ sessions[sessionID] = {
+ ...prev,
+ probe: {
+ ...next,
+ states: [...next.states],
+ },
+ }
+ }
+
+ return {
+ set,
+ drop() {
+ set({
+ mounted: false,
+ collapsed: false,
+ hidden: true,
+ count: 0,
+ states: [],
+ })
+ },
+ }
+}