Skip to content

Commit b562863

Browse files
authored
feat: add session.started event that triggers when a new session is created (#3413)
1 parent db85f01 commit b562863

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

packages/opencode/src/session/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ export namespace Session {
7878
export type ShareInfo = z.output<typeof ShareInfo>
7979

8080
export const Event = {
81+
Started: Bus.event(
82+
"session.started",
83+
z.object({
84+
info: Info,
85+
}),
86+
),
8187
Updated: Bus.event(
8288
"session.updated",
8389
z.object({
@@ -167,6 +173,9 @@ export namespace Session {
167173
}
168174
log.info("created", result)
169175
await Storage.write(["session", Instance.project.id, result.id], result)
176+
Bus.publish(Event.Started, {
177+
info: result,
178+
})
170179
const cfg = await Config.get()
171180
if (!result.parentID && (Flag.OPENCODE_AUTO_SHARE || cfg.share === "auto"))
172181
share(result.id)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { describe, expect, test } from "bun:test"
2+
import path from "path"
3+
import { Session } from "../../src/session"
4+
import { Bus } from "../../src/bus"
5+
import { Log } from "../../src/util/log"
6+
import { Instance } from "../../src/project/instance"
7+
8+
const projectRoot = path.join(__dirname, "../..")
9+
Log.init({ print: false })
10+
11+
describe("session.started event", () => {
12+
test("should emit session.started event when session is created", async () => {
13+
await Instance.provide({
14+
directory: projectRoot,
15+
fn: async () => {
16+
let eventReceived = false
17+
let receivedInfo: Session.Info | undefined
18+
19+
const unsub = Bus.subscribe(Session.Event.Started, (event) => {
20+
eventReceived = true
21+
receivedInfo = event.properties.info as Session.Info
22+
})
23+
24+
const session = await Session.create({})
25+
26+
await new Promise((resolve) => setTimeout(resolve, 100))
27+
28+
unsub()
29+
30+
expect(eventReceived).toBe(true)
31+
expect(receivedInfo).toBeDefined()
32+
expect(receivedInfo?.id).toBe(session.id)
33+
expect(receivedInfo?.projectID).toBe(session.projectID)
34+
expect(receivedInfo?.directory).toBe(session.directory)
35+
expect(receivedInfo?.title).toBe(session.title)
36+
37+
await Session.remove(session.id)
38+
},
39+
})
40+
})
41+
42+
test("session.started event should be emitted before session.updated", async () => {
43+
await Instance.provide({
44+
directory: projectRoot,
45+
fn: async () => {
46+
const events: string[] = []
47+
48+
const unsubStarted = Bus.subscribe(Session.Event.Started, () => {
49+
events.push("started")
50+
})
51+
52+
const unsubUpdated = Bus.subscribe(Session.Event.Updated, () => {
53+
events.push("updated")
54+
})
55+
56+
const session = await Session.create({})
57+
58+
await new Promise((resolve) => setTimeout(resolve, 100))
59+
60+
unsubStarted()
61+
unsubUpdated()
62+
63+
expect(events).toContain("started")
64+
expect(events).toContain("updated")
65+
expect(events.indexOf("started")).toBeLessThan(events.indexOf("updated"))
66+
67+
await Session.remove(session.id)
68+
},
69+
})
70+
})
71+
})

0 commit comments

Comments
 (0)