@opencode-ai/client 0.0.0-dev-17471

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +27 -0
  2. package/dist/contract.d.ts +1 -0
  3. package/dist/contract.js +1 -0
  4. package/dist/effect/api/api.d.ts +2155 -0
  5. package/dist/effect/api/api.js +0 -0
  6. package/dist/effect/api.d.ts +7 -0
  7. package/dist/effect/api.js +0 -0
  8. package/dist/effect/generated/client-error.d.ts +7 -0
  9. package/dist/effect/generated/client-error.js +5 -0
  10. package/dist/effect/generated/client.d.ts +2208 -0
  11. package/dist/effect/generated/client.js +460 -0
  12. package/dist/effect/generated/index.d.ts +2 -0
  13. package/dist/effect/generated/index.js +2 -0
  14. package/dist/effect/index.d.ts +32 -0
  15. package/dist/effect/index.js +28 -0
  16. package/dist/effect/service.d.ts +78 -0
  17. package/dist/effect/service.js +286 -0
  18. package/dist/promise/api.d.ts +18 -0
  19. package/dist/promise/api.js +0 -0
  20. package/dist/promise/generated/client-error.d.ts +6 -0
  21. package/dist/promise/generated/client-error.js +8 -0
  22. package/dist/promise/generated/client.d.ts +228 -0
  23. package/dist/promise/generated/client.js +1205 -0
  24. package/dist/promise/generated/index.d.ts +3 -0
  25. package/dist/promise/generated/index.js +3 -0
  26. package/dist/promise/generated/types.d.ts +7807 -0
  27. package/dist/promise/generated/types.js +26 -0
  28. package/dist/promise/index.d.ts +4 -0
  29. package/dist/promise/index.js +1 -0
  30. package/dist/promise/service.d.ts +26 -0
  31. package/dist/promise/service.js +273 -0
  32. package/dist/service-contender.d.ts +11 -0
  33. package/dist/service-contender.js +52 -0
  34. package/dist/service-timing.d.ts +13 -0
  35. package/dist/service-timing.js +19 -0
  36. package/dist/service-version.d.ts +2 -0
  37. package/dist/service-version.js +9 -0
  38. package/dist/service.d.ts +48 -0
  39. package/dist/service.js +0 -0
  40. package/package.json +75 -0
@@ -0,0 +1,26 @@
1
+ export const isUnauthorizedError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "UnauthorizedError";
2
+ export const isInvalidRequestError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "InvalidRequestError";
3
+ export const isAgentNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "AgentNotFoundError";
4
+ export const isInvalidCursorError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "InvalidCursorError";
5
+ export const isConflictError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "ConflictError";
6
+ export const isSessionNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "SessionNotFoundError";
7
+ export const isUnknownError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "UnknownError";
8
+ export const isMessageNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "MessageNotFoundError";
9
+ export const isCommandNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "CommandNotFoundError";
10
+ export const isCommandEvaluationError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "CommandEvaluationError";
11
+ export const isSkillNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "SkillNotFoundError";
12
+ export const isServiceUnavailableError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "ServiceUnavailableError";
13
+ export const isSessionBusyError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "SessionBusyError";
14
+ export const isInstructionEntryValueTooLargeError = (value) => typeof value === "object" &&
15
+ value !== null &&
16
+ "_tag" in value &&
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 isFormNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "FormNotFoundError";
21
+ export const isFormAlreadySettledError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "FormAlreadySettledError";
22
+ export const isFormInvalidAnswerError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "FormInvalidAnswerError";
23
+ export const isPermissionNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "PermissionNotFoundError";
24
+ export const isPtyNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "PtyNotFoundError";
25
+ export const isShellNotFoundError = (value) => typeof value === "object" && value !== null && "_tag" in value && value["_tag"] === "ShellNotFoundError";
26
+ export const isWorktreeError = (value) => typeof value === "object" && value !== null && "name" in value && value["name"] === "WorktreeError";
@@ -0,0 +1,4 @@
1
+ export * from "./generated/index.js";
2
+ export type { AgentApi, CatalogApi, CommandApi, ConfigApi, EventApi, IntegrationApi, ModelApi, PluginApi, ProviderApi, ReferenceApi, WebSearchApi, SessionApi, SkillApi, } from "./api.js";
3
+ export type { EventSubscribeOutput as OpenCodeEvent } from "./generated/types.js";
4
+ export type OpenCodeClient = ReturnType<typeof import("./generated/client.js").make>;
@@ -0,0 +1 @@
1
+ export * from "./generated/index.js";
@@ -0,0 +1,26 @@
1
+ import type { DiscoverOptions, Endpoint, EnsureOptions, StopOptions } from "../service.js";
2
+ export * from "../service.js";
3
+ /** Discover a healthy, compatible local service without starting one. */
4
+ export declare function discover(options?: DiscoverOptions): Promise<{
5
+ url: string;
6
+ auth: {
7
+ type: "basic";
8
+ username: string;
9
+ password: string;
10
+ } | undefined;
11
+ } | undefined>;
12
+ /** Ensure a healthy, compatible local service is running. */
13
+ export declare function ensure(options?: EnsureOptions): Promise<Endpoint>;
14
+ /** Stop the registered local service. */
15
+ export declare function stop(options?: StopOptions): Promise<void>;
16
+ /** Create HTTP authentication headers for a service endpoint. */
17
+ export declare function headers(endpoint: Endpoint): {
18
+ authorization: string;
19
+ } | undefined;
20
+ /** Promise-based local service lifecycle operations. */
21
+ export declare const Service: {
22
+ discover: typeof discover;
23
+ ensure: typeof ensure;
24
+ stop: typeof stop;
25
+ headers: typeof headers;
26
+ };
@@ -0,0 +1,273 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { contenderFailure, contenderFinished, spawnServiceContender, } from "../service-contender.js";
5
+ import { defaultEnsureTiming, ensureTiming } from "../service-timing.js";
6
+ import { matchesVersion } from "../service-version.js";
7
+ export * from "../service.js";
8
+ // Find, start, and stop the local opencode background service.
9
+ //
10
+ // The registration file is the complete discovery contract. This module is
11
+ // intentionally implemented with Node APIs so Promise clients do not need
12
+ // Effect or @effect/platform-node at runtime.
13
+ /** Discover a healthy, compatible local service without starting one. */
14
+ export async function discover(options = {}) {
15
+ return (await discoverLocal(options))?.endpoint;
16
+ }
17
+ async function discoverLocal(options) {
18
+ const found = (await registered(options.file)).service;
19
+ if (found?.state !== "ready")
20
+ return undefined;
21
+ if (!matchesVersion(found.version, options))
22
+ return undefined;
23
+ return found;
24
+ }
25
+ /** Ensure a healthy, compatible local service is running. */
26
+ export async function ensure(options = {}) {
27
+ const timing = ensureTiming(options);
28
+ const deadline = Date.now() + timing.promiseTimeout;
29
+ const contenders = new Set();
30
+ let timeouts;
31
+ let announced = false;
32
+ let lastSpawn = 0;
33
+ let spawnDelay = timing.spawnDelay;
34
+ const announce = (reason, previousVersion) => {
35
+ if (announced)
36
+ return;
37
+ announced = true;
38
+ options.onStart?.(reason, previousVersion);
39
+ };
40
+ const spawnContender = () => {
41
+ const [command, ...args] = options.command ?? ["opencode", "serve", "--service"];
42
+ if (command === undefined)
43
+ throw new Error("Missing service command");
44
+ try {
45
+ return spawnServiceContender(command, args);
46
+ }
47
+ catch (cause) {
48
+ throw new Error("Failed to start server", { cause });
49
+ }
50
+ };
51
+ try {
52
+ while (true) {
53
+ if (Date.now() >= deadline)
54
+ throw new Error("Timed out waiting for the background service to start");
55
+ const registration = await registered(options.file, true, timing.requestTimeout);
56
+ if (registration.timedOut && registration.info !== undefined) {
57
+ timeouts = {
58
+ info: registration.info,
59
+ count: timeouts !== undefined && same(timeouts.info, registration.info) ? timeouts.count + 1 : 1,
60
+ };
61
+ if (timeouts.count >= 3) {
62
+ announce("missing");
63
+ await evict(registration.info, options, timing);
64
+ timeouts = undefined;
65
+ lastSpawn = Date.now() - spawnDelay;
66
+ }
67
+ }
68
+ else
69
+ timeouts = undefined;
70
+ if (registration.service !== undefined) {
71
+ spawnDelay = timing.spawnDelay;
72
+ const service = registration.service;
73
+ const compatible = !service.legacy && matchesVersion(service.version, options);
74
+ if (compatible && service.state === "ready")
75
+ return service.endpoint;
76
+ if (compatible && service.state === "failed")
77
+ throw new Error("Background service failed to start");
78
+ if (!compatible) {
79
+ announce("version-mismatch", service.version);
80
+ await kill(service, options, timing).catch(() => undefined);
81
+ lastSpawn = 0;
82
+ }
83
+ }
84
+ else {
85
+ if (lastSpawn === 0 && registration.info !== undefined)
86
+ lastSpawn = Date.now();
87
+ const finished = [...contenders].filter(contenderFinished);
88
+ const failure = finished.map(contenderFailure).find((error) => error !== undefined);
89
+ if (finished.some((item) => item.child.exitCode === 0)) {
90
+ spawnDelay = Math.min(spawnDelay * 2, timing.maxSpawnDelay);
91
+ }
92
+ finished.forEach((item) => contenders.delete(item));
93
+ if (failure !== undefined && contenders.size === 0)
94
+ throw failure;
95
+ // Keep one candidate plus one lock probe so a pre-lock stall cannot block recovery.
96
+ if (contenders.size < 2 && Date.now() - lastSpawn >= spawnDelay) {
97
+ announce("missing");
98
+ contenders.add(spawnContender());
99
+ lastSpawn = Date.now();
100
+ }
101
+ }
102
+ await delay(timing.pollInterval);
103
+ }
104
+ }
105
+ finally {
106
+ contenders.forEach((contender) => contender.release());
107
+ }
108
+ }
109
+ /** Stop the registered local service. */
110
+ export async function stop(options = {}) {
111
+ const existing = await find(options);
112
+ if (existing !== undefined)
113
+ await kill(existing, options, defaultEnsureTiming);
114
+ }
115
+ function fallback() {
116
+ return join(process.env["XDG_STATE_HOME"] ?? join(homedir(), ".local", "state"), "opencode", "service.json");
117
+ }
118
+ /** Create HTTP authentication headers for a service endpoint. */
119
+ export function headers(endpoint) {
120
+ if (endpoint.auth === undefined)
121
+ return undefined;
122
+ return {
123
+ authorization: "Basic " + Buffer.from(endpoint.auth.username + ":" + endpoint.auth.password).toString("base64"),
124
+ };
125
+ }
126
+ async function read(file) {
127
+ const text = await readFile(file ?? fallback(), "utf8").catch(() => undefined);
128
+ if (text === undefined)
129
+ return undefined;
130
+ try {
131
+ return JSON.parse(text);
132
+ }
133
+ catch {
134
+ return undefined;
135
+ }
136
+ }
137
+ async function probe(info, allowLegacy = false) {
138
+ return (await probeResult(info, allowLegacy)).service;
139
+ }
140
+ async function probeResult(info, allowLegacy = false, timeout = defaultEnsureTiming.requestTimeout) {
141
+ const endpoint = {
142
+ url: info.url,
143
+ auth: info.password === undefined
144
+ ? undefined
145
+ : { type: "basic", username: "opencode", password: info.password },
146
+ };
147
+ const signal = AbortSignal.timeout(timeout);
148
+ const result = await fetch(new URL("/api/health", info.url), {
149
+ headers: headers(endpoint),
150
+ signal,
151
+ })
152
+ .then(async (response) => ({
153
+ response,
154
+ body: (await response.json()),
155
+ }))
156
+ .then((value) => ({ value }), (cause) => ({ cause }));
157
+ if ("cause" in result)
158
+ return { service: undefined, timedOut: signal.aborted };
159
+ const response = result.value.response;
160
+ const body = result.value.body;
161
+ if (body !== undefined && "version" in body && "pid" in body) {
162
+ if (body.pid !== info.pid)
163
+ return { service: undefined, timedOut: false };
164
+ if (info.version !== undefined && body.version !== info.version)
165
+ return { service: undefined, timedOut: false };
166
+ return {
167
+ service: {
168
+ info,
169
+ endpoint,
170
+ version: body.version,
171
+ state: response.ok ? "ready" : response.status === 500 ? "failed" : "waiting",
172
+ legacy: false,
173
+ },
174
+ timedOut: false,
175
+ };
176
+ }
177
+ if (!allowLegacy || body?.healthy !== true)
178
+ return { service: undefined, timedOut: false };
179
+ return {
180
+ service: { info, endpoint, state: "ready", legacy: true },
181
+ timedOut: false,
182
+ };
183
+ }
184
+ async function registered(file, allowLegacy = false, timeout) {
185
+ const info = await read(file);
186
+ if (info === undefined)
187
+ return { info: undefined, service: undefined, timedOut: false };
188
+ return { info, ...(await probeResult(info, allowLegacy, timeout)) };
189
+ }
190
+ async function find(options) {
191
+ return (await registered(options.file, true)).service;
192
+ }
193
+ function signal(pid, name) {
194
+ try {
195
+ process.kill(pid, name);
196
+ }
197
+ catch { }
198
+ }
199
+ function stopped(pid) {
200
+ try {
201
+ process.kill(pid, 0);
202
+ return false;
203
+ }
204
+ catch {
205
+ return true;
206
+ }
207
+ }
208
+ async function waitUntilStopped(pid, timing) {
209
+ for (let attempt = 0; attempt <= timing.stopPollAttempts; attempt++) {
210
+ if (stopped(pid))
211
+ return true;
212
+ if (attempt < timing.stopPollAttempts)
213
+ await delay(timing.stopPollInterval);
214
+ }
215
+ return false;
216
+ }
217
+ function same(left, right) {
218
+ return left.id === right.id && left.version === right.version && left.url === right.url && left.pid === right.pid;
219
+ }
220
+ async function evict(info, options, timing) {
221
+ const current = await read(options.file);
222
+ if (current === undefined || !same(current, info))
223
+ return;
224
+ signal(info.pid, "SIGTERM");
225
+ if (await waitUntilStopped(info.pid, timing))
226
+ return;
227
+ const latest = await read(options.file);
228
+ if (latest === undefined || !same(latest, info))
229
+ return;
230
+ signal(info.pid, "SIGKILL");
231
+ if (!(await waitUntilStopped(info.pid, timing)))
232
+ throw new Error(`Server process ${info.pid} is still running`);
233
+ }
234
+ async function kill(service, options, timing) {
235
+ const requested = await requestStop(service, timing.requestTimeout);
236
+ if (requested === "rejected")
237
+ return;
238
+ if (requested === "unsupported") {
239
+ const current = await find(options);
240
+ if (current === undefined || !same(current.info, service.info))
241
+ return;
242
+ signal(service.info.pid, "SIGTERM");
243
+ }
244
+ if (await waitUntilStopped(service.info.pid, timing))
245
+ return;
246
+ const latest = await find(options);
247
+ if (latest === undefined || !same(latest.info, service.info))
248
+ return;
249
+ signal(service.info.pid, "SIGKILL");
250
+ if (!(await waitUntilStopped(service.info.pid, timing)))
251
+ throw new Error(`Server process ${service.info.pid} is still running`);
252
+ }
253
+ async function requestStop(service, timeout = defaultEnsureTiming.requestTimeout) {
254
+ if (service.info.id === undefined || service.legacy)
255
+ return "unsupported";
256
+ const response = await fetch(new URL("/api/service/stop", service.info.url), {
257
+ method: "POST",
258
+ headers: { ...headers(service.endpoint), "content-type": "application/json" },
259
+ body: JSON.stringify({ instanceID: service.info.id }),
260
+ signal: AbortSignal.timeout(timeout),
261
+ }).catch(() => undefined);
262
+ if (response === undefined || response.status === 404 || response.status === 405)
263
+ return "unsupported";
264
+ const body = (await response.json().catch(() => undefined));
265
+ if (!response.ok || body?.accepted !== true)
266
+ return "rejected";
267
+ return "accepted";
268
+ }
269
+ function delay(milliseconds) {
270
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
271
+ }
272
+ /** Promise-based local service lifecycle operations. */
273
+ export const Service = { discover, ensure, stop, headers };
@@ -0,0 +1,11 @@
1
+ import { type ChildProcess } from "node:child_process";
2
+ export type ServiceContender = {
3
+ readonly child: ChildProcess;
4
+ readonly error: () => Error | undefined;
5
+ readonly closed: () => boolean;
6
+ readonly stderr: () => string;
7
+ readonly release: () => void;
8
+ };
9
+ export declare function spawnServiceContender(command: string, args: ReadonlyArray<string>): ServiceContender;
10
+ export declare function contenderFailure(contender: ServiceContender): Error | undefined;
11
+ export declare function contenderFinished(contender: ServiceContender): boolean;
@@ -0,0 +1,52 @@
1
+ import { spawn } from "node:child_process";
2
+ const stderrLimit = 8 * 1024;
3
+ export function spawnServiceContender(command, args) {
4
+ const child = spawn(command, args, { detached: true, stdio: ["ignore", "ignore", "pipe"] });
5
+ let error;
6
+ let closed = false;
7
+ let stderr = Buffer.alloc(0);
8
+ const onStderr = (chunk) => {
9
+ const tail = chunk.subarray(-stderrLimit);
10
+ stderr =
11
+ tail.length === stderrLimit
12
+ ? Buffer.from(tail)
13
+ : Buffer.concat([stderr.subarray(-(stderrLimit - tail.length)), tail]);
14
+ };
15
+ child.stderr?.on("data", onStderr);
16
+ if (child.stderr !== null && "unref" in child.stderr && typeof child.stderr.unref === "function")
17
+ child.stderr.unref();
18
+ child.once("error", (cause) => {
19
+ error = new Error("Failed to start server", { cause });
20
+ });
21
+ child.once("close", () => {
22
+ closed = true;
23
+ });
24
+ child.unref();
25
+ return {
26
+ child,
27
+ error: () => error,
28
+ closed: () => closed,
29
+ stderr: () => stderr.toString("utf8").trim(),
30
+ release: () => {
31
+ child.stderr?.off("data", onStderr);
32
+ child.stderr?.resume();
33
+ stderr = Buffer.alloc(0);
34
+ },
35
+ };
36
+ }
37
+ export function contenderFailure(contender) {
38
+ const error = contender.error();
39
+ if (error !== undefined)
40
+ return error;
41
+ if (contender.child.exitCode !== null && contender.child.exitCode !== 0)
42
+ return startupError(`Server process exited with code ${contender.child.exitCode}`, contender.stderr());
43
+ if (contender.child.signalCode !== null)
44
+ return startupError(`Server process terminated by ${contender.child.signalCode}`, contender.stderr());
45
+ return undefined;
46
+ }
47
+ export function contenderFinished(contender) {
48
+ return contender.error() !== undefined || contender.closed();
49
+ }
50
+ function startupError(message, stderr) {
51
+ return new Error(stderr ? `${message}\n${stderr}` : message);
52
+ }
@@ -0,0 +1,13 @@
1
+ export type EnsureTiming = {
2
+ readonly pollInterval: number;
3
+ readonly attempts: number;
4
+ readonly requestTimeout: number;
5
+ readonly spawnDelay: number;
6
+ readonly maxSpawnDelay: number;
7
+ readonly promiseTimeout: number;
8
+ readonly stopPollInterval: number;
9
+ readonly stopPollAttempts: number;
10
+ };
11
+ export declare const defaultEnsureTiming: EnsureTiming;
12
+ export declare function ensureTiming(options: object): EnsureTiming;
13
+ export declare function withEnsureTiming<A extends object>(options: A, overrides: Partial<EnsureTiming>): A;
@@ -0,0 +1,19 @@
1
+ const timings = new WeakMap();
2
+ export const defaultEnsureTiming = {
3
+ pollInterval: 1_000,
4
+ attempts: 120,
5
+ requestTimeout: 2_000,
6
+ spawnDelay: 5_000,
7
+ maxSpawnDelay: 30_000,
8
+ promiseTimeout: 120_000,
9
+ stopPollInterval: 50,
10
+ stopPollAttempts: 100,
11
+ };
12
+ export function ensureTiming(options) {
13
+ return timings.get(options) ?? defaultEnsureTiming;
14
+ }
15
+ // Keep test timing out of the public lifecycle option types.
16
+ export function withEnsureTiming(options, overrides) {
17
+ timings.set(options, { ...defaultEnsureTiming, ...overrides });
18
+ return options;
19
+ }
@@ -0,0 +1,2 @@
1
+ import type { DiscoverOptions } from "./service.js";
2
+ export declare function matchesVersion(version: string | undefined, options: DiscoverOptions): boolean;
@@ -0,0 +1,9 @@
1
+ export function matchesVersion(version, options) {
2
+ if (options.version === undefined)
3
+ return true;
4
+ if (version === undefined)
5
+ return false;
6
+ if (typeof options.version === "function")
7
+ return options.version(version);
8
+ return version === options.version;
9
+ }
@@ -0,0 +1,48 @@
1
+ /** Connection details for a local OpenCode service. */
2
+ export type Endpoint = {
3
+ /** Base URL of the service. */
4
+ readonly url: string;
5
+ /** Authentication required by the service, when configured. */
6
+ readonly auth?: {
7
+ /** HTTP authentication scheme. */
8
+ readonly type: "basic";
9
+ /** Basic authentication username. */
10
+ readonly username: string;
11
+ /** Basic authentication password. */
12
+ readonly password: string;
13
+ };
14
+ };
15
+ /** Options used to discover the local OpenCode service. */
16
+ export type DiscoverOptions = {
17
+ /** Absolute registration file path. Defaults to the XDG state directory. */
18
+ readonly file?: string;
19
+ /** Required exact service version or compatibility predicate. */
20
+ readonly version?: string | ((version: string) => boolean);
21
+ };
22
+ /** Reason ensuring the service requires a new process. */
23
+ export type EnsureReason = "missing" | "version-mismatch";
24
+ /** Options used to ensure the local OpenCode service is running. */
25
+ export type EnsureOptions = DiscoverOptions & {
26
+ /** Service command and arguments. Defaults to `opencode serve --service`. */
27
+ readonly command?: ReadonlyArray<string>;
28
+ /** Called once before spawning a new service process. */
29
+ readonly onStart?: (reason: EnsureReason, previousVersion?: string) => void;
30
+ };
31
+ /** Options used to stop the local OpenCode service. */
32
+ export type StopOptions = {
33
+ /** Absolute registration file path. Defaults to the XDG state directory. */
34
+ readonly file?: string;
35
+ };
36
+ /** Contents of the local service registration file. */
37
+ export type Info = {
38
+ /** Unique service instance identifier. */
39
+ readonly id?: string;
40
+ /** OpenCode version served by the process. */
41
+ readonly version?: string;
42
+ /** Base URL advertised by the service. */
43
+ readonly url: string;
44
+ /** Operating system process identifier. */
45
+ readonly pid: number;
46
+ /** Private service password, when authentication is enabled. */
47
+ readonly password?: string;
48
+ };
File without changes
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/package.json",
3
+ "name": "@opencode-ai/client",
4
+ "version": "0.0.0-dev-17471",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/anomalyco/opencode.git",
10
+ "directory": "packages/client"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "exports": {
19
+ ".": {
20
+ "import": "./dist/promise/index.js",
21
+ "types": "./dist/promise/index.d.ts"
22
+ },
23
+ "./promise": {
24
+ "import": "./dist/promise/index.js",
25
+ "types": "./dist/promise/index.d.ts"
26
+ },
27
+ "./promise/api": {
28
+ "import": "./dist/promise/api.js",
29
+ "types": "./dist/promise/api.d.ts"
30
+ },
31
+ "./service": {
32
+ "import": "./dist/promise/service.js",
33
+ "types": "./dist/promise/service.d.ts"
34
+ },
35
+ "./effect": {
36
+ "import": "./dist/effect/index.js",
37
+ "types": "./dist/effect/index.d.ts"
38
+ },
39
+ "./effect/api": {
40
+ "import": "./dist/effect/api.js",
41
+ "types": "./dist/effect/api.d.ts"
42
+ },
43
+ "./effect/service": {
44
+ "import": "./dist/effect/service.js",
45
+ "types": "./dist/effect/service.d.ts"
46
+ }
47
+ },
48
+ "scripts": {
49
+ "build": "bun run script/build-package.ts",
50
+ "generate": "bun run script/build.ts",
51
+ "check:generated": "bun run generate && git diff --exit-code -- src/promise/generated src/effect/generated src/effect/api",
52
+ "test": "bun test --timeout 5000",
53
+ "typecheck": "tsgo --noEmit"
54
+ },
55
+ "dependencies": {
56
+ "@opencode-ai/schema": "0.0.0-dev-17471",
57
+ "@opencode-ai/protocol": "0.0.0-dev-17471"
58
+ },
59
+ "peerDependencies": {
60
+ "effect": "4.0.0-beta.101"
61
+ },
62
+ "peerDependenciesMeta": {
63
+ "effect": {
64
+ "optional": true
65
+ }
66
+ },
67
+ "devDependencies": {
68
+ "@effect/platform-node": "4.0.0-beta.101",
69
+ "@opencode-ai/httpapi-codegen": "0.0.0-dev-17471",
70
+ "@tsconfig/bun": "1.0.9",
71
+ "@types/bun": "1.3.13",
72
+ "@typescript/native-preview": "7.0.0-dev.20251207.1",
73
+ "effect": "4.0.0-beta.101"
74
+ }
75
+ }