@opencode/client 2.0.3 → 2.0.5

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.
@@ -15,12 +15,15 @@ export const isInstructionEntryValueTooLargeError = (value) => typeof value ===
15
15
  value !== null &&
16
16
  "_tag" in value &&
17
17
  value["_tag"] === "InstructionEntryValueTooLargeError";
18
- export const isProviderNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "ProviderNotFoundError";
19
- export const isMcpServerNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "McpServerNotFoundError";
20
- export const isProjectNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "ProjectNotFoundError";
21
18
  export const isFormNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "FormNotFoundError";
22
19
  export const isFormInvalidAnswerError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "FormInvalidAnswerError";
23
20
  export const isFormAlreadySettledError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "FormAlreadySettledError";
21
+ export const isProviderNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "ProviderNotFoundError";
22
+ export const isIntegrationNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "IntegrationNotFoundError";
23
+ export const isIntegrationAttemptNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "IntegrationAttemptNotFoundError";
24
+ export const isIntegrationMethodNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "IntegrationMethodNotFoundError";
25
+ export const isMcpServerNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "McpServerNotFoundError";
26
+ export const isProjectNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "ProjectNotFoundError";
24
27
  export const isPermissionNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "PermissionNotFoundError";
25
28
  export const isFileNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "FileNotFoundError";
26
29
  export const isRpcError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "RpcError";
@@ -1,6 +1,6 @@
1
1
  import type { OpenCode } from "./client.js";
2
2
  export * from "./generated/index.js";
3
3
  export { OpenCode } from "./client.js";
4
- export type { AgentApi, CatalogApi, CommandApi, ConfigApi, EventApi, IntegrationApi, ModelApi, PluginApi, ProviderApi, ReferenceApi, RpcApi, RpcCallOptions, RpcClient, RpcEventPayload, WebSearchApi, SessionApi, SkillApi, } from "./api.js";
4
+ export type { AgentApi, CommandApi, ConfigApi, EventApi, IntegrationApi, ModelApi, PluginApi, ProviderApi, ReferenceApi, RpcApi, RpcCallOptions, RpcClient, RpcEventPayload, WebSearchApi, SessionApi, SkillApi, } from "./api.js";
5
5
  export type { EventSubscribeOutput as OpenCodeEvent } from "./generated/types.js";
6
6
  export type OpenCodeClient = ReturnType<typeof OpenCode.make>;
@@ -16,6 +16,8 @@ export async function discover(options = {}) {
16
16
  const found = (await registered(options.file)).service;
17
17
  if (found?.state !== "ready")
18
18
  return undefined;
19
+ if (!found.compatible)
20
+ return undefined;
19
21
  if (!matchesVersion(found.version, options))
20
22
  return undefined;
21
23
  return found.endpoint;
@@ -50,7 +52,7 @@ export async function ensure(options = {}) {
50
52
  while (true) {
51
53
  if (Date.now() >= deadline)
52
54
  throw new Error("Timed out waiting for the background service to start");
53
- const registration = await registered(options.file, true, timing.requestTimeout);
55
+ const registration = await registered(options.file, timing.requestTimeout);
54
56
  if (registration.timedOut && registration.info !== undefined) {
55
57
  timeouts = {
56
58
  info: registration.info,
@@ -70,7 +72,7 @@ export async function ensure(options = {}) {
70
72
  if (registration.service !== undefined) {
71
73
  spawnDelay = timing.spawnDelay;
72
74
  const service = registration.service;
73
- const compatible = !service.legacy && matchesVersion(service.version, options);
75
+ const compatible = service.compatible && matchesVersion(service.version, options);
74
76
  if (compatible && service.state === "ready") {
75
77
  await PtyHandoff.complete(options.file ?? fallback(), service.info);
76
78
  return service.endpoint;
@@ -79,11 +81,11 @@ export async function ensure(options = {}) {
79
81
  throw new Error("Background service failed to start");
80
82
  if (!compatible) {
81
83
  announce("version-mismatch", service.version);
82
- if (!service.legacy && service.state !== "ready")
84
+ if (service.state !== "ready")
83
85
  console.warn("Background service is not ready; replacement cannot preserve persistent terminals");
84
86
  await stop({
85
87
  file: options.file,
86
- pty: !service.legacy && service.state === "ready" ? "handoff" : "clear",
88
+ pty: service.state === "ready" ? "handoff" : "clear",
87
89
  }).catch(() => undefined);
88
90
  lastSpawn = 0;
89
91
  }
@@ -145,7 +147,7 @@ async function read(file) {
145
147
  return undefined;
146
148
  }
147
149
  }
148
- async function probeResult(info, allowLegacy = false, timeout = defaultEnsureTiming.requestTimeout) {
150
+ async function probeResult(info, timeout = defaultEnsureTiming.requestTimeout) {
149
151
  const endpoint = {
150
152
  url: info.url,
151
153
  auth: info.password === undefined
@@ -153,47 +155,61 @@ async function probeResult(info, allowLegacy = false, timeout = defaultEnsureTim
153
155
  : { type: "basic", username: "opencode", password: info.password },
154
156
  };
155
157
  const signal = AbortSignal.timeout(timeout);
156
- const result = await fetch(new URL("/api/health", info.url), {
157
- headers: headers(endpoint),
158
- signal,
159
- })
158
+ const result = await fetch(new URL("/api/status", info.url), { headers: headers(endpoint), signal })
160
159
  .then(async (response) => ({
161
160
  response,
162
- body: (await response.json()),
161
+ body: response.status === 404 ? undefined : (await response.json()),
163
162
  }))
164
163
  .then((value) => ({ value }), (cause) => ({ cause }));
165
164
  if ("cause" in result)
166
165
  return { service: undefined, timedOut: signal.aborted };
167
166
  const response = result.value.response;
168
- const body = result.value.body;
169
- if (body !== undefined && "version" in body && "pid" in body) {
170
- if (body.pid !== info.pid)
167
+ // The previous V2 service exposes /api/health instead. Its authenticated 404 is enough
168
+ // to recognize the registered daemon as incompatible and route it through replacement.
169
+ if (response.status === 404)
170
+ return {
171
+ service: {
172
+ info,
173
+ endpoint,
174
+ version: info.version,
175
+ state: "ready",
176
+ compatible: false,
177
+ },
178
+ timedOut: false,
179
+ };
180
+ const status = decodeStatus(result.value.body);
181
+ if (status !== undefined) {
182
+ if (status.pid !== info.pid)
171
183
  return { service: undefined, timedOut: false };
172
- if (info.version !== undefined && body.version !== info.version)
184
+ if (info.version !== undefined && status.version !== info.version)
173
185
  return { service: undefined, timedOut: false };
174
186
  return {
175
187
  service: {
176
188
  info,
177
189
  endpoint,
178
- version: body.version,
190
+ version: status.version,
179
191
  state: response.ok ? "ready" : response.status === 500 ? "failed" : "waiting",
180
- legacy: false,
192
+ compatible: true,
181
193
  },
182
194
  timedOut: false,
183
195
  };
184
196
  }
185
- if (!allowLegacy || body?.healthy !== true)
186
- return { service: undefined, timedOut: false };
187
- return {
188
- service: { info, endpoint, state: "ready", legacy: true },
189
- timedOut: false,
190
- };
197
+ return { service: undefined, timedOut: false };
198
+ }
199
+ function decodeStatus(input) {
200
+ if (typeof input !== "object" || input === null)
201
+ return;
202
+ if (!("version" in input) || typeof input.version !== "string")
203
+ return;
204
+ if (!("pid" in input) || typeof input.pid !== "number" || !Number.isInteger(input.pid) || input.pid < 0)
205
+ return;
206
+ return { version: input.version, pid: input.pid };
191
207
  }
192
- async function registered(file, allowLegacy = false, timeout) {
208
+ async function registered(file, timeout) {
193
209
  const info = await read(file);
194
210
  if (info === undefined)
195
211
  return { info: undefined, service: undefined, timedOut: false };
196
- return { info, ...(await probeResult(info, allowLegacy, timeout)) };
212
+ return { info, ...(await probeResult(info, timeout)) };
197
213
  }
198
214
  function signal(pid, name) {
199
215
  try {
@@ -7,7 +7,6 @@ export declare const event: <D extends Rpc.Definition, Name extends keyof D["eve
7
7
  readonly id: string & import("effect/Brand").Brand<"Event.ID">;
8
8
  readonly location: {
9
9
  readonly directory: string & import("effect/Brand").Brand<"AbsolutePath">;
10
- readonly workspaceID?: (string & import("effect/Brand").Brand<"Workspace.ID">) | undefined;
11
10
  };
12
11
  readonly data: {
13
12
  readonly [x: string]: unknown;
@@ -1,4 +1,4 @@
1
- import type { AgentInfo, CommandInfo, ConfigEntry, FormCancelInput, FormInfo, FormReplyInput, IntegrationInfo, LocationRef, LocationGetOutput, McpResource, McpServer, ModelInfo, ModelRef, PermissionSavedInfo, PermissionRequest, PermissionReplyInput, Project, ProviderInfo, ReferenceInfo, SessionMessageInfo, SessionInfo, SessionInboxInfo, SessionInboxCompaction, ShellInfo, SkillInfo, VcsInfo, OpenCodeEvent, OpenCodeClient, WebSearchProvider } from "../promise";
1
+ import type { AgentInfo, CommandInfo, ConfigEntry, SessionFormCancelInput, FormInfo, SessionFormReplyInput, IntegrationInfo, LocationRef, McpResource, McpServer, ModelInfo, ModelRef, PermissionSavedInfo, PermissionRequest, PermissionReplyInput, Project, ProviderInfo, ReferenceInfo, SessionMessageInfo, SessionInfo, SessionInboxInfo, SessionInboxCompaction, ShellInfo, SkillInfo, VcsInfo, OpenCodeEvent, OpenCodeClient, WebSearchProvider } from "../promise";
2
2
  import { type SessionPromptInput } from "../promise";
3
3
  export type DataSessionStatus = "idle" | "running";
4
4
  type OpenCodeEventMap = {
@@ -106,8 +106,8 @@ export declare function createData(config: CreateDataInput): {
106
106
  list(sessionID: string, ref?: LocationRef): FormWithLocation[] | undefined;
107
107
  sync(sessionID: string, ref?: LocationRef): Promise<void>;
108
108
  invalidate(sessionID: string, ref?: LocationRef): void;
109
- reply(input: FormReplyInput, ref?: LocationRef): Promise<void>;
110
- cancel(input: FormCancelInput, ref?: LocationRef): Promise<void>;
109
+ reply(input: SessionFormReplyInput, ref?: LocationRef): Promise<void>;
110
+ cancel(input: SessionFormCancelInput, ref?: LocationRef): Promise<void>;
111
111
  };
112
112
  };
113
113
  project: {
@@ -129,7 +129,7 @@ export declare function createData(config: CreateDataInput): {
129
129
  invalidate: (ref?: LocationRef) => void;
130
130
  };
131
131
  location: {
132
- info(ref?: LocationRef): LocationGetOutput | undefined;
132
+ info(ref?: LocationRef): import("../promise").LocationPublicInfo | undefined;
133
133
  default(): LocationRef;
134
134
  syncInfo(ref?: LocationRef): Promise<void>;
135
135
  sync(ref?: LocationRef): Promise<void>;
@@ -16,7 +16,7 @@ export function locationKey(location) {
16
16
  return JSON.stringify([location.directory, location.workspaceID]);
17
17
  }
18
18
  function locationQuery(ref) {
19
- return { directory: ref.directory, workspace: ref.workspaceID };
19
+ return { directory: ref.directory };
20
20
  }
21
21
  function formRequestOptions(sessionID, ref) {
22
22
  if (sessionID !== "global" || !ref)
@@ -24,7 +24,6 @@ function formRequestOptions(sessionID, ref) {
24
24
  return {
25
25
  headers: {
26
26
  "x-opencode-directory": encodeURIComponent(ref.directory),
27
- ...(ref.workspaceID ? { "x-opencode-workspace": ref.workspaceID } : {}),
28
27
  },
29
28
  };
30
29
  }
@@ -137,6 +136,7 @@ export function createData(config) {
137
136
  const messageIndex = new Map();
138
137
  const sync = createSync();
139
138
  let activeUpdates;
139
+ const pendingUpdates = new Map();
140
140
  function setSessionActive(sessionID, status) {
141
141
  activeUpdates?.set(sessionID, status);
142
142
  setStore("session", "active", sessionID, status);
@@ -144,6 +144,7 @@ export function createData(config) {
144
144
  function removePending(sessionID, inboxID) {
145
145
  if (!inboxID)
146
146
  return;
147
+ pendingUpdates.get(sessionID)?.set(inboxID, undefined);
147
148
  if (store.session.pending[sessionID]?.some((item) => item.id === inboxID))
148
149
  setStore("session", "pending", sessionID, (store.session.pending[sessionID] ?? []).filter((item) => item.id !== inboxID));
149
150
  }
@@ -186,6 +187,7 @@ export function createData(config) {
186
187
  function updatePending(sessionID, inboxID, delivery) {
187
188
  const index = store.session.pending[sessionID]?.findIndex((item) => item.id === inboxID) ?? -1;
188
189
  const item = store.session.pending[sessionID]?.[index];
190
+ pendingUpdates.get(sessionID)?.set(inboxID, item ? { ...item, delivery } : delivery);
189
191
  if (index < 0 || !item || item.delivery === delivery)
190
192
  return;
191
193
  setStore("session", "pending", sessionID, index, { ...item, delivery });
@@ -252,8 +254,8 @@ export function createData(config) {
252
254
  return;
253
255
  message.update(item.sessionID, (draft, index) => {
254
256
  const row = item.type === "user"
255
- ? { id: item.id, type: "user", ...item.payload, time: { created: item.timeCreated } }
256
- : { id: item.id, type: "synthetic", ...item.payload, time: { created: item.timeCreated } };
257
+ ? { id: item.id, type: "user", ...item.payload, time: { created: item.time.created } }
258
+ : { id: item.id, type: "synthetic", ...item.payload, time: { created: item.time.created } };
257
259
  const position = index.get(item.id);
258
260
  if (position === undefined)
259
261
  return message.append(draft, index, row);
@@ -527,7 +529,7 @@ export function createData(config) {
527
529
  time: { created: event.created },
528
530
  });
529
531
  refresh(() => api()
530
- .session.message({ sessionID: event.data.sessionID, messageID: messageIDFromEvent(event.id) })
532
+ .session.message.get({ sessionID: event.data.sessionID, messageID: messageIDFromEvent(event.id) })
531
533
  .then((item) => {
532
534
  message.update(event.data.sessionID, (draft, index) => {
533
535
  const position = index.get(item.id);
@@ -550,7 +552,7 @@ export function createData(config) {
550
552
  });
551
553
  return;
552
554
  }
553
- case "session.permissions.updated":
555
+ case "session.permissions":
554
556
  if (store.session.info[event.data.sessionID])
555
557
  setStore("session", "info", event.data.sessionID, "permissions", event.data.permissions);
556
558
  return;
@@ -583,8 +585,6 @@ export function createData(config) {
583
585
  const explicit = event.data.adopted?.includes(info.projectID);
584
586
  const directory = explicit ? store.project.info[info.projectID]?.canonical : info.location.directory;
585
587
  if (!directory) {
586
- if (info.location.workspaceID)
587
- continue;
588
588
  result.session.invalidate(sessionID);
589
589
  refresh(() => result.session.sync(sessionID));
590
590
  continue;
@@ -592,7 +592,6 @@ export function createData(config) {
592
592
  const adopted = Worktree.adopt({
593
593
  projectID: info.projectID,
594
594
  directory,
595
- workspaceID: info.location.workspaceID,
596
595
  }, event.data);
597
596
  if (!adopted)
598
597
  continue;
@@ -629,12 +628,14 @@ export function createData(config) {
629
628
  }
630
629
  case "session.inbox.enqueued": {
631
630
  outbox.delete(event.data.inboxID);
632
- admitLocal({
631
+ const item = {
633
632
  id: event.data.inboxID,
634
633
  sessionID: event.data.sessionID,
635
- timeCreated: event.created,
634
+ time: { created: event.created },
636
635
  ...event.data.item,
637
- });
636
+ };
637
+ pendingUpdates.get(item.sessionID)?.set(item.id, item);
638
+ admitLocal(item);
638
639
  if (event.data.item.type === "compaction") {
639
640
  const active = compacting.get(event.data.sessionID);
640
641
  active?.observed.add(event.data.inboxID);
@@ -1061,10 +1062,13 @@ export function createData(config) {
1061
1062
  return;
1062
1063
  const location = event.location;
1063
1064
  switch (event.type) {
1064
- case "catalog.updated":
1065
- result.location.model.invalidate(location);
1065
+ case "provider.updated":
1066
1066
  result.location.provider.invalidate(location);
1067
- refresh(() => Promise.all([result.location.model.sync(location), result.location.provider.sync(location)]));
1067
+ refresh(() => result.location.provider.sync(location));
1068
+ break;
1069
+ case "model.updated":
1070
+ result.location.model.invalidate(location);
1071
+ refresh(() => result.location.model.sync(location));
1068
1072
  break;
1069
1073
  case "agent.updated":
1070
1074
  result.location.agent.invalidate(location);
@@ -1170,7 +1174,7 @@ export function createData(config) {
1170
1174
  const vcs = locationResource("vcs", (location) => api().vcs.get({ location }));
1171
1175
  const shells = locationResource("shell", async (location) => {
1172
1176
  const response = await api().shell.list({ location });
1173
- const ref = { directory: response.location.directory, workspaceID: response.location.workspaceID };
1177
+ const ref = { directory: response.location.directory };
1174
1178
  return {
1175
1179
  location: response.location,
1176
1180
  data: Object.fromEntries(response.data.map((info) => [info.id, { ...info, location: ref }])),
@@ -1239,23 +1243,46 @@ export function createData(config) {
1239
1243
  },
1240
1244
  sync(sessionID) {
1241
1245
  return sync.run(`session.pending:${sessionID}`, async () => {
1242
- const pending = await api().session.inbox.list({ sessionID });
1243
- // A positive read acknowledges admission even when its SSE echo is delayed.
1244
- pending.forEach((item) => outbox.delete(item.id));
1245
- // Compactions also coalesce by Session, not just by the proposed ID.
1246
- if (pending.some((item) => item.type === "compaction"))
1247
- store.session.pending[sessionID]
1248
- ?.filter((item) => item.type === "compaction")
1249
- .forEach((item) => outbox.delete(item.id));
1250
- // Keep optimistic rows still awaiting their echo: this fetch may
1251
- // have raced ahead of an in-flight admission the server does not
1252
- // know about yet.
1253
- const inflight = (store.session.pending[sessionID] ?? []).filter((item) => outbox.has(item.id));
1254
- const merged = inflight.length === 0 ? pending : [...pending, ...inflight];
1255
- batch(() => {
1256
- setStore("session", "pending", sessionID, reconcile(merged));
1257
- merged.forEach(materializeInboxMessage);
1258
- });
1246
+ const updates = new Map();
1247
+ pendingUpdates.set(sessionID, updates);
1248
+ try {
1249
+ const snapshot = await api().session.inbox.list({ sessionID });
1250
+ // Events can overtake this HTTP response on a remote connection.
1251
+ // Reconcile them before an older snapshot can resurrect delivered input.
1252
+ const current = new Map(snapshot.map((item) => [item.id, item]));
1253
+ updates.forEach((item, id) => {
1254
+ if (item === undefined)
1255
+ current.delete(id);
1256
+ else if (typeof item === "string") {
1257
+ const existing = current.get(id);
1258
+ if (existing)
1259
+ current.set(id, { ...existing, delivery: item });
1260
+ }
1261
+ else
1262
+ current.set(id, item);
1263
+ });
1264
+ const pending = [...current.values()];
1265
+ // A positive read acknowledges admission even when its SSE echo is delayed.
1266
+ pending.forEach((item) => outbox.delete(item.id));
1267
+ // Compactions also coalesce by Session, not just by the proposed ID.
1268
+ if (pending.some((item) => item.type === "compaction"))
1269
+ store.session.pending[sessionID]
1270
+ ?.filter((item) => item.type === "compaction")
1271
+ .forEach((item) => outbox.delete(item.id));
1272
+ // Keep optimistic rows still awaiting their echo: this fetch may
1273
+ // have raced ahead of an in-flight admission the server does not
1274
+ // know about yet.
1275
+ const inflight = (store.session.pending[sessionID] ?? []).filter((item) => outbox.has(item.id));
1276
+ const merged = inflight.length === 0 ? pending : [...pending, ...inflight];
1277
+ batch(() => {
1278
+ setStore("session", "pending", sessionID, reconcile(merged));
1279
+ merged.forEach(materializeInboxMessage);
1280
+ });
1281
+ }
1282
+ finally {
1283
+ if (pendingUpdates.get(sessionID) === updates)
1284
+ pendingUpdates.delete(sessionID);
1285
+ }
1259
1286
  });
1260
1287
  },
1261
1288
  invalidate(sessionID) {
@@ -1325,7 +1352,7 @@ export function createData(config) {
1325
1352
  admitLocal({
1326
1353
  id,
1327
1354
  sessionID: input.sessionID,
1328
- timeCreated: Date.now(),
1355
+ time: { created: Date.now() },
1329
1356
  type: "compaction",
1330
1357
  delivery: "steer",
1331
1358
  payload: {},
@@ -1380,7 +1407,7 @@ export function createData(config) {
1380
1407
  admitLocal({
1381
1408
  id,
1382
1409
  sessionID: request.sessionID,
1383
- timeCreated: Date.now(),
1410
+ time: { created: Date.now() },
1384
1411
  type: "user",
1385
1412
  delivery: request.delivery ?? "steer",
1386
1413
  // Files and skills stay off the optimistic row: their durable
@@ -1568,12 +1595,11 @@ export function createData(config) {
1568
1595
  const key = `session.form:${sessionID}:${sessionID === "global" ? locationKey(ref ?? defaultLocation()) : ""}`;
1569
1596
  return sync.run(key, async () => {
1570
1597
  if (sessionID === "global") {
1571
- const response = await api().form.request.list({
1598
+ const response = await api().form.list({
1572
1599
  location: locationQuery(ref ?? defaultLocation()),
1573
1600
  });
1574
1601
  const location = {
1575
1602
  directory: response.location.directory,
1576
- workspaceID: response.location.workspaceID,
1577
1603
  };
1578
1604
  const locationID = locationKey(location);
1579
1605
  setStore("session", "form", sessionID, [
@@ -1582,17 +1608,17 @@ export function createData(config) {
1582
1608
  ]);
1583
1609
  return;
1584
1610
  }
1585
- setStore("session", "form", sessionID, await api().form.list({ sessionID }));
1611
+ setStore("session", "form", sessionID, await api().session.form.list({ sessionID }));
1586
1612
  });
1587
1613
  },
1588
1614
  invalidate(sessionID, ref) {
1589
1615
  sync.invalidate(`session.form:${sessionID}:${sessionID === "global" ? locationKey(ref ?? defaultLocation()) : ""}`);
1590
1616
  },
1591
1617
  reply(input, ref) {
1592
- return settleForm(input, ref, api().form.reply(input, formRequestOptions(input.sessionID, ref)));
1618
+ return settleForm(input, ref, api().session.form.reply(input, formRequestOptions(input.sessionID, ref)));
1593
1619
  },
1594
1620
  cancel(input, ref) {
1595
- return settleForm(input, ref, api().form.cancel(input, formRequestOptions(input.sessionID, ref)));
1621
+ return settleForm(input, ref, api().session.form.cancel(input, formRequestOptions(input.sessionID, ref)));
1596
1622
  },
1597
1623
  },
1598
1624
  },
@@ -1659,7 +1685,7 @@ export function createData(config) {
1659
1685
  setStore("location", key, {});
1660
1686
  setStore("location", key, "info", location);
1661
1687
  if (!ref) {
1662
- setDefaultLocation({ directory: location.directory, workspaceID: location.workspaceID });
1688
+ setDefaultLocation({ directory: location.directory });
1663
1689
  }
1664
1690
  });
1665
1691
  },
@@ -1702,7 +1728,7 @@ export function createData(config) {
1702
1728
  agent: locationResource("agent", (location) => api().agent.list({ location })),
1703
1729
  command: locationResource("command", (location) => api().command.list({ location })),
1704
1730
  config: locationResource("config", async (location) => ({
1705
- location: { directory: location.directory, workspaceID: location.workspace },
1731
+ location: { directory: location.directory },
1706
1732
  data: await api().config.get({ location }),
1707
1733
  })),
1708
1734
  integration: locationResource("integration", (location) => api().integration.list({ location })),
package/dist/solid/pty.js CHANGED
@@ -9,8 +9,6 @@ export function createPtyClient(api, options) {
9
9
  const url = new URL(`/api/pty/${encodeURIComponent(input.ptyID)}/connect`, options.url);
10
10
  if (input.location?.directory)
11
11
  url.searchParams.set("location[directory]", input.location.directory);
12
- if (input.location?.workspace)
13
- url.searchParams.set("location[workspace]", input.location.workspace);
14
12
  if (input.cursor !== undefined)
15
13
  url.searchParams.set("cursor", String(input.cursor));
16
14
  url.searchParams.set("ticket", result.data.ticket);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@opencode/client",
4
- "version": "2.0.3",
4
+ "version": "2.0.5",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -57,8 +57,8 @@
57
57
  "typecheck": "tsgo --noEmit"
58
58
  },
59
59
  "dependencies": {
60
- "@opencode/schema": "2.0.3",
61
- "@opencode/protocol": "2.0.3"
60
+ "@opencode/schema": "2.0.5",
61
+ "@opencode/protocol": "2.0.5"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "effect": "4.0.0-rc.112",
@@ -74,7 +74,7 @@
74
74
  },
75
75
  "devDependencies": {
76
76
  "@effect/platform-node": "4.0.0-rc.112",
77
- "@opencode/httpapi-codegen": "2.0.3",
77
+ "@opencode/httpapi-codegen": "2.0.5",
78
78
  "@tsconfig/bun": "1.0.9",
79
79
  "@types/bun": "1.4.0",
80
80
  "@typescript/native-preview": "7.0.0-dev.20251207.1",