@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.
- package/dist/effect/api/api.d.ts +3 -11
- package/dist/effect/client.d.ts +1 -4
- package/dist/effect/generated/client.d.ts +2 -5
- package/dist/effect/generated/client.js +2 -5
- package/dist/effect/service.js +19 -31
- package/dist/promise/client.d.ts +1 -4
- package/dist/promise/generated/client.d.ts +2 -5
- package/dist/promise/generated/client.js +1 -4
- package/dist/promise/generated/types.d.ts +3 -6
- package/dist/promise/service.js +9 -18
- package/package.json +4 -4
package/dist/effect/api/api.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
46
|
+
export type ServerStatusOperation<E = never> = () => Effect.Effect<ServerStatusOutput, E>;
|
|
54
47
|
export interface ServerApi<E = never> {
|
|
55
|
-
readonly
|
|
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>;
|
package/dist/effect/client.d.ts
CHANGED
|
@@ -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
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
|
14
|
-
const
|
|
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"]),
|
package/dist/effect/service.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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,
|
|
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 =
|
|
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 (
|
|
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:
|
|
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
|
|
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
|
|
174
|
-
return (yield* probeResult(info
|
|
172
|
+
const probe = Effect.fnUntraced(function* (info) {
|
|
173
|
+
return (yield* probeResult(info)).service;
|
|
175
174
|
});
|
|
176
|
-
const probeResult = Effect.fnUntraced(function* (info,
|
|
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/
|
|
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
|
|
195
|
-
if (Option.isSome(
|
|
196
|
-
if (
|
|
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 &&
|
|
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:
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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.
|
package/dist/promise/client.d.ts
CHANGED
|
@@ -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
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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?: {
|
package/dist/promise/service.js
CHANGED
|
@@ -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,
|
|
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 =
|
|
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 (
|
|
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:
|
|
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,
|
|
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/
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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-
|
|
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-
|
|
61
|
-
"@opencode/protocol": "0.0.0-dev-
|
|
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-
|
|
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",
|