pi-studio-opencode 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/ARCHITECTURE.md +122 -0
  2. package/LICENSE +21 -0
  3. package/README.md +108 -0
  4. package/dist/demo-host-pi.d.ts +1 -0
  5. package/dist/demo-host-pi.js +71 -0
  6. package/dist/demo-host-pi.js.map +1 -0
  7. package/dist/demo-host.d.ts +1 -0
  8. package/dist/demo-host.js +154 -0
  9. package/dist/demo-host.js.map +1 -0
  10. package/dist/host-opencode-plugin.d.ts +52 -0
  11. package/dist/host-opencode-plugin.js +396 -0
  12. package/dist/host-opencode-plugin.js.map +1 -0
  13. package/dist/host-opencode.d.ts +154 -0
  14. package/dist/host-opencode.js +627 -0
  15. package/dist/host-opencode.js.map +1 -0
  16. package/dist/host-pi.d.ts +45 -0
  17. package/dist/host-pi.js +258 -0
  18. package/dist/host-pi.js.map +1 -0
  19. package/dist/install-config.d.ts +36 -0
  20. package/dist/install-config.js +136 -0
  21. package/dist/install-config.js.map +1 -0
  22. package/dist/install.d.ts +16 -0
  23. package/dist/install.js +168 -0
  24. package/dist/install.js.map +1 -0
  25. package/dist/launcher.d.ts +2 -0
  26. package/dist/launcher.js +124 -0
  27. package/dist/launcher.js.map +1 -0
  28. package/dist/main.d.ts +1 -0
  29. package/dist/main.js +732 -0
  30. package/dist/main.js.map +1 -0
  31. package/dist/mock-pi-session.d.ts +27 -0
  32. package/dist/mock-pi-session.js +138 -0
  33. package/dist/mock-pi-session.js.map +1 -0
  34. package/dist/open-browser.d.ts +1 -0
  35. package/dist/open-browser.js +29 -0
  36. package/dist/open-browser.js.map +1 -0
  37. package/dist/opencode-plugin.d.ts +3 -0
  38. package/dist/opencode-plugin.js +326 -0
  39. package/dist/opencode-plugin.js.map +1 -0
  40. package/dist/prototype-pdf.d.ts +12 -0
  41. package/dist/prototype-pdf.js +991 -0
  42. package/dist/prototype-pdf.js.map +1 -0
  43. package/dist/prototype-server.d.ts +88 -0
  44. package/dist/prototype-server.js +1002 -0
  45. package/dist/prototype-server.js.map +1 -0
  46. package/dist/prototype-theme.d.ts +36 -0
  47. package/dist/prototype-theme.js +1471 -0
  48. package/dist/prototype-theme.js.map +1 -0
  49. package/dist/studio-core.d.ts +63 -0
  50. package/dist/studio-core.js +251 -0
  51. package/dist/studio-core.js.map +1 -0
  52. package/dist/studio-host-types.d.ts +50 -0
  53. package/dist/studio-host-types.js +14 -0
  54. package/dist/studio-host-types.js.map +1 -0
  55. package/examples/opencode/INSTALL.md +67 -0
  56. package/examples/opencode/opencode.local-path.jsonc +16 -0
  57. package/package.json +68 -0
  58. package/static/prototype.css +1277 -0
  59. package/static/prototype.html +173 -0
  60. package/static/prototype.js +3198 -0
@@ -0,0 +1,396 @@
1
+ import { setTimeout as sleep } from "node:timers/promises";
2
+ import { collectObservedAssistantResponsesForUser, collectObservedExternalResponses, eventSessionId, extractAssistantPartText, extractMessageTokenUsage, extractMessageVariant, isMessagePartDeltaEvent, normalizeSessionMessageRecord, selectLatestObservedAssistantResponse, sortObservedMessages, summarizeEvent, } from "./host-opencode.js";
3
+ import { StudioCore } from "./studio-core.js";
4
+ const OPENCODE_PLUGIN_HOST_CAPABILITIES = {
5
+ steeringMode: "adapter-queue",
6
+ stopSupported: true,
7
+ };
8
+ export class PluginBackedOpencodeStudioHost {
9
+ options;
10
+ listeners = new Set();
11
+ baselineMessageIds = new Set();
12
+ matchedUserIds = new Set();
13
+ matchedAssistantIds = new Set();
14
+ partTypesById = new Map();
15
+ messageRolesById = new Map();
16
+ core = new StudioCore({ backend: "opencode" });
17
+ client;
18
+ session;
19
+ handlingIdle = false;
20
+ closed = false;
21
+ static async create(options) {
22
+ const host = new PluginBackedOpencodeStudioHost(options);
23
+ await host.initialize();
24
+ return host;
25
+ }
26
+ constructor(options) {
27
+ this.options = options;
28
+ this.client = options.client;
29
+ }
30
+ getState() {
31
+ return this.core.getState();
32
+ }
33
+ getCapabilities() {
34
+ return { ...OPENCODE_PLUGIN_HOST_CAPABILITIES };
35
+ }
36
+ getHistory() {
37
+ return this.core.getHistory();
38
+ }
39
+ subscribe(listener) {
40
+ this.listeners.add(listener);
41
+ listener(this.getState());
42
+ return () => {
43
+ this.listeners.delete(listener);
44
+ };
45
+ }
46
+ async startRun(prompt) {
47
+ this.assertReady();
48
+ const submission = this.core.startRun(prompt);
49
+ this.emitState();
50
+ await this.dispatchSubmission(submission);
51
+ }
52
+ async queueSteer(prompt) {
53
+ this.assertReady();
54
+ this.core.queueSteer(prompt);
55
+ this.emitState();
56
+ }
57
+ async stop() {
58
+ this.assertReady();
59
+ const active = this.core.getActiveSubmission();
60
+ if (!active)
61
+ return;
62
+ this.core.markStopRequested({ clearQueuedSteers: true, backendStatus: "aborting" });
63
+ this.emitState();
64
+ await this.client.session.abort({
65
+ path: { id: this.session.id },
66
+ query: { directory: this.options.directory },
67
+ throwOnError: true,
68
+ });
69
+ }
70
+ async waitUntilIdle(timeoutMs = 60_000) {
71
+ const started = Date.now();
72
+ while (Date.now() - started < timeoutMs) {
73
+ const state = this.core.getState();
74
+ if (state.runState === "idle" && !this.core.hasActiveChain() && !state.activePromptId && state.queueLength === 0) {
75
+ return;
76
+ }
77
+ await sleep(100);
78
+ }
79
+ throw new Error("Timed out waiting for host to become idle.");
80
+ }
81
+ async close() {
82
+ if (this.closed)
83
+ return;
84
+ this.closed = true;
85
+ this.core.markClosed();
86
+ this.emitState();
87
+ }
88
+ async ingestEvent(event) {
89
+ if (this.closed)
90
+ return;
91
+ if (eventSessionId(event) !== this.session.id && event.type !== "server.connected")
92
+ return;
93
+ this.options.eventLogger?.(`[event] ${summarizeEvent(event)}`);
94
+ await this.handleEvent(event);
95
+ }
96
+ async initialize() {
97
+ this.session = await this.createOrReuseSession();
98
+ this.core.setSessionInfo({ sessionId: this.session.id, sessionTitle: this.session.title });
99
+ this.emitState();
100
+ const initialMessages = await this.fetchSessionMessages();
101
+ for (const message of initialMessages) {
102
+ this.baselineMessageIds.add(message.info.id);
103
+ this.messageRolesById.set(message.info.id, message.info.role);
104
+ for (const part of message.parts) {
105
+ this.partTypesById.set(part.id, part.type);
106
+ }
107
+ this.emitModelTelemetryForMessage(message.info);
108
+ }
109
+ }
110
+ async createOrReuseSession() {
111
+ if (this.options.sessionId) {
112
+ const existing = await this.client.session.get({
113
+ path: { id: this.options.sessionId },
114
+ query: { directory: this.options.directory },
115
+ throwOnError: true,
116
+ });
117
+ if (!existing.data) {
118
+ throw new Error(`Session not found: ${this.options.sessionId}`);
119
+ }
120
+ return existing.data;
121
+ }
122
+ const created = await this.client.session.create({
123
+ query: { directory: this.options.directory },
124
+ body: { title: this.options.title ?? "π Studio" },
125
+ throwOnError: true,
126
+ });
127
+ if (!created.data) {
128
+ throw new Error("Session creation returned no data.");
129
+ }
130
+ return created.data;
131
+ }
132
+ emitModelTelemetryForMessage(info) {
133
+ const at = info.role === "assistant"
134
+ ? (info.time.completed ?? info.time.created)
135
+ : info.time.created;
136
+ if (info.role === "user") {
137
+ this.emitTelemetry({
138
+ type: "user.message.updated",
139
+ at,
140
+ messageId: info.id,
141
+ providerID: info.model?.providerID,
142
+ modelID: info.model?.modelID,
143
+ agent: info.agent,
144
+ variant: extractMessageVariant(info),
145
+ });
146
+ return;
147
+ }
148
+ this.emitTelemetry({
149
+ type: "assistant.message.updated",
150
+ at,
151
+ messageId: info.id,
152
+ providerID: info.providerID,
153
+ modelID: info.modelID,
154
+ agent: typeof info.agent === "string"
155
+ ? info.agent
156
+ : undefined,
157
+ variant: extractMessageVariant(info),
158
+ tokenUsage: extractMessageTokenUsage(info),
159
+ });
160
+ }
161
+ async handleEvent(event) {
162
+ if (event.type === "session.status") {
163
+ const props = event.properties;
164
+ const status = props.status?.type ?? null;
165
+ this.core.noteBackendStatus(status);
166
+ this.emitTelemetry({ type: "backend.status", at: Date.now(), status });
167
+ this.emitState();
168
+ return;
169
+ }
170
+ if (event.type === "message.updated") {
171
+ const props = event.properties;
172
+ if (props.info && typeof props.info.id === "string" && typeof props.info.role === "string") {
173
+ this.messageRolesById.set(props.info.id, props.info.role);
174
+ this.emitModelTelemetryForMessage(props.info);
175
+ }
176
+ return;
177
+ }
178
+ if (event.type === "message.part.updated") {
179
+ const props = event.properties;
180
+ const part = props.part;
181
+ if (part) {
182
+ this.partTypesById.set(part.id, part.type);
183
+ if (typeof part.messageID === "string" && this.messageRolesById.get(part.messageID) === "assistant") {
184
+ this.emitTelemetry({
185
+ type: "assistant.part.updated",
186
+ at: Date.now(),
187
+ messageId: part.messageID,
188
+ partId: part.id,
189
+ partType: part.type,
190
+ text: extractAssistantPartText(part),
191
+ });
192
+ }
193
+ }
194
+ return;
195
+ }
196
+ const deltaEvent = event;
197
+ if (isMessagePartDeltaEvent(deltaEvent)) {
198
+ const props = deltaEvent.properties;
199
+ if (typeof props.messageID === "string"
200
+ && typeof props.partID === "string"
201
+ && typeof props.field === "string"
202
+ && typeof props.delta === "string"
203
+ && this.messageRolesById.get(props.messageID) === "assistant") {
204
+ this.emitTelemetry({
205
+ type: "assistant.part.delta",
206
+ at: Date.now(),
207
+ messageId: props.messageID,
208
+ partId: props.partID,
209
+ field: props.field,
210
+ delta: props.delta,
211
+ partType: this.partTypesById.get(props.partID),
212
+ });
213
+ }
214
+ return;
215
+ }
216
+ if (event.type === "session.idle") {
217
+ this.core.noteBackendStatus("idle");
218
+ this.emitTelemetry({ type: "session.idle", at: Date.now() });
219
+ this.emitState();
220
+ await this.handleSessionIdle();
221
+ }
222
+ }
223
+ async handleSessionIdle() {
224
+ if (this.handlingIdle || this.closed)
225
+ return;
226
+ this.handlingIdle = true;
227
+ try {
228
+ const active = this.core.getActiveSubmission();
229
+ if (active) {
230
+ await this.finalizeActiveSubmission(active);
231
+ }
232
+ const next = this.core.activateNextQueuedSteer();
233
+ if (next) {
234
+ this.emitState();
235
+ await this.dispatchSubmission(next);
236
+ return;
237
+ }
238
+ const observed = await this.reconcileObservedExternalResponses();
239
+ this.core.noteBackendIdle();
240
+ for (const item of observed) {
241
+ this.emitTelemetry({ type: "submission.completed", at: item.completedAt ?? Date.now(), historyItem: item });
242
+ }
243
+ this.emitState();
244
+ }
245
+ finally {
246
+ this.handlingIdle = false;
247
+ }
248
+ }
249
+ async dispatchSubmission(submission) {
250
+ this.emitTelemetry({ type: "submission.dispatched", at: Date.now(), submission });
251
+ this.emitState();
252
+ try {
253
+ await this.client.session.promptAsync({
254
+ path: { id: this.session.id },
255
+ query: { directory: this.options.directory },
256
+ body: {
257
+ parts: [{ type: "text", text: submission.promptText }],
258
+ },
259
+ throwOnError: true,
260
+ });
261
+ }
262
+ catch (error) {
263
+ this.fail(error instanceof Error ? error : new Error(String(error)));
264
+ throw error;
265
+ }
266
+ }
267
+ async finalizeActiveSubmission(active) {
268
+ const bound = await this.bindSubmissionToMessages(active);
269
+ if (bound.userMessageId) {
270
+ this.matchedUserIds.add(bound.userMessageId);
271
+ this.core.noteUserMessage({ text: active.promptText, messageId: bound.userMessageId });
272
+ }
273
+ for (const assistantMessageId of bound.consumedAssistantMessageIds) {
274
+ this.matchedAssistantIds.add(assistantMessageId);
275
+ }
276
+ const stopping = this.core.getState().runState === "stopping";
277
+ const completed = this.core.completeActiveResponse({
278
+ responseMessageId: bound.response?.id ?? null,
279
+ responseText: bound.response?.text ?? "",
280
+ responseError: bound.response?.error ?? (stopping ? "Aborted" : undefined),
281
+ completedAt: bound.response?.completed ?? Date.now(),
282
+ });
283
+ if (completed) {
284
+ this.emitTelemetry({ type: "submission.completed", at: Date.now(), historyItem: completed });
285
+ }
286
+ this.emitState();
287
+ }
288
+ async bindSubmissionToMessages(active) {
289
+ const deadline = Date.now() + 4000;
290
+ let userMessageId = active.userMessageId ?? null;
291
+ let response = null;
292
+ let consumedAssistantMessageIds = [];
293
+ while (Date.now() < deadline) {
294
+ const messages = (await this.fetchSessionMessages())
295
+ .map(normalizeSessionMessageRecord)
296
+ .filter((message) => !this.baselineMessageIds.has(message.id));
297
+ if (!userMessageId) {
298
+ const userMatch = [...messages].reverse().find((message) => (message.role === "user"
299
+ && !this.matchedUserIds.has(message.id)
300
+ && message.text === active.promptText
301
+ && message.created >= active.submittedAt - 10_000));
302
+ if (userMatch) {
303
+ userMessageId = userMatch.id;
304
+ }
305
+ }
306
+ let responseCandidate = null;
307
+ let consumedCandidateIds = [];
308
+ if (userMessageId) {
309
+ const linkedAssistantMessages = collectObservedAssistantResponsesForUser(messages, this.matchedAssistantIds, userMessageId);
310
+ responseCandidate = selectLatestObservedAssistantResponse(linkedAssistantMessages);
311
+ consumedCandidateIds = linkedAssistantMessages.map((message) => message.id);
312
+ }
313
+ else {
314
+ const assistantCandidates = sortObservedMessages(messages).filter((message) => (message.role === "assistant"
315
+ && !this.matchedAssistantIds.has(message.id)
316
+ && message.created >= active.submittedAt - 10_000));
317
+ responseCandidate = selectLatestObservedAssistantResponse(assistantCandidates);
318
+ consumedCandidateIds = assistantCandidates.map((message) => message.id);
319
+ }
320
+ if (responseCandidate) {
321
+ response = responseCandidate;
322
+ consumedAssistantMessageIds = consumedCandidateIds;
323
+ }
324
+ if (userMessageId && responseCandidate) {
325
+ return { userMessageId, response: responseCandidate, consumedAssistantMessageIds: consumedCandidateIds };
326
+ }
327
+ await sleep(150);
328
+ }
329
+ return { userMessageId, response, consumedAssistantMessageIds };
330
+ }
331
+ async reconcileObservedExternalResponses() {
332
+ const messages = (await this.fetchSessionMessages())
333
+ .map(normalizeSessionMessageRecord)
334
+ .filter((message) => !this.baselineMessageIds.has(message.id));
335
+ const observed = collectObservedExternalResponses(messages, this.matchedAssistantIds);
336
+ if (observed.length === 0) {
337
+ return [];
338
+ }
339
+ const adopted = [];
340
+ for (const item of observed) {
341
+ if (item.userMessageId) {
342
+ this.matchedUserIds.add(item.userMessageId);
343
+ }
344
+ for (const assistantMessageId of item.consumedAssistantMessageIds) {
345
+ this.matchedAssistantIds.add(assistantMessageId);
346
+ }
347
+ adopted.push(this.core.recordObservedResponse({
348
+ promptText: item.promptText,
349
+ userMessageId: item.userMessageId,
350
+ responseMessageId: item.response.id,
351
+ responseText: item.response.text,
352
+ responseError: item.response.error,
353
+ submittedAt: item.submittedAt,
354
+ completedAt: item.response.completed ?? item.response.created,
355
+ }));
356
+ }
357
+ return adopted;
358
+ }
359
+ async fetchSessionMessages() {
360
+ const response = await this.client.session.messages({
361
+ path: { id: this.session.id },
362
+ query: { directory: this.options.directory, limit: 200 },
363
+ throwOnError: true,
364
+ });
365
+ return response.data ?? [];
366
+ }
367
+ emitState() {
368
+ const snapshot = this.getState();
369
+ for (const listener of this.listeners) {
370
+ listener(snapshot);
371
+ }
372
+ }
373
+ emitTelemetry(event) {
374
+ this.options.telemetryListener?.(event);
375
+ }
376
+ fail(error) {
377
+ this.core.markError(error.message);
378
+ this.emitState();
379
+ }
380
+ assertReady() {
381
+ const state = this.core.getState();
382
+ if (this.closed || state.runState === "closed") {
383
+ throw new Error("Host is closed.");
384
+ }
385
+ if (!this.session) {
386
+ throw new Error("Host is not initialized.");
387
+ }
388
+ if (state.runState === "error") {
389
+ throw new Error(state.lastError ?? "Host is in an error state.");
390
+ }
391
+ }
392
+ }
393
+ export async function createPluginBackedOpencodeStudioHost(options) {
394
+ return PluginBackedOpencodeStudioHost.create(options);
395
+ }
396
+ //# sourceMappingURL=host-opencode-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-opencode-plugin.js","sourceRoot":"","sources":["../src/host-opencode-plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,154 @@
1
+ import { type Event, type Message, type Part } from "@opencode-ai/sdk";
2
+ import type { StudioHost, StudioHostCapabilities, StudioHostHistoryItem, StudioHostListener, StudioHostState } from "./studio-host-types.js";
3
+ export type OpencodeMessageTokenUsage = {
4
+ total?: number;
5
+ input?: number;
6
+ output?: number;
7
+ reasoning?: number;
8
+ };
9
+ export type OpencodeStudioHostTelemetryEvent = {
10
+ type: "submission.dispatched";
11
+ at: number;
12
+ submission: StudioHostHistoryItem;
13
+ } | {
14
+ type: "backend.status";
15
+ at: number;
16
+ status: string | null;
17
+ } | {
18
+ type: "user.message.updated";
19
+ at: number;
20
+ messageId: string;
21
+ providerID?: string;
22
+ modelID?: string;
23
+ agent?: string;
24
+ variant?: string;
25
+ } | {
26
+ type: "assistant.message.updated";
27
+ at: number;
28
+ messageId: string;
29
+ providerID?: string;
30
+ modelID?: string;
31
+ agent?: string;
32
+ variant?: string;
33
+ tokenUsage?: OpencodeMessageTokenUsage;
34
+ } | {
35
+ type: "assistant.part.updated";
36
+ at: number;
37
+ messageId: string;
38
+ partId: string;
39
+ partType: string;
40
+ text?: string;
41
+ } | {
42
+ type: "assistant.part.delta";
43
+ at: number;
44
+ messageId: string;
45
+ partId: string;
46
+ field: string;
47
+ delta: string;
48
+ partType?: string;
49
+ } | {
50
+ type: "session.idle";
51
+ at: number;
52
+ } | {
53
+ type: "submission.completed";
54
+ at: number;
55
+ historyItem: StudioHostHistoryItem;
56
+ };
57
+ export type OpencodeStudioHostOptions = {
58
+ directory: string;
59
+ baseUrl?: string;
60
+ sessionId?: string;
61
+ title?: string;
62
+ eventLogger?: (line: string) => void;
63
+ telemetryListener?: (event: OpencodeStudioHostTelemetryEvent) => void;
64
+ };
65
+ export type SessionMessageRecord = {
66
+ info: Message;
67
+ parts: Part[];
68
+ };
69
+ export type ObservedSessionMessage = {
70
+ id: string;
71
+ role: Message["role"];
72
+ created: number;
73
+ completed?: number;
74
+ error?: string;
75
+ text: string;
76
+ parentMessageId?: string | null;
77
+ };
78
+ export type NormalizedMessage = ObservedSessionMessage;
79
+ export declare function extractMessageVariant(info: unknown): string | undefined;
80
+ export declare function extractMessageTokenUsage(info: unknown): OpencodeMessageTokenUsage | undefined;
81
+ export type ObservedExternalResponse = {
82
+ userMessageId: string | null;
83
+ promptText: string;
84
+ submittedAt: number;
85
+ response: ObservedSessionMessage;
86
+ consumedAssistantMessageIds: string[];
87
+ };
88
+ export declare function normalizeSessionMessageRecord(record: SessionMessageRecord): NormalizedMessage;
89
+ export declare function compareObservedMessages(a: ObservedSessionMessage, b: ObservedSessionMessage): number;
90
+ export declare function sortObservedMessages(messages: ReadonlyArray<ObservedSessionMessage>): ObservedSessionMessage[];
91
+ export declare function hasObservedAssistantContent(message: ObservedSessionMessage): boolean;
92
+ export declare function resolveObservedRootUserMessage(message: ObservedSessionMessage, messageById: ReadonlyMap<string, ObservedSessionMessage>): ObservedSessionMessage | null;
93
+ export declare function selectLatestObservedAssistantResponse(messages: ReadonlyArray<ObservedSessionMessage>): ObservedSessionMessage | null;
94
+ export declare function collectObservedAssistantResponsesForUser(messages: ReadonlyArray<ObservedSessionMessage>, matchedAssistantIds: ReadonlySet<string>, userMessageId: string): ObservedSessionMessage[];
95
+ export declare function eventSessionId(event: Event): string | null;
96
+ export declare function summarizeEvent(event: Event): string;
97
+ export declare function extractAssistantPartText(part: Part): string | undefined;
98
+ export declare function collectObservedExternalResponses(messages: ReadonlyArray<ObservedSessionMessage>, matchedAssistantIds: ReadonlySet<string>): ObservedExternalResponse[];
99
+ export declare function isMessagePartDeltaEvent(event: {
100
+ type?: string;
101
+ properties?: unknown;
102
+ }): event is {
103
+ type: "message.part.delta";
104
+ properties: {
105
+ sessionID?: string;
106
+ messageID?: string;
107
+ partID?: string;
108
+ field?: string;
109
+ delta?: string;
110
+ };
111
+ };
112
+ export declare class OpencodeStudioHost implements StudioHost {
113
+ private readonly options;
114
+ private readonly listeners;
115
+ private readonly baselineMessageIds;
116
+ private readonly matchedUserIds;
117
+ private readonly matchedAssistantIds;
118
+ private readonly partTypesById;
119
+ private readonly messageRolesById;
120
+ private readonly core;
121
+ private client;
122
+ private startedServer;
123
+ private session;
124
+ private eventAbortController;
125
+ private eventLoop;
126
+ private handlingIdle;
127
+ private closed;
128
+ static create(options: OpencodeStudioHostOptions): Promise<OpencodeStudioHost>;
129
+ private constructor();
130
+ getState(): StudioHostState;
131
+ getCapabilities(): StudioHostCapabilities;
132
+ getHistory(): StudioHostHistoryItem[];
133
+ subscribe(listener: StudioHostListener): () => void;
134
+ startRun(prompt: string): Promise<void>;
135
+ queueSteer(prompt: string): Promise<void>;
136
+ stop(): Promise<void>;
137
+ waitUntilIdle(timeoutMs?: number): Promise<void>;
138
+ close(): Promise<void>;
139
+ private initialize;
140
+ private createOrReuseSession;
141
+ private emitModelTelemetryForMessage;
142
+ private handleEvent;
143
+ private handleSessionIdle;
144
+ private dispatchSubmission;
145
+ private finalizeActiveSubmission;
146
+ private bindSubmissionToMessages;
147
+ private reconcileObservedExternalResponses;
148
+ private fetchSessionMessages;
149
+ private emitState;
150
+ private emitTelemetry;
151
+ private fail;
152
+ private assertReady;
153
+ }
154
+ export declare function createOpencodeStudioHost(options: OpencodeStudioHostOptions): Promise<StudioHost>;