oh-my-opencode 2.5.2 → 2.5.3

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/cli/index.js CHANGED
@@ -2244,7 +2244,7 @@ var require_picocolors = __commonJS((exports, module) => {
2244
2244
  var require_package = __commonJS((exports, module) => {
2245
2245
  module.exports = {
2246
2246
  name: "oh-my-opencode",
2247
- version: "2.5.1",
2247
+ version: "2.5.2",
2248
2248
  description: "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
2249
2249
  main: "dist/index.js",
2250
2250
  types: "dist/index.d.ts",
@@ -2300,6 +2300,7 @@ var require_package = __commonJS((exports, module) => {
2300
2300
  "@code-yeongyu/comment-checker": "^0.6.0",
2301
2301
  "@openauthjs/openauth": "^0.4.3",
2302
2302
  "@opencode-ai/plugin": "^1.0.162",
2303
+ "@opencode-ai/sdk": "^1.0.162",
2303
2304
  commander: "^14.0.2",
2304
2305
  hono: "^4.10.4",
2305
2306
  picocolors: "^1.1.1",
@@ -3711,7 +3712,1649 @@ async function install(args) {
3711
3712
  Se(import_picocolors2.default.green("oMoMoMoMo... Enjoy!"));
3712
3713
  return 0;
3713
3714
  }
3715
+ // node_modules/@opencode-ai/sdk/dist/gen/core/serverSentEvents.gen.js
3716
+ var createSseClient = ({ onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) => {
3717
+ let lastEventId;
3718
+ const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
3719
+ const createStream = async function* () {
3720
+ let retryDelay = sseDefaultRetryDelay ?? 3000;
3721
+ let attempt = 0;
3722
+ const signal = options.signal ?? new AbortController().signal;
3723
+ while (true) {
3724
+ if (signal.aborted)
3725
+ break;
3726
+ attempt++;
3727
+ const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
3728
+ if (lastEventId !== undefined) {
3729
+ headers.set("Last-Event-ID", lastEventId);
3730
+ }
3731
+ try {
3732
+ const response = await fetch(url, { ...options, headers, signal });
3733
+ if (!response.ok)
3734
+ throw new Error(`SSE failed: ${response.status} ${response.statusText}`);
3735
+ if (!response.body)
3736
+ throw new Error("No body in SSE response");
3737
+ const reader = response.body.pipeThrough(new TextDecoderStream).getReader();
3738
+ let buffer = "";
3739
+ const abortHandler = () => {
3740
+ try {
3741
+ reader.cancel();
3742
+ } catch {}
3743
+ };
3744
+ signal.addEventListener("abort", abortHandler);
3745
+ try {
3746
+ while (true) {
3747
+ const { done, value } = await reader.read();
3748
+ if (done)
3749
+ break;
3750
+ buffer += value;
3751
+ const chunks = buffer.split(`
3752
+
3753
+ `);
3754
+ buffer = chunks.pop() ?? "";
3755
+ for (const chunk of chunks) {
3756
+ const lines = chunk.split(`
3757
+ `);
3758
+ const dataLines = [];
3759
+ let eventName;
3760
+ for (const line of lines) {
3761
+ if (line.startsWith("data:")) {
3762
+ dataLines.push(line.replace(/^data:\s*/, ""));
3763
+ } else if (line.startsWith("event:")) {
3764
+ eventName = line.replace(/^event:\s*/, "");
3765
+ } else if (line.startsWith("id:")) {
3766
+ lastEventId = line.replace(/^id:\s*/, "");
3767
+ } else if (line.startsWith("retry:")) {
3768
+ const parsed = Number.parseInt(line.replace(/^retry:\s*/, ""), 10);
3769
+ if (!Number.isNaN(parsed)) {
3770
+ retryDelay = parsed;
3771
+ }
3772
+ }
3773
+ }
3774
+ let data;
3775
+ let parsedJson = false;
3776
+ if (dataLines.length) {
3777
+ const rawData = dataLines.join(`
3778
+ `);
3779
+ try {
3780
+ data = JSON.parse(rawData);
3781
+ parsedJson = true;
3782
+ } catch {
3783
+ data = rawData;
3784
+ }
3785
+ }
3786
+ if (parsedJson) {
3787
+ if (responseValidator) {
3788
+ await responseValidator(data);
3789
+ }
3790
+ if (responseTransformer) {
3791
+ data = await responseTransformer(data);
3792
+ }
3793
+ }
3794
+ onSseEvent?.({
3795
+ data,
3796
+ event: eventName,
3797
+ id: lastEventId,
3798
+ retry: retryDelay
3799
+ });
3800
+ if (dataLines.length) {
3801
+ yield data;
3802
+ }
3803
+ }
3804
+ }
3805
+ } finally {
3806
+ signal.removeEventListener("abort", abortHandler);
3807
+ reader.releaseLock();
3808
+ }
3809
+ break;
3810
+ } catch (error) {
3811
+ onSseError?.(error);
3812
+ if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) {
3813
+ break;
3814
+ }
3815
+ const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000);
3816
+ await sleep(backoff);
3817
+ }
3818
+ }
3819
+ };
3820
+ const stream = createStream();
3821
+ return { stream };
3822
+ };
3823
+
3824
+ // node_modules/@opencode-ai/sdk/dist/gen/core/auth.gen.js
3825
+ var getAuthToken = async (auth, callback) => {
3826
+ const token = typeof callback === "function" ? await callback(auth) : callback;
3827
+ if (!token) {
3828
+ return;
3829
+ }
3830
+ if (auth.scheme === "bearer") {
3831
+ return `Bearer ${token}`;
3832
+ }
3833
+ if (auth.scheme === "basic") {
3834
+ return `Basic ${btoa(token)}`;
3835
+ }
3836
+ return token;
3837
+ };
3838
+
3839
+ // node_modules/@opencode-ai/sdk/dist/gen/core/bodySerializer.gen.js
3840
+ var jsonBodySerializer = {
3841
+ bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value)
3842
+ };
3843
+
3844
+ // node_modules/@opencode-ai/sdk/dist/gen/core/pathSerializer.gen.js
3845
+ var separatorArrayExplode = (style) => {
3846
+ switch (style) {
3847
+ case "label":
3848
+ return ".";
3849
+ case "matrix":
3850
+ return ";";
3851
+ case "simple":
3852
+ return ",";
3853
+ default:
3854
+ return "&";
3855
+ }
3856
+ };
3857
+ var separatorArrayNoExplode = (style) => {
3858
+ switch (style) {
3859
+ case "form":
3860
+ return ",";
3861
+ case "pipeDelimited":
3862
+ return "|";
3863
+ case "spaceDelimited":
3864
+ return "%20";
3865
+ default:
3866
+ return ",";
3867
+ }
3868
+ };
3869
+ var separatorObjectExplode = (style) => {
3870
+ switch (style) {
3871
+ case "label":
3872
+ return ".";
3873
+ case "matrix":
3874
+ return ";";
3875
+ case "simple":
3876
+ return ",";
3877
+ default:
3878
+ return "&";
3879
+ }
3880
+ };
3881
+ var serializeArrayParam = ({ allowReserved, explode, name, style, value }) => {
3882
+ if (!explode) {
3883
+ const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
3884
+ switch (style) {
3885
+ case "label":
3886
+ return `.${joinedValues2}`;
3887
+ case "matrix":
3888
+ return `;${name}=${joinedValues2}`;
3889
+ case "simple":
3890
+ return joinedValues2;
3891
+ default:
3892
+ return `${name}=${joinedValues2}`;
3893
+ }
3894
+ }
3895
+ const separator = separatorArrayExplode(style);
3896
+ const joinedValues = value.map((v) => {
3897
+ if (style === "label" || style === "simple") {
3898
+ return allowReserved ? v : encodeURIComponent(v);
3899
+ }
3900
+ return serializePrimitiveParam({
3901
+ allowReserved,
3902
+ name,
3903
+ value: v
3904
+ });
3905
+ }).join(separator);
3906
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
3907
+ };
3908
+ var serializePrimitiveParam = ({ allowReserved, name, value }) => {
3909
+ if (value === undefined || value === null) {
3910
+ return "";
3911
+ }
3912
+ if (typeof value === "object") {
3913
+ throw new Error("Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these.");
3914
+ }
3915
+ return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
3916
+ };
3917
+ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueOnly }) => {
3918
+ if (value instanceof Date) {
3919
+ return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
3920
+ }
3921
+ if (style !== "deepObject" && !explode) {
3922
+ let values = [];
3923
+ Object.entries(value).forEach(([key, v]) => {
3924
+ values = [...values, key, allowReserved ? v : encodeURIComponent(v)];
3925
+ });
3926
+ const joinedValues2 = values.join(",");
3927
+ switch (style) {
3928
+ case "form":
3929
+ return `${name}=${joinedValues2}`;
3930
+ case "label":
3931
+ return `.${joinedValues2}`;
3932
+ case "matrix":
3933
+ return `;${name}=${joinedValues2}`;
3934
+ default:
3935
+ return joinedValues2;
3936
+ }
3937
+ }
3938
+ const separator = separatorObjectExplode(style);
3939
+ const joinedValues = Object.entries(value).map(([key, v]) => serializePrimitiveParam({
3940
+ allowReserved,
3941
+ name: style === "deepObject" ? `${name}[${key}]` : key,
3942
+ value: v
3943
+ })).join(separator);
3944
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
3945
+ };
3946
+
3947
+ // node_modules/@opencode-ai/sdk/dist/gen/core/utils.gen.js
3948
+ var PATH_PARAM_RE = /\{[^{}]+\}/g;
3949
+ var defaultPathSerializer = ({ path, url: _url }) => {
3950
+ let url = _url;
3951
+ const matches = _url.match(PATH_PARAM_RE);
3952
+ if (matches) {
3953
+ for (const match of matches) {
3954
+ let explode = false;
3955
+ let name = match.substring(1, match.length - 1);
3956
+ let style = "simple";
3957
+ if (name.endsWith("*")) {
3958
+ explode = true;
3959
+ name = name.substring(0, name.length - 1);
3960
+ }
3961
+ if (name.startsWith(".")) {
3962
+ name = name.substring(1);
3963
+ style = "label";
3964
+ } else if (name.startsWith(";")) {
3965
+ name = name.substring(1);
3966
+ style = "matrix";
3967
+ }
3968
+ const value = path[name];
3969
+ if (value === undefined || value === null) {
3970
+ continue;
3971
+ }
3972
+ if (Array.isArray(value)) {
3973
+ url = url.replace(match, serializeArrayParam({ explode, name, style, value }));
3974
+ continue;
3975
+ }
3976
+ if (typeof value === "object") {
3977
+ url = url.replace(match, serializeObjectParam({
3978
+ explode,
3979
+ name,
3980
+ style,
3981
+ value,
3982
+ valueOnly: true
3983
+ }));
3984
+ continue;
3985
+ }
3986
+ if (style === "matrix") {
3987
+ url = url.replace(match, `;${serializePrimitiveParam({
3988
+ name,
3989
+ value
3990
+ })}`);
3991
+ continue;
3992
+ }
3993
+ const replaceValue = encodeURIComponent(style === "label" ? `.${value}` : value);
3994
+ url = url.replace(match, replaceValue);
3995
+ }
3996
+ }
3997
+ return url;
3998
+ };
3999
+ var getUrl = ({ baseUrl, path, query, querySerializer, url: _url }) => {
4000
+ const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
4001
+ let url = (baseUrl ?? "") + pathUrl;
4002
+ if (path) {
4003
+ url = defaultPathSerializer({ path, url });
4004
+ }
4005
+ let search = query ? querySerializer(query) : "";
4006
+ if (search.startsWith("?")) {
4007
+ search = search.substring(1);
4008
+ }
4009
+ if (search) {
4010
+ url += `?${search}`;
4011
+ }
4012
+ return url;
4013
+ };
4014
+
4015
+ // node_modules/@opencode-ai/sdk/dist/gen/client/utils.gen.js
4016
+ var createQuerySerializer = ({ allowReserved, array, object } = {}) => {
4017
+ const querySerializer = (queryParams) => {
4018
+ const search = [];
4019
+ if (queryParams && typeof queryParams === "object") {
4020
+ for (const name in queryParams) {
4021
+ const value = queryParams[name];
4022
+ if (value === undefined || value === null) {
4023
+ continue;
4024
+ }
4025
+ if (Array.isArray(value)) {
4026
+ const serializedArray = serializeArrayParam({
4027
+ allowReserved,
4028
+ explode: true,
4029
+ name,
4030
+ style: "form",
4031
+ value,
4032
+ ...array
4033
+ });
4034
+ if (serializedArray)
4035
+ search.push(serializedArray);
4036
+ } else if (typeof value === "object") {
4037
+ const serializedObject = serializeObjectParam({
4038
+ allowReserved,
4039
+ explode: true,
4040
+ name,
4041
+ style: "deepObject",
4042
+ value,
4043
+ ...object
4044
+ });
4045
+ if (serializedObject)
4046
+ search.push(serializedObject);
4047
+ } else {
4048
+ const serializedPrimitive = serializePrimitiveParam({
4049
+ allowReserved,
4050
+ name,
4051
+ value
4052
+ });
4053
+ if (serializedPrimitive)
4054
+ search.push(serializedPrimitive);
4055
+ }
4056
+ }
4057
+ }
4058
+ return search.join("&");
4059
+ };
4060
+ return querySerializer;
4061
+ };
4062
+ var getParseAs = (contentType) => {
4063
+ if (!contentType) {
4064
+ return "stream";
4065
+ }
4066
+ const cleanContent = contentType.split(";")[0]?.trim();
4067
+ if (!cleanContent) {
4068
+ return;
4069
+ }
4070
+ if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) {
4071
+ return "json";
4072
+ }
4073
+ if (cleanContent === "multipart/form-data") {
4074
+ return "formData";
4075
+ }
4076
+ if (["application/", "audio/", "image/", "video/"].some((type) => cleanContent.startsWith(type))) {
4077
+ return "blob";
4078
+ }
4079
+ if (cleanContent.startsWith("text/")) {
4080
+ return "text";
4081
+ }
4082
+ return;
4083
+ };
4084
+ var checkForExistence = (options, name) => {
4085
+ if (!name) {
4086
+ return false;
4087
+ }
4088
+ if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) {
4089
+ return true;
4090
+ }
4091
+ return false;
4092
+ };
4093
+ var setAuthParams = async ({ security, ...options }) => {
4094
+ for (const auth of security) {
4095
+ if (checkForExistence(options, auth.name)) {
4096
+ continue;
4097
+ }
4098
+ const token = await getAuthToken(auth, options.auth);
4099
+ if (!token) {
4100
+ continue;
4101
+ }
4102
+ const name = auth.name ?? "Authorization";
4103
+ switch (auth.in) {
4104
+ case "query":
4105
+ if (!options.query) {
4106
+ options.query = {};
4107
+ }
4108
+ options.query[name] = token;
4109
+ break;
4110
+ case "cookie":
4111
+ options.headers.append("Cookie", `${name}=${token}`);
4112
+ break;
4113
+ case "header":
4114
+ default:
4115
+ options.headers.set(name, token);
4116
+ break;
4117
+ }
4118
+ }
4119
+ };
4120
+ var buildUrl = (options) => getUrl({
4121
+ baseUrl: options.baseUrl,
4122
+ path: options.path,
4123
+ query: options.query,
4124
+ querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
4125
+ url: options.url
4126
+ });
4127
+ var mergeConfigs = (a, b3) => {
4128
+ const config = { ...a, ...b3 };
4129
+ if (config.baseUrl?.endsWith("/")) {
4130
+ config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
4131
+ }
4132
+ config.headers = mergeHeaders(a.headers, b3.headers);
4133
+ return config;
4134
+ };
4135
+ var mergeHeaders = (...headers) => {
4136
+ const mergedHeaders = new Headers;
4137
+ for (const header of headers) {
4138
+ if (!header || typeof header !== "object") {
4139
+ continue;
4140
+ }
4141
+ const iterator = header instanceof Headers ? header.entries() : Object.entries(header);
4142
+ for (const [key, value] of iterator) {
4143
+ if (value === null) {
4144
+ mergedHeaders.delete(key);
4145
+ } else if (Array.isArray(value)) {
4146
+ for (const v of value) {
4147
+ mergedHeaders.append(key, v);
4148
+ }
4149
+ } else if (value !== undefined) {
4150
+ mergedHeaders.set(key, typeof value === "object" ? JSON.stringify(value) : value);
4151
+ }
4152
+ }
4153
+ }
4154
+ return mergedHeaders;
4155
+ };
4156
+
4157
+ class Interceptors {
4158
+ _fns;
4159
+ constructor() {
4160
+ this._fns = [];
4161
+ }
4162
+ clear() {
4163
+ this._fns = [];
4164
+ }
4165
+ getInterceptorIndex(id) {
4166
+ if (typeof id === "number") {
4167
+ return this._fns[id] ? id : -1;
4168
+ } else {
4169
+ return this._fns.indexOf(id);
4170
+ }
4171
+ }
4172
+ exists(id) {
4173
+ const index = this.getInterceptorIndex(id);
4174
+ return !!this._fns[index];
4175
+ }
4176
+ eject(id) {
4177
+ const index = this.getInterceptorIndex(id);
4178
+ if (this._fns[index]) {
4179
+ this._fns[index] = null;
4180
+ }
4181
+ }
4182
+ update(id, fn) {
4183
+ const index = this.getInterceptorIndex(id);
4184
+ if (this._fns[index]) {
4185
+ this._fns[index] = fn;
4186
+ return id;
4187
+ } else {
4188
+ return false;
4189
+ }
4190
+ }
4191
+ use(fn) {
4192
+ this._fns = [...this._fns, fn];
4193
+ return this._fns.length - 1;
4194
+ }
4195
+ }
4196
+ var createInterceptors = () => ({
4197
+ error: new Interceptors,
4198
+ request: new Interceptors,
4199
+ response: new Interceptors
4200
+ });
4201
+ var defaultQuerySerializer = createQuerySerializer({
4202
+ allowReserved: false,
4203
+ array: {
4204
+ explode: true,
4205
+ style: "form"
4206
+ },
4207
+ object: {
4208
+ explode: true,
4209
+ style: "deepObject"
4210
+ }
4211
+ });
4212
+ var defaultHeaders = {
4213
+ "Content-Type": "application/json"
4214
+ };
4215
+ var createConfig = (override = {}) => ({
4216
+ ...jsonBodySerializer,
4217
+ headers: defaultHeaders,
4218
+ parseAs: "auto",
4219
+ querySerializer: defaultQuerySerializer,
4220
+ ...override
4221
+ });
4222
+
4223
+ // node_modules/@opencode-ai/sdk/dist/gen/client/client.gen.js
4224
+ var createClient = (config = {}) => {
4225
+ let _config = mergeConfigs(createConfig(), config);
4226
+ const getConfig = () => ({ ..._config });
4227
+ const setConfig = (config2) => {
4228
+ _config = mergeConfigs(_config, config2);
4229
+ return getConfig();
4230
+ };
4231
+ const interceptors = createInterceptors();
4232
+ const beforeRequest = async (options) => {
4233
+ const opts = {
4234
+ ..._config,
4235
+ ...options,
4236
+ fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
4237
+ headers: mergeHeaders(_config.headers, options.headers),
4238
+ serializedBody: undefined
4239
+ };
4240
+ if (opts.security) {
4241
+ await setAuthParams({
4242
+ ...opts,
4243
+ security: opts.security
4244
+ });
4245
+ }
4246
+ if (opts.requestValidator) {
4247
+ await opts.requestValidator(opts);
4248
+ }
4249
+ if (opts.body && opts.bodySerializer) {
4250
+ opts.serializedBody = opts.bodySerializer(opts.body);
4251
+ }
4252
+ if (opts.serializedBody === undefined || opts.serializedBody === "") {
4253
+ opts.headers.delete("Content-Type");
4254
+ }
4255
+ const url = buildUrl(opts);
4256
+ return { opts, url };
4257
+ };
4258
+ const request = async (options) => {
4259
+ const { opts, url } = await beforeRequest(options);
4260
+ const requestInit = {
4261
+ redirect: "follow",
4262
+ ...opts,
4263
+ body: opts.serializedBody
4264
+ };
4265
+ let request2 = new Request(url, requestInit);
4266
+ for (const fn of interceptors.request._fns) {
4267
+ if (fn) {
4268
+ request2 = await fn(request2, opts);
4269
+ }
4270
+ }
4271
+ const _fetch = opts.fetch;
4272
+ let response = await _fetch(request2);
4273
+ for (const fn of interceptors.response._fns) {
4274
+ if (fn) {
4275
+ response = await fn(response, request2, opts);
4276
+ }
4277
+ }
4278
+ const result = {
4279
+ request: request2,
4280
+ response
4281
+ };
4282
+ if (response.ok) {
4283
+ if (response.status === 204 || response.headers.get("Content-Length") === "0") {
4284
+ return opts.responseStyle === "data" ? {} : {
4285
+ data: {},
4286
+ ...result
4287
+ };
4288
+ }
4289
+ const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
4290
+ let data;
4291
+ switch (parseAs) {
4292
+ case "arrayBuffer":
4293
+ case "blob":
4294
+ case "formData":
4295
+ case "json":
4296
+ case "text":
4297
+ data = await response[parseAs]();
4298
+ break;
4299
+ case "stream":
4300
+ return opts.responseStyle === "data" ? response.body : {
4301
+ data: response.body,
4302
+ ...result
4303
+ };
4304
+ }
4305
+ if (parseAs === "json") {
4306
+ if (opts.responseValidator) {
4307
+ await opts.responseValidator(data);
4308
+ }
4309
+ if (opts.responseTransformer) {
4310
+ data = await opts.responseTransformer(data);
4311
+ }
4312
+ }
4313
+ return opts.responseStyle === "data" ? data : {
4314
+ data,
4315
+ ...result
4316
+ };
4317
+ }
4318
+ const textError = await response.text();
4319
+ let jsonError;
4320
+ try {
4321
+ jsonError = JSON.parse(textError);
4322
+ } catch {}
4323
+ const error = jsonError ?? textError;
4324
+ let finalError = error;
4325
+ for (const fn of interceptors.error._fns) {
4326
+ if (fn) {
4327
+ finalError = await fn(error, response, request2, opts);
4328
+ }
4329
+ }
4330
+ finalError = finalError || {};
4331
+ if (opts.throwOnError) {
4332
+ throw finalError;
4333
+ }
4334
+ return opts.responseStyle === "data" ? undefined : {
4335
+ error: finalError,
4336
+ ...result
4337
+ };
4338
+ };
4339
+ const makeMethod = (method) => {
4340
+ const fn = (options) => request({ ...options, method });
4341
+ fn.sse = async (options) => {
4342
+ const { opts, url } = await beforeRequest(options);
4343
+ return createSseClient({
4344
+ ...opts,
4345
+ body: opts.body,
4346
+ headers: opts.headers,
4347
+ method,
4348
+ url
4349
+ });
4350
+ };
4351
+ return fn;
4352
+ };
4353
+ return {
4354
+ buildUrl,
4355
+ connect: makeMethod("CONNECT"),
4356
+ delete: makeMethod("DELETE"),
4357
+ get: makeMethod("GET"),
4358
+ getConfig,
4359
+ head: makeMethod("HEAD"),
4360
+ interceptors,
4361
+ options: makeMethod("OPTIONS"),
4362
+ patch: makeMethod("PATCH"),
4363
+ post: makeMethod("POST"),
4364
+ put: makeMethod("PUT"),
4365
+ request,
4366
+ setConfig,
4367
+ trace: makeMethod("TRACE")
4368
+ };
4369
+ };
4370
+ // node_modules/@opencode-ai/sdk/dist/gen/core/params.gen.js
4371
+ var extraPrefixesMap = {
4372
+ $body_: "body",
4373
+ $headers_: "headers",
4374
+ $path_: "path",
4375
+ $query_: "query"
4376
+ };
4377
+ var extraPrefixes = Object.entries(extraPrefixesMap);
4378
+ // node_modules/@opencode-ai/sdk/dist/gen/client.gen.js
4379
+ var client = createClient(createConfig({
4380
+ baseUrl: "http://localhost:4096"
4381
+ }));
4382
+
4383
+ // node_modules/@opencode-ai/sdk/dist/gen/sdk.gen.js
4384
+ class _HeyApiClient {
4385
+ _client = client;
4386
+ constructor(args) {
4387
+ if (args?.client) {
4388
+ this._client = args.client;
4389
+ }
4390
+ }
4391
+ }
4392
+
4393
+ class Global extends _HeyApiClient {
4394
+ event(options) {
4395
+ return (options?.client ?? this._client).get.sse({
4396
+ url: "/global/event",
4397
+ ...options
4398
+ });
4399
+ }
4400
+ }
4401
+
4402
+ class Project extends _HeyApiClient {
4403
+ list(options) {
4404
+ return (options?.client ?? this._client).get({
4405
+ url: "/project",
4406
+ ...options
4407
+ });
4408
+ }
4409
+ current(options) {
4410
+ return (options?.client ?? this._client).get({
4411
+ url: "/project/current",
4412
+ ...options
4413
+ });
4414
+ }
4415
+ }
4416
+
4417
+ class Pty extends _HeyApiClient {
4418
+ list(options) {
4419
+ return (options?.client ?? this._client).get({
4420
+ url: "/pty",
4421
+ ...options
4422
+ });
4423
+ }
4424
+ create(options) {
4425
+ return (options?.client ?? this._client).post({
4426
+ url: "/pty",
4427
+ ...options,
4428
+ headers: {
4429
+ "Content-Type": "application/json",
4430
+ ...options?.headers
4431
+ }
4432
+ });
4433
+ }
4434
+ remove(options) {
4435
+ return (options.client ?? this._client).delete({
4436
+ url: "/pty/{id}",
4437
+ ...options
4438
+ });
4439
+ }
4440
+ get(options) {
4441
+ return (options.client ?? this._client).get({
4442
+ url: "/pty/{id}",
4443
+ ...options
4444
+ });
4445
+ }
4446
+ update(options) {
4447
+ return (options.client ?? this._client).put({
4448
+ url: "/pty/{id}",
4449
+ ...options,
4450
+ headers: {
4451
+ "Content-Type": "application/json",
4452
+ ...options.headers
4453
+ }
4454
+ });
4455
+ }
4456
+ connect(options) {
4457
+ return (options.client ?? this._client).get({
4458
+ url: "/pty/{id}/connect",
4459
+ ...options
4460
+ });
4461
+ }
4462
+ }
4463
+
4464
+ class Config extends _HeyApiClient {
4465
+ get(options) {
4466
+ return (options?.client ?? this._client).get({
4467
+ url: "/config",
4468
+ ...options
4469
+ });
4470
+ }
4471
+ update(options) {
4472
+ return (options?.client ?? this._client).patch({
4473
+ url: "/config",
4474
+ ...options,
4475
+ headers: {
4476
+ "Content-Type": "application/json",
4477
+ ...options?.headers
4478
+ }
4479
+ });
4480
+ }
4481
+ providers(options) {
4482
+ return (options?.client ?? this._client).get({
4483
+ url: "/config/providers",
4484
+ ...options
4485
+ });
4486
+ }
4487
+ }
4488
+
4489
+ class Tool extends _HeyApiClient {
4490
+ ids(options) {
4491
+ return (options?.client ?? this._client).get({
4492
+ url: "/experimental/tool/ids",
4493
+ ...options
4494
+ });
4495
+ }
4496
+ list(options) {
4497
+ return (options.client ?? this._client).get({
4498
+ url: "/experimental/tool",
4499
+ ...options
4500
+ });
4501
+ }
4502
+ }
4503
+
4504
+ class Instance extends _HeyApiClient {
4505
+ dispose(options) {
4506
+ return (options?.client ?? this._client).post({
4507
+ url: "/instance/dispose",
4508
+ ...options
4509
+ });
4510
+ }
4511
+ }
4512
+
4513
+ class Path extends _HeyApiClient {
4514
+ get(options) {
4515
+ return (options?.client ?? this._client).get({
4516
+ url: "/path",
4517
+ ...options
4518
+ });
4519
+ }
4520
+ }
4521
+
4522
+ class Vcs extends _HeyApiClient {
4523
+ get(options) {
4524
+ return (options?.client ?? this._client).get({
4525
+ url: "/vcs",
4526
+ ...options
4527
+ });
4528
+ }
4529
+ }
4530
+
4531
+ class Session extends _HeyApiClient {
4532
+ list(options) {
4533
+ return (options?.client ?? this._client).get({
4534
+ url: "/session",
4535
+ ...options
4536
+ });
4537
+ }
4538
+ create(options) {
4539
+ return (options?.client ?? this._client).post({
4540
+ url: "/session",
4541
+ ...options,
4542
+ headers: {
4543
+ "Content-Type": "application/json",
4544
+ ...options?.headers
4545
+ }
4546
+ });
4547
+ }
4548
+ status(options) {
4549
+ return (options?.client ?? this._client).get({
4550
+ url: "/session/status",
4551
+ ...options
4552
+ });
4553
+ }
4554
+ delete(options) {
4555
+ return (options.client ?? this._client).delete({
4556
+ url: "/session/{id}",
4557
+ ...options
4558
+ });
4559
+ }
4560
+ get(options) {
4561
+ return (options.client ?? this._client).get({
4562
+ url: "/session/{id}",
4563
+ ...options
4564
+ });
4565
+ }
4566
+ update(options) {
4567
+ return (options.client ?? this._client).patch({
4568
+ url: "/session/{id}",
4569
+ ...options,
4570
+ headers: {
4571
+ "Content-Type": "application/json",
4572
+ ...options.headers
4573
+ }
4574
+ });
4575
+ }
4576
+ children(options) {
4577
+ return (options.client ?? this._client).get({
4578
+ url: "/session/{id}/children",
4579
+ ...options
4580
+ });
4581
+ }
4582
+ todo(options) {
4583
+ return (options.client ?? this._client).get({
4584
+ url: "/session/{id}/todo",
4585
+ ...options
4586
+ });
4587
+ }
4588
+ init(options) {
4589
+ return (options.client ?? this._client).post({
4590
+ url: "/session/{id}/init",
4591
+ ...options,
4592
+ headers: {
4593
+ "Content-Type": "application/json",
4594
+ ...options.headers
4595
+ }
4596
+ });
4597
+ }
4598
+ fork(options) {
4599
+ return (options.client ?? this._client).post({
4600
+ url: "/session/{id}/fork",
4601
+ ...options,
4602
+ headers: {
4603
+ "Content-Type": "application/json",
4604
+ ...options.headers
4605
+ }
4606
+ });
4607
+ }
4608
+ abort(options) {
4609
+ return (options.client ?? this._client).post({
4610
+ url: "/session/{id}/abort",
4611
+ ...options
4612
+ });
4613
+ }
4614
+ unshare(options) {
4615
+ return (options.client ?? this._client).delete({
4616
+ url: "/session/{id}/share",
4617
+ ...options
4618
+ });
4619
+ }
4620
+ share(options) {
4621
+ return (options.client ?? this._client).post({
4622
+ url: "/session/{id}/share",
4623
+ ...options
4624
+ });
4625
+ }
4626
+ diff(options) {
4627
+ return (options.client ?? this._client).get({
4628
+ url: "/session/{id}/diff",
4629
+ ...options
4630
+ });
4631
+ }
4632
+ summarize(options) {
4633
+ return (options.client ?? this._client).post({
4634
+ url: "/session/{id}/summarize",
4635
+ ...options,
4636
+ headers: {
4637
+ "Content-Type": "application/json",
4638
+ ...options.headers
4639
+ }
4640
+ });
4641
+ }
4642
+ messages(options) {
4643
+ return (options.client ?? this._client).get({
4644
+ url: "/session/{id}/message",
4645
+ ...options
4646
+ });
4647
+ }
4648
+ prompt(options) {
4649
+ return (options.client ?? this._client).post({
4650
+ url: "/session/{id}/message",
4651
+ ...options,
4652
+ headers: {
4653
+ "Content-Type": "application/json",
4654
+ ...options.headers
4655
+ }
4656
+ });
4657
+ }
4658
+ message(options) {
4659
+ return (options.client ?? this._client).get({
4660
+ url: "/session/{id}/message/{messageID}",
4661
+ ...options
4662
+ });
4663
+ }
4664
+ promptAsync(options) {
4665
+ return (options.client ?? this._client).post({
4666
+ url: "/session/{id}/prompt_async",
4667
+ ...options,
4668
+ headers: {
4669
+ "Content-Type": "application/json",
4670
+ ...options.headers
4671
+ }
4672
+ });
4673
+ }
4674
+ command(options) {
4675
+ return (options.client ?? this._client).post({
4676
+ url: "/session/{id}/command",
4677
+ ...options,
4678
+ headers: {
4679
+ "Content-Type": "application/json",
4680
+ ...options.headers
4681
+ }
4682
+ });
4683
+ }
4684
+ shell(options) {
4685
+ return (options.client ?? this._client).post({
4686
+ url: "/session/{id}/shell",
4687
+ ...options,
4688
+ headers: {
4689
+ "Content-Type": "application/json",
4690
+ ...options.headers
4691
+ }
4692
+ });
4693
+ }
4694
+ revert(options) {
4695
+ return (options.client ?? this._client).post({
4696
+ url: "/session/{id}/revert",
4697
+ ...options,
4698
+ headers: {
4699
+ "Content-Type": "application/json",
4700
+ ...options.headers
4701
+ }
4702
+ });
4703
+ }
4704
+ unrevert(options) {
4705
+ return (options.client ?? this._client).post({
4706
+ url: "/session/{id}/unrevert",
4707
+ ...options
4708
+ });
4709
+ }
4710
+ }
4711
+
4712
+ class Command2 extends _HeyApiClient {
4713
+ list(options) {
4714
+ return (options?.client ?? this._client).get({
4715
+ url: "/command",
4716
+ ...options
4717
+ });
4718
+ }
4719
+ }
4720
+
4721
+ class Oauth extends _HeyApiClient {
4722
+ authorize(options) {
4723
+ return (options.client ?? this._client).post({
4724
+ url: "/provider/{id}/oauth/authorize",
4725
+ ...options,
4726
+ headers: {
4727
+ "Content-Type": "application/json",
4728
+ ...options.headers
4729
+ }
4730
+ });
4731
+ }
4732
+ callback(options) {
4733
+ return (options.client ?? this._client).post({
4734
+ url: "/provider/{id}/oauth/callback",
4735
+ ...options,
4736
+ headers: {
4737
+ "Content-Type": "application/json",
4738
+ ...options.headers
4739
+ }
4740
+ });
4741
+ }
4742
+ }
4743
+
4744
+ class Provider extends _HeyApiClient {
4745
+ list(options) {
4746
+ return (options?.client ?? this._client).get({
4747
+ url: "/provider",
4748
+ ...options
4749
+ });
4750
+ }
4751
+ auth(options) {
4752
+ return (options?.client ?? this._client).get({
4753
+ url: "/provider/auth",
4754
+ ...options
4755
+ });
4756
+ }
4757
+ oauth = new Oauth({ client: this._client });
4758
+ }
3714
4759
 
4760
+ class Find extends _HeyApiClient {
4761
+ text(options) {
4762
+ return (options.client ?? this._client).get({
4763
+ url: "/find",
4764
+ ...options
4765
+ });
4766
+ }
4767
+ files(options) {
4768
+ return (options.client ?? this._client).get({
4769
+ url: "/find/file",
4770
+ ...options
4771
+ });
4772
+ }
4773
+ symbols(options) {
4774
+ return (options.client ?? this._client).get({
4775
+ url: "/find/symbol",
4776
+ ...options
4777
+ });
4778
+ }
4779
+ }
4780
+
4781
+ class File extends _HeyApiClient {
4782
+ list(options) {
4783
+ return (options.client ?? this._client).get({
4784
+ url: "/file",
4785
+ ...options
4786
+ });
4787
+ }
4788
+ read(options) {
4789
+ return (options.client ?? this._client).get({
4790
+ url: "/file/content",
4791
+ ...options
4792
+ });
4793
+ }
4794
+ status(options) {
4795
+ return (options?.client ?? this._client).get({
4796
+ url: "/file/status",
4797
+ ...options
4798
+ });
4799
+ }
4800
+ }
4801
+
4802
+ class App extends _HeyApiClient {
4803
+ log(options) {
4804
+ return (options?.client ?? this._client).post({
4805
+ url: "/log",
4806
+ ...options,
4807
+ headers: {
4808
+ "Content-Type": "application/json",
4809
+ ...options?.headers
4810
+ }
4811
+ });
4812
+ }
4813
+ agents(options) {
4814
+ return (options?.client ?? this._client).get({
4815
+ url: "/agent",
4816
+ ...options
4817
+ });
4818
+ }
4819
+ }
4820
+
4821
+ class Auth extends _HeyApiClient {
4822
+ remove(options) {
4823
+ return (options.client ?? this._client).delete({
4824
+ url: "/mcp/{name}/auth",
4825
+ ...options
4826
+ });
4827
+ }
4828
+ start(options) {
4829
+ return (options.client ?? this._client).post({
4830
+ url: "/mcp/{name}/auth",
4831
+ ...options
4832
+ });
4833
+ }
4834
+ callback(options) {
4835
+ return (options.client ?? this._client).post({
4836
+ url: "/mcp/{name}/auth/callback",
4837
+ ...options,
4838
+ headers: {
4839
+ "Content-Type": "application/json",
4840
+ ...options.headers
4841
+ }
4842
+ });
4843
+ }
4844
+ authenticate(options) {
4845
+ return (options.client ?? this._client).post({
4846
+ url: "/mcp/{name}/auth/authenticate",
4847
+ ...options
4848
+ });
4849
+ }
4850
+ set(options) {
4851
+ return (options.client ?? this._client).put({
4852
+ url: "/auth/{id}",
4853
+ ...options,
4854
+ headers: {
4855
+ "Content-Type": "application/json",
4856
+ ...options.headers
4857
+ }
4858
+ });
4859
+ }
4860
+ }
4861
+
4862
+ class Mcp extends _HeyApiClient {
4863
+ status(options) {
4864
+ return (options?.client ?? this._client).get({
4865
+ url: "/mcp",
4866
+ ...options
4867
+ });
4868
+ }
4869
+ add(options) {
4870
+ return (options?.client ?? this._client).post({
4871
+ url: "/mcp",
4872
+ ...options,
4873
+ headers: {
4874
+ "Content-Type": "application/json",
4875
+ ...options?.headers
4876
+ }
4877
+ });
4878
+ }
4879
+ connect(options) {
4880
+ return (options.client ?? this._client).post({
4881
+ url: "/mcp/{name}/connect",
4882
+ ...options
4883
+ });
4884
+ }
4885
+ disconnect(options) {
4886
+ return (options.client ?? this._client).post({
4887
+ url: "/mcp/{name}/disconnect",
4888
+ ...options
4889
+ });
4890
+ }
4891
+ auth = new Auth({ client: this._client });
4892
+ }
4893
+
4894
+ class Lsp extends _HeyApiClient {
4895
+ status(options) {
4896
+ return (options?.client ?? this._client).get({
4897
+ url: "/lsp",
4898
+ ...options
4899
+ });
4900
+ }
4901
+ }
4902
+
4903
+ class Formatter extends _HeyApiClient {
4904
+ status(options) {
4905
+ return (options?.client ?? this._client).get({
4906
+ url: "/formatter",
4907
+ ...options
4908
+ });
4909
+ }
4910
+ }
4911
+
4912
+ class Control extends _HeyApiClient {
4913
+ next(options) {
4914
+ return (options?.client ?? this._client).get({
4915
+ url: "/tui/control/next",
4916
+ ...options
4917
+ });
4918
+ }
4919
+ response(options) {
4920
+ return (options?.client ?? this._client).post({
4921
+ url: "/tui/control/response",
4922
+ ...options,
4923
+ headers: {
4924
+ "Content-Type": "application/json",
4925
+ ...options?.headers
4926
+ }
4927
+ });
4928
+ }
4929
+ }
4930
+
4931
+ class Tui extends _HeyApiClient {
4932
+ appendPrompt(options) {
4933
+ return (options?.client ?? this._client).post({
4934
+ url: "/tui/append-prompt",
4935
+ ...options,
4936
+ headers: {
4937
+ "Content-Type": "application/json",
4938
+ ...options?.headers
4939
+ }
4940
+ });
4941
+ }
4942
+ openHelp(options) {
4943
+ return (options?.client ?? this._client).post({
4944
+ url: "/tui/open-help",
4945
+ ...options
4946
+ });
4947
+ }
4948
+ openSessions(options) {
4949
+ return (options?.client ?? this._client).post({
4950
+ url: "/tui/open-sessions",
4951
+ ...options
4952
+ });
4953
+ }
4954
+ openThemes(options) {
4955
+ return (options?.client ?? this._client).post({
4956
+ url: "/tui/open-themes",
4957
+ ...options
4958
+ });
4959
+ }
4960
+ openModels(options) {
4961
+ return (options?.client ?? this._client).post({
4962
+ url: "/tui/open-models",
4963
+ ...options
4964
+ });
4965
+ }
4966
+ submitPrompt(options) {
4967
+ return (options?.client ?? this._client).post({
4968
+ url: "/tui/submit-prompt",
4969
+ ...options
4970
+ });
4971
+ }
4972
+ clearPrompt(options) {
4973
+ return (options?.client ?? this._client).post({
4974
+ url: "/tui/clear-prompt",
4975
+ ...options
4976
+ });
4977
+ }
4978
+ executeCommand(options) {
4979
+ return (options?.client ?? this._client).post({
4980
+ url: "/tui/execute-command",
4981
+ ...options,
4982
+ headers: {
4983
+ "Content-Type": "application/json",
4984
+ ...options?.headers
4985
+ }
4986
+ });
4987
+ }
4988
+ showToast(options) {
4989
+ return (options?.client ?? this._client).post({
4990
+ url: "/tui/show-toast",
4991
+ ...options,
4992
+ headers: {
4993
+ "Content-Type": "application/json",
4994
+ ...options?.headers
4995
+ }
4996
+ });
4997
+ }
4998
+ publish(options) {
4999
+ return (options?.client ?? this._client).post({
5000
+ url: "/tui/publish",
5001
+ ...options,
5002
+ headers: {
5003
+ "Content-Type": "application/json",
5004
+ ...options?.headers
5005
+ }
5006
+ });
5007
+ }
5008
+ control = new Control({ client: this._client });
5009
+ }
5010
+
5011
+ class Event extends _HeyApiClient {
5012
+ subscribe(options) {
5013
+ return (options?.client ?? this._client).get.sse({
5014
+ url: "/event",
5015
+ ...options
5016
+ });
5017
+ }
5018
+ }
5019
+
5020
+ class OpencodeClient extends _HeyApiClient {
5021
+ postSessionIdPermissionsPermissionId(options) {
5022
+ return (options.client ?? this._client).post({
5023
+ url: "/session/{id}/permissions/{permissionID}",
5024
+ ...options,
5025
+ headers: {
5026
+ "Content-Type": "application/json",
5027
+ ...options.headers
5028
+ }
5029
+ });
5030
+ }
5031
+ global = new Global({ client: this._client });
5032
+ project = new Project({ client: this._client });
5033
+ pty = new Pty({ client: this._client });
5034
+ config = new Config({ client: this._client });
5035
+ tool = new Tool({ client: this._client });
5036
+ instance = new Instance({ client: this._client });
5037
+ path = new Path({ client: this._client });
5038
+ vcs = new Vcs({ client: this._client });
5039
+ session = new Session({ client: this._client });
5040
+ command = new Command2({ client: this._client });
5041
+ provider = new Provider({ client: this._client });
5042
+ find = new Find({ client: this._client });
5043
+ file = new File({ client: this._client });
5044
+ app = new App({ client: this._client });
5045
+ mcp = new Mcp({ client: this._client });
5046
+ lsp = new Lsp({ client: this._client });
5047
+ formatter = new Formatter({ client: this._client });
5048
+ tui = new Tui({ client: this._client });
5049
+ auth = new Auth({ client: this._client });
5050
+ event = new Event({ client: this._client });
5051
+ }
5052
+
5053
+ // node_modules/@opencode-ai/sdk/dist/client.js
5054
+ function createOpencodeClient(config) {
5055
+ if (!config?.fetch) {
5056
+ const customFetch = (req) => {
5057
+ req.timeout = false;
5058
+ return fetch(req);
5059
+ };
5060
+ config = {
5061
+ ...config,
5062
+ fetch: customFetch
5063
+ };
5064
+ }
5065
+ if (config?.directory) {
5066
+ config.headers = {
5067
+ ...config.headers,
5068
+ "x-opencode-directory": config.directory
5069
+ };
5070
+ }
5071
+ const client2 = createClient(config);
5072
+ return new OpencodeClient({ client: client2 });
5073
+ }
5074
+ // node_modules/@opencode-ai/sdk/dist/server.js
5075
+ import { spawn } from "child_process";
5076
+ async function createOpencodeServer(options) {
5077
+ options = Object.assign({
5078
+ hostname: "127.0.0.1",
5079
+ port: 4096,
5080
+ timeout: 5000
5081
+ }, options ?? {});
5082
+ const proc = spawn(`opencode`, [`serve`, `--hostname=${options.hostname}`, `--port=${options.port}`], {
5083
+ signal: options.signal,
5084
+ env: {
5085
+ ...process.env,
5086
+ OPENCODE_CONFIG_CONTENT: JSON.stringify(options.config ?? {})
5087
+ }
5088
+ });
5089
+ const url = await new Promise((resolve, reject) => {
5090
+ const id = setTimeout(() => {
5091
+ reject(new Error(`Timeout waiting for server to start after ${options.timeout}ms`));
5092
+ }, options.timeout);
5093
+ let output = "";
5094
+ proc.stdout?.on("data", (chunk) => {
5095
+ output += chunk.toString();
5096
+ const lines = output.split(`
5097
+ `);
5098
+ for (const line of lines) {
5099
+ if (line.startsWith("opencode server listening")) {
5100
+ const match = line.match(/on\s+(https?:\/\/[^\s]+)/);
5101
+ if (!match) {
5102
+ throw new Error(`Failed to parse server url from output: ${line}`);
5103
+ }
5104
+ clearTimeout(id);
5105
+ resolve(match[1]);
5106
+ return;
5107
+ }
5108
+ }
5109
+ });
5110
+ proc.stderr?.on("data", (chunk) => {
5111
+ output += chunk.toString();
5112
+ });
5113
+ proc.on("exit", (code) => {
5114
+ clearTimeout(id);
5115
+ let msg = `Server exited with code ${code}`;
5116
+ if (output.trim()) {
5117
+ msg += `
5118
+ Server output: ${output}`;
5119
+ }
5120
+ reject(new Error(msg));
5121
+ });
5122
+ proc.on("error", (error) => {
5123
+ clearTimeout(id);
5124
+ reject(error);
5125
+ });
5126
+ if (options.signal) {
5127
+ options.signal.addEventListener("abort", () => {
5128
+ clearTimeout(id);
5129
+ reject(new Error("Aborted"));
5130
+ });
5131
+ }
5132
+ });
5133
+ return {
5134
+ url,
5135
+ close() {
5136
+ proc.kill();
5137
+ }
5138
+ };
5139
+ }
5140
+ // node_modules/@opencode-ai/sdk/dist/index.js
5141
+ async function createOpencode(options) {
5142
+ const server2 = await createOpencodeServer({
5143
+ ...options
5144
+ });
5145
+ const client3 = createOpencodeClient({
5146
+ baseUrl: server2.url
5147
+ });
5148
+ return {
5149
+ client: client3,
5150
+ server: server2
5151
+ };
5152
+ }
5153
+
5154
+ // src/cli/run/runner.ts
5155
+ var import_picocolors4 = __toESM(require_picocolors(), 1);
5156
+
5157
+ // src/cli/run/completion.ts
5158
+ var import_picocolors3 = __toESM(require_picocolors(), 1);
5159
+ async function checkCompletionConditions(ctx) {
5160
+ try {
5161
+ if (!await areAllTodosComplete(ctx)) {
5162
+ return false;
5163
+ }
5164
+ if (!await areAllChildrenIdle(ctx)) {
5165
+ return false;
5166
+ }
5167
+ return true;
5168
+ } catch {
5169
+ return false;
5170
+ }
5171
+ }
5172
+ async function areAllTodosComplete(ctx) {
5173
+ const todosRes = await ctx.client.session.todo({ path: { id: ctx.sessionID } });
5174
+ const todos = todosRes.data ?? [];
5175
+ const incompleteTodos = todos.filter((t) => t.status !== "completed" && t.status !== "cancelled");
5176
+ if (incompleteTodos.length > 0) {
5177
+ console.log(import_picocolors3.default.dim(` Waiting: ${incompleteTodos.length} todos remaining`));
5178
+ return false;
5179
+ }
5180
+ return true;
5181
+ }
5182
+ async function areAllChildrenIdle(ctx) {
5183
+ const allStatuses = await fetchAllStatuses(ctx);
5184
+ return areAllDescendantsIdle(ctx, ctx.sessionID, allStatuses);
5185
+ }
5186
+ async function fetchAllStatuses(ctx) {
5187
+ const statusRes = await ctx.client.session.status();
5188
+ return statusRes.data ?? {};
5189
+ }
5190
+ async function areAllDescendantsIdle(ctx, sessionID, allStatuses) {
5191
+ const childrenRes = await ctx.client.session.children({
5192
+ path: { id: sessionID }
5193
+ });
5194
+ const children = childrenRes.data ?? [];
5195
+ for (const child of children) {
5196
+ const status = allStatuses[child.id];
5197
+ if (status && status.type !== "idle") {
5198
+ console.log(import_picocolors3.default.dim(` Waiting: session ${child.id.slice(0, 8)}... is ${status.type}`));
5199
+ return false;
5200
+ }
5201
+ const descendantsIdle = await areAllDescendantsIdle(ctx, child.id, allStatuses);
5202
+ if (!descendantsIdle) {
5203
+ return false;
5204
+ }
5205
+ }
5206
+ return true;
5207
+ }
5208
+
5209
+ // src/cli/run/events.ts
5210
+ function createEventState() {
5211
+ return {
5212
+ mainSessionIdle: false,
5213
+ lastOutput: ""
5214
+ };
5215
+ }
5216
+ async function processEvents(ctx, stream, state) {
5217
+ for await (const event of stream) {
5218
+ if (ctx.abortController.signal.aborted)
5219
+ break;
5220
+ try {
5221
+ const payload = event.payload;
5222
+ if (!payload)
5223
+ continue;
5224
+ handleSessionIdle(ctx, payload, state);
5225
+ handleSessionStatus(ctx, payload, state);
5226
+ handleMessageUpdated(ctx, payload, state);
5227
+ } catch {}
5228
+ }
5229
+ }
5230
+ function handleSessionIdle(ctx, payload, state) {
5231
+ if (payload.type !== "session.idle")
5232
+ return;
5233
+ const props = payload.properties;
5234
+ if (props?.sessionID === ctx.sessionID) {
5235
+ state.mainSessionIdle = true;
5236
+ }
5237
+ }
5238
+ function handleSessionStatus(ctx, payload, state) {
5239
+ if (payload.type !== "session.status")
5240
+ return;
5241
+ const props = payload.properties;
5242
+ if (props?.sessionID === ctx.sessionID && props?.status?.type === "busy") {
5243
+ state.mainSessionIdle = false;
5244
+ }
5245
+ }
5246
+ function handleMessageUpdated(ctx, payload, state) {
5247
+ if (payload.type !== "message.updated")
5248
+ return;
5249
+ const props = payload.properties;
5250
+ if (props?.info?.sessionID !== ctx.sessionID)
5251
+ return;
5252
+ if (props?.info?.role !== "assistant")
5253
+ return;
5254
+ const content = props.content;
5255
+ if (!content || content === state.lastOutput)
5256
+ return;
5257
+ const newContent = content.slice(state.lastOutput.length);
5258
+ if (newContent) {
5259
+ process.stdout.write(newContent);
5260
+ }
5261
+ state.lastOutput = content;
5262
+ }
5263
+
5264
+ // src/cli/run/runner.ts
5265
+ var POLL_INTERVAL_MS = 500;
5266
+ var DEFAULT_TIMEOUT_MS = 30 * 60 * 1000;
5267
+ async function run(options) {
5268
+ const {
5269
+ message,
5270
+ agent,
5271
+ directory = process.cwd(),
5272
+ timeout = DEFAULT_TIMEOUT_MS
5273
+ } = options;
5274
+ console.log(import_picocolors4.default.cyan("Starting opencode server..."));
5275
+ const abortController = new AbortController;
5276
+ const timeoutId = setTimeout(() => {
5277
+ console.log(import_picocolors4.default.yellow(`
5278
+ Timeout reached. Aborting...`));
5279
+ abortController.abort();
5280
+ }, timeout);
5281
+ try {
5282
+ const { client: client3, server: server2 } = await createOpencode({
5283
+ signal: abortController.signal
5284
+ });
5285
+ const cleanup = () => {
5286
+ clearTimeout(timeoutId);
5287
+ server2.close();
5288
+ };
5289
+ process.on("SIGINT", () => {
5290
+ console.log(import_picocolors4.default.yellow(`
5291
+ Interrupted. Shutting down...`));
5292
+ cleanup();
5293
+ process.exit(130);
5294
+ });
5295
+ try {
5296
+ const sessionRes = await client3.session.create({
5297
+ body: { title: "oh-my-opencode run" }
5298
+ });
5299
+ const sessionID = sessionRes.data?.id;
5300
+ if (!sessionID) {
5301
+ console.error(import_picocolors4.default.red("Failed to create session"));
5302
+ return 1;
5303
+ }
5304
+ console.log(import_picocolors4.default.dim(`Session: ${sessionID}`));
5305
+ const ctx = {
5306
+ client: client3,
5307
+ sessionID,
5308
+ directory,
5309
+ abortController
5310
+ };
5311
+ const events = await client3.event.subscribe();
5312
+ const eventState = createEventState();
5313
+ const eventProcessor = processEvents(ctx, events.stream, eventState);
5314
+ console.log(import_picocolors4.default.dim(`
5315
+ Sending prompt...`));
5316
+ await client3.session.promptAsync({
5317
+ path: { id: sessionID },
5318
+ body: {
5319
+ agent,
5320
+ parts: [{ type: "text", text: message }]
5321
+ },
5322
+ query: { directory }
5323
+ });
5324
+ console.log(import_picocolors4.default.dim(`Waiting for completion...
5325
+ `));
5326
+ while (!abortController.signal.aborted) {
5327
+ await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
5328
+ if (!eventState.mainSessionIdle) {
5329
+ continue;
5330
+ }
5331
+ const shouldExit = await checkCompletionConditions(ctx);
5332
+ if (shouldExit) {
5333
+ console.log(import_picocolors4.default.green(`
5334
+
5335
+ All tasks completed.`));
5336
+ abortController.abort();
5337
+ await eventProcessor.catch(() => {});
5338
+ cleanup();
5339
+ return 0;
5340
+ }
5341
+ }
5342
+ await eventProcessor.catch(() => {});
5343
+ cleanup();
5344
+ return 130;
5345
+ } catch (err) {
5346
+ cleanup();
5347
+ throw err;
5348
+ }
5349
+ } catch (err) {
5350
+ clearTimeout(timeoutId);
5351
+ if (err instanceof Error && err.name === "AbortError") {
5352
+ return 130;
5353
+ }
5354
+ console.error(import_picocolors4.default.red(`Error: ${err}`));
5355
+ return 1;
5356
+ }
5357
+ }
3715
5358
  // src/cli/index.ts
3716
5359
  var packageJson = await Promise.resolve().then(() => __toESM(require_package(), 1));
3717
5360
  var VERSION = packageJson.version;
@@ -3738,6 +5381,25 @@ Model Providers:
3738
5381
  const exitCode = await install(args);
3739
5382
  process.exit(exitCode);
3740
5383
  });
5384
+ program2.command("run <message>").description("Run opencode with todo/background task completion enforcement").option("-a, --agent <name>", "Agent to use (default: Sisyphus)").option("-d, --directory <path>", "Working directory").option("-t, --timeout <ms>", "Timeout in milliseconds (default: 30 minutes)", parseInt).addHelpText("after", `
5385
+ Examples:
5386
+ $ bunx oh-my-opencode run "Fix the bug in index.ts"
5387
+ $ bunx oh-my-opencode run --agent Sisyphus "Implement feature X"
5388
+ $ bunx oh-my-opencode run --timeout 3600000 "Large refactoring task"
5389
+
5390
+ Unlike 'opencode run', this command waits until:
5391
+ - All todos are completed or cancelled
5392
+ - All child sessions (background tasks) are idle
5393
+ `).action(async (message, options) => {
5394
+ const runOptions = {
5395
+ message,
5396
+ agent: options.agent,
5397
+ directory: options.directory,
5398
+ timeout: options.timeout
5399
+ };
5400
+ const exitCode = await run(runOptions);
5401
+ process.exit(exitCode);
5402
+ });
3741
5403
  program2.command("version").description("Show version information").action(() => {
3742
5404
  console.log(`oh-my-opencode v${VERSION}`);
3743
5405
  });