@opencode/client 0.0.0-dev-19551 → 0.0.0-dev-19553

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.
@@ -38,21 +38,14 @@ import type { Worktree } from "@opencode/schema/worktree";
38
38
  import type { Vcs } from "@opencode/schema/vcs";
39
39
  import type { WebSearch } from "@opencode/schema/websearch";
40
40
  import type { Config } from "@opencode/schema/config";
41
- export type HealthGetOutput = {
42
- readonly healthy: true;
41
+ export type ServerStatusOutput = {
43
42
  readonly version: string;
44
43
  readonly pid: number;
45
- };
46
- export type HealthGetOperation<E = never> = () => Effect.Effect<HealthGetOutput, E>;
47
- export interface HealthApi<E = never> {
48
- readonly get: HealthGetOperation<E>;
49
- }
50
- export type ServerGetOutput = {
51
44
  readonly urls: ReadonlyArray<string>;
52
45
  };
53
- export type ServerGetOperation<E = never> = () => Effect.Effect<ServerGetOutput, E>;
46
+ export type ServerStatusOperation<E = never> = () => Effect.Effect<ServerStatusOutput, E>;
54
47
  export interface ServerApi<E = never> {
55
- readonly get: ServerGetOperation<E>;
48
+ readonly status: ServerStatusOperation<E>;
56
49
  }
57
50
  export type LocationGetInput = {
58
51
  readonly location?: {
@@ -2682,7 +2675,6 @@ export interface ConfigApi<E = never> {
2682
2675
  readonly shells: ConfigShellsOperation<E>;
2683
2676
  }
2684
2677
  export interface AppApi<E = never> {
2685
- readonly health: HealthApi<E>;
2686
2678
  readonly server: ServerApi<E>;
2687
2679
  readonly location: LocationApi<E>;
2688
2680
  readonly agent: AgentApi<E>;
@@ -2222,11 +2222,8 @@ export declare const make: (options?: {
2222
2222
  rpc: RpcClientRuntime.RpcApi<import("@opencode/protocol/errors").InvalidRequestError | import("@opencode/protocol/errors").UnauthorizedError | import("effect/Schema").SchemaError | import("@opencode/schema/rpc").SystemError | ClientError | import("effect/unstable/http/HttpClientError").HttpClientError, RpcCallOptions, import("@opencode/protocol/errors").InvalidRequestError | import("@opencode/protocol/errors").UnauthorizedError | import("effect/Schema").SchemaError | ClientError | import("effect/unstable/http/HttpClientError").HttpClientError | import("effect/unstable/encoding/Sse").Retry | import("effect/unstable/encoding/Sse").SseError> & {
2223
2223
  call: (input: import("./api.js").RpcCallInput) => Effect.Effect<import("./api.js").RpcCallOutput, import("@opencode/protocol/errors").InvalidRequestError | import("@opencode/protocol/errors").RpcError | import("@opencode/protocol/errors").RpcInternalError | import("@opencode/protocol/errors").UnauthorizedError | import("effect/Schema").SchemaError | ClientError | import("effect/unstable/http/HttpClientError").HttpClientError, never>;
2224
2224
  };
2225
- health: {
2226
- get: () => Effect.Effect<import("./api.js").HealthGetOutput, import("@opencode/protocol/errors").InvalidRequestError | import("@opencode/protocol/errors").UnauthorizedError | import("effect/Schema").SchemaError | ClientError | import("effect/unstable/http/HttpClientError").HttpClientError, never>;
2227
- };
2228
2225
  server: {
2229
- get: () => Effect.Effect<import("./api.js").ServerGetOutput, import("@opencode/protocol/errors").InvalidRequestError | import("@opencode/protocol/errors").UnauthorizedError | import("effect/Schema").SchemaError | ClientError | import("effect/unstable/http/HttpClientError").HttpClientError, never>;
2226
+ status: () => Effect.Effect<import("./api.js").ServerStatusOutput, import("@opencode/protocol/errors").InvalidRequestError | import("@opencode/protocol/errors").UnauthorizedError | import("effect/Schema").SchemaError | ClientError | import("effect/unstable/http/HttpClientError").HttpClientError, never>;
2230
2227
  };
2231
2228
  location: {
2232
2229
  get: (input?: import("./api.js").LocationGetInput) => Effect.Effect<import("@opencode/schema/location").Info, import("@opencode/protocol/errors").InvalidRequestError | import("@opencode/protocol/errors").UnauthorizedError | import("effect/Schema").SchemaError | ClientError | import("effect/unstable/http/HttpClientError").HttpClientError, never>;
@@ -1,16 +1,13 @@
1
1
  import { Effect, Stream, Schema } from "effect";
2
2
  import { Sse } from "effect/unstable/encoding";
3
3
  import { HttpClientError } from "effect/unstable/http";
4
- import type { HealthGetOutput, ServerGetOutput, LocationGetInput, AgentListInput, AgentListOutput, AgentGetInput, AgentGetOutput, PluginListInput, PluginListOutput, PluginAwaitActivationInput, PluginCheckInput, PluginCheckOutput, PluginUpdateInput, SessionListInput, SessionListOutput, SessionStatsInput, SessionStatsOutput, SessionCreateInput, SessionImportInput, SessionExportInput, SessionExportOutput, SessionActiveOutput, SessionGetInput, SessionRemoveInput, SessionForkInput, SessionSwitchAgentInput, SessionSwitchModelInput, SessionRenameInput, SessionMoveInput, SessionPromptInput, SessionCommandInput, SessionSkillInput, SessionSyntheticInput, SessionShellInput, SessionCompactInput, SessionWaitInput, SessionRevertStageInput, SessionRevertClearInput, SessionRevertCommitInput, SessionContextInput, SessionContextOutput, SessionDiffInput, SessionDiffOutput, SessionInboxListInput, SessionInboxListOutput, SessionInboxCancelInput, SessionInboxSteerInput, SessionInboxQueueInput, SessionInstructionsEntryListInput, SessionInstructionsEntryListOutput, SessionInstructionsEntryPutInput, SessionInstructionsEntryRemoveInput, SessionGenerateInput, SessionGenerateOutput, SessionLogInput, SessionLogOutput, SessionInterruptInput, SessionInterruptOutput, SessionBackgroundInput, SessionMessageInput, SessionEnvironmentInput, SessionViewInput, MessageListInput, MessageListOutput, ModelListInput, ModelListOutput, ModelDefaultInput, ModelDefaultOutput, GenerateTextInput, GenerateTextOutput, ProviderListInput, ProviderListOutput, ProviderGetInput, ProviderGetOutput, IntegrationListInput, IntegrationListOutput, IntegrationGetInput, IntegrationGetOutput, IntegrationWellknownAddInput, IntegrationConnectKeyInput, IntegrationOauthConnectInput, IntegrationOauthConnectOutput, IntegrationOauthStatusInput, IntegrationOauthStatusOutput, IntegrationOauthCompleteInput, IntegrationOauthCancelInput, IntegrationCommandConnectInput, IntegrationCommandConnectOutput, IntegrationCommandStatusInput, IntegrationCommandStatusOutput, IntegrationCommandCancelInput, McpListInput, McpListOutput, McpAddInput, McpRemoveInput, McpConnectInput, McpDisconnectInput, McpResourceCatalogInput, McpResourceCatalogOutput, CredentialUpdateInput, CredentialActivateInput, CredentialRemoveInput, ProjectListOutput, ProjectUpdateInput, FormRequestListInput, FormRequestListOutput, FormListInput, FormListOutput, FormCreateInput, FormGetInput, FormStateInput, FormReplyInput, FormCancelInput, PermissionRequestListInput, PermissionRequestListOutput, PermissionSavedListInput, PermissionSavedListOutput, PermissionSavedRemoveInput, PermissionCreateInput, PermissionCreateOutput, PermissionListInput, PermissionListOutput, PermissionGetInput, PermissionReplyInput, PermissionRulesInput, FileListInput, FileListOutput, FileFindInput, FileFindOutput, CommandListInput, CommandListOutput, SkillListInput, SkillListOutput, RpcCallInput, RpcCallOutput, PtyListInput, PtyListOutput, PtyCreateInput, PtyCreateOutput, PtyGetInput, PtyGetOutput, PtyUpdateInput, PtyUpdateOutput, PtyRemoveInput, PtyConnectTokenInput, PtyConnectTokenOutput, ExperimentalPersistentPtyReadInput, ExperimentalPersistentPtyReadOutput, ExperimentalPersistentPtyListInput, ExperimentalPersistentPtyListOutput, ExperimentalPersistentPtyCreateInput, ExperimentalPersistentPtyCreateOutput, ExperimentalPersistentPtyHandoffOutput, ExperimentalPersistentPtyGetInput, ExperimentalPersistentPtyGetOutput, ExperimentalPersistentPtyUpdateInput, ExperimentalPersistentPtyUpdateOutput, ExperimentalPersistentPtySnapshotInput, ExperimentalPersistentPtySnapshotOutput, ExperimentalPersistentPtyRemoveInput, ExperimentalPersistentPtyConnectTokenInput, ShellListInput, ShellListOutput, ShellCreateInput, ShellCreateOutput, ShellGetInput, ShellGetOutput, ShellTimeoutInput, ShellTimeoutOutput, ShellOutputInput, ShellOutputOutput, ShellRemoveInput, ReferenceListInput, ReferenceListOutput, WorktreeListInput, WorktreeCreateInput, WorktreeRemoveInput, WorktreeRefreshInput, WorkspaceCreateInput, WorkspaceDestroyInput, VcsGetInput, VcsGetOutput, VcsBaseInput, VcsBaseOutput, VcsStatusInput, VcsStatusOutput, VcsBranchesInput, VcsBranchesOutput, VcsDiffInput, VcsDiffOutput, DebugLocationListOutput, DebugLocationEvictInput, MigrationV1StatusOutput, WebsearchProvidersInput, WebsearchProvidersOutput, WebsearchQueryInput, WebsearchQueryOutput, ConfigGetInput, ConfigGetOutput, ConfigUpdatePreferencesInput, ConfigShellsOutput } from "../api/api.js";
4
+ import type { ServerStatusOutput, LocationGetInput, AgentListInput, AgentListOutput, AgentGetInput, AgentGetOutput, PluginListInput, PluginListOutput, PluginAwaitActivationInput, PluginCheckInput, PluginCheckOutput, PluginUpdateInput, SessionListInput, SessionListOutput, SessionStatsInput, SessionStatsOutput, SessionCreateInput, SessionImportInput, SessionExportInput, SessionExportOutput, SessionActiveOutput, SessionGetInput, SessionRemoveInput, SessionForkInput, SessionSwitchAgentInput, SessionSwitchModelInput, SessionRenameInput, SessionMoveInput, SessionPromptInput, SessionCommandInput, SessionSkillInput, SessionSyntheticInput, SessionShellInput, SessionCompactInput, SessionWaitInput, SessionRevertStageInput, SessionRevertClearInput, SessionRevertCommitInput, SessionContextInput, SessionContextOutput, SessionDiffInput, SessionDiffOutput, SessionInboxListInput, SessionInboxListOutput, SessionInboxCancelInput, SessionInboxSteerInput, SessionInboxQueueInput, SessionInstructionsEntryListInput, SessionInstructionsEntryListOutput, SessionInstructionsEntryPutInput, SessionInstructionsEntryRemoveInput, SessionGenerateInput, SessionGenerateOutput, SessionLogInput, SessionLogOutput, SessionInterruptInput, SessionInterruptOutput, SessionBackgroundInput, SessionMessageInput, SessionEnvironmentInput, SessionViewInput, MessageListInput, MessageListOutput, ModelListInput, ModelListOutput, ModelDefaultInput, ModelDefaultOutput, GenerateTextInput, GenerateTextOutput, ProviderListInput, ProviderListOutput, ProviderGetInput, ProviderGetOutput, IntegrationListInput, IntegrationListOutput, IntegrationGetInput, IntegrationGetOutput, IntegrationWellknownAddInput, IntegrationConnectKeyInput, IntegrationOauthConnectInput, IntegrationOauthConnectOutput, IntegrationOauthStatusInput, IntegrationOauthStatusOutput, IntegrationOauthCompleteInput, IntegrationOauthCancelInput, IntegrationCommandConnectInput, IntegrationCommandConnectOutput, IntegrationCommandStatusInput, IntegrationCommandStatusOutput, IntegrationCommandCancelInput, McpListInput, McpListOutput, McpAddInput, McpRemoveInput, McpConnectInput, McpDisconnectInput, McpResourceCatalogInput, McpResourceCatalogOutput, CredentialUpdateInput, CredentialActivateInput, CredentialRemoveInput, ProjectListOutput, ProjectUpdateInput, FormRequestListInput, FormRequestListOutput, FormListInput, FormListOutput, FormCreateInput, FormGetInput, FormStateInput, FormReplyInput, FormCancelInput, PermissionRequestListInput, PermissionRequestListOutput, PermissionSavedListInput, PermissionSavedListOutput, PermissionSavedRemoveInput, PermissionCreateInput, PermissionCreateOutput, PermissionListInput, PermissionListOutput, PermissionGetInput, PermissionReplyInput, PermissionRulesInput, FileListInput, FileListOutput, FileFindInput, FileFindOutput, CommandListInput, CommandListOutput, SkillListInput, SkillListOutput, RpcCallInput, RpcCallOutput, PtyListInput, PtyListOutput, PtyCreateInput, PtyCreateOutput, PtyGetInput, PtyGetOutput, PtyUpdateInput, PtyUpdateOutput, PtyRemoveInput, PtyConnectTokenInput, PtyConnectTokenOutput, ExperimentalPersistentPtyReadInput, ExperimentalPersistentPtyReadOutput, ExperimentalPersistentPtyListInput, ExperimentalPersistentPtyListOutput, ExperimentalPersistentPtyCreateInput, ExperimentalPersistentPtyCreateOutput, ExperimentalPersistentPtyHandoffOutput, ExperimentalPersistentPtyGetInput, ExperimentalPersistentPtyGetOutput, ExperimentalPersistentPtyUpdateInput, ExperimentalPersistentPtyUpdateOutput, ExperimentalPersistentPtySnapshotInput, ExperimentalPersistentPtySnapshotOutput, ExperimentalPersistentPtyRemoveInput, ExperimentalPersistentPtyConnectTokenInput, ShellListInput, ShellListOutput, ShellCreateInput, ShellCreateOutput, ShellGetInput, ShellGetOutput, ShellTimeoutInput, ShellTimeoutOutput, ShellOutputInput, ShellOutputOutput, ShellRemoveInput, ReferenceListInput, ReferenceListOutput, WorktreeListInput, WorktreeCreateInput, WorktreeRemoveInput, WorktreeRefreshInput, WorkspaceCreateInput, WorkspaceDestroyInput, VcsGetInput, VcsGetOutput, VcsBaseInput, VcsBaseOutput, VcsStatusInput, VcsStatusOutput, VcsBranchesInput, VcsBranchesOutput, VcsDiffInput, VcsDiffOutput, DebugLocationListOutput, DebugLocationEvictInput, MigrationV1StatusOutput, WebsearchProvidersInput, WebsearchProvidersOutput, WebsearchQueryInput, WebsearchQueryOutput, ConfigGetInput, ConfigGetOutput, ConfigUpdatePreferencesInput, ConfigShellsOutput } from "../api/api.js";
5
5
  import { ClientError } from "./client-error.js";
6
6
  export declare const make: (options?: {
7
7
  readonly baseUrl?: URL | string;
8
8
  }) => Effect.Effect<{
9
- health: {
10
- get: () => Effect.Effect<HealthGetOutput, import("@opencode/protocol/errors").InvalidRequestError | import("@opencode/protocol/errors").UnauthorizedError | Schema.SchemaError | ClientError | HttpClientError.HttpClientError, never>;
11
- };
12
9
  server: {
13
- get: () => Effect.Effect<ServerGetOutput, import("@opencode/protocol/errors").InvalidRequestError | import("@opencode/protocol/errors").UnauthorizedError | Schema.SchemaError | ClientError | HttpClientError.HttpClientError, never>;
10
+ status: () => Effect.Effect<ServerStatusOutput, import("@opencode/protocol/errors").InvalidRequestError | import("@opencode/protocol/errors").UnauthorizedError | Schema.SchemaError | ClientError | HttpClientError.HttpClientError, never>;
14
11
  };
15
12
  location: {
16
13
  get: (input?: LocationGetInput) => Effect.Effect<import("@opencode/schema/location").Info, import("@opencode/protocol/errors").InvalidRequestError | import("@opencode/protocol/errors").UnauthorizedError | Schema.SchemaError | ClientError | HttpClientError.HttpClientError, never>;
@@ -10,10 +10,8 @@ const mapClientError = (error) => HttpClientError.isHttpClientError(error) || Sc
10
10
  : error;
11
11
  const preserveEffect = () => (effect) => effect;
12
12
  const preserveStream = () => (stream) => stream;
13
- const EndpointHealthGet = (raw) => () => preserveEffect()(raw["health.get"]({}).pipe(Effect.mapError(mapClientError)));
14
- const adaptGroupHealth = (raw) => ({ get: EndpointHealthGet(raw) });
15
- const EndpointServerGet = (raw) => () => preserveEffect()(raw["server.get"]({}).pipe(Effect.mapError(mapClientError)));
16
- const adaptGroupServer = (raw) => ({ get: EndpointServerGet(raw) });
13
+ const EndpointServerStatus = (raw) => () => preserveEffect()(raw["server.status"]({}).pipe(Effect.mapError(mapClientError)));
14
+ const adaptGroupServer = (raw) => ({ status: EndpointServerStatus(raw) });
17
15
  const EndpointLocationGet = (raw) => (input) => preserveEffect()(raw["location.get"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError)));
18
16
  const adaptGroupLocation = (raw) => ({ get: EndpointLocationGet(raw) });
19
17
  const EndpointAgentList = (raw) => (input) => preserveEffect()(raw["agent.list"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError)));
@@ -578,7 +576,6 @@ const adaptGroupConfig = (raw) => ({
578
576
  shells: EndpointConfigShells(raw),
579
577
  });
580
578
  const adaptClient = (raw) => ({
581
- health: adaptGroupHealth(raw["server.health"]),
582
579
  server: adaptGroupServer(raw["server.server"]),
583
580
  location: adaptGroupLocation(raw["server.location"]),
584
581
  agent: adaptGroupAgent(raw["server.agent"]),
@@ -1,4 +1,4 @@
1
- import { ServiceStatus } from "@opencode/protocol/groups/health";
1
+ import { ServerStatus } from "@opencode/protocol/groups/server";
2
2
  import { Effect, FileSystem, Option, Schedule, Schema } from "effect";
3
3
  import { homedir } from "node:os";
4
4
  import { join } from "node:path";
@@ -29,7 +29,7 @@ export const discover = Effect.fn("service.discover")(function* (options = {}) {
29
29
  export const incumbent = Effect.fn("service.incumbent")(function* (options) {
30
30
  const info = yield* read(options.file);
31
31
  const found = info === undefined ? undefined : yield* probe({ ...info, url: options.url });
32
- if (found === undefined || found.legacy)
32
+ if (found === undefined)
33
33
  return undefined;
34
34
  if (!matchesVersion(found.version, options))
35
35
  return undefined;
@@ -65,7 +65,7 @@ export const ensure = Effect.fn("service.ensure")(function* (options = {}) {
65
65
  });
66
66
  });
67
67
  const found = yield* Effect.gen(function* () {
68
- const registration = yield* registered(options.file, true, timing.requestTimeout);
68
+ const registration = yield* registered(options.file, timing.requestTimeout);
69
69
  const info = registration.info;
70
70
  const service = registration.service;
71
71
  if (registration.timedOut && info !== undefined) {
@@ -86,7 +86,7 @@ export const ensure = Effect.fn("service.ensure")(function* (options = {}) {
86
86
  timeouts = undefined;
87
87
  if (service !== undefined) {
88
88
  spawnDelay = timing.spawnDelay;
89
- const compatible = !service.legacy && matchesVersion(service.version, options);
89
+ const compatible = matchesVersion(service.version, options);
90
90
  if (compatible && service.state === "ready") {
91
91
  yield* Effect.tryPromise(() => PtyHandoff.complete(options.file ?? fallback(), service.info));
92
92
  return Option.some(service);
@@ -96,11 +96,11 @@ export const ensure = Effect.fn("service.ensure")(function* (options = {}) {
96
96
  if (compatible)
97
97
  return Option.none();
98
98
  yield* announce("version-mismatch", service.version);
99
- if (!service.legacy && service.state !== "ready")
99
+ if (service.state !== "ready")
100
100
  yield* Effect.logWarning("Background service is not ready; replacement cannot preserve persistent terminals");
101
101
  yield* stop({
102
102
  file: options.file,
103
- pty: !service.legacy && service.state === "ready" ? "handoff" : "clear",
103
+ pty: service.state === "ready" ? "handoff" : "clear",
104
104
  }).pipe(Effect.ignore);
105
105
  lastSpawn = 0;
106
106
  return Option.none();
@@ -159,8 +159,7 @@ export const Info = Schema.Struct({
159
159
  password: Schema.optional(Schema.String),
160
160
  });
161
161
  const decode = Schema.decodeUnknownEffect(Schema.fromJsonString(Info));
162
- const decodeHealth = Schema.decodeUnknownOption(ServiceStatus.Health);
163
- const decodeLegacyHealth = Schema.decodeUnknownOption(Schema.Struct({ healthy: Schema.Literal(true) }));
162
+ const decodeStatus = Schema.decodeUnknownOption(ServerStatus);
164
163
  // A missing or corrupt file means no valid info; callers treat both
165
164
  // the same (the registering server self-evicts, clients rediscover).
166
165
  const read = Effect.fnUntraced(function* (file) {
@@ -170,10 +169,10 @@ const read = Effect.fnUntraced(function* (file) {
170
169
  return undefined;
171
170
  return yield* decode(text.value).pipe(Effect.option, Effect.map(Option.getOrUndefined));
172
171
  });
173
- const probe = Effect.fnUntraced(function* (info, allowLegacy = false) {
174
- return (yield* probeResult(info, allowLegacy)).service;
172
+ const probe = Effect.fnUntraced(function* (info) {
173
+ return (yield* probeResult(info)).service;
175
174
  });
176
- const probeResult = Effect.fnUntraced(function* (info, allowLegacy = false, timeout = defaultEnsureTiming.requestTimeout) {
175
+ const probeResult = Effect.fnUntraced(function* (info, timeout = defaultEnsureTiming.requestTimeout) {
177
176
  const endpoint = {
178
177
  url: info.url,
179
178
  auth: info.password === undefined
@@ -181,47 +180,36 @@ const probeResult = Effect.fnUntraced(function* (info, allowLegacy = false, time
181
180
  : { type: "basic", username: "opencode", password: info.password },
182
181
  };
183
182
  const signal = AbortSignal.timeout(timeout);
184
- const result = yield* Effect.promise(() => fetch(new URL("/api/health", info.url), {
185
- headers: headers(endpoint),
186
- signal,
187
- })
183
+ const result = yield* Effect.promise(() => fetch(new URL("/api/status", info.url), { headers: headers(endpoint), signal })
188
184
  .then(async (response) => ({ response, body: (await response.json()) }))
189
185
  .then((value) => ({ value }), (cause) => ({ cause })));
190
186
  if ("cause" in result)
191
187
  return { service: undefined, timedOut: signal.aborted };
192
188
  const response = result.value.response;
193
189
  const body = result.value.body;
194
- const health = decodeHealth(body);
195
- if (Option.isSome(health)) {
196
- if (health.value.pid !== info.pid)
190
+ const status = decodeStatus(body);
191
+ if (Option.isSome(status)) {
192
+ if (status.value.pid !== info.pid)
197
193
  return { service: undefined, timedOut: false };
198
- if (info.version !== undefined && health.value.version !== info.version)
194
+ if (info.version !== undefined && status.value.version !== info.version)
199
195
  return { service: undefined, timedOut: false };
200
196
  return {
201
197
  service: {
202
198
  info,
203
199
  endpoint,
204
- version: health.value.version,
200
+ version: status.value.version,
205
201
  state: response.ok ? "ready" : response.status === 500 ? "failed" : "waiting",
206
- legacy: false,
207
202
  },
208
203
  timedOut: false,
209
204
  };
210
205
  }
211
- if (!allowLegacy ||
212
- Option.isNone(decodeLegacyHealth(body)) ||
213
- (typeof body === "object" && body !== null && ("version" in body || "pid" in body)))
214
- return { service: undefined, timedOut: false };
215
- return {
216
- service: { info, endpoint, state: "ready", legacy: true },
217
- timedOut: false,
218
- };
206
+ return { service: undefined, timedOut: false };
219
207
  });
220
- const registered = Effect.fnUntraced(function* (file, allowLegacy = false, timeout) {
208
+ const registered = Effect.fnUntraced(function* (file, timeout) {
221
209
  const info = yield* read(file);
222
210
  if (info === undefined)
223
211
  return { info: undefined, service: undefined, timedOut: false };
224
- return { info, ...(yield* probeResult(info, allowLegacy, timeout)) };
212
+ return { info, ...(yield* probeResult(info, timeout)) };
225
213
  });
226
214
  // 50ms cadence bounded at ~5s, shared by stop escalation and each ensure
227
215
  // discovery window.
@@ -10,11 +10,8 @@ export declare function make(options: ClientOptions): {
10
10
  event: {
11
11
  subscribe(options?: SharedEvents.SubscribeOptions): AsyncIterable<import("./index.js").V2Event>;
12
12
  };
13
- health: {
14
- get: (requestOptions?: OpenCode.RequestOptions) => Promise<import("./index.js").ServiceHealth>;
15
- };
16
13
  server: {
17
- get: (requestOptions?: OpenCode.RequestOptions) => Promise<import("./index.js").ServerGetOutput>;
14
+ status: (requestOptions?: OpenCode.RequestOptions) => Promise<import("./index.js").ServerStatus>;
18
15
  };
19
16
  location: {
20
17
  get: (input?: import("./index.js").LocationGetInput, requestOptions?: OpenCode.RequestOptions) => Promise<import("./index.js").LocationGetOutput>;
@@ -1,4 +1,4 @@
1
- import type { ServerGetOutput, LocationGetInput, LocationGetOutput, AgentListInput, AgentListOutput, AgentGetInput, AgentGetOutput, PluginListInput, PluginListOutput, PluginAwaitActivationInput, PluginCheckInput, PluginCheckOutput, PluginUpdateInput, SessionListInput, SessionStatsInput, SessionCreateInput, SessionImportInput, SessionExportInput, SessionGetInput, SessionRemoveInput, SessionForkInput, SessionSwitchAgentInput, SessionSwitchModelInput, SessionRenameInput, SessionMoveInput, SessionPromptInput, SessionCommandInput, SessionSkillInput, SessionSyntheticInput, SessionShellInput, SessionCompactInput, SessionWaitInput, SessionRevertStageInput, SessionRevertClearInput, SessionRevertCommitInput, SessionContextInput, SessionDiffInput, SessionInboxListInput, SessionInboxCancelInput, SessionInboxSteerInput, SessionInboxQueueInput, SessionInstructionsEntryListInput, SessionInstructionsEntryPutInput, SessionInstructionsEntryRemoveInput, SessionGenerateInput, SessionLogInput, SessionLogOutput, SessionInterruptInput, SessionBackgroundInput, SessionMessageInput, SessionEnvironmentInput, SessionViewInput, MessageListInput, ModelListInput, ModelListOutput, ModelDefaultInput, ModelDefaultOutput, GenerateTextInput, ProviderListInput, ProviderListOutput, ProviderGetInput, ProviderGetOutput, IntegrationListInput, IntegrationListOutput, IntegrationGetInput, IntegrationGetOutput, IntegrationWellknownAddInput, IntegrationConnectKeyInput, IntegrationOauthConnectInput, IntegrationOauthConnectOutput, IntegrationOauthStatusInput, IntegrationOauthStatusOutput, IntegrationOauthCompleteInput, IntegrationOauthCancelInput, IntegrationCommandConnectInput, IntegrationCommandConnectOutput, IntegrationCommandStatusInput, IntegrationCommandStatusOutput, IntegrationCommandCancelInput, McpListInput, McpListOutput, McpAddInput, McpRemoveInput, McpConnectInput, McpDisconnectInput, McpResourceCatalogInput, McpResourceCatalogOutput, CredentialUpdateInput, CredentialActivateInput, CredentialRemoveInput, ProjectListOutput, ProjectUpdateInput, FormRequestListInput, FormRequestListOutput, FormListInput, FormCreateInput, FormGetInput, FormStateInput, FormReplyInput, FormCancelInput, PermissionRequestListInput, PermissionRequestListOutput, PermissionSavedListInput, PermissionSavedRemoveInput, PermissionCreateInput, PermissionListInput, PermissionGetInput, PermissionReplyInput, PermissionRulesInput, FileReadInput, FileReadOutput, FileListInput, FileListOutput, FileFindInput, FileFindOutput, CommandListInput, CommandListOutput, SkillListInput, SkillListOutput, RpcCallInput, EventSubscribeOutput, PtyListInput, PtyListOutput, PtyCreateInput, PtyCreateOutput, PtyGetInput, PtyGetOutput, PtyUpdateInput, PtyUpdateOutput, PtyRemoveInput, PtyConnectTokenInput, PtyConnectTokenOutput, ExperimentalPersistentPtyReadInput, ExperimentalPersistentPtyListInput, ExperimentalPersistentPtyCreateInput, ExperimentalPersistentPtyHandoffOutput, ExperimentalPersistentPtyGetInput, ExperimentalPersistentPtyUpdateInput, ExperimentalPersistentPtySnapshotInput, ExperimentalPersistentPtyRemoveInput, ExperimentalPersistentPtyConnectTokenInput, ShellListInput, ShellListOutput, ShellCreateInput, ShellCreateOutput, ShellGetInput, ShellGetOutput, ShellTimeoutInput, ShellTimeoutOutput, ShellOutputInput, ShellOutputOutput, ShellRemoveInput, ReferenceListInput, ReferenceListOutput, WorktreeListInput, WorktreeCreateInput, WorktreeRemoveInput, WorktreeRefreshInput, WorkspaceCreateInput, WorkspaceDestroyInput, VcsGetInput, VcsGetOutput, VcsBaseInput, VcsBaseOutput, VcsStatusInput, VcsStatusOutput, VcsBranchesInput, VcsBranchesOutput, VcsDiffInput, VcsDiffOutput, DebugLocationListOutput, DebugLocationEvictInput, MigrationV1StatusOutput, WebsearchProvidersInput, WebsearchProvidersOutput, WebsearchQueryInput, WebsearchQueryOutput, ConfigGetInput, ConfigGetOutput, ConfigUpdatePreferencesInput, ConfigShellsOutput } from "./types.js";
1
+ import type { LocationGetInput, LocationGetOutput, AgentListInput, AgentListOutput, AgentGetInput, AgentGetOutput, PluginListInput, PluginListOutput, PluginAwaitActivationInput, PluginCheckInput, PluginCheckOutput, PluginUpdateInput, SessionListInput, SessionStatsInput, SessionCreateInput, SessionImportInput, SessionExportInput, SessionGetInput, SessionRemoveInput, SessionForkInput, SessionSwitchAgentInput, SessionSwitchModelInput, SessionRenameInput, SessionMoveInput, SessionPromptInput, SessionCommandInput, SessionSkillInput, SessionSyntheticInput, SessionShellInput, SessionCompactInput, SessionWaitInput, SessionRevertStageInput, SessionRevertClearInput, SessionRevertCommitInput, SessionContextInput, SessionDiffInput, SessionInboxListInput, SessionInboxCancelInput, SessionInboxSteerInput, SessionInboxQueueInput, SessionInstructionsEntryListInput, SessionInstructionsEntryPutInput, SessionInstructionsEntryRemoveInput, SessionGenerateInput, SessionLogInput, SessionLogOutput, SessionInterruptInput, SessionBackgroundInput, SessionMessageInput, SessionEnvironmentInput, SessionViewInput, MessageListInput, ModelListInput, ModelListOutput, ModelDefaultInput, ModelDefaultOutput, GenerateTextInput, ProviderListInput, ProviderListOutput, ProviderGetInput, ProviderGetOutput, IntegrationListInput, IntegrationListOutput, IntegrationGetInput, IntegrationGetOutput, IntegrationWellknownAddInput, IntegrationConnectKeyInput, IntegrationOauthConnectInput, IntegrationOauthConnectOutput, IntegrationOauthStatusInput, IntegrationOauthStatusOutput, IntegrationOauthCompleteInput, IntegrationOauthCancelInput, IntegrationCommandConnectInput, IntegrationCommandConnectOutput, IntegrationCommandStatusInput, IntegrationCommandStatusOutput, IntegrationCommandCancelInput, McpListInput, McpListOutput, McpAddInput, McpRemoveInput, McpConnectInput, McpDisconnectInput, McpResourceCatalogInput, McpResourceCatalogOutput, CredentialUpdateInput, CredentialActivateInput, CredentialRemoveInput, ProjectListOutput, ProjectUpdateInput, FormRequestListInput, FormRequestListOutput, FormListInput, FormCreateInput, FormGetInput, FormStateInput, FormReplyInput, FormCancelInput, PermissionRequestListInput, PermissionRequestListOutput, PermissionSavedListInput, PermissionSavedRemoveInput, PermissionCreateInput, PermissionListInput, PermissionGetInput, PermissionReplyInput, PermissionRulesInput, FileReadInput, FileReadOutput, FileListInput, FileListOutput, FileFindInput, FileFindOutput, CommandListInput, CommandListOutput, SkillListInput, SkillListOutput, RpcCallInput, EventSubscribeOutput, PtyListInput, PtyListOutput, PtyCreateInput, PtyCreateOutput, PtyGetInput, PtyGetOutput, PtyUpdateInput, PtyUpdateOutput, PtyRemoveInput, PtyConnectTokenInput, PtyConnectTokenOutput, ExperimentalPersistentPtyReadInput, ExperimentalPersistentPtyListInput, ExperimentalPersistentPtyCreateInput, ExperimentalPersistentPtyHandoffOutput, ExperimentalPersistentPtyGetInput, ExperimentalPersistentPtyUpdateInput, ExperimentalPersistentPtySnapshotInput, ExperimentalPersistentPtyRemoveInput, ExperimentalPersistentPtyConnectTokenInput, ShellListInput, ShellListOutput, ShellCreateInput, ShellCreateOutput, ShellGetInput, ShellGetOutput, ShellTimeoutInput, ShellTimeoutOutput, ShellOutputInput, ShellOutputOutput, ShellRemoveInput, ReferenceListInput, ReferenceListOutput, WorktreeListInput, WorktreeCreateInput, WorktreeRemoveInput, WorktreeRefreshInput, WorkspaceCreateInput, WorkspaceDestroyInput, VcsGetInput, VcsGetOutput, VcsBaseInput, VcsBaseOutput, VcsStatusInput, VcsStatusOutput, VcsBranchesInput, VcsBranchesOutput, VcsDiffInput, VcsDiffOutput, DebugLocationListOutput, DebugLocationEvictInput, MigrationV1StatusOutput, WebsearchProvidersInput, WebsearchProvidersOutput, WebsearchQueryInput, WebsearchQueryOutput, ConfigGetInput, ConfigGetOutput, ConfigUpdatePreferencesInput, ConfigShellsOutput } from "./types.js";
2
2
  export interface ClientOptions {
3
3
  readonly baseUrl: string;
4
4
  readonly fetch?: typeof globalThis.fetch;
@@ -11,11 +11,8 @@ export interface RequestOptions {
11
11
  readonly onActivity?: () => void;
12
12
  }
13
13
  export declare function make(options: ClientOptions): {
14
- health: {
15
- get: (requestOptions?: RequestOptions) => Promise<import("./types.js").ServiceHealth>;
16
- };
17
14
  server: {
18
- get: (requestOptions?: RequestOptions) => Promise<ServerGetOutput>;
15
+ status: (requestOptions?: RequestOptions) => Promise<import("./types.js").ServerStatus>;
19
16
  };
20
17
  location: {
21
18
  get: (input?: LocationGetInput, requestOptions?: RequestOptions) => Promise<LocationGetOutput>;
@@ -129,11 +129,8 @@ export function make(options) {
129
129
  },
130
130
  });
131
131
  return {
132
- health: {
133
- get: (requestOptions) => request({ method: "GET", path: `/api/health`, successStatus: 200, declaredStatuses: [400, 401], empty: false }, requestOptions),
134
- },
135
132
  server: {
136
- get: (requestOptions) => request({ method: "GET", path: `/api/server`, successStatus: 200, declaredStatuses: [400, 401], empty: false }, requestOptions),
133
+ status: (requestOptions) => request({ method: "GET", path: `/api/status`, successStatus: 200, declaredStatuses: [400, 401], empty: false }, requestOptions),
137
134
  },
138
135
  location: {
139
136
  get: (input, requestOptions) => request({
@@ -1,10 +1,10 @@
1
1
  export type JsonValue = null | boolean | number | string | Array<JsonValue> | {
2
2
  [key: string]: JsonValue;
3
3
  };
4
- export type ServiceHealth = {
5
- healthy: true;
4
+ export type ServerStatus = {
6
5
  version: string;
7
6
  pid: number;
7
+ urls: Array<string>;
8
8
  };
9
9
  export type ModelRef = {
10
10
  id: string;
@@ -3377,10 +3377,7 @@ export type WorktreeError = {
3377
3377
  };
3378
3378
  };
3379
3379
  export declare const isWorktreeError: (value: unknown) => value is WorktreeError;
3380
- export type HealthGetOutput = ServiceHealth;
3381
- export type ServerGetOutput = {
3382
- urls: Array<string>;
3383
- };
3380
+ export type ServerStatusOutput = ServerStatus;
3384
3381
  export type LocationGetInput = {
3385
3382
  readonly location?: {
3386
3383
  readonly location?: {
@@ -50,7 +50,7 @@ export async function ensure(options = {}) {
50
50
  while (true) {
51
51
  if (Date.now() >= deadline)
52
52
  throw new Error("Timed out waiting for the background service to start");
53
- const registration = await registered(options.file, true, timing.requestTimeout);
53
+ const registration = await registered(options.file, timing.requestTimeout);
54
54
  if (registration.timedOut && registration.info !== undefined) {
55
55
  timeouts = {
56
56
  info: registration.info,
@@ -70,7 +70,7 @@ export async function ensure(options = {}) {
70
70
  if (registration.service !== undefined) {
71
71
  spawnDelay = timing.spawnDelay;
72
72
  const service = registration.service;
73
- const compatible = !service.legacy && matchesVersion(service.version, options);
73
+ const compatible = matchesVersion(service.version, options);
74
74
  if (compatible && service.state === "ready") {
75
75
  await PtyHandoff.complete(options.file ?? fallback(), service.info);
76
76
  return service.endpoint;
@@ -79,11 +79,11 @@ export async function ensure(options = {}) {
79
79
  throw new Error("Background service failed to start");
80
80
  if (!compatible) {
81
81
  announce("version-mismatch", service.version);
82
- if (!service.legacy && service.state !== "ready")
82
+ if (service.state !== "ready")
83
83
  console.warn("Background service is not ready; replacement cannot preserve persistent terminals");
84
84
  await stop({
85
85
  file: options.file,
86
- pty: !service.legacy && service.state === "ready" ? "handoff" : "clear",
86
+ pty: service.state === "ready" ? "handoff" : "clear",
87
87
  }).catch(() => undefined);
88
88
  lastSpawn = 0;
89
89
  }
@@ -145,7 +145,7 @@ async function read(file) {
145
145
  return undefined;
146
146
  }
147
147
  }
148
- async function probeResult(info, allowLegacy = false, timeout = defaultEnsureTiming.requestTimeout) {
148
+ async function probeResult(info, timeout = defaultEnsureTiming.requestTimeout) {
149
149
  const endpoint = {
150
150
  url: info.url,
151
151
  auth: info.password === undefined
@@ -153,10 +153,7 @@ async function probeResult(info, allowLegacy = false, timeout = defaultEnsureTim
153
153
  : { type: "basic", username: "opencode", password: info.password },
154
154
  };
155
155
  const signal = AbortSignal.timeout(timeout);
156
- const result = await fetch(new URL("/api/health", info.url), {
157
- headers: headers(endpoint),
158
- signal,
159
- })
156
+ const result = await fetch(new URL("/api/status", info.url), { headers: headers(endpoint), signal })
160
157
  .then(async (response) => ({
161
158
  response,
162
159
  body: (await response.json()),
@@ -177,23 +174,17 @@ async function probeResult(info, allowLegacy = false, timeout = defaultEnsureTim
177
174
  endpoint,
178
175
  version: body.version,
179
176
  state: response.ok ? "ready" : response.status === 500 ? "failed" : "waiting",
180
- legacy: false,
181
177
  },
182
178
  timedOut: false,
183
179
  };
184
180
  }
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
- };
181
+ return { service: undefined, timedOut: false };
191
182
  }
192
- async function registered(file, allowLegacy = false, timeout) {
183
+ async function registered(file, timeout) {
193
184
  const info = await read(file);
194
185
  if (info === undefined)
195
186
  return { info: undefined, service: undefined, timedOut: false };
196
- return { info, ...(await probeResult(info, allowLegacy, timeout)) };
187
+ return { info, ...(await probeResult(info, timeout)) };
197
188
  }
198
189
  function signal(pid, name) {
199
190
  try {
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": "0.0.0-dev-19551",
4
+ "version": "0.0.0-dev-19553",
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": "0.0.0-dev-19551",
61
- "@opencode/protocol": "0.0.0-dev-19551"
60
+ "@opencode/schema": "0.0.0-dev-19553",
61
+ "@opencode/protocol": "0.0.0-dev-19553"
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": "0.0.0-dev-19551",
77
+ "@opencode/httpapi-codegen": "0.0.0-dev-19553",
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",