@opencode/client 2.0.8 → 2.0.9

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 (56) hide show
  1. package/dist/chunks/pty-handoff-1tbj6z39.js +81 -0
  2. package/dist/chunks/pty-handoff-4tveyqeh.js +34 -0
  3. package/dist/chunks/pty-handoff-65kht65h.js +62 -0
  4. package/dist/chunks/pty-handoff-6mptkzbc.js +0 -0
  5. package/dist/chunks/pty-handoff-9rqn6x4v.js +16 -0
  6. package/dist/chunks/pty-handoff-atpwm825.js +1638 -0
  7. package/dist/chunks/pty-handoff-bssvn03b.js +594 -0
  8. package/dist/chunks/pty-handoff-frbwqjmf.js +145 -0
  9. package/dist/chunks/pty-handoff-m2eywc8w.js +0 -0
  10. package/dist/chunks/pty-handoff-n3c99vt5.js +11 -0
  11. package/dist/chunks/pty-handoff-nqd0dnpk.js +112 -0
  12. package/dist/chunks/pty-handoff-qav6mfdz.js +0 -0
  13. package/dist/chunks/pty-handoff-radw39tv.js +1402 -0
  14. package/dist/chunks/pty-handoff-sxt88q69.js +12 -0
  15. package/dist/chunks/pty-handoff-t1xa31vm.js +39 -0
  16. package/dist/chunks/pty-handoff-txckps9j.js +57 -0
  17. package/dist/chunks/pty-handoff-vgxtr9hm.js +30 -0
  18. package/dist/chunks/pty-handoff-vmytr4q8.js +4 -0
  19. package/dist/chunks/pty-handoff-vyas3vgt.js +0 -0
  20. package/dist/chunks/pty-handoff-xgnj2w4v.js +20 -0
  21. package/dist/chunks/pty-handoff-y2etg5bs.js +9 -0
  22. package/dist/chunks/pty-handoff-ydhz1zrh.js +238 -0
  23. package/dist/chunks/pty-handoff-yepdgb80.js +44 -0
  24. package/dist/chunks/pty-handoff-zadn5mwr.js +52 -0
  25. package/dist/contract.js +12 -1
  26. package/dist/effect/client.d.ts +4 -4
  27. package/dist/effect/client.js +15 -29
  28. package/dist/effect/generated/client-error.js +6 -5
  29. package/dist/effect/generated/client.d.ts +4 -4
  30. package/dist/effect/generated/client.js +8 -582
  31. package/dist/effect/generated/index.js +12 -2
  32. package/dist/effect/index.js +75 -30
  33. package/dist/effect/rpc.js +11 -49
  34. package/dist/effect/service.js +238 -245
  35. package/dist/promise/client.js +14 -13
  36. package/dist/promise/generated/client-error.js +6 -8
  37. package/dist/promise/generated/client.js +7 -1396
  38. package/dist/promise/generated/index.js +75 -3
  39. package/dist/promise/generated/types.d.ts +90 -88
  40. package/dist/promise/generated/types.js +66 -34
  41. package/dist/promise/index.js +79 -2
  42. package/dist/promise/rpc.js +7 -86
  43. package/dist/promise/service.js +230 -227
  44. package/dist/pty-handoff.js +14 -121
  45. package/dist/rpc-runtime.js +14 -32
  46. package/dist/service-contender.js +10 -56
  47. package/dist/service-timing.d.ts +0 -1
  48. package/dist/service-timing.js +9 -18
  49. package/dist/service-version.js +6 -9
  50. package/dist/service.js +1 -0
  51. package/dist/shared-events.js +8 -137
  52. package/dist/solid/connection.js +10 -246
  53. package/dist/solid/data.js +18 -1774
  54. package/dist/solid/index.js +32 -3
  55. package/dist/solid/pty.js +8 -41
  56. package/package.json +4 -4
@@ -0,0 +1,145 @@
1
+ import {
2
+ __export
3
+ } from "./pty-handoff-9rqn6x4v.js";
4
+
5
+ // src/shared-events.ts
6
+ var exports_shared_events = {};
7
+ __export(exports_shared_events, {
8
+ SharedEvents: () => exports_shared_events,
9
+ make: () => make7
10
+ });
11
+ function make7(connect) {
12
+ let current;
13
+ const capacity = 4096;
14
+ function stop(connection) {
15
+ connection.connected = undefined;
16
+ connection.controller.abort();
17
+ if (current === connection)
18
+ current = undefined;
19
+ }
20
+ async function run(connection) {
21
+ let iterator;
22
+ let completion = {};
23
+ try {
24
+ if (connection.controller.signal.aborted)
25
+ return;
26
+ iterator = connect(connection.controller.signal, () => {
27
+ connection.subscribers.forEach((subscriber) => subscriber.activity?.());
28
+ })[Symbol.asyncIterator]();
29
+ while (!connection.controller.signal.aborted) {
30
+ const item = await iterator.next();
31
+ if (item.done || connection.controller.signal.aborted)
32
+ break;
33
+ if (item.value.type === "server.connected")
34
+ connection.connected = item.value;
35
+ connection.subscribers.forEach((subscriber) => subscriber.push(item.value));
36
+ }
37
+ } catch (error) {
38
+ completion = { error };
39
+ } finally {
40
+ stop(connection);
41
+ try {
42
+ await iterator?.return?.();
43
+ } catch (error) {
44
+ if (!("error" in completion))
45
+ completion = { error };
46
+ }
47
+ connection.subscribers.forEach((subscriber) => subscriber.finish(completion));
48
+ }
49
+ }
50
+ return {
51
+ subscribe(options) {
52
+ return {
53
+ [Symbol.asyncIterator]() {
54
+ const pending = [];
55
+ const queued = [];
56
+ let started = false;
57
+ let completion;
58
+ let connection;
59
+ function finish(result, discard = true) {
60
+ completion = result;
61
+ if (discard)
62
+ queued.length = 0;
63
+ options?.signal?.removeEventListener("abort", abort);
64
+ if (connection?.subscribers.delete(subscriber) && !connection.subscribers.size)
65
+ stop(connection);
66
+ pending.splice(0).forEach((request) => {
67
+ if ("error" in result)
68
+ request.reject(result.error);
69
+ else
70
+ request.resolve({ done: true, value: undefined });
71
+ });
72
+ }
73
+ function abort() {
74
+ finish({});
75
+ }
76
+ const subscriber = {
77
+ activity: options?.onActivity,
78
+ finish(result) {
79
+ finish(result, false);
80
+ },
81
+ push(value) {
82
+ if (completion)
83
+ return;
84
+ const request = pending.shift();
85
+ if (request) {
86
+ request.resolve({ done: false, value });
87
+ return;
88
+ }
89
+ if (queued.length === capacity) {
90
+ finish({ error: new Error(`Event subscriber exceeded its ${capacity}-event capacity`) });
91
+ return;
92
+ }
93
+ queued.push(value);
94
+ }
95
+ };
96
+ function start() {
97
+ if (completion)
98
+ return;
99
+ const fresh = !current;
100
+ connection = current ?? {
101
+ controller: new AbortController,
102
+ subscribers: new Set
103
+ };
104
+ current = connection;
105
+ connection.subscribers.add(subscriber);
106
+ if (connection.connected)
107
+ subscriber.push(connection.connected);
108
+ if (fresh)
109
+ run(connection);
110
+ }
111
+ return {
112
+ next() {
113
+ const value = queued.shift();
114
+ if (value)
115
+ return Promise.resolve({ done: false, value });
116
+ if (completion) {
117
+ if ("error" in completion)
118
+ return Promise.reject(completion.error);
119
+ return Promise.resolve({ done: true, value: undefined });
120
+ }
121
+ if (options?.signal?.aborted) {
122
+ abort();
123
+ return Promise.resolve({ done: true, value: undefined });
124
+ }
125
+ const request = Promise.withResolvers();
126
+ pending.push(request);
127
+ if (!started) {
128
+ started = true;
129
+ options?.signal?.addEventListener("abort", abort, { once: true });
130
+ start();
131
+ }
132
+ return request.promise;
133
+ },
134
+ return() {
135
+ finish({});
136
+ return Promise.resolve({ done: true, value: undefined });
137
+ }
138
+ };
139
+ }
140
+ };
141
+ }
142
+ };
143
+ }
144
+
145
+ export { make7, exports_shared_events };
File without changes
@@ -0,0 +1,11 @@
1
+ // src/promise/generated/client-error.ts
2
+ class ClientError3 extends Error {
3
+ reason;
4
+ name = "ClientError";
5
+ constructor(reason, options) {
6
+ super(reason, options);
7
+ this.reason = reason;
8
+ }
9
+ }
10
+
11
+ export { ClientError3 };
@@ -0,0 +1,112 @@
1
+ import {
2
+ __export
3
+ } from "./pty-handoff-9rqn6x4v.js";
4
+
5
+ // src/pty-handoff.ts
6
+ var exports_pty_handoff = {};
7
+ __export(exports_pty_handoff, {
8
+ PtyHandoff: () => exports_pty_handoff,
9
+ clear: () => clear2,
10
+ complete: () => complete2,
11
+ environment: () => environment2,
12
+ prepare: () => prepare2
13
+ });
14
+ import { readFile, rename, rm, writeFile } from "node:fs/promises";
15
+ async function prepare2(file, info, timeout) {
16
+ const existing = await read(file);
17
+ if (existing !== undefined && existing.expiresAt > Date.now() && same(existing.source, info))
18
+ return;
19
+ const { ClientError, OpenCode } = await import("../promise/index.js");
20
+ const client = OpenCode.make({
21
+ baseUrl: info.url,
22
+ headers: info.password === undefined ? undefined : { authorization: "Basic " + Buffer.from(`opencode:${info.password}`).toString("base64") }
23
+ });
24
+ const missing = (error) => error instanceof ClientError && error.reason === "UnexpectedStatus" && typeof error.cause === "object" && error.cause !== null && ("status" in error.cause) && error.cause.status === 404;
25
+ const result = await client.experimental.persistentPty.handoff({ signal: AbortSignal.timeout(timeout) }).then((value) => ({ value }), (cause) => ({ cause }));
26
+ if ("cause" in result) {
27
+ const concurrent = await read(file);
28
+ if (concurrent !== undefined && concurrent.expiresAt > Date.now() && same(concurrent.source, info))
29
+ return;
30
+ if (!missing(result.cause))
31
+ throw new Error("Failed to prepare persistent terminals for service replacement", { cause: result.cause });
32
+ console.warn("Background service cannot hand off persistent terminals; shutting them down before replacement");
33
+ await client.experimental.persistentPty.shutdown({ signal: AbortSignal.timeout(timeout) }).catch((cause) => {
34
+ if (missing(cause))
35
+ return;
36
+ throw new Error("Failed to shut down persistent terminals before service replacement", { cause });
37
+ });
38
+ await publish(file, info, null);
39
+ return;
40
+ }
41
+ const body = result.value;
42
+ if (typeof body !== "object" || body === null || !("handoff" in body))
43
+ throw new Error("Invalid persistent terminal handoff response");
44
+ if (body.handoff === null) {
45
+ await publish(file, info, null);
46
+ return;
47
+ }
48
+ if (!isHandoff(body.handoff) || body.handoff.expiresAt <= Date.now())
49
+ throw new Error("Invalid or expired persistent terminal handoff");
50
+ await publish(file, info, body.handoff);
51
+ }
52
+ async function publish(file, info, handoff) {
53
+ const temporary = `${file}.pty-handoff.${crypto.randomUUID()}.tmp`;
54
+ await writeFile(temporary, JSON.stringify({
55
+ source: { id: info.id, pid: info.pid, url: info.url },
56
+ handoff,
57
+ expiresAt: handoff?.expiresAt ?? Date.now() + 30000
58
+ }), { mode: 384, flag: "wx" });
59
+ await rename(temporary, file + ".pty-handoff").finally(() => rm(temporary, { force: true }));
60
+ }
61
+ async function environment2(file, env) {
62
+ const record = await read(file);
63
+ const current = await readFile(file, "utf8").then((text) => JSON.parse(text)).catch(() => {
64
+ return;
65
+ });
66
+ const handoff = record !== undefined && record.expiresAt > Date.now() && (current === undefined || same(record.source, current)) ? record.handoff : undefined;
67
+ return { ...env, OPENCODE_PTY_HANDOFF: handoff == null ? undefined : JSON.stringify(handoff) };
68
+ }
69
+ async function complete2(file, info) {
70
+ const record = await read(file);
71
+ if (record !== undefined && !same(record.source, info))
72
+ await clear2(file);
73
+ }
74
+ async function clear2(file) {
75
+ await rm(file + ".pty-handoff", { force: true });
76
+ }
77
+ async function read(file) {
78
+ const value = await readFile(file + ".pty-handoff", "utf8").then((text) => JSON.parse(text)).catch(() => {
79
+ return;
80
+ });
81
+ if (typeof value !== "object" || value === null || !("source" in value) || !("handoff" in value))
82
+ return;
83
+ if (typeof value.source !== "object" || value.source === null)
84
+ return;
85
+ if (!("pid" in value.source) || typeof value.source.pid !== "number")
86
+ return;
87
+ if (!("url" in value.source) || typeof value.source.url !== "string")
88
+ return;
89
+ if ("id" in value.source && typeof value.source.id !== "string")
90
+ return;
91
+ if (value.handoff !== null && !isHandoff(value.handoff))
92
+ return;
93
+ if (!("expiresAt" in value) || typeof value.expiresAt !== "number" || !Number.isFinite(value.expiresAt))
94
+ return;
95
+ return {
96
+ source: {
97
+ id: "id" in value.source && typeof value.source.id === "string" ? value.source.id : undefined,
98
+ pid: value.source.pid,
99
+ url: value.source.url
100
+ },
101
+ handoff: value.handoff,
102
+ expiresAt: value.expiresAt
103
+ };
104
+ }
105
+ function same(left, right) {
106
+ return left.id === right.id && left.pid === right.pid && left.url === right.url;
107
+ }
108
+ function isHandoff(value) {
109
+ return typeof value === "object" && value !== null && "directory" in value && typeof value.directory === "string" && "instanceID" in value && typeof value.instanceID === "string" && "ticket" in value && typeof value.ticket === "string" && "expiresAt" in value && typeof value.expiresAt === "number" && Number.isFinite(value.expiresAt);
110
+ }
111
+
112
+ export { prepare2, environment2, complete2, clear2, exports_pty_handoff };
File without changes