@cortexkit/aft-opencode 0.56.1 → 0.57.0

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 (42) hide show
  1. package/dist/bg-notifications.d.ts +1 -0
  2. package/dist/bg-notifications.d.ts.map +1 -1
  3. package/dist/config.d.ts +2 -0
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/entry/server.js +2682 -282
  6. package/dist/index.js +448 -244
  7. package/dist/lsp-github-install.d.ts.map +1 -1
  8. package/dist/permissions/v2-service.d.ts +30 -0
  9. package/dist/permissions/v2-service.d.ts.map +1 -0
  10. package/dist/permissions/v2.d.ts +121 -9
  11. package/dist/permissions/v2.d.ts.map +1 -1
  12. package/dist/shared/rpc-server.d.ts.map +1 -1
  13. package/dist/shared/status.d.ts +8 -1
  14. package/dist/shared/status.d.ts.map +1 -1
  15. package/dist/subc-tool-schemas.d.ts +11 -0
  16. package/dist/subc-tool-schemas.d.ts.map +1 -1
  17. package/dist/tool-registration.d.ts.map +1 -1
  18. package/dist/tools/definitions/v2.d.ts +6 -0
  19. package/dist/tools/definitions/v2.d.ts.map +1 -1
  20. package/dist/tools/hoisted/v2.d.ts +12 -2
  21. package/dist/tools/hoisted/v2.d.ts.map +1 -1
  22. package/dist/tools/hoisted.d.ts.map +1 -1
  23. package/dist/tools/semantic.d.ts.map +1 -1
  24. package/dist/tui/v2-status.d.ts +8 -0
  25. package/dist/tui/v2-status.d.ts.map +1 -1
  26. package/index.js +14 -0
  27. package/package.json +14 -10
  28. package/server.js +8 -0
  29. package/src/entry/server-runtime.mjs +11 -0
  30. package/src/shared/rpc-server.ts +5 -0
  31. package/src/shared/status.ts +16 -9
  32. package/src/tui/index.tsx +1 -0
  33. package/src/tui/sidebar-view.tsx +722 -0
  34. package/src/tui/sidebar.tsx +42 -560
  35. package/src/tui/v2-status.ts +8 -1
  36. package/src/tui/v2.tsx +173 -30
  37. package/src/tui-compiled/index.tsx +1 -1
  38. package/src/tui-compiled/sidebar-view.tsx +815 -0
  39. package/src/tui-compiled/sidebar.tsx +45 -693
  40. package/src/tui-compiled/v2-status.ts +8 -1
  41. package/src/tui-compiled/v2.tsx +163 -54
  42. package/tui.js +7 -0
@@ -44,6 +44,17 @@ var __export = (target, all) => {
44
44
  set: __exportSetter.bind(all, name)
45
45
  });
46
46
  };
47
+ var __esm = (fn, res, err) => () => {
48
+ if (fn)
49
+ try {
50
+ res = fn(fn = 0);
51
+ } catch (e) {
52
+ err = [e];
53
+ }
54
+ if (err)
55
+ throw err[0];
56
+ return res;
57
+ };
47
58
 
48
59
  // ../../node_modules/.bun/esprima@4.0.1/node_modules/esprima/dist/esprima.js
49
60
  var require_esprima = __commonJS(function(exports, module) {
@@ -7802,6 +7813,1702 @@ var require_src2 = __commonJS(function(exports, module) {
7802
7813
  };
7803
7814
  });
7804
7815
 
7816
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-m2eywc8w.js
7817
+ var init_service_m2eywc8w = () => {};
7818
+
7819
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-9rqn6x4v.js
7820
+ function __exportSetter2(name, newValue) {
7821
+ this[name] = __returnValue2.bind(null, newValue);
7822
+ }
7823
+ var __defProp2, __returnValue2 = (v) => v, __export2 = (target, all) => {
7824
+ for (var name in all)
7825
+ __defProp2(target, name, {
7826
+ get: all[name],
7827
+ enumerable: true,
7828
+ configurable: true,
7829
+ set: __exportSetter2.bind(all, name)
7830
+ });
7831
+ };
7832
+ var init_service_9rqn6x4v = __esm(() => {
7833
+ __defProp2 = Object.defineProperty;
7834
+ });
7835
+
7836
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-frbwqjmf.js
7837
+ function make7(connect) {
7838
+ let current;
7839
+ const capacity = 4096;
7840
+ function stop(connection) {
7841
+ connection.connected = undefined;
7842
+ connection.controller.abort();
7843
+ if (current === connection)
7844
+ current = undefined;
7845
+ }
7846
+ async function run(connection) {
7847
+ let iterator;
7848
+ let completion = {};
7849
+ try {
7850
+ if (connection.controller.signal.aborted)
7851
+ return;
7852
+ iterator = connect(connection.controller.signal, () => {
7853
+ connection.subscribers.forEach((subscriber) => subscriber.activity?.());
7854
+ })[Symbol.asyncIterator]();
7855
+ while (!connection.controller.signal.aborted) {
7856
+ const item = await iterator.next();
7857
+ if (item.done || connection.controller.signal.aborted)
7858
+ break;
7859
+ if (item.value.type === "server.connected")
7860
+ connection.connected = item.value;
7861
+ connection.subscribers.forEach((subscriber) => subscriber.push(item.value));
7862
+ }
7863
+ } catch (error) {
7864
+ completion = { error };
7865
+ } finally {
7866
+ stop(connection);
7867
+ try {
7868
+ await iterator?.return?.();
7869
+ } catch (error) {
7870
+ if (!("error" in completion))
7871
+ completion = { error };
7872
+ }
7873
+ connection.subscribers.forEach((subscriber) => subscriber.finish(completion));
7874
+ }
7875
+ }
7876
+ return {
7877
+ subscribe(options) {
7878
+ return {
7879
+ [Symbol.asyncIterator]() {
7880
+ const pending = [];
7881
+ const queued = [];
7882
+ let started = false;
7883
+ let completion;
7884
+ let connection;
7885
+ function finish(result, discard = true) {
7886
+ completion = result;
7887
+ if (discard)
7888
+ queued.length = 0;
7889
+ options?.signal?.removeEventListener("abort", abort);
7890
+ if (connection?.subscribers.delete(subscriber) && !connection.subscribers.size)
7891
+ stop(connection);
7892
+ pending.splice(0).forEach((request) => {
7893
+ if ("error" in result)
7894
+ request.reject(result.error);
7895
+ else
7896
+ request.resolve({ done: true, value: undefined });
7897
+ });
7898
+ }
7899
+ function abort() {
7900
+ finish({});
7901
+ }
7902
+ const subscriber = {
7903
+ activity: options?.onActivity,
7904
+ finish(result) {
7905
+ finish(result, false);
7906
+ },
7907
+ push(value) {
7908
+ if (completion)
7909
+ return;
7910
+ const request = pending.shift();
7911
+ if (request) {
7912
+ request.resolve({ done: false, value });
7913
+ return;
7914
+ }
7915
+ if (queued.length === capacity) {
7916
+ finish({ error: new Error(`Event subscriber exceeded its ${capacity}-event capacity`) });
7917
+ return;
7918
+ }
7919
+ queued.push(value);
7920
+ }
7921
+ };
7922
+ function start() {
7923
+ if (completion)
7924
+ return;
7925
+ const fresh = !current;
7926
+ connection = current ?? {
7927
+ controller: new AbortController,
7928
+ subscribers: new Set
7929
+ };
7930
+ current = connection;
7931
+ connection.subscribers.add(subscriber);
7932
+ if (connection.connected)
7933
+ subscriber.push(connection.connected);
7934
+ if (fresh)
7935
+ run(connection);
7936
+ }
7937
+ return {
7938
+ next() {
7939
+ const value = queued.shift();
7940
+ if (value)
7941
+ return Promise.resolve({ done: false, value });
7942
+ if (completion) {
7943
+ if ("error" in completion)
7944
+ return Promise.reject(completion.error);
7945
+ return Promise.resolve({ done: true, value: undefined });
7946
+ }
7947
+ if (options?.signal?.aborted) {
7948
+ abort();
7949
+ return Promise.resolve({ done: true, value: undefined });
7950
+ }
7951
+ const request = Promise.withResolvers();
7952
+ pending.push(request);
7953
+ if (!started) {
7954
+ started = true;
7955
+ options?.signal?.addEventListener("abort", abort, { once: true });
7956
+ start();
7957
+ }
7958
+ return request.promise;
7959
+ },
7960
+ return() {
7961
+ finish({});
7962
+ return Promise.resolve({ done: true, value: undefined });
7963
+ }
7964
+ };
7965
+ }
7966
+ };
7967
+ }
7968
+ };
7969
+ }
7970
+ var exports_shared_events;
7971
+ var init_service_frbwqjmf = __esm(() => {
7972
+ init_service_9rqn6x4v();
7973
+ exports_shared_events = {};
7974
+ __export2(exports_shared_events, {
7975
+ SharedEvents: () => exports_shared_events,
7976
+ make: () => make7
7977
+ });
7978
+ });
7979
+
7980
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-qc0tvgb4.js
7981
+ var ClientError2;
7982
+ var init_service_qc0tvgb4 = __esm(() => {
7983
+ ClientError2 = class ClientError2 extends Error {
7984
+ reason;
7985
+ name = "ClientError";
7986
+ constructor(reason, options) {
7987
+ super(reason, options);
7988
+ this.reason = reason;
7989
+ }
7990
+ };
7991
+ });
7992
+
7993
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-5mmhmmk7.js
7994
+ function make3(options) {
7995
+ const fetch2 = options.fetch ?? globalThis.fetch;
7996
+ const prepare = (descriptor, requestOptions) => {
7997
+ const url = new URL(descriptor.path, options.baseUrl);
7998
+ for (const [key, value] of Object.entries(descriptor.query ?? {}))
7999
+ appendQuery(url.searchParams, key, value);
8000
+ const headers = new Headers(options.headers);
8001
+ for (const [key, value] of Object.entries(descriptor.headers ?? {})) {
8002
+ if (value !== undefined && value !== null)
8003
+ headers.set(key, String(value));
8004
+ }
8005
+ for (const [key, value] of new Headers(requestOptions?.headers))
8006
+ headers.set(key, value);
8007
+ if (descriptor.body !== undefined && !headers.has("content-type"))
8008
+ headers.set("content-type", descriptor.binaryBody ? "application/octet-stream" : "application/json");
8009
+ return {
8010
+ url,
8011
+ init: {
8012
+ method: descriptor.method,
8013
+ signal: requestOptions?.signal,
8014
+ headers,
8015
+ body: descriptor.body === undefined ? undefined : descriptor.binaryBody ? descriptor.body : JSON.stringify(descriptor.body)
8016
+ }
8017
+ };
8018
+ };
8019
+ const execute = async (descriptor, requestOptions) => {
8020
+ try {
8021
+ const prepared = prepare(descriptor, requestOptions);
8022
+ return await fetch2(prepared.url, prepared.init);
8023
+ } catch (cause) {
8024
+ throw new ClientError2("Transport", { cause });
8025
+ }
8026
+ };
8027
+ const responseError = async (response, descriptor) => {
8028
+ if (descriptor.declaredStatuses.includes(response.status))
8029
+ throw await json3(response);
8030
+ try {
8031
+ await response.body?.cancel();
8032
+ } catch {}
8033
+ throw new ClientError2("UnexpectedStatus", { cause: { status: response.status } });
8034
+ };
8035
+ const request = async (descriptor, requestOptions) => {
8036
+ const response = await execute(descriptor, requestOptions);
8037
+ if (response.status !== descriptor.successStatus)
8038
+ return responseError(response, descriptor);
8039
+ if (descriptor.binary)
8040
+ return new Uint8Array(await response.arrayBuffer());
8041
+ if (descriptor.empty) {
8042
+ try {
8043
+ await response.body?.cancel();
8044
+ } catch {}
8045
+ return;
8046
+ }
8047
+ return await json3(response);
8048
+ };
8049
+ const sse = (descriptor, requestOptions) => ({
8050
+ async* [Symbol.asyncIterator]() {
8051
+ const response = await execute(descriptor, requestOptions);
8052
+ if (response.status !== descriptor.successStatus)
8053
+ await responseError(response, descriptor);
8054
+ if (!isContentType(response, "text/event-stream")) {
8055
+ try {
8056
+ await response.body?.cancel();
8057
+ } catch {}
8058
+ throw new ClientError2("UnsupportedContentType");
8059
+ }
8060
+ if (response.body === null)
8061
+ throw new ClientError2("MalformedResponse");
8062
+ const reader = response.body.getReader();
8063
+ const decoder = new TextDecoder;
8064
+ let buffer = "";
8065
+ try {
8066
+ while (true) {
8067
+ let next;
8068
+ try {
8069
+ next = await reader.read();
8070
+ } catch (cause) {
8071
+ throw new ClientError2("Transport", { cause });
8072
+ }
8073
+ if (!next.done)
8074
+ requestOptions?.onActivity?.();
8075
+ buffer += decoder.decode(next.value, { stream: !next.done });
8076
+ if (buffer.length > maxSseEventBytes)
8077
+ throw new ClientError2("SseEventTooLarge");
8078
+ const trailingCarriageReturn = !next.done && buffer.endsWith("\r");
8079
+ if (trailingCarriageReturn)
8080
+ buffer = buffer.slice(0, -1);
8081
+ buffer = buffer.replaceAll(`\r
8082
+ `, `
8083
+ `).replaceAll("\r", `
8084
+ `);
8085
+ if (trailingCarriageReturn)
8086
+ buffer += "\r";
8087
+ if (next.done && buffer !== "")
8088
+ buffer += `
8089
+
8090
+ `;
8091
+ let boundary = buffer.indexOf(`
8092
+
8093
+ `);
8094
+ while (boundary >= 0) {
8095
+ const block = buffer.slice(0, boundary);
8096
+ buffer = buffer.slice(boundary + 2);
8097
+ const data = block.split(`
8098
+ `).flatMap((line) => line.startsWith("data:") ? [line.slice(5).trimStart()] : []).join(`
8099
+ `);
8100
+ if (data !== "") {
8101
+ try {
8102
+ yield JSON.parse(data);
8103
+ } catch (cause) {
8104
+ throw new ClientError2("MalformedResponse", { cause });
8105
+ }
8106
+ }
8107
+ boundary = buffer.indexOf(`
8108
+
8109
+ `);
8110
+ }
8111
+ if (next.done)
8112
+ return;
8113
+ }
8114
+ } finally {
8115
+ try {
8116
+ await reader.cancel();
8117
+ } catch {}
8118
+ reader.releaseLock();
8119
+ }
8120
+ }
8121
+ });
8122
+ return {
8123
+ server: {
8124
+ info: (requestOptions) => request({ method: "GET", path: `/api/info`, successStatus: 200, declaredStatuses: [400, 401], empty: false }, requestOptions)
8125
+ },
8126
+ location: {
8127
+ get: (input, requestOptions) => request({
8128
+ method: "GET",
8129
+ path: `/api/location`,
8130
+ query: { location: input?.["location"] },
8131
+ successStatus: 200,
8132
+ declaredStatuses: [400, 401],
8133
+ empty: false
8134
+ }, requestOptions),
8135
+ reload: (requestOptions) => request({
8136
+ method: "POST",
8137
+ path: `/api/location/reload`,
8138
+ successStatus: 204,
8139
+ declaredStatuses: [400, 401, 503],
8140
+ empty: true
8141
+ }, requestOptions)
8142
+ },
8143
+ agent: {
8144
+ list: (input, requestOptions) => request({
8145
+ method: "GET",
8146
+ path: `/api/agent`,
8147
+ query: { location: input?.["location"] },
8148
+ successStatus: 200,
8149
+ declaredStatuses: [400, 401],
8150
+ empty: false
8151
+ }, requestOptions),
8152
+ get: (input, requestOptions) => request({
8153
+ method: "GET",
8154
+ path: `/api/agent/${encodeURIComponent(input.agentID)}`,
8155
+ query: { location: input["location"] },
8156
+ successStatus: 200,
8157
+ declaredStatuses: [400, 401, 404],
8158
+ empty: false
8159
+ }, requestOptions)
8160
+ },
8161
+ plugin: {
8162
+ list: (input, requestOptions) => request({
8163
+ method: "GET",
8164
+ path: `/api/plugin`,
8165
+ query: { location: input?.["location"] },
8166
+ successStatus: 200,
8167
+ declaredStatuses: [400, 401],
8168
+ empty: false
8169
+ }, requestOptions),
8170
+ check: (input, requestOptions) => request({
8171
+ method: "POST",
8172
+ path: `/api/plugin/check`,
8173
+ query: { location: input?.["location"] },
8174
+ body: { target: input?.["target"] },
8175
+ successStatus: 200,
8176
+ declaredStatuses: [400, 401],
8177
+ empty: false
8178
+ }, requestOptions),
8179
+ update: (input, requestOptions) => request({
8180
+ method: "POST",
8181
+ path: `/api/plugin/update`,
8182
+ query: { location: input["location"] },
8183
+ body: { targets: input["targets"] },
8184
+ successStatus: 204,
8185
+ declaredStatuses: [400, 401, 503],
8186
+ empty: true
8187
+ }, requestOptions)
8188
+ },
8189
+ session: {
8190
+ list: (input, requestOptions) => request({
8191
+ method: "GET",
8192
+ path: `/api/session`,
8193
+ query: {
8194
+ limit: input?.["limit"],
8195
+ order: input?.["order"],
8196
+ search: input?.["search"],
8197
+ parentID: input?.["parentID"],
8198
+ directory: input?.["directory"],
8199
+ project: input?.["project"],
8200
+ subpath: input?.["subpath"],
8201
+ cursor: input?.["cursor"]
8202
+ },
8203
+ successStatus: 200,
8204
+ declaredStatuses: [400, 401],
8205
+ empty: false
8206
+ }, requestOptions),
8207
+ stats: (input, requestOptions) => request({
8208
+ method: "GET",
8209
+ path: `/api/experimental/session/stats`,
8210
+ query: {
8211
+ from: input?.["from"],
8212
+ to: input?.["to"],
8213
+ project: input?.["project"],
8214
+ timezone: input?.["timezone"],
8215
+ tools: input?.["tools"]
8216
+ },
8217
+ successStatus: 200,
8218
+ declaredStatuses: [400, 401],
8219
+ empty: false
8220
+ }, requestOptions).then((value) => value.data),
8221
+ create: (input, requestOptions) => request({
8222
+ method: "POST",
8223
+ path: `/api/session`,
8224
+ body: {
8225
+ id: input?.["id"],
8226
+ title: input?.["title"],
8227
+ agent: input?.["agent"],
8228
+ model: input?.["model"],
8229
+ location: input?.["location"],
8230
+ metadata: input?.["metadata"],
8231
+ permissions: input?.["permissions"]
8232
+ },
8233
+ successStatus: 200,
8234
+ declaredStatuses: [400, 401],
8235
+ empty: false
8236
+ }, requestOptions).then((value) => value.data),
8237
+ import: (input, requestOptions) => request({
8238
+ method: "POST",
8239
+ path: `/api/experimental/session/import`,
8240
+ body: { info: input["info"], messages: input["messages"], location: input["location"] },
8241
+ successStatus: 200,
8242
+ declaredStatuses: [400, 401, 404, 409],
8243
+ empty: false
8244
+ }, requestOptions).then((value) => value.data),
8245
+ export: (input, requestOptions) => request({
8246
+ method: "GET",
8247
+ path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/export`,
8248
+ query: { sanitize: input["sanitize"] },
8249
+ successStatus: 200,
8250
+ declaredStatuses: [400, 401, 404, 500],
8251
+ empty: false
8252
+ }, requestOptions).then((value) => value.data),
8253
+ active: (requestOptions) => request({
8254
+ method: "GET",
8255
+ path: `/api/session/active`,
8256
+ successStatus: 200,
8257
+ declaredStatuses: [400, 401],
8258
+ empty: false
8259
+ }, requestOptions).then((value) => value.data),
8260
+ get: (input, requestOptions) => request({
8261
+ method: "GET",
8262
+ path: `/api/session/${encodeURIComponent(input.sessionID)}`,
8263
+ successStatus: 200,
8264
+ declaredStatuses: [400, 401, 404],
8265
+ empty: false
8266
+ }, requestOptions).then((value) => value.data),
8267
+ remove: (input, requestOptions) => request({
8268
+ method: "DELETE",
8269
+ path: `/api/session/${encodeURIComponent(input.sessionID)}`,
8270
+ successStatus: 204,
8271
+ declaredStatuses: [400, 401, 404],
8272
+ empty: true
8273
+ }, requestOptions),
8274
+ fork: (input, requestOptions) => request({
8275
+ method: "POST",
8276
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/fork`,
8277
+ body: { before: input["before"] },
8278
+ successStatus: 200,
8279
+ declaredStatuses: [400, 401, 404],
8280
+ empty: false
8281
+ }, requestOptions).then((value) => value.data),
8282
+ switchAgent: (input, requestOptions) => request({
8283
+ method: "POST",
8284
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/agent`,
8285
+ body: { agent: input["agent"] },
8286
+ successStatus: 204,
8287
+ declaredStatuses: [400, 401, 404],
8288
+ empty: true
8289
+ }, requestOptions),
8290
+ switchModel: (input, requestOptions) => request({
8291
+ method: "POST",
8292
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/model`,
8293
+ body: { model: input["model"] },
8294
+ successStatus: 204,
8295
+ declaredStatuses: [400, 401, 404],
8296
+ empty: true
8297
+ }, requestOptions),
8298
+ update: (input, requestOptions) => request({
8299
+ method: "PATCH",
8300
+ path: `/api/session/${encodeURIComponent(input.sessionID)}`,
8301
+ body: { title: input["title"], permissions: input["permissions"] },
8302
+ successStatus: 204,
8303
+ declaredStatuses: [400, 401, 404],
8304
+ empty: true
8305
+ }, requestOptions),
8306
+ move: (input, requestOptions) => request({
8307
+ method: "POST",
8308
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/move`,
8309
+ body: { directory: input["directory"], delivery: input["delivery"] },
8310
+ successStatus: 204,
8311
+ declaredStatuses: [400, 401, 404],
8312
+ empty: true
8313
+ }, requestOptions),
8314
+ prompt: (input, requestOptions) => request({
8315
+ method: "POST",
8316
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/prompt`,
8317
+ body: {
8318
+ id: input["id"],
8319
+ text: input["text"],
8320
+ files: input["files"],
8321
+ agents: input["agents"],
8322
+ skills: input["skills"],
8323
+ metadata: input["metadata"],
8324
+ delivery: input["delivery"],
8325
+ resume: input["resume"]
8326
+ },
8327
+ successStatus: 200,
8328
+ declaredStatuses: [400, 401, 404, 409],
8329
+ empty: false
8330
+ }, requestOptions).then((value) => value.data),
8331
+ command: (input, requestOptions) => request({
8332
+ method: "POST",
8333
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/command`,
8334
+ body: {
8335
+ name: input["name"],
8336
+ text: input["text"],
8337
+ files: input["files"],
8338
+ agents: input["agents"],
8339
+ skills: input["skills"],
8340
+ delivery: input["delivery"]
8341
+ },
8342
+ successStatus: 204,
8343
+ declaredStatuses: [400, 401, 404, 500],
8344
+ empty: true
8345
+ }, requestOptions),
8346
+ skill: (input, requestOptions) => request({
8347
+ method: "POST",
8348
+ path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/skill`,
8349
+ body: { id: input["id"], resume: input["resume"] },
8350
+ successStatus: 204,
8351
+ declaredStatuses: [400, 401, 404],
8352
+ empty: true
8353
+ }, requestOptions),
8354
+ synthetic: (input, requestOptions) => request({
8355
+ method: "POST",
8356
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/synthetic`,
8357
+ body: {
8358
+ id: input["id"],
8359
+ text: input["text"],
8360
+ description: input["description"],
8361
+ metadata: input["metadata"],
8362
+ delivery: input["delivery"],
8363
+ resume: input["resume"]
8364
+ },
8365
+ successStatus: 200,
8366
+ declaredStatuses: [400, 401, 404, 409],
8367
+ empty: false
8368
+ }, requestOptions).then((value) => value.data),
8369
+ shell: (input, requestOptions) => request({
8370
+ method: "POST",
8371
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/shell`,
8372
+ body: { id: input["id"], command: input["command"] },
8373
+ successStatus: 204,
8374
+ declaredStatuses: [400, 401, 404],
8375
+ empty: true
8376
+ }, requestOptions),
8377
+ compact: (input, requestOptions) => request({
8378
+ method: "POST",
8379
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/compact`,
8380
+ body: { id: input["id"], delivery: input["delivery"] },
8381
+ successStatus: 200,
8382
+ declaredStatuses: [400, 401, 404, 409],
8383
+ empty: false
8384
+ }, requestOptions).then((value) => value.data),
8385
+ wait: (input, requestOptions) => request({
8386
+ method: "POST",
8387
+ path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/wait`,
8388
+ successStatus: 204,
8389
+ declaredStatuses: [400, 401, 404, 503],
8390
+ empty: true
8391
+ }, requestOptions),
8392
+ revert: {
8393
+ stage: (input, requestOptions) => request({
8394
+ method: "POST",
8395
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/revert/stage`,
8396
+ body: { messageID: input["messageID"], files: input["files"] },
8397
+ successStatus: 200,
8398
+ declaredStatuses: [400, 401, 404, 409, 500],
8399
+ empty: false
8400
+ }, requestOptions).then((value) => value.data),
8401
+ clear: (input, requestOptions) => request({
8402
+ method: "DELETE",
8403
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/revert`,
8404
+ successStatus: 204,
8405
+ declaredStatuses: [400, 401, 404, 409, 500],
8406
+ empty: true
8407
+ }, requestOptions),
8408
+ commit: (input, requestOptions) => request({
8409
+ method: "POST",
8410
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/revert/commit`,
8411
+ successStatus: 204,
8412
+ declaredStatuses: [400, 401, 404, 409],
8413
+ empty: true
8414
+ }, requestOptions)
8415
+ },
8416
+ context: (input, requestOptions) => request({
8417
+ method: "GET",
8418
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/context`,
8419
+ successStatus: 200,
8420
+ declaredStatuses: [400, 401, 404, 500],
8421
+ empty: false
8422
+ }, requestOptions).then((value) => value.data),
8423
+ diff: (input, requestOptions) => request({
8424
+ method: "GET",
8425
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/diff`,
8426
+ query: { from: input["from"], to: input["to"], context: input["context"] },
8427
+ successStatus: 200,
8428
+ declaredStatuses: [400, 401, 404, 500],
8429
+ empty: false
8430
+ }, requestOptions).then((value) => value.data),
8431
+ inbox: {
8432
+ list: (input, requestOptions) => request({
8433
+ method: "GET",
8434
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/inbox`,
8435
+ successStatus: 200,
8436
+ declaredStatuses: [400, 401, 404],
8437
+ empty: false
8438
+ }, requestOptions).then((value) => value.data),
8439
+ cancel: (input, requestOptions) => request({
8440
+ method: "DELETE",
8441
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/inbox/${encodeURIComponent(input.inboxID)}`,
8442
+ successStatus: 204,
8443
+ declaredStatuses: [400, 401, 404],
8444
+ empty: true
8445
+ }, requestOptions),
8446
+ update: (input, requestOptions) => request({
8447
+ method: "PATCH",
8448
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/inbox/${encodeURIComponent(input.inboxID)}`,
8449
+ body: { delivery: input["delivery"] },
8450
+ successStatus: 204,
8451
+ declaredStatuses: [400, 401, 404, 409],
8452
+ empty: true
8453
+ }, requestOptions)
8454
+ },
8455
+ instructions: {
8456
+ entry: {
8457
+ list: (input, requestOptions) => request({
8458
+ method: "GET",
8459
+ path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/instructions/entries`,
8460
+ successStatus: 200,
8461
+ declaredStatuses: [400, 401, 404],
8462
+ empty: false
8463
+ }, requestOptions).then((value) => value.data),
8464
+ put: (input, requestOptions) => request({
8465
+ method: "PUT",
8466
+ path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/instructions/entries/${encodeURIComponent(input.key)}`,
8467
+ body: { value: input["value"] },
8468
+ successStatus: 204,
8469
+ declaredStatuses: [400, 401, 404, 413],
8470
+ empty: true
8471
+ }, requestOptions),
8472
+ remove: (input, requestOptions) => request({
8473
+ method: "DELETE",
8474
+ path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/instructions/entries/${encodeURIComponent(input.key)}`,
8475
+ successStatus: 204,
8476
+ declaredStatuses: [400, 401, 404],
8477
+ empty: true
8478
+ }, requestOptions)
8479
+ }
8480
+ },
8481
+ generate: (input, requestOptions) => request({
8482
+ method: "POST",
8483
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/generate`,
8484
+ body: { prompt: input["prompt"] },
8485
+ successStatus: 200,
8486
+ declaredStatuses: [400, 401, 404, 503],
8487
+ empty: false
8488
+ }, requestOptions).then((value) => value.data),
8489
+ log: (input, requestOptions) => sse({
8490
+ method: "GET",
8491
+ path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/log`,
8492
+ query: { after: input["after"], follow: input["follow"] },
8493
+ successStatus: 200,
8494
+ declaredStatuses: [400, 401, 404],
8495
+ empty: false
8496
+ }, requestOptions),
8497
+ interrupt: (input, requestOptions) => request({
8498
+ method: "POST",
8499
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/interrupt`,
8500
+ query: { resume: input["resume"] },
8501
+ successStatus: 200,
8502
+ declaredStatuses: [400, 401, 404],
8503
+ empty: false
8504
+ }, requestOptions),
8505
+ background: (input, requestOptions) => request({
8506
+ method: "POST",
8507
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/background`,
8508
+ successStatus: 204,
8509
+ declaredStatuses: [400, 401, 404],
8510
+ empty: true
8511
+ }, requestOptions),
8512
+ message: {
8513
+ get: (input, requestOptions) => request({
8514
+ method: "GET",
8515
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/message/${encodeURIComponent(input.messageID)}`,
8516
+ successStatus: 200,
8517
+ declaredStatuses: [400, 401, 404],
8518
+ empty: false
8519
+ }, requestOptions).then((value) => value.data)
8520
+ },
8521
+ form: {
8522
+ list: (input, requestOptions) => request({
8523
+ method: "GET",
8524
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/form`,
8525
+ successStatus: 200,
8526
+ declaredStatuses: [400, 401, 404],
8527
+ empty: false
8528
+ }, requestOptions).then((value) => value.data),
8529
+ create: (input, requestOptions) => request({
8530
+ method: "POST",
8531
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/form`,
8532
+ body: { id: input["id"], title: input["title"], metadata: input["metadata"], fields: input["fields"] },
8533
+ successStatus: 200,
8534
+ declaredStatuses: [400, 401, 404, 409],
8535
+ empty: false
8536
+ }, requestOptions).then((value) => value.data),
8537
+ get: (input, requestOptions) => request({
8538
+ method: "GET",
8539
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/form/${encodeURIComponent(input.formID)}`,
8540
+ successStatus: 200,
8541
+ declaredStatuses: [400, 401, 404],
8542
+ empty: false
8543
+ }, requestOptions).then((value) => value.data),
8544
+ reply: (input, requestOptions) => request({
8545
+ method: "POST",
8546
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/form/${encodeURIComponent(input.formID)}/reply`,
8547
+ body: { answer: input["answer"] },
8548
+ successStatus: 204,
8549
+ declaredStatuses: [400, 401, 404, 409],
8550
+ empty: true
8551
+ }, requestOptions),
8552
+ cancel: (input, requestOptions) => request({
8553
+ method: "DELETE",
8554
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/form/${encodeURIComponent(input.formID)}`,
8555
+ successStatus: 204,
8556
+ declaredStatuses: [400, 401, 404, 409],
8557
+ empty: true
8558
+ }, requestOptions)
8559
+ },
8560
+ environment: (input, requestOptions) => request({
8561
+ method: "PUT",
8562
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/environment`,
8563
+ body: { variables: input["variables"] },
8564
+ successStatus: 204,
8565
+ declaredStatuses: [400, 401, 404],
8566
+ empty: true
8567
+ }, requestOptions),
8568
+ view: (input, requestOptions) => request({
8569
+ method: "POST",
8570
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/view`,
8571
+ body: { idle: input["idle"] },
8572
+ successStatus: 204,
8573
+ declaredStatuses: [400, 401, 404],
8574
+ empty: true
8575
+ }, requestOptions)
8576
+ },
8577
+ message: {
8578
+ list: (input, requestOptions) => request({
8579
+ method: "GET",
8580
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/message`,
8581
+ query: { limit: input["limit"], order: input["order"], cursor: input["cursor"], type: input["type"] },
8582
+ successStatus: 200,
8583
+ declaredStatuses: [400, 401, 404, 500],
8584
+ empty: false
8585
+ }, requestOptions)
8586
+ },
8587
+ model: {
8588
+ list: (input, requestOptions) => request({
8589
+ method: "GET",
8590
+ path: `/api/model`,
8591
+ query: { location: input?.["location"] },
8592
+ successStatus: 200,
8593
+ declaredStatuses: [400, 401, 503],
8594
+ empty: false
8595
+ }, requestOptions),
8596
+ default: (input, requestOptions) => request({
8597
+ method: "GET",
8598
+ path: `/api/model/default`,
8599
+ query: { location: input?.["location"] },
8600
+ successStatus: 200,
8601
+ declaredStatuses: [400, 401, 503],
8602
+ empty: false
8603
+ }, requestOptions)
8604
+ },
8605
+ generate: {
8606
+ text: (input, requestOptions) => request({
8607
+ method: "POST",
8608
+ path: `/api/experimental/generate`,
8609
+ body: { prompt: input["prompt"], model: input["model"] },
8610
+ successStatus: 200,
8611
+ declaredStatuses: [400, 401, 503],
8612
+ empty: false
8613
+ }, requestOptions).then((value) => value.data)
8614
+ },
8615
+ provider: {
8616
+ list: (input, requestOptions) => request({
8617
+ method: "GET",
8618
+ path: `/api/provider`,
8619
+ query: { location: input?.["location"] },
8620
+ successStatus: 200,
8621
+ declaredStatuses: [400, 401, 503],
8622
+ empty: false
8623
+ }, requestOptions),
8624
+ get: (input, requestOptions) => request({
8625
+ method: "GET",
8626
+ path: `/api/provider/${encodeURIComponent(input.providerID)}`,
8627
+ query: { location: input["location"] },
8628
+ successStatus: 200,
8629
+ declaredStatuses: [400, 401, 404, 503],
8630
+ empty: false
8631
+ }, requestOptions)
8632
+ },
8633
+ integration: {
8634
+ list: (input, requestOptions) => request({
8635
+ method: "GET",
8636
+ path: `/api/integration`,
8637
+ query: { location: input?.["location"] },
8638
+ successStatus: 200,
8639
+ declaredStatuses: [400, 401],
8640
+ empty: false
8641
+ }, requestOptions),
8642
+ get: (input, requestOptions) => request({
8643
+ method: "GET",
8644
+ path: `/api/integration/${encodeURIComponent(input.integrationID)}`,
8645
+ query: { location: input["location"] },
8646
+ successStatus: 200,
8647
+ declaredStatuses: [400, 401, 404],
8648
+ empty: false
8649
+ }, requestOptions),
8650
+ wellknown: {
8651
+ add: (input, requestOptions) => request({
8652
+ method: "POST",
8653
+ path: `/api/experimental/integration/wellknown`,
8654
+ query: { location: input["location"] },
8655
+ body: { url: input["url"] },
8656
+ successStatus: 204,
8657
+ declaredStatuses: [400, 401],
8658
+ empty: true
8659
+ }, requestOptions)
8660
+ },
8661
+ connect: {
8662
+ key: (input, requestOptions) => request({
8663
+ method: "POST",
8664
+ path: `/api/integration/${encodeURIComponent(input.integrationID)}/connect/key`,
8665
+ query: { location: input["location"] },
8666
+ body: { key: input["key"], answer: input["answer"], label: input["label"] },
8667
+ successStatus: 204,
8668
+ declaredStatuses: [400, 401, 404],
8669
+ empty: true
8670
+ }, requestOptions)
8671
+ },
8672
+ oauth: {
8673
+ connect: (input, requestOptions) => request({
8674
+ method: "POST",
8675
+ path: `/api/integration/${encodeURIComponent(input.integrationID)}/connect/oauth`,
8676
+ query: { location: input["location"] },
8677
+ body: { methodID: input["methodID"], answer: input["answer"], label: input["label"] },
8678
+ successStatus: 200,
8679
+ declaredStatuses: [400, 401],
8680
+ empty: false
8681
+ }, requestOptions),
8682
+ status: (input, requestOptions) => request({
8683
+ method: "GET",
8684
+ path: `/api/integration/${encodeURIComponent(input.integrationID)}/connect/oauth/${encodeURIComponent(input.attemptID)}`,
8685
+ query: { location: input["location"] },
8686
+ successStatus: 200,
8687
+ declaredStatuses: [400, 401, 404],
8688
+ empty: false
8689
+ }, requestOptions),
8690
+ complete: (input, requestOptions) => request({
8691
+ method: "POST",
8692
+ path: `/api/integration/${encodeURIComponent(input.integrationID)}/connect/oauth/${encodeURIComponent(input.attemptID)}/complete`,
8693
+ query: { location: input["location"] },
8694
+ body: { code: input["code"] },
8695
+ successStatus: 204,
8696
+ declaredStatuses: [400, 401, 404],
8697
+ empty: true
8698
+ }, requestOptions),
8699
+ cancel: (input, requestOptions) => request({
8700
+ method: "DELETE",
8701
+ path: `/api/integration/${encodeURIComponent(input.integrationID)}/connect/oauth/${encodeURIComponent(input.attemptID)}`,
8702
+ query: { location: input["location"] },
8703
+ successStatus: 204,
8704
+ declaredStatuses: [400, 401],
8705
+ empty: true
8706
+ }, requestOptions)
8707
+ },
8708
+ command: {
8709
+ connect: (input, requestOptions) => request({
8710
+ method: "POST",
8711
+ path: `/api/integration/${encodeURIComponent(input.integrationID)}/connect/command`,
8712
+ query: { location: input["location"] },
8713
+ body: { methodID: input["methodID"], label: input["label"] },
8714
+ successStatus: 200,
8715
+ declaredStatuses: [400, 401, 404],
8716
+ empty: false
8717
+ }, requestOptions),
8718
+ status: (input, requestOptions) => request({
8719
+ method: "GET",
8720
+ path: `/api/integration/${encodeURIComponent(input.integrationID)}/connect/command/${encodeURIComponent(input.attemptID)}`,
8721
+ query: { location: input["location"] },
8722
+ successStatus: 200,
8723
+ declaredStatuses: [400, 401, 404],
8724
+ empty: false
8725
+ }, requestOptions),
8726
+ cancel: (input, requestOptions) => request({
8727
+ method: "DELETE",
8728
+ path: `/api/integration/${encodeURIComponent(input.integrationID)}/connect/command/${encodeURIComponent(input.attemptID)}`,
8729
+ query: { location: input["location"] },
8730
+ successStatus: 204,
8731
+ declaredStatuses: [400, 401],
8732
+ empty: true
8733
+ }, requestOptions)
8734
+ }
8735
+ },
8736
+ mcp: {
8737
+ list: (input, requestOptions) => request({
8738
+ method: "GET",
8739
+ path: `/api/mcp`,
8740
+ query: { location: input?.["location"] },
8741
+ successStatus: 200,
8742
+ declaredStatuses: [400, 401],
8743
+ empty: false
8744
+ }, requestOptions),
8745
+ add: (input, requestOptions) => request({
8746
+ method: "PUT",
8747
+ path: `/api/experimental/mcp/${encodeURIComponent(input.server)}`,
8748
+ query: { location: input["location"] },
8749
+ body: { config: input["config"] },
8750
+ successStatus: 204,
8751
+ declaredStatuses: [400, 401],
8752
+ empty: true
8753
+ }, requestOptions),
8754
+ remove: (input, requestOptions) => request({
8755
+ method: "DELETE",
8756
+ path: `/api/experimental/mcp/${encodeURIComponent(input.server)}`,
8757
+ query: { location: input["location"] },
8758
+ successStatus: 204,
8759
+ declaredStatuses: [400, 401, 404],
8760
+ empty: true
8761
+ }, requestOptions),
8762
+ connect: (input, requestOptions) => request({
8763
+ method: "POST",
8764
+ path: `/api/experimental/mcp/${encodeURIComponent(input.server)}/connect`,
8765
+ query: { location: input["location"] },
8766
+ successStatus: 204,
8767
+ declaredStatuses: [400, 401, 404],
8768
+ empty: true
8769
+ }, requestOptions),
8770
+ disconnect: (input, requestOptions) => request({
8771
+ method: "POST",
8772
+ path: `/api/experimental/mcp/${encodeURIComponent(input.server)}/disconnect`,
8773
+ query: { location: input["location"] },
8774
+ successStatus: 204,
8775
+ declaredStatuses: [400, 401, 404],
8776
+ empty: true
8777
+ }, requestOptions),
8778
+ resource: {
8779
+ catalog: (input, requestOptions) => request({
8780
+ method: "GET",
8781
+ path: `/api/mcp/resource`,
8782
+ query: { location: input?.["location"] },
8783
+ successStatus: 200,
8784
+ declaredStatuses: [400, 401],
8785
+ empty: false
8786
+ }, requestOptions)
8787
+ }
8788
+ },
8789
+ credential: {
8790
+ update: (input, requestOptions) => request({
8791
+ method: "PATCH",
8792
+ path: `/api/credential/${encodeURIComponent(input.credentialID)}`,
8793
+ body: { label: input["label"] },
8794
+ successStatus: 204,
8795
+ declaredStatuses: [400, 401],
8796
+ empty: true
8797
+ }, requestOptions),
8798
+ activate: (input, requestOptions) => request({
8799
+ method: "POST",
8800
+ path: `/api/credential/${encodeURIComponent(input.credentialID)}/activate`,
8801
+ successStatus: 204,
8802
+ declaredStatuses: [400, 401],
8803
+ empty: true
8804
+ }, requestOptions),
8805
+ remove: (input, requestOptions) => request({
8806
+ method: "DELETE",
8807
+ path: `/api/credential/${encodeURIComponent(input.credentialID)}`,
8808
+ successStatus: 204,
8809
+ declaredStatuses: [400, 401],
8810
+ empty: true
8811
+ }, requestOptions)
8812
+ },
8813
+ project: {
8814
+ list: (requestOptions) => request({ method: "GET", path: `/api/project`, successStatus: 200, declaredStatuses: [400, 401], empty: false }, requestOptions),
8815
+ update: (input, requestOptions) => request({
8816
+ method: "PATCH",
8817
+ path: `/api/project/${encodeURIComponent(input.projectID)}`,
8818
+ body: {
8819
+ canonical: input["canonical"],
8820
+ name: input["name"],
8821
+ icon: input["icon"],
8822
+ commands: input["commands"]
8823
+ },
8824
+ successStatus: 200,
8825
+ declaredStatuses: [400, 401, 404],
8826
+ empty: false
8827
+ }, requestOptions)
8828
+ },
8829
+ form: {
8830
+ list: (input, requestOptions) => request({
8831
+ method: "GET",
8832
+ path: `/api/form`,
8833
+ query: { location: input?.["location"] },
8834
+ successStatus: 200,
8835
+ declaredStatuses: [400, 401],
8836
+ empty: false
8837
+ }, requestOptions)
8838
+ },
8839
+ permission: {
8840
+ request: {
8841
+ list: (input, requestOptions) => request({
8842
+ method: "GET",
8843
+ path: `/api/permission/request`,
8844
+ query: { location: input?.["location"] },
8845
+ successStatus: 200,
8846
+ declaredStatuses: [400, 401],
8847
+ empty: false
8848
+ }, requestOptions)
8849
+ },
8850
+ saved: {
8851
+ list: (input, requestOptions) => request({
8852
+ method: "GET",
8853
+ path: `/api/permission/saved`,
8854
+ query: { projectID: input?.["projectID"] },
8855
+ successStatus: 200,
8856
+ declaredStatuses: [400, 401],
8857
+ empty: false
8858
+ }, requestOptions).then((value) => value.data),
8859
+ remove: (input, requestOptions) => request({
8860
+ method: "DELETE",
8861
+ path: `/api/permission/saved/${encodeURIComponent(input.id)}`,
8862
+ successStatus: 204,
8863
+ declaredStatuses: [400, 401],
8864
+ empty: true
8865
+ }, requestOptions)
8866
+ },
8867
+ create: (input, requestOptions) => request({
8868
+ method: "POST",
8869
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/permission`,
8870
+ body: {
8871
+ id: input["id"],
8872
+ action: input["action"],
8873
+ resources: input["resources"],
8874
+ save: input["save"],
8875
+ metadata: input["metadata"],
8876
+ source: input["source"],
8877
+ agent: input["agent"]
8878
+ },
8879
+ successStatus: 200,
8880
+ declaredStatuses: [400, 401, 404],
8881
+ empty: false
8882
+ }, requestOptions).then((value) => value.data),
8883
+ list: (input, requestOptions) => request({
8884
+ method: "GET",
8885
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/permission`,
8886
+ successStatus: 200,
8887
+ declaredStatuses: [400, 401, 404],
8888
+ empty: false
8889
+ }, requestOptions).then((value) => value.data),
8890
+ get: (input, requestOptions) => request({
8891
+ method: "GET",
8892
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/permission/${encodeURIComponent(input.requestID)}`,
8893
+ successStatus: 200,
8894
+ declaredStatuses: [400, 401, 404],
8895
+ empty: false
8896
+ }, requestOptions).then((value) => value.data),
8897
+ reply: (input, requestOptions) => request({
8898
+ method: "POST",
8899
+ path: `/api/session/${encodeURIComponent(input.sessionID)}/permission/${encodeURIComponent(input.requestID)}/reply`,
8900
+ body: { decision: input["decision"], message: input["message"] },
8901
+ successStatus: 204,
8902
+ declaredStatuses: [400, 401, 404],
8903
+ empty: true
8904
+ }, requestOptions)
8905
+ },
8906
+ file: {
8907
+ read: (input, requestOptions) => request({
8908
+ method: "GET",
8909
+ path: `/api/fs/read/${encodePath(input.path)}`,
8910
+ query: { location: input["location"] },
8911
+ successStatus: 200,
8912
+ declaredStatuses: [400, 401, 404],
8913
+ empty: false,
8914
+ binary: true
8915
+ }, requestOptions),
8916
+ list: (input, requestOptions) => request({
8917
+ method: "GET",
8918
+ path: `/api/fs/list`,
8919
+ query: { location: input?.["location"], path: input?.["path"] },
8920
+ successStatus: 200,
8921
+ declaredStatuses: [400, 401],
8922
+ empty: false
8923
+ }, requestOptions),
8924
+ find: (input, requestOptions) => request({
8925
+ method: "GET",
8926
+ path: `/api/fs/find`,
8927
+ query: { location: input["location"], query: input["query"], type: input["type"], limit: input["limit"] },
8928
+ successStatus: 200,
8929
+ declaredStatuses: [400, 401],
8930
+ empty: false
8931
+ }, requestOptions),
8932
+ write: (input, requestOptions) => request({
8933
+ method: "POST",
8934
+ path: `/api/experimental/fs/write`,
8935
+ query: { location: input["location"], path: input["path"] },
8936
+ body: input["payload"],
8937
+ successStatus: 200,
8938
+ declaredStatuses: [400, 401],
8939
+ empty: false,
8940
+ binaryBody: true
8941
+ }, requestOptions)
8942
+ },
8943
+ command: {
8944
+ list: (input, requestOptions) => request({
8945
+ method: "GET",
8946
+ path: `/api/command`,
8947
+ query: { location: input?.["location"] },
8948
+ successStatus: 200,
8949
+ declaredStatuses: [400, 401],
8950
+ empty: false
8951
+ }, requestOptions)
8952
+ },
8953
+ skill: {
8954
+ list: (input, requestOptions) => request({
8955
+ method: "GET",
8956
+ path: `/api/skill`,
8957
+ query: { location: input?.["location"] },
8958
+ successStatus: 200,
8959
+ declaredStatuses: [400, 401],
8960
+ empty: false
8961
+ }, requestOptions)
8962
+ },
8963
+ rpc: {
8964
+ call: (input, requestOptions) => request({
8965
+ method: "POST",
8966
+ path: `/api/rpc/${encodeURIComponent(input.rpcID)}/${encodeURIComponent(input.method)}`,
8967
+ query: { location: input["location"] },
8968
+ body: { input: input["input"] },
8969
+ successStatus: 200,
8970
+ declaredStatuses: [400, 401, 500],
8971
+ empty: false
8972
+ }, requestOptions)
8973
+ },
8974
+ event: {
8975
+ subscribe: (requestOptions) => sse({ method: "GET", path: `/api/event`, successStatus: 200, declaredStatuses: [400, 401], empty: false }, requestOptions)
8976
+ },
8977
+ pty: {
8978
+ list: (input, requestOptions) => request({
8979
+ method: "GET",
8980
+ path: `/api/pty`,
8981
+ query: { location: input?.["location"] },
8982
+ successStatus: 200,
8983
+ declaredStatuses: [400, 401],
8984
+ empty: false
8985
+ }, requestOptions),
8986
+ create: (input, requestOptions) => request({
8987
+ method: "POST",
8988
+ path: `/api/pty`,
8989
+ query: { location: input?.["location"] },
8990
+ body: {
8991
+ command: input?.["command"],
8992
+ args: input?.["args"],
8993
+ cwd: input?.["cwd"],
8994
+ title: input?.["title"],
8995
+ env: input?.["env"]
8996
+ },
8997
+ successStatus: 200,
8998
+ declaredStatuses: [400, 401],
8999
+ empty: false
9000
+ }, requestOptions),
9001
+ get: (input, requestOptions) => request({
9002
+ method: "GET",
9003
+ path: `/api/pty/${encodeURIComponent(input.ptyID)}`,
9004
+ query: { location: input["location"] },
9005
+ successStatus: 200,
9006
+ declaredStatuses: [400, 401, 404],
9007
+ empty: false
9008
+ }, requestOptions),
9009
+ update: (input, requestOptions) => request({
9010
+ method: "PUT",
9011
+ path: `/api/pty/${encodeURIComponent(input.ptyID)}`,
9012
+ query: { location: input["location"] },
9013
+ body: { title: input["title"], size: input["size"] },
9014
+ successStatus: 200,
9015
+ declaredStatuses: [400, 401, 404],
9016
+ empty: false
9017
+ }, requestOptions),
9018
+ remove: (input, requestOptions) => request({
9019
+ method: "DELETE",
9020
+ path: `/api/pty/${encodeURIComponent(input.ptyID)}`,
9021
+ query: { location: input["location"] },
9022
+ successStatus: 204,
9023
+ declaredStatuses: [400, 401, 404],
9024
+ empty: true
9025
+ }, requestOptions),
9026
+ connect: {
9027
+ token: (input, requestOptions) => request({
9028
+ method: "POST",
9029
+ path: `/api/pty/${encodeURIComponent(input.ptyID)}/connect-token`,
9030
+ query: { location: input["location"] },
9031
+ headers: { "x-opencode-ticket": input["x-opencode-ticket"] },
9032
+ successStatus: 200,
9033
+ declaredStatuses: [400, 401, 403, 404],
9034
+ empty: false
9035
+ }, requestOptions)
9036
+ }
9037
+ },
9038
+ experimental: {
9039
+ persistentPty: {
9040
+ read: (input, requestOptions) => request({
9041
+ method: "GET",
9042
+ path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/terminal/read`,
9043
+ query: { lines: input["lines"] },
9044
+ successStatus: 200,
9045
+ declaredStatuses: [400, 401, 503],
9046
+ empty: false
9047
+ }, requestOptions).then((value) => value.data),
9048
+ list: (input, requestOptions) => request({
9049
+ method: "GET",
9050
+ path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/terminal`,
9051
+ successStatus: 200,
9052
+ declaredStatuses: [400, 401, 503],
9053
+ empty: false
9054
+ }, requestOptions).then((value) => value.data),
9055
+ create: (input, requestOptions) => request({
9056
+ method: "POST",
9057
+ path: `/api/experimental/session/${encodeURIComponent(input.sessionID)}/terminal`,
9058
+ body: {
9059
+ command: input["command"],
9060
+ args: input["args"],
9061
+ cwd: input["cwd"],
9062
+ title: input["title"],
9063
+ env: input["env"],
9064
+ size: input["size"]
9065
+ },
9066
+ successStatus: 200,
9067
+ declaredStatuses: [400, 401, 503],
9068
+ empty: false
9069
+ }, requestOptions).then((value) => value.data),
9070
+ shutdown: (requestOptions) => request({
9071
+ method: "POST",
9072
+ path: `/api/experimental/persistent-pty/shutdown`,
9073
+ successStatus: 204,
9074
+ declaredStatuses: [400, 401, 503],
9075
+ empty: true
9076
+ }, requestOptions),
9077
+ handoff: (requestOptions) => request({
9078
+ method: "POST",
9079
+ path: `/api/experimental/persistent-pty/handoff`,
9080
+ successStatus: 200,
9081
+ declaredStatuses: [400, 401, 503],
9082
+ empty: false
9083
+ }, requestOptions),
9084
+ get: (input, requestOptions) => request({
9085
+ method: "GET",
9086
+ path: `/api/experimental/persistent-pty/${encodeURIComponent(input.ptyID)}`,
9087
+ successStatus: 200,
9088
+ declaredStatuses: [400, 401, 404, 503],
9089
+ empty: false
9090
+ }, requestOptions).then((value) => value.data),
9091
+ update: (input, requestOptions) => request({
9092
+ method: "PUT",
9093
+ path: `/api/experimental/persistent-pty/${encodeURIComponent(input.ptyID)}`,
9094
+ body: { attachmentID: input["attachmentID"], size: input["size"] },
9095
+ successStatus: 200,
9096
+ declaredStatuses: [400, 401, 404, 503],
9097
+ empty: false
9098
+ }, requestOptions).then((value) => value.data),
9099
+ snapshot: (input, requestOptions) => request({
9100
+ method: "GET",
9101
+ path: `/api/experimental/persistent-pty/${encodeURIComponent(input.ptyID)}/snapshot`,
9102
+ successStatus: 200,
9103
+ declaredStatuses: [400, 401, 404, 503],
9104
+ empty: false
9105
+ }, requestOptions).then((value) => value.data),
9106
+ remove: (input, requestOptions) => request({
9107
+ method: "DELETE",
9108
+ path: `/api/experimental/persistent-pty/${encodeURIComponent(input.ptyID)}`,
9109
+ successStatus: 204,
9110
+ declaredStatuses: [400, 401, 404, 503],
9111
+ empty: true
9112
+ }, requestOptions),
9113
+ connectToken: (input, requestOptions) => request({
9114
+ method: "POST",
9115
+ path: `/api/experimental/persistent-pty/${encodeURIComponent(input.ptyID)}/connect-token`,
9116
+ headers: { "x-opencode-ticket": input["x-opencode-ticket"] },
9117
+ successStatus: 200,
9118
+ declaredStatuses: [400, 401, 403, 404, 503],
9119
+ empty: false
9120
+ }, requestOptions).then((value) => value.data)
9121
+ }
9122
+ },
9123
+ shell: {
9124
+ list: (input, requestOptions) => request({
9125
+ method: "GET",
9126
+ path: `/api/shell`,
9127
+ query: { location: input?.["location"] },
9128
+ successStatus: 200,
9129
+ declaredStatuses: [400, 401],
9130
+ empty: false
9131
+ }, requestOptions),
9132
+ create: (input, requestOptions) => request({
9133
+ method: "POST",
9134
+ path: `/api/shell`,
9135
+ query: { location: input["location"] },
9136
+ body: {
9137
+ command: input["command"],
9138
+ cwd: input["cwd"],
9139
+ timeout: input["timeout"],
9140
+ metadata: input["metadata"]
9141
+ },
9142
+ successStatus: 200,
9143
+ declaredStatuses: [400, 401],
9144
+ empty: false
9145
+ }, requestOptions),
9146
+ get: (input, requestOptions) => request({
9147
+ method: "GET",
9148
+ path: `/api/shell/${encodeURIComponent(input.id)}`,
9149
+ query: { location: input["location"] },
9150
+ successStatus: 200,
9151
+ declaredStatuses: [400, 401, 404],
9152
+ empty: false
9153
+ }, requestOptions),
9154
+ output: (input, requestOptions) => request({
9155
+ method: "GET",
9156
+ path: `/api/shell/${encodeURIComponent(input.id)}/output`,
9157
+ query: { location: input["location"], cursor: input["cursor"], limit: input["limit"] },
9158
+ successStatus: 200,
9159
+ declaredStatuses: [400, 401, 404],
9160
+ empty: false
9161
+ }, requestOptions),
9162
+ remove: (input, requestOptions) => request({
9163
+ method: "DELETE",
9164
+ path: `/api/shell/${encodeURIComponent(input.id)}`,
9165
+ query: { location: input["location"] },
9166
+ successStatus: 204,
9167
+ declaredStatuses: [400, 401],
9168
+ empty: true
9169
+ }, requestOptions)
9170
+ },
9171
+ reference: {
9172
+ list: (input, requestOptions) => request({
9173
+ method: "GET",
9174
+ path: `/api/reference`,
9175
+ query: { location: input?.["location"] },
9176
+ successStatus: 200,
9177
+ declaredStatuses: [400, 401],
9178
+ empty: false
9179
+ }, requestOptions)
9180
+ },
9181
+ worktree: {
9182
+ list: (input, requestOptions) => request({
9183
+ method: "GET",
9184
+ path: `/api/worktree`,
9185
+ query: { projectID: input["projectID"] },
9186
+ successStatus: 200,
9187
+ declaredStatuses: [400, 401, 404],
9188
+ empty: false
9189
+ }, requestOptions),
9190
+ create: (input, requestOptions) => request({
9191
+ method: "POST",
9192
+ path: `/api/worktree`,
9193
+ body: {
9194
+ projectID: input["projectID"],
9195
+ from: input["from"],
9196
+ branch: input["branch"],
9197
+ directory: input["directory"],
9198
+ name: input["name"]
9199
+ },
9200
+ successStatus: 200,
9201
+ declaredStatuses: [400, 401, 404],
9202
+ empty: false
9203
+ }, requestOptions),
9204
+ remove: (input, requestOptions) => request({
9205
+ method: "DELETE",
9206
+ path: `/api/worktree`,
9207
+ body: { projectID: input["projectID"], directory: input["directory"], force: input["force"] },
9208
+ successStatus: 204,
9209
+ declaredStatuses: [400, 401, 404],
9210
+ empty: true
9211
+ }, requestOptions),
9212
+ refresh: (input, requestOptions) => request({
9213
+ method: "POST",
9214
+ path: `/api/worktree/refresh`,
9215
+ body: { projectID: input["projectID"] },
9216
+ successStatus: 204,
9217
+ declaredStatuses: [400, 401, 404],
9218
+ empty: true
9219
+ }, requestOptions)
9220
+ },
9221
+ vcs: {
9222
+ get: (input, requestOptions) => request({
9223
+ method: "GET",
9224
+ path: `/api/vcs`,
9225
+ query: { location: input?.["location"] },
9226
+ successStatus: 200,
9227
+ declaredStatuses: [400, 401],
9228
+ empty: false
9229
+ }, requestOptions),
9230
+ base: (input, requestOptions) => request({
9231
+ method: "GET",
9232
+ path: `/api/vcs/base`,
9233
+ query: { location: input?.["location"] },
9234
+ successStatus: 200,
9235
+ declaredStatuses: [400, 401, 503],
9236
+ empty: false
9237
+ }, requestOptions),
9238
+ status: (input, requestOptions) => request({
9239
+ method: "GET",
9240
+ path: `/api/vcs/status`,
9241
+ query: { location: input?.["location"] },
9242
+ successStatus: 200,
9243
+ declaredStatuses: [400, 401],
9244
+ empty: false
9245
+ }, requestOptions),
9246
+ branch: {
9247
+ list: (input, requestOptions) => request({
9248
+ method: "GET",
9249
+ path: `/api/vcs/branch`,
9250
+ query: { location: input?.["location"], search: input?.["search"], limit: input?.["limit"] },
9251
+ successStatus: 200,
9252
+ declaredStatuses: [400, 401],
9253
+ empty: false
9254
+ }, requestOptions)
9255
+ },
9256
+ diff: (input, requestOptions) => request({
9257
+ method: "GET",
9258
+ path: `/api/vcs/diff`,
9259
+ query: { location: input["location"], mode: input["mode"], base: input["base"], context: input["context"] },
9260
+ successStatus: 200,
9261
+ declaredStatuses: [400, 401, 503],
9262
+ empty: false
9263
+ }, requestOptions)
9264
+ },
9265
+ debug: {
9266
+ location: {
9267
+ list: (requestOptions) => request({
9268
+ method: "GET",
9269
+ path: `/api/debug/location`,
9270
+ successStatus: 200,
9271
+ declaredStatuses: [400, 401],
9272
+ empty: false
9273
+ }, requestOptions),
9274
+ evict: (input, requestOptions) => request({
9275
+ method: "DELETE",
9276
+ path: `/api/debug/location`,
9277
+ query: { location: input?.["location"] },
9278
+ successStatus: 204,
9279
+ declaredStatuses: [400, 401],
9280
+ empty: true
9281
+ }, requestOptions)
9282
+ }
9283
+ },
9284
+ migration: {
9285
+ v1: {
9286
+ status: (requestOptions) => request({
9287
+ method: "GET",
9288
+ path: `/api/experimental/migration/v1`,
9289
+ successStatus: 200,
9290
+ declaredStatuses: [400, 401],
9291
+ empty: false
9292
+ }, requestOptions)
9293
+ }
9294
+ },
9295
+ websearch: {
9296
+ providers: (input, requestOptions) => request({
9297
+ method: "GET",
9298
+ path: `/api/websearch/provider`,
9299
+ query: { location: input?.["location"] },
9300
+ successStatus: 200,
9301
+ declaredStatuses: [400, 401, 503],
9302
+ empty: false
9303
+ }, requestOptions),
9304
+ query: (input, requestOptions) => request({
9305
+ method: "POST",
9306
+ path: `/api/websearch`,
9307
+ query: { location: input["location"] },
9308
+ body: { query: input["query"], providerID: input["providerID"] },
9309
+ successStatus: 200,
9310
+ declaredStatuses: [400, 401, 503],
9311
+ empty: false
9312
+ }, requestOptions)
9313
+ },
9314
+ config: {
9315
+ get: (input, requestOptions) => request({
9316
+ method: "GET",
9317
+ path: `/api/config`,
9318
+ query: { location: input?.["location"] },
9319
+ successStatus: 200,
9320
+ declaredStatuses: [400, 401],
9321
+ empty: false
9322
+ }, requestOptions),
9323
+ shells: (requestOptions) => request({ method: "GET", path: `/api/config/shell`, successStatus: 200, declaredStatuses: [400, 401], empty: false }, requestOptions),
9324
+ update: (input, requestOptions) => request({
9325
+ method: "PATCH",
9326
+ path: `/api/experimental/config`,
9327
+ body: { shell: input["shell"] },
9328
+ successStatus: 204,
9329
+ declaredStatuses: [400, 401],
9330
+ empty: true
9331
+ }, requestOptions)
9332
+ }
9333
+ };
9334
+ }
9335
+ function encodePath(value) {
9336
+ return value.split("/").map(encodeURIComponent).join("/");
9337
+ }
9338
+ function appendQuery(params, key, value) {
9339
+ if (value === undefined)
9340
+ return;
9341
+ if (value === null) {
9342
+ params.append(key, "null");
9343
+ return;
9344
+ }
9345
+ if (Array.isArray(value)) {
9346
+ for (const item of value)
9347
+ appendQuery(params, key, item);
9348
+ return;
9349
+ }
9350
+ if (typeof value === "object") {
9351
+ for (const [child, item] of Object.entries(value))
9352
+ appendQuery(params, `${key}[${child}]`, item);
9353
+ return;
9354
+ }
9355
+ params.append(key, String(value));
9356
+ }
9357
+ async function json3(response) {
9358
+ if (!isContentType(response, "application/json") && !response.headers.get("content-type")?.includes("+json")) {
9359
+ try {
9360
+ await response.body?.cancel();
9361
+ } catch {}
9362
+ throw new ClientError2("UnsupportedContentType");
9363
+ }
9364
+ let text;
9365
+ try {
9366
+ text = await response.text();
9367
+ } catch (cause) {
9368
+ throw new ClientError2("Transport", { cause });
9369
+ }
9370
+ if (text === "")
9371
+ throw new ClientError2("MalformedResponse");
9372
+ try {
9373
+ return JSON.parse(text);
9374
+ } catch (cause) {
9375
+ throw new ClientError2("MalformedResponse", { cause });
9376
+ }
9377
+ }
9378
+ function isContentType(response, expected) {
9379
+ return response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase() === expected;
9380
+ }
9381
+ var exports_client2, maxSseEventBytes;
9382
+ var init_service_5mmhmmk7 = __esm(() => {
9383
+ init_service_qc0tvgb4();
9384
+ init_service_9rqn6x4v();
9385
+ exports_client2 = {};
9386
+ __export2(exports_client2, {
9387
+ make: () => make3
9388
+ });
9389
+ maxSseEventBytes = 16 * 1024 * 1024;
9390
+ });
9391
+
9392
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-4tveyqeh.js
9393
+ var isRpcError2 = (value) => typeof value === "object" && value !== null && ("_tag" in value) && value["_tag"] === "RpcError", isRpcInternalError2 = (value) => typeof value === "object" && value !== null && ("_tag" in value) && value["_tag"] === "RpcInternalError";
9394
+ var init_service_4tveyqeh = () => {};
9395
+
9396
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-1tbj6z39.js
9397
+ function makeRpc2(raw, events) {
9398
+ return (definition) => {
9399
+ const subscribe = (name, options) => {
9400
+ if (!Object.hasOwn(definition.events, name))
9401
+ throw new Error(`Unknown RPC event: ${definition.id}.${name}`);
9402
+ const type = eventType(definition, name);
9403
+ return {
9404
+ [Symbol.asyncIterator]() {
9405
+ const controller = new AbortController;
9406
+ const signal = options?.signal ? AbortSignal.any([controller.signal, options.signal]) : controller.signal;
9407
+ const iterator = async function* () {
9408
+ try {
9409
+ for await (const published of events.subscribe({ signal })) {
9410
+ if (signal.aborted)
9411
+ return;
9412
+ if (published.type !== type)
9413
+ continue;
9414
+ yield published;
9415
+ }
9416
+ } catch (error) {
9417
+ if (!signal.aborted)
9418
+ throw error;
9419
+ } finally {
9420
+ controller.abort();
9421
+ }
9422
+ }();
9423
+ return {
9424
+ next: () => iterator.next(),
9425
+ return: () => {
9426
+ controller.abort();
9427
+ return iterator.return();
9428
+ }
9429
+ };
9430
+ }
9431
+ };
9432
+ };
9433
+ return Object.assign(Object.fromEntries(Object.keys(definition.methods).map((name) => [
9434
+ name,
9435
+ async (input, options) => {
9436
+ try {
9437
+ const result = await raw.rpc.call({
9438
+ rpcID: definition.id,
9439
+ method: name,
9440
+ input,
9441
+ location: options?.location
9442
+ }, { signal: options?.signal, headers: options?.headers });
9443
+ return result.output;
9444
+ } catch (error) {
9445
+ if (!isRpcError2(error) && !isRpcInternalError2(error))
9446
+ throw error;
9447
+ throw error.data === undefined ? { type: error.type, message: error.message } : { type: error.type, message: error.message, data: error.data };
9448
+ }
9449
+ }
9450
+ ])), {
9451
+ events: {
9452
+ subscribe,
9453
+ on: (name, handler, options) => {
9454
+ const controller = new AbortController;
9455
+ const signal = options?.signal ? AbortSignal.any([controller.signal, options.signal]) : controller.signal;
9456
+ const source = subscribe(name, { signal });
9457
+ (async () => {
9458
+ for await (const event of source)
9459
+ await handler(event);
9460
+ })().catch((error) => console.error(error));
9461
+ return () => controller.abort();
9462
+ }
9463
+ }
9464
+ });
9465
+ };
9466
+ }
9467
+ function eventType(definition, name) {
9468
+ return `rpc.${definition.id}.${name}`;
9469
+ }
9470
+ var init_service_1tbj6z39 = __esm(() => {
9471
+ init_service_4tveyqeh();
9472
+ });
9473
+
9474
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-465j0w1p.js
9475
+ function make2(options) {
9476
+ const raw = make3(options);
9477
+ const events = make7((signal, onActivity) => raw.event.subscribe({ signal, onActivity }));
9478
+ return {
9479
+ ...raw,
9480
+ rpc: Object.assign(makeRpc2(raw, events), raw.rpc),
9481
+ event: events
9482
+ };
9483
+ }
9484
+ var exports_client;
9485
+ var init_service_465j0w1p = __esm(() => {
9486
+ init_service_frbwqjmf();
9487
+ init_service_5mmhmmk7();
9488
+ init_service_1tbj6z39();
9489
+ init_service_9rqn6x4v();
9490
+ exports_client = {};
9491
+ __export2(exports_client, {
9492
+ OpenCode: () => exports_client,
9493
+ make: () => make2
9494
+ });
9495
+ });
9496
+
9497
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-vyas3vgt.js
9498
+ var init_service_vyas3vgt = () => {};
9499
+
9500
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/promise/index.js
9501
+ var init_promise = __esm(() => {
9502
+ init_service_m2eywc8w();
9503
+ init_service_465j0w1p();
9504
+ init_service_vyas3vgt();
9505
+ init_service_5mmhmmk7();
9506
+ init_service_qc0tvgb4();
9507
+ init_service_1tbj6z39();
9508
+ init_service_4tveyqeh();
9509
+ init_service_frbwqjmf();
9510
+ });
9511
+
7805
9512
  // ../aft-bridge/dist/active-logger.js
7806
9513
  var ACTIVE_LOGGER_SYMBOL = Symbol.for("aft-bridge-active-logger");
7807
9514
  function loggerGlobal() {
@@ -8677,6 +10384,7 @@ class BinaryBridge {
8677
10384
  pending = new Map;
8678
10385
  outstandingBackgroundTaskIds = new Set;
8679
10386
  nextId = 1;
10387
+ processGeneration = 0;
8680
10388
  stdoutBuffer = "";
8681
10389
  stdoutReadOffset = 0;
8682
10390
  stderrBuffer = "";
@@ -8989,6 +10697,7 @@ class BinaryBridge {
8989
10697
  }
8990
10698
  }
8991
10699
  const id = String(this.nextId++);
10700
+ const tool = command === "tool_call" && typeof params.name === "string" ? params.name : command;
8992
10701
  let request;
8993
10702
  if (command === "cancel_request" || Object.hasOwn(params, "command") || Object.hasOwn(params, "method")) {
8994
10703
  const nested = { ...params };
@@ -9042,14 +10751,20 @@ class BinaryBridge {
9042
10751
  return;
9043
10752
  }
9044
10753
  entry.reject(new Error(`${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
9045
- this.handleTimeout(requestSessionId);
10754
+ this.handleTimeout({
10755
+ requestId: id,
10756
+ tool: entry.tool,
10757
+ generation: entry.generation
10758
+ }, requestSessionId);
9046
10759
  }, effectiveTimeoutMs);
9047
10760
  const entry = {
9048
10761
  resolve,
9049
10762
  reject,
9050
10763
  timer,
9051
10764
  onProgress: options?.onProgress,
9052
- command
10765
+ command,
10766
+ tool,
10767
+ generation: this.processGeneration
9053
10768
  };
9054
10769
  this.pending.set(id, entry);
9055
10770
  if (!child?.stdin?.writable) {
@@ -9352,6 +11067,7 @@ class BinaryBridge {
9352
11067
  this.handleCrash();
9353
11068
  });
9354
11069
  this.process = child;
11070
+ this.processGeneration += 1;
9355
11071
  this.spawnedBinaryFingerprint = readBinaryFingerprint(this.binaryPath);
9356
11072
  this.lastBinaryFingerprintCheckAt = Date.now();
9357
11073
  this.stdoutBuffer = "";
@@ -9523,10 +11239,15 @@ class BinaryBridge {
9523
11239
  this.outstandingBackgroundTaskIds.add(taskId);
9524
11240
  }
9525
11241
  }
9526
- handleTimeout(triggeringSessionId) {
11242
+ handleTimeout(trigger, triggeringSessionId) {
9527
11243
  this.consecutiveRequestTimeouts = 0;
9528
11244
  this.spawnedBinaryFingerprint = null;
9529
- this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} bridge killed during sibling timeout — request aborted`));
11245
+ const abortedSiblings = Array.from(this.pending, ([requestId, entry]) => ({
11246
+ request_id: requestId,
11247
+ tool: entry.tool
11248
+ }));
11249
+ const attribution = `triggering_request_id=${trigger.requestId} ` + `triggering_tool=${JSON.stringify(trigger.tool)} ` + `bridge_generation=${trigger.generation} ` + `aborted_siblings=${JSON.stringify(abortedSiblings)}`;
11250
+ this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} bridge killed during sibling timeout — request aborted; ${attribution}`));
9530
11251
  this.outstandingBackgroundTaskIds.clear();
9531
11252
  if (this.process) {
9532
11253
  this.process.kill("SIGKILL");
@@ -9536,17 +11257,11 @@ class BinaryBridge {
9536
11257
  this.configured = false;
9537
11258
  const tail = this.formatStderrTail();
9538
11259
  this.stderrTail = [];
9539
- const killedMsg = tail ? `Bridge killed after timeout.${tail}` : `Bridge killed after timeout (see ${this.getLogFilePathVia()})`;
9540
- if (tail) {
9541
- if (triggeringSessionId) {
9542
- this.sessionErrorVia(triggeringSessionId, killedMsg);
9543
- } else {
9544
- this.errorVia(killedMsg);
9545
- }
9546
- } else if (triggeringSessionId) {
9547
- this.sessionWarnVia(triggeringSessionId, killedMsg);
11260
+ const killedMsg = tail ? `Bridge killed after timeout; ${attribution}.${tail}` : `Bridge killed after timeout; ${attribution} (see ${this.getLogFilePathVia()})`;
11261
+ if (triggeringSessionId) {
11262
+ this.sessionErrorVia(triggeringSessionId, killedMsg);
9548
11263
  } else {
9549
- this.warnVia(killedMsg);
11264
+ this.errorVia(killedMsg);
9550
11265
  }
9551
11266
  }
9552
11267
  handleCrash(cause) {
@@ -15535,12 +17250,36 @@ function isNpmAvailable(deps = defaultDeps()) {
15535
17250
  return resolveNpm(deps) !== null;
15536
17251
  }
15537
17252
  // ../aft-bridge/dist/onnx-runtime.js
15538
- import { execFileSync } from "node:child_process";
17253
+ import { execFileSync as execFileSync2 } from "node:child_process";
15539
17254
  import { createHash as createHash4 } from "node:crypto";
15540
- import { chmodSync as chmodSync3, closeSync as closeSync4, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as existsSync9, lstatSync, mkdirSync as mkdirSync5, openSync as openSync4, readdirSync as readdirSync3, readFileSync as readFileSync6, readlinkSync, realpathSync as realpathSync2, rmSync as rmSync3, statSync as statSync6, symlinkSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
15541
- import { basename as basename2, dirname as dirname5, isAbsolute as isAbsolute5, join as join12, relative as relative2, resolve as resolve7, win32 } from "node:path";
17255
+ import { chmodSync as chmodSync3, closeSync as closeSync4, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as existsSync10, lstatSync, mkdirSync as mkdirSync5, openSync as openSync4, readdirSync as readdirSync3, readFileSync as readFileSync6, readlinkSync, realpathSync as realpathSync2, renameSync as renameSync5, rmSync as rmSync3, statSync as statSync6, symlinkSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
17256
+ import { basename as basename2, dirname as dirname5, isAbsolute as isAbsolute5, join as join13, relative as relative2, resolve as resolve7, win32 } from "node:path";
15542
17257
  import { Readable as Readable2 } from "node:stream";
15543
17258
  import { pipeline as pipeline2 } from "node:stream/promises";
17259
+
17260
+ // ../aft-bridge/dist/tar-executable.js
17261
+ import { execFileSync } from "node:child_process";
17262
+ import { existsSync as existsSync9 } from "node:fs";
17263
+ import { join as join12 } from "node:path";
17264
+ function windowsTarExecutable(options = {}) {
17265
+ const platform = options.platform ?? process.platform;
17266
+ if (platform !== "win32")
17267
+ return "tar";
17268
+ const env = options.env ?? process.env;
17269
+ const systemTar = join12(env.SystemRoot ?? "C:\\Windows", "System32", "tar.exe");
17270
+ return (options.exists ?? existsSync9)(systemTar) ? systemTar : "tar";
17271
+ }
17272
+ function execTarExtractionSync(args, timeout) {
17273
+ const executable = windowsTarExecutable();
17274
+ try {
17275
+ execFileSync(executable, args, { stdio: "pipe", timeout });
17276
+ } catch (cause) {
17277
+ const detail = cause instanceof Error ? cause.message : String(cause);
17278
+ throw new Error(`tar extraction failed using ${executable}: ${detail}`, { cause });
17279
+ }
17280
+ }
17281
+
17282
+ // ../aft-bridge/dist/onnx-runtime.js
15544
17283
  var ORT_VERSION = "1.24.4";
15545
17284
  var ORT_REPO = "microsoft/onnxruntime";
15546
17285
  var MAX_DOWNLOAD_BYTES2 = 256 * 1024 * 1024;
@@ -15604,11 +17343,11 @@ function getManualInstallHint() {
15604
17343
  }
15605
17344
  async function ensureOnnxRuntime(storageDir) {
15606
17345
  const info = getPlatformInfo();
15607
- const ortVersionDir = join12(storageDir, "onnxruntime", ORT_VERSION);
17346
+ const ortVersionDir = join13(storageDir, "onnxruntime", ORT_VERSION);
15608
17347
  const libName = info?.libName ?? "libonnxruntime.dylib";
15609
17348
  const resolvedOrtDir = resolveCachedOnnxRuntimeDir(ortVersionDir, libName);
15610
- const libPath = join12(resolvedOrtDir, libName);
15611
- if (existsSync9(libPath)) {
17349
+ const libPath = join13(resolvedOrtDir, libName);
17350
+ if (existsSync10(libPath)) {
15612
17351
  const meta = readOnnxInstalledMeta(ortVersionDir);
15613
17352
  if (meta?.sha256) {
15614
17353
  try {
@@ -15637,9 +17376,9 @@ async function ensureOnnxRuntime(storageDir) {
15637
17376
  warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
15638
17377
  return null;
15639
17378
  }
15640
- const onnxBaseDir = join12(storageDir, "onnxruntime");
17379
+ const onnxBaseDir = join13(storageDir, "onnxruntime");
15641
17380
  mkdirSync5(onnxBaseDir, { recursive: true });
15642
- const lockPath = join12(onnxBaseDir, ONNX_LOCK_FILE);
17381
+ const lockPath = join13(onnxBaseDir, ONNX_LOCK_FILE);
15643
17382
  cleanupAbandonedStagingDirs(onnxBaseDir);
15644
17383
  if (!acquireLock(lockPath)) {
15645
17384
  warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
@@ -15658,7 +17397,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
15658
17397
  for (const entry of entries) {
15659
17398
  if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
15660
17399
  continue;
15661
- const stagingDir = join12(onnxBaseDir, entry);
17400
+ const stagingDir = join13(onnxBaseDir, entry);
15662
17401
  const parts = entry.split(".");
15663
17402
  const pidStr = parts[parts.length - 2];
15664
17403
  const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
@@ -15695,7 +17434,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
15695
17434
  }
15696
17435
  function cleanupIncompleteTargetIfUnowned(ortDir) {
15697
17436
  try {
15698
- if (existsSync9(ortDir) && !existsSync9(join12(ortDir, ONNX_INSTALLED_META_FILE))) {
17437
+ if (existsSync10(ortDir) && !existsSync10(join13(ortDir, ONNX_INSTALLED_META_FILE))) {
15699
17438
  log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
15700
17439
  rmSync3(ortDir, { recursive: true, force: true });
15701
17440
  }
@@ -15739,8 +17478,8 @@ function detectOnnxVersion(libDir, libName) {
15739
17478
  if (version)
15740
17479
  return version;
15741
17480
  }
15742
- const base = join12(libDir, libName);
15743
- if (existsSync9(base)) {
17481
+ const base = join13(libDir, libName);
17482
+ if (existsSync10(base)) {
15744
17483
  try {
15745
17484
  const real = realpathSync2(base);
15746
17485
  const version = parseOnnxVersionFromPath(real) ?? parseOnnxVersionFromDirectoryPath(real);
@@ -15806,10 +17545,10 @@ function directoryContainsLibrary(dir, libName) {
15806
17545
  }
15807
17546
  }
15808
17547
  function resolveCachedOnnxRuntimeDir(ortVersionDir, libName) {
15809
- if (existsSync9(join12(ortVersionDir, libName)))
17548
+ if (existsSync10(join13(ortVersionDir, libName)))
15810
17549
  return ortVersionDir;
15811
- const libSubdir = join12(ortVersionDir, "lib");
15812
- if (existsSync9(join12(libSubdir, libName)))
17550
+ const libSubdir = join13(ortVersionDir, "lib");
17551
+ if (existsSync10(join13(libSubdir, libName)))
15813
17552
  return libSubdir;
15814
17553
  return ortVersionDir;
15815
17554
  }
@@ -15824,13 +17563,13 @@ function findSystemOnnxRuntime(libName) {
15824
17563
  } else if (process.platform === "win32") {
15825
17564
  const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
15826
17565
  const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
15827
- searchPaths.push(join12(programFiles, "onnxruntime", "lib"), join12(programFiles, "Microsoft ONNX Runtime", "lib"), join12(programFiles, "Microsoft Machine Learning", "lib"), join12(programFilesX86, "onnxruntime", "lib"), ...(() => {
17566
+ searchPaths.push(join13(programFiles, "onnxruntime", "lib"), join13(programFiles, "Microsoft ONNX Runtime", "lib"), join13(programFiles, "Microsoft Machine Learning", "lib"), join13(programFilesX86, "onnxruntime", "lib"), ...(() => {
15828
17567
  const nugetPaths = [];
15829
17568
  const userProfile = process.env.USERPROFILE ?? "";
15830
17569
  if (!userProfile)
15831
17570
  return nugetPaths;
15832
- const nugetPackageDir = join12(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
15833
- if (!existsSync9(nugetPackageDir))
17571
+ const nugetPackageDir = join13(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
17572
+ if (!existsSync10(nugetPackageDir))
15834
17573
  return nugetPaths;
15835
17574
  try {
15836
17575
  for (const entry of readdirSync3(nugetPackageDir, { withFileTypes: true })) {
@@ -15838,7 +17577,7 @@ function findSystemOnnxRuntime(libName) {
15838
17577
  continue;
15839
17578
  if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
15840
17579
  continue;
15841
- nugetPaths.push(join12(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join12(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
17580
+ nugetPaths.push(join13(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join13(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
15842
17581
  }
15843
17582
  } catch (err) {
15844
17583
  warn(`Failed to scan NuGet ONNX Runtime cache ${nugetPackageDir}: ${err instanceof Error ? err.message : String(err)}`);
@@ -15860,11 +17599,11 @@ function findSystemOnnxRuntime(libName) {
15860
17599
  });
15861
17600
  const unknownVersionPaths = [];
15862
17601
  for (const dir of uniquePaths) {
15863
- const libPath = join12(dir, libName);
17602
+ const libPath = join13(dir, libName);
15864
17603
  if (process.platform === "win32") {
15865
17604
  if (!directoryContainsLibrary(dir, libName))
15866
17605
  continue;
15867
- } else if (!existsSync9(libPath)) {
17606
+ } else if (!existsSync10(libPath)) {
15868
17607
  continue;
15869
17608
  }
15870
17609
  const version = detectOnnxVersion(dir, libName);
@@ -15930,7 +17669,7 @@ function validateExtractedTree(stagingRoot) {
15930
17669
  const walk = (dir) => {
15931
17670
  const entries = readdirSync3(dir);
15932
17671
  for (const entry of entries) {
15933
- const fullPath = join12(dir, entry);
17672
+ const fullPath = join13(dir, entry);
15934
17673
  const lst = lstatSync(fullPath);
15935
17674
  if (lst.isSymbolicLink()) {
15936
17675
  const linkTarget = readlinkSync(fullPath);
@@ -15963,34 +17702,32 @@ async function downloadOnnxRuntime(info, targetDir) {
15963
17702
  const url = `https://github.com/${ORT_REPO}/releases/download/v${ORT_VERSION}/${info.assetName}.${info.archiveType === "tgz" ? "tgz" : "zip"}`;
15964
17703
  log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
15965
17704
  const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
17705
+ const extractionRoot = join13(tmpDir, "extract");
17706
+ const stagedInstallDir = join13(tmpDir, "install");
15966
17707
  try {
15967
- mkdirSync5(tmpDir, { recursive: true });
15968
- const archivePath = join12(tmpDir, `onnxruntime.${info.archiveType}`);
17708
+ mkdirSync5(extractionRoot, { recursive: true });
17709
+ const archivePath = join13(tmpDir, `onnxruntime.${info.archiveType}`);
15969
17710
  await downloadFileWithCap(url, archivePath);
15970
17711
  const archiveSha256 = sha256File(archivePath);
15971
17712
  log(`ONNX Runtime archive sha256=${archiveSha256}`);
15972
17713
  if (info.archiveType === "tgz") {
15973
- execFileSync("tar", ["xzf", archivePath, "-C", tmpDir], {
15974
- stdio: "pipe",
15975
- timeout: 120000
15976
- });
17714
+ execTarExtractionSync(["xzf", archivePath, "-C", extractionRoot], 120000);
15977
17715
  } else {
15978
- await extractZipArchive(archivePath, tmpDir);
17716
+ await extractZipArchive(archivePath, extractionRoot);
15979
17717
  }
15980
17718
  try {
15981
17719
  unlinkSync4(archivePath);
15982
17720
  } catch {}
15983
- validateExtractedTree(tmpDir);
15984
- const extractedDir = join12(tmpDir, info.assetName, "lib");
15985
- if (!existsSync9(extractedDir)) {
17721
+ validateExtractedTree(extractionRoot);
17722
+ const extractedDir = join13(extractionRoot, info.assetName, "lib");
17723
+ if (!existsSync10(extractedDir)) {
15986
17724
  throw new Error(`Expected directory not found: ${extractedDir}`);
15987
17725
  }
15988
- mkdirSync5(targetDir, { recursive: true });
15989
17726
  const libFiles = readdirSync3(extractedDir).filter((f) => f.startsWith("libonnxruntime") || f.startsWith("onnxruntime"));
15990
17727
  const realFiles = [];
15991
17728
  const symlinks = [];
15992
17729
  for (const libFile of libFiles) {
15993
- const src = join12(extractedDir, libFile);
17730
+ const src = join13(extractedDir, libFile);
15994
17731
  try {
15995
17732
  const stat = lstatSync(src);
15996
17733
  log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
@@ -16004,15 +17741,11 @@ async function downloadOnnxRuntime(info, targetDir) {
16004
17741
  realFiles.push(libFile);
16005
17742
  }
16006
17743
  }
16007
- copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks);
16008
- const libPath = join12(targetDir, info.libName);
16009
- let libHash = null;
16010
- try {
16011
- libHash = sha256File(libPath);
16012
- } catch (err) {
16013
- warn(`Could not hash newly-installed ONNX library at ${libPath}: ${err}`);
16014
- }
16015
- writeOnnxInstalledMeta(targetDir, ORT_VERSION, libHash, archiveSha256);
17744
+ copyOnnxLibraries(info, extractedDir, stagedInstallDir, realFiles, symlinks);
17745
+ const libPath = join13(stagedInstallDir, info.libName);
17746
+ const libHash = sha256File(libPath);
17747
+ writeOnnxInstalledMeta(stagedInstallDir, ORT_VERSION, libHash, archiveSha256);
17748
+ publishOnnxRuntime(stagedInstallDir, targetDir);
16016
17749
  rmSync3(tmpDir, { recursive: true, force: true });
16017
17750
  log(`ONNX Runtime v${ORT_VERSION} installed to ${targetDir}`);
16018
17751
  return targetDir;
@@ -16021,17 +17754,39 @@ async function downloadOnnxRuntime(info, targetDir) {
16021
17754
  try {
16022
17755
  rmSync3(tmpDir, { recursive: true, force: true });
16023
17756
  } catch {}
16024
- try {
16025
- rmSync3(targetDir, { recursive: true, force: true });
16026
- } catch {}
16027
17757
  return null;
16028
17758
  }
16029
17759
  }
17760
+ function publishOnnxRuntime(stagedInstallDir, targetDir) {
17761
+ const backupDir = `${targetDir}.backup.${process.pid}.${Date.now().toString(36)}`;
17762
+ const hadTarget = existsSync10(targetDir);
17763
+ if (hadTarget)
17764
+ renameSync5(targetDir, backupDir);
17765
+ try {
17766
+ renameSync5(stagedInstallDir, targetDir);
17767
+ } catch (installError) {
17768
+ if (hadTarget) {
17769
+ try {
17770
+ renameSync5(backupDir, targetDir);
17771
+ } catch (restoreError) {
17772
+ throw new Error(`ONNX Runtime replacement failed and the previous runtime could not be restored from ${backupDir}: ${restoreError}`, { cause: installError });
17773
+ }
17774
+ }
17775
+ throw installError;
17776
+ }
17777
+ if (hadTarget) {
17778
+ try {
17779
+ rmSync3(backupDir, { recursive: true, force: true });
17780
+ } catch (err) {
17781
+ warn(`Could not remove replaced ONNX Runtime backup at ${backupDir}: ${err}`);
17782
+ }
17783
+ }
17784
+ }
16030
17785
  function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync3) {
16031
17786
  const requiredLibs = new Set([info.libName]);
16032
17787
  for (const libFile of realFiles) {
16033
- const src = join12(extractedDir, libFile);
16034
- const dst = join12(targetDir, libFile);
17788
+ const src = join13(extractedDir, libFile);
17789
+ const dst = join13(targetDir, libFile);
16035
17790
  try {
16036
17791
  copyFile(src, dst);
16037
17792
  if (process.platform !== "win32") {
@@ -16047,11 +17802,11 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
16047
17802
  }
16048
17803
  const targetRoot = realpathSync2(targetDir);
16049
17804
  for (const link of symlinks) {
16050
- const dst = join12(targetDir, link.name);
17805
+ const dst = join13(targetDir, link.name);
16051
17806
  try {
16052
17807
  unlinkSync4(dst);
16053
17808
  } catch {}
16054
- const dstForContainment = join12(targetRoot, link.name);
17809
+ const dstForContainment = join13(targetRoot, link.name);
16055
17810
  const resolvedTarget = resolve7(dirname5(dstForContainment), link.target);
16056
17811
  if (!isPathInsideRoot(targetRoot, resolvedTarget)) {
16057
17812
  const message = `ONNX Runtime symlink ${link.name} points outside install dir: ${link.target}`;
@@ -16072,21 +17827,18 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
16072
17827
  log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
16073
17828
  }
16074
17829
  }
16075
- const requiredPath = join12(targetDir, info.libName);
16076
- if (!existsSync9(requiredPath)) {
17830
+ const requiredPath = join13(targetDir, info.libName);
17831
+ if (!existsSync10(requiredPath)) {
16077
17832
  rmSync3(targetDir, { recursive: true, force: true });
16078
17833
  throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
16079
17834
  }
16080
17835
  }
16081
17836
  async function extractZipArchive(archivePath, destinationDir) {
16082
17837
  if (process.platform === "win32") {
16083
- execFileSync("tar.exe", ["-xf", archivePath, "-C", destinationDir], {
16084
- stdio: "pipe",
16085
- timeout: 120000
16086
- });
17838
+ execTarExtractionSync(["-xf", archivePath, "-C", destinationDir], 120000);
16087
17839
  return;
16088
17840
  }
16089
- execFileSync("unzip", ["-q", archivePath, "-d", destinationDir], {
17841
+ execFileSync2("unzip", ["-q", archivePath, "-d", destinationDir], {
16090
17842
  stdio: "pipe",
16091
17843
  timeout: 120000
16092
17844
  });
@@ -16099,13 +17851,13 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
16099
17851
  ...sha256 ? { sha256 } : {},
16100
17852
  archiveSha256
16101
17853
  };
16102
- writeFileSync3(join12(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
17854
+ writeFileSync3(join13(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
16103
17855
  } catch (err) {
16104
17856
  log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
16105
17857
  }
16106
17858
  }
16107
17859
  function readOnnxInstalledMeta(installDir) {
16108
- const path = join12(installDir, ONNX_INSTALLED_META_FILE);
17860
+ const path = join13(installDir, ONNX_INSTALLED_META_FILE);
16109
17861
  try {
16110
17862
  if (!statSync6(path).isFile())
16111
17863
  return null;
@@ -16217,7 +17969,7 @@ function isWindowsProcessAlive(pid) {
16217
17969
  if (!Number.isInteger(pid) || pid <= 0)
16218
17970
  return false;
16219
17971
  try {
16220
- const output = execFileSync("tasklist.exe", ["/FI", `PID eq ${pid}`, "/FO", "CSV", "/NH"], {
17972
+ const output = execFileSync2("tasklist.exe", ["/FI", `PID eq ${pid}`, "/FO", "CSV", "/NH"], {
16221
17973
  encoding: "utf8",
16222
17974
  timeout: 2000,
16223
17975
  windowsHide: true
@@ -16438,10 +18190,8 @@ function prepareCanonicalEditArguments(toolName, rawArguments) {
16438
18190
  if (unknownRootKeys.length > 0) {
16439
18191
  throw new InvalidRequestError(formatUnknownKeys(unknownRootKeys));
16440
18192
  }
18193
+ validateSymbolModePair(record);
16441
18194
  const modes = editModesPresent(record);
16442
- if (hasOrphanedSymbolContent(record)) {
16443
- throw new InvalidRequestError("edit: 'content' requires a non-empty string 'symbol' when symbol mode is selected");
16444
- }
16445
18195
  if (modes.length > 1) {
16446
18196
  throw new InvalidRequestError(`edit: conflicting modes: ${modes.join(", ")}. ${OMIT_OPTIONAL_FIELDS_STEERING}`);
16447
18197
  }
@@ -16461,7 +18211,7 @@ function prepareCanonicalEditArguments(toolName, rawArguments) {
16461
18211
  throw new InvalidRequestError("edit: 'symbol' must be a string when symbol mode is selected");
16462
18212
  }
16463
18213
  if (!hasOwn(record, "content") || typeof record.content !== "string") {
16464
- throw new InvalidRequestError("edit: symbol mode requires both 'symbol' and 'content' string properties");
18214
+ throw new InvalidRequestError("edit: incomplete symbol mode: property 'content' must be a string. " + "Retry with `symbol` + `content`, or use `edits[]`.");
16465
18215
  }
16466
18216
  } else {
16467
18217
  const item = {};
@@ -16514,6 +18264,29 @@ function validateEditPath(record) {
16514
18264
  function formatUnknownKeys(keys) {
16515
18265
  return `Unrecognized keys: ${keys.map((key) => `"${key}"`).join(", ")}`;
16516
18266
  }
18267
+ function validateSymbolModePair(record) {
18268
+ const completeShapes = "Retry with `symbol` + `content`, or use `edits[]`.";
18269
+ const hasSymbol = isNonEmptyString(record.symbol);
18270
+ const hasContent = isNonEmptyString(record.content);
18271
+ if (hasSymbol) {
18272
+ if (!hasOwn(record, "content")) {
18273
+ throw new InvalidRequestError(`edit: incomplete symbol mode: missing property 'content'. ${completeShapes}`);
18274
+ }
18275
+ if (record.content === null) {
18276
+ throw new InvalidRequestError(`edit: incomplete symbol mode: property 'content' is null. ${completeShapes}`);
18277
+ }
18278
+ return;
18279
+ }
18280
+ if (!hasContent)
18281
+ return;
18282
+ if (!hasOwn(record, "symbol")) {
18283
+ throw new InvalidRequestError(`edit: incomplete symbol mode: missing property 'symbol'. ${completeShapes}`);
18284
+ }
18285
+ if (record.symbol === null) {
18286
+ throw new InvalidRequestError(`edit: incomplete symbol mode: property 'symbol' is null. ${completeShapes}`);
18287
+ }
18288
+ throw new InvalidRequestError(`edit: incomplete symbol mode: property 'symbol' must be a non-empty string. ${completeShapes}`);
18289
+ }
16517
18290
  function editModesPresent(record) {
16518
18291
  const hasAppendContent = isNonEmptyString(record.appendContent);
16519
18292
  if (!hasAppendContent)
@@ -16599,9 +18372,6 @@ function normalizeEditArraySentinels(record) {
16599
18372
  return true;
16600
18373
  }
16601
18374
  }
16602
- function hasOrphanedSymbolContent(record) {
16603
- return isNonEmptyString(record.content) && !isNonEmptyString(record.symbol);
16604
- }
16605
18375
  function parseEditArray(value) {
16606
18376
  if (typeof value === "string") {
16607
18377
  let parsed;
@@ -16784,8 +18554,50 @@ function copyOwnProperties(source) {
16784
18554
  copy[key] = source[key];
16785
18555
  return copy;
16786
18556
  }
18557
+ // ../aft-bridge/dist/semantic-status.js
18558
+ var MISSING_ONNX_RUNTIME_MARKER = "ONNX Runtime not found.";
18559
+ var MISSING_ONNX_RUNTIME_LABEL = "unavailable — ONNX Runtime missing (npx @cortexkit/aft doctor --fix)";
18560
+ var REBUILDING_LABEL = "Rebuilding (model changed)";
18561
+ var SEMANTIC_PROGRESS_STATUSES = new Set(["building", "loading"]);
18562
+ var SEMANTIC_READY_STATUSES = new Set(["ready", "empty"]);
18563
+ var SEMANTIC_INACTIVE_STATUSES = new Set(["disabled", "busy"]);
18564
+ var SEMANTIC_FAILURE_LABELS = {
18565
+ backend_unavailable: "backend unavailable",
18566
+ degraded: "degraded",
18567
+ error: "error",
18568
+ failed: "failed",
18569
+ unavailable: "unavailable"
18570
+ };
18571
+ function semanticIndexStatusKind(status) {
18572
+ if (SEMANTIC_READY_STATUSES.has(status))
18573
+ return "ready";
18574
+ if (SEMANTIC_PROGRESS_STATUSES.has(status))
18575
+ return "progress";
18576
+ if (status in SEMANTIC_FAILURE_LABELS)
18577
+ return "failure";
18578
+ if (SEMANTIC_INACTIVE_STATUSES.has(status))
18579
+ return "inactive";
18580
+ return "unrecognized";
18581
+ }
18582
+ function mentionsMissingOnnxRuntime(...values) {
18583
+ return values.some((value) => typeof value === "string" && value.includes(MISSING_ONNX_RUNTIME_MARKER));
18584
+ }
18585
+ function semanticFailureLabel(status, stage, error) {
18586
+ if (mentionsMissingOnnxRuntime(error, stage))
18587
+ return MISSING_ONNX_RUNTIME_LABEL;
18588
+ return SEMANTIC_FAILURE_LABELS[status] ?? null;
18589
+ }
18590
+ function formatSemanticIndexStatus(status, stage, error) {
18591
+ const failure = semanticFailureLabel(status, stage, error);
18592
+ if (failure)
18593
+ return failure;
18594
+ if (semanticIndexStatusKind(status) === "progress" && stage === "fingerprint_change") {
18595
+ return REBUILDING_LABEL;
18596
+ }
18597
+ return status;
18598
+ }
16787
18599
  // src/config.ts
16788
- import { existsSync as existsSync10, readFileSync as readFileSync7, renameSync as renameSync5, unlinkSync as unlinkSync5, writeFileSync as writeFileSync4 } from "node:fs";
18600
+ import { existsSync as existsSync11, readFileSync as readFileSync7, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync4 } from "node:fs";
16789
18601
  import { homedir as homedir10 } from "node:os";
16790
18602
  import { isAbsolute as isAbsolute6, parse as parsePath, resolve as resolvePath } from "node:path";
16791
18603
  var import_comment_json = __toESM(require_src2(), 1);
@@ -21492,6 +23304,9 @@ function write(level, message, data, sessionId) {
21492
23304
  function log2(message, data) {
21493
23305
  write("INFO", message, data);
21494
23306
  }
23307
+ function debug2(message, data) {
23308
+ write("DEBUG", message, data);
23309
+ }
21495
23310
  function warn2(message, data) {
21496
23311
  write("WARN", message, data);
21497
23312
  }
@@ -21690,6 +23505,7 @@ var InspectConfigSchema = object({
21690
23505
  enabled: boolean2().optional(),
21691
23506
  diagnostics_timeout_ms: number2().int().positive().optional().transform((value) => value === undefined ? undefined : clampInspectDiagnosticsTimeoutMs(value)),
21692
23507
  tier2_idle_minutes: number2().min(0).optional(),
23508
+ tier2_pass_timeout_ms: number2().int().positive().optional(),
21693
23509
  categories: record(string2(), boolean2()).optional(),
21694
23510
  tier2_soft_deadline_ms: number2().int().positive().optional(),
21695
23511
  max_drill_down_items: number2().int().positive().max(100).optional(),
@@ -22012,7 +23828,7 @@ function migrateExperimentalBashBlock(rawConfig, configPath, logger) {
22012
23828
  return movedKeys;
22013
23829
  }
22014
23830
  function migrateAftConfigFile2(configPath, logger = { log: log2, warn: warn2 }) {
22015
- if (!existsSync10(configPath)) {
23831
+ if (!existsSync11(configPath)) {
22016
23832
  return { migrated: false, oldKeys: [] };
22017
23833
  }
22018
23834
  let tmpPath = null;
@@ -22036,7 +23852,7 @@ function migrateAftConfigFile2(configPath, logger = { log: log2, warn: warn2 })
22036
23852
  ${serialized}` : serialized;
22037
23853
  tmpPath = `${configPath}.tmp.${process.pid}`;
22038
23854
  writeFileSync4(tmpPath, nextContent, "utf-8");
22039
- renameSync5(tmpPath, configPath);
23855
+ renameSync6(tmpPath, configPath);
22040
23856
  logger.log(`Migrated config at ${configPath}: removed ${oldKeys.join(", ")}`);
22041
23857
  return { migrated: true, oldKeys };
22042
23858
  } catch (err) {
@@ -22097,7 +23913,7 @@ function recordConfigParseFailure(configPath, errorMessage) {
22097
23913
  }
22098
23914
  function loadConfigFromPath(configPath) {
22099
23915
  try {
22100
- if (!existsSync10(configPath)) {
23916
+ if (!existsSync11(configPath)) {
22101
23917
  return null;
22102
23918
  }
22103
23919
  const content = readFileSync7(configPath, "utf-8");
@@ -22437,7 +24253,7 @@ function loadAftConfig(projectDirectory) {
22437
24253
  }
22438
24254
 
22439
24255
  // src/tools/_shared.ts
22440
- import { existsSync as existsSync11 } from "node:fs";
24256
+ import { existsSync as existsSync12 } from "node:fs";
22441
24257
  import * as os2 from "node:os";
22442
24258
  import * as path2 from "node:path";
22443
24259
 
@@ -34850,6 +36666,7 @@ var DEBOUNCE_STEP_MS = 200;
34850
36666
  var DEBOUNCE_CAP_MS = 1000;
34851
36667
  var MAX_WAKE_SEND_ATTEMPTS = 5;
34852
36668
  var DEFAULT_WAKE_CONFIRMATION_WINDOW_MS = 5000;
36669
+ var BUSY_WAKE_DEFER_CEILING_MS = 60000;
34853
36670
  var UNKNOWN_COMPLETION_TTL_MS = 5000;
34854
36671
  var UNKNOWN_COMPLETION_CAP = 32;
34855
36672
  var DEFAULT_SESSION_ID2 = "__default__";
@@ -34881,10 +36698,12 @@ function logDroppedForeignSessionFrame(drainContext, droppedSessionId, liveSessi
34881
36698
  var DEFAULT_BG_HOP_TIMEOUT_MS = 15000;
34882
36699
  var bgHopTimeoutMs = DEFAULT_BG_HOP_TIMEOUT_MS;
34883
36700
  var wakeConfirmationWindowMs = DEFAULT_WAKE_CONFIRMATION_WINDOW_MS;
36701
+ var busyWakeDeferCeilingMs = BUSY_WAKE_DEFER_CEILING_MS;
34884
36702
  var lastWakeMessageTimestamp = 0;
34885
36703
  var wakeMessageCounter = 0;
34886
36704
  var subcNudgesInFlight = new Map;
34887
36705
  var subcNudgeLogState = new Map;
36706
+ var deferredBusyWakes = new Map;
34888
36707
  function consumeBgCompletion(sessionID, taskId) {
34889
36708
  const state = stateFor(sessionID);
34890
36709
  state.pendingCompletions = state.pendingCompletions.filter((c) => c.task_id !== taskId);
@@ -34899,6 +36718,9 @@ function consumeBgCompletion(sessionID, taskId) {
34899
36718
  }
34900
36719
  }
34901
36720
  clearWakeTimerIfNoPending(state);
36721
+ if (state.pendingCompletions.length === 0 && state.pendingLongRunning.length === 0 && state.pendingPatternMatches.length === 0) {
36722
+ clearDeferredBusyWake(sessionID || DEFAULT_SESSION_ID2);
36723
+ }
34902
36724
  }
34903
36725
  async function markBgCompletionDelivered(drainContext, taskId) {
34904
36726
  const state = stateFor(drainContext.sessionID);
@@ -35004,7 +36826,7 @@ async function handlePushedPatternMatch(drainContext, frame) {
35004
36826
  }
35005
36827
  const state = stateFor(drainContext.sessionID);
35006
36828
  queuePendingPatternMatch(state, { ...frame, ackCompletionOnDelivery: true });
35007
- await triggerWakeIfPending(drainContext, true);
36829
+ await triggerWakeIfPending(drainContext, true, true, false, true);
35008
36830
  }
35009
36831
  function ingestBgCompletions(sessionID, completions) {
35010
36832
  if (!Array.isArray(completions) || completions.length === 0)
@@ -35042,11 +36864,11 @@ function ingestBgCompletions(sessionID, completions) {
35042
36864
  }
35043
36865
  async function handlePushedBgCompletion(drainContext, completion) {
35044
36866
  ingestBgCompletions(drainContext.sessionID, [completion]);
35045
- await triggerWakeIfPending(drainContext, true, false);
36867
+ await triggerWakeIfPending(drainContext, true, false, false, true);
35046
36868
  }
35047
36869
  async function handlePushedBgLongRunning(drainContext, reminder) {
35048
36870
  stateFor(drainContext.sessionID).pendingLongRunning.push(reminder);
35049
- await triggerWakeIfPending(drainContext, true);
36871
+ await triggerWakeIfPending(drainContext, true, true, false, true);
35050
36872
  }
35051
36873
  async function appendInTurnBgCompletions(drainContext, output) {
35052
36874
  if (!output)
@@ -35091,6 +36913,7 @@ async function appendInTurnBgCompletions(drainContext, output) {
35091
36913
  if (inTurnAcked)
35092
36914
  confirmAcked(state, inTurnAckIds);
35093
36915
  clearWakeTimerIfNoPending(state);
36916
+ clearDeferredBusyWake(drainContext.sessionID);
35094
36917
  }
35095
36918
  async function handleIdleBgCompletions(drainContext) {
35096
36919
  stateFor(drainContext.sessionID).wakeDeferredTaskIds.clear();
@@ -35118,7 +36941,7 @@ async function handleSubcBgEventsNudgeOnce(drainContext) {
35118
36941
  const state = stateFor(drainContext.sessionID);
35119
36942
  state.wakeDeferredTaskIds.clear();
35120
36943
  rearmHardStoppedWake(state, drainContext);
35121
- await triggerWakeIfPending(drainContext, false, true, true);
36944
+ await triggerWakeIfPending(drainContext, false, true, true, true);
35122
36945
  }
35123
36946
  function logSubcNudgeLifecycle(drainContext, kind, message) {
35124
36947
  logDeliveryHop(drainContext, kind, message, {
@@ -35333,6 +37156,42 @@ function registerWakeAdmission(state, admission) {
35333
37156
  }, wakeConfirmationWindowMs);
35334
37157
  tracked.confirmationTimer.unref?.();
35335
37158
  }
37159
+ function clearDeferredBusyWake(sessionID) {
37160
+ const deferred = deferredBusyWakes.get(sessionID);
37161
+ if (!deferred)
37162
+ return;
37163
+ deferredBusyWakes.delete(sessionID);
37164
+ clearTimeout(deferred.timer);
37165
+ return deferred;
37166
+ }
37167
+ function deferBusyWake(drainContext) {
37168
+ const existing = deferredBusyWakes.get(drainContext.sessionID);
37169
+ if (existing) {
37170
+ existing.context = drainContext;
37171
+ return;
37172
+ }
37173
+ const deferredAt = Date.now();
37174
+ const deferred = {
37175
+ context: drainContext,
37176
+ deferredAt,
37177
+ timer: setTimeout(() => {
37178
+ if (deferredBusyWakes.get(drainContext.sessionID) !== deferred)
37179
+ return;
37180
+ deferredBusyWakes.delete(drainContext.sessionID);
37181
+ const waitMs = Math.max(0, Date.now() - deferredAt);
37182
+ sessionLog(drainContext.sessionID, `${LOG_PREFIX} busy wake defer ceiling reached`, {
37183
+ event: "bash_completion_wake_deferred_ceiling",
37184
+ wait_ms: waitMs,
37185
+ ceiling_ms: busyWakeDeferCeilingMs
37186
+ });
37187
+ triggerWakeIfPending(deferred.context, true).catch(() => {
37188
+ return;
37189
+ });
37190
+ }, busyWakeDeferCeilingMs)
37191
+ };
37192
+ deferred.timer.unref?.();
37193
+ deferredBusyWakes.set(drainContext.sessionID, deferred);
37194
+ }
35336
37195
  function observeOpenCodeBgNotificationEvent(event) {
35337
37196
  try {
35338
37197
  if (!event || typeof event !== "object")
@@ -35381,12 +37240,17 @@ function observeOpenCodeBgNotificationEvent(event) {
35381
37240
  return;
35382
37241
  }
35383
37242
  if (nextStatus === "idle") {
37243
+ const deferred = clearDeferredBusyWake(sessionID);
37244
+ if (deferred)
37245
+ triggerWakeIfPending(deferred.context, true).catch(() => {
37246
+ return;
37247
+ });
35384
37248
  for (const admission of state.wakeAdmissions.values())
35385
37249
  queueWakeRefire(state, admission);
35386
37250
  }
35387
37251
  } catch {}
35388
37252
  }
35389
- async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredCompletions = true, forceDrain = false) {
37253
+ async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredCompletions = true, forceDrain = false, deferWhileBusy = false) {
35390
37254
  const state = stateFor(drainContext.sessionID);
35391
37255
  if (!skipDrain && (forceDrain || state.outstandingTaskIds.size > 0 || !state.forcedDrainCompleted)) {
35392
37256
  await drainCompletions(drainContext);
@@ -35394,6 +37258,10 @@ async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredComp
35394
37258
  routeExplicitControlCompletions(state);
35395
37259
  if (!hasWakeEligiblePending(state, includeDeferredCompletions))
35396
37260
  return;
37261
+ if (deferWhileBusy && state.hostStatus === "busy") {
37262
+ deferBusyWake(drainContext);
37263
+ return;
37264
+ }
35397
37265
  scheduleWake(state, async (reminder, deliveredCompletions, deliveredPatternMatches) => {
35398
37266
  const liveSession = getActiveSessionId() ?? drainContext.sessionID;
35399
37267
  if (liveSession && drainContext.sessionID && drainContext.sessionID !== liveSession) {
@@ -36235,7 +38103,7 @@ function bridgeFor(ctx, runtime) {
36235
38103
  if (ctx.isProjectEnabled?.(projectRoot) === false) {
36236
38104
  throw new Error(`AFT disabled by config for ${projectRoot}`);
36237
38105
  }
36238
- if (!existsSync11(projectRoot)) {
38106
+ if (!existsSync12(projectRoot)) {
36239
38107
  throw new Error(`project directory no longer exists: ${projectRoot} (stale restored session?)`);
36240
38108
  }
36241
38109
  return ctx.pool.getBridge(projectRoot);
@@ -36392,9 +38260,9 @@ async function signalBashWaitDetachForProject(pool, projectRoot, sessionID) {
36392
38260
  }
36393
38261
 
36394
38262
  // src/notifications.ts
36395
- import { existsSync as existsSync12, readFileSync as readFileSync8 } from "node:fs";
38263
+ import { existsSync as existsSync13, readFileSync as readFileSync8 } from "node:fs";
36396
38264
  import { homedir as homedir12, platform } from "node:os";
36397
- import { join as join13 } from "node:path";
38265
+ import { join as join14 } from "node:path";
36398
38266
  function isTuiMode() {
36399
38267
  return process.env.OPENCODE_CLIENT === "cli";
36400
38268
  }
@@ -36416,21 +38284,21 @@ function getDesktopStatePath() {
36416
38284
  const os = platform();
36417
38285
  const home = homedir12();
36418
38286
  if (os === "darwin") {
36419
- return join13(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
38287
+ return join14(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
36420
38288
  }
36421
38289
  if (os === "linux") {
36422
- const xdgConfig = process.env.XDG_CONFIG_HOME || join13(home, ".config");
36423
- return join13(xdgConfig, "ai.opencode.desktop", "opencode.global.dat");
38290
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join14(home, ".config");
38291
+ return join14(xdgConfig, "ai.opencode.desktop", "opencode.global.dat");
36424
38292
  }
36425
38293
  if (os === "win32") {
36426
- const appData = process.env.APPDATA || join13(home, "AppData", "Roaming");
36427
- return join13(appData, "ai.opencode.desktop", "opencode.global.dat");
38294
+ const appData = process.env.APPDATA || join14(home, "AppData", "Roaming");
38295
+ return join14(appData, "ai.opencode.desktop", "opencode.global.dat");
36428
38296
  }
36429
38297
  return null;
36430
38298
  }
36431
38299
  function readDesktopState() {
36432
38300
  const statePath = getDesktopStatePath();
36433
- if (!statePath || !existsSync12(statePath)) {
38301
+ if (!statePath || !existsSync13(statePath)) {
36434
38302
  return { serverUrl: null };
36435
38303
  }
36436
38304
  try {
@@ -36930,11 +38798,11 @@ async function flushConfigureWarningsOnIdle(sessionId) {
36930
38798
  // src/hooks/auto-update-checker/index.ts
36931
38799
  import {
36932
38800
  closeSync as closeSync5,
36933
- existsSync as existsSync15,
38801
+ existsSync as existsSync16,
36934
38802
  mkdirSync as mkdirSync6,
36935
38803
  openSync as openSync5,
36936
38804
  readFileSync as readFileSync11,
36937
- renameSync as renameSync6,
38805
+ renameSync as renameSync7,
36938
38806
  rmSync as rmSync5,
36939
38807
  statSync as statSync8,
36940
38808
  writeFileSync as writeFileSync7
@@ -36943,30 +38811,30 @@ import { dirname as dirname8 } from "node:path";
36943
38811
 
36944
38812
  // src/hooks/auto-update-checker/cache.ts
36945
38813
  import { spawn as spawn4 } from "node:child_process";
36946
- import { cpSync, existsSync as existsSync14, mkdtempSync, readFileSync as readFileSync10, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "node:fs";
38814
+ import { cpSync, existsSync as existsSync15, mkdtempSync, readFileSync as readFileSync10, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "node:fs";
36947
38815
  import { tmpdir as tmpdir2 } from "node:os";
36948
- import { basename as basename3, dirname as dirname7, join as join16 } from "node:path";
38816
+ import { basename as basename3, dirname as dirname7, join as join17 } from "node:path";
36949
38817
  var import_comment_json3 = __toESM(require_src2(), 1);
36950
38818
 
36951
38819
  // src/hooks/auto-update-checker/checker.ts
36952
- import { existsSync as existsSync13, readFileSync as readFileSync9, statSync as statSync7, writeFileSync as writeFileSync5 } from "node:fs";
36953
- import { dirname as dirname6, isAbsolute as isAbsolute8, join as join15, resolve as resolve9 } from "node:path";
38820
+ import { existsSync as existsSync14, readFileSync as readFileSync9, statSync as statSync7, writeFileSync as writeFileSync5 } from "node:fs";
38821
+ import { dirname as dirname6, isAbsolute as isAbsolute8, join as join16, resolve as resolve9 } from "node:path";
36954
38822
  import { fileURLToPath } from "node:url";
36955
38823
  var import_comment_json2 = __toESM(require_src2(), 1);
36956
38824
 
36957
38825
  // src/hooks/auto-update-checker/constants.ts
36958
- import { join as join14 } from "node:path";
38826
+ import { join as join15 } from "node:path";
36959
38827
  var PACKAGE_NAME = "@cortexkit/aft-opencode";
36960
38828
  var NPM_REGISTRY_URL = "https://registry.npmjs.org";
36961
38829
  var NPM_FETCH_TIMEOUT = 1e4;
36962
38830
  function cacheDir() {
36963
- return join14(getOpenCodeCacheRoot(), "packages");
38831
+ return join15(getOpenCodeCacheRoot(), "packages");
36964
38832
  }
36965
38833
  function userOpenCodeConfig() {
36966
- return join14(getOpenCodeConfigRoot(), "opencode.json");
38834
+ return join15(getOpenCodeConfigRoot(), "opencode.json");
36967
38835
  }
36968
38836
  function userOpenCodeConfigJsonc() {
36969
- return join14(getOpenCodeConfigRoot(), "opencode.jsonc");
38837
+ return join15(getOpenCodeConfigRoot(), "opencode.jsonc");
36970
38838
  }
36971
38839
 
36972
38840
  // src/hooks/auto-update-checker/types.ts
@@ -37025,8 +38893,8 @@ function extractChannel(version) {
37025
38893
  }
37026
38894
  function getConfigPaths(directory) {
37027
38895
  return [
37028
- join15(directory, ".opencode", "opencode.json"),
37029
- join15(directory, ".opencode", "opencode.jsonc"),
38896
+ join16(directory, ".opencode", "opencode.json"),
38897
+ join16(directory, ".opencode", "opencode.jsonc"),
37030
38898
  userOpenCodeConfig(),
37031
38899
  userOpenCodeConfigJsonc()
37032
38900
  ];
@@ -37046,7 +38914,7 @@ function resolvePathPluginSpec(spec, configPath) {
37046
38914
  function getLocalDevPath(directory) {
37047
38915
  for (const configPath of getConfigPaths(directory)) {
37048
38916
  try {
37049
- if (!existsSync13(configPath))
38917
+ if (!existsSync14(configPath))
37050
38918
  continue;
37051
38919
  const rawConfig = parseJsonConfig(readFileSync9(configPath, "utf-8"));
37052
38920
  const plugins = getPluginEntries(rawConfig);
@@ -37072,8 +38940,8 @@ function findPackageJsonUp(startPath) {
37072
38940
  const stat = statSync7(startPath);
37073
38941
  let dir = stat.isDirectory() ? startPath : dirname6(startPath);
37074
38942
  for (let i = 0;i < 10; i++) {
37075
- const pkgPath = join15(dir, "package.json");
37076
- if (existsSync13(pkgPath)) {
38943
+ const pkgPath = join16(dir, "package.json");
38944
+ if (existsSync14(pkgPath)) {
37077
38945
  try {
37078
38946
  const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(pkgPath, "utf-8")));
37079
38947
  if (pkg.success && pkg.data.name === PACKAGE_NAME)
@@ -37113,7 +38981,7 @@ function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
37113
38981
  function findPluginEntry(directory) {
37114
38982
  for (const configPath of getConfigPaths(directory)) {
37115
38983
  try {
37116
- if (!existsSync13(configPath))
38984
+ if (!existsSync14(configPath))
37117
38985
  continue;
37118
38986
  const rawConfig = parseJsonConfig(readFileSync9(configPath, "utf-8"));
37119
38987
  const plugins = getPluginEntries(rawConfig);
@@ -37133,7 +39001,7 @@ function findPluginEntry(directory) {
37133
39001
  }
37134
39002
  var cachedPackageVersion = null;
37135
39003
  function getSpecCachePackageJsonPath(spec) {
37136
- return join15(cacheDir(), spec, "node_modules", PACKAGE_NAME, "package.json");
39004
+ return join16(cacheDir(), spec, "node_modules", PACKAGE_NAME, "package.json");
37137
39005
  }
37138
39006
  function getCachedVersion(spec) {
37139
39007
  if (!spec && cachedPackageVersion)
@@ -37142,11 +39010,11 @@ function getCachedVersion(spec) {
37142
39010
  getCurrentRuntimePackageJsonPath(),
37143
39011
  spec ? getSpecCachePackageJsonPath(spec) : null,
37144
39012
  getSpecCachePackageJsonPath(`${PACKAGE_NAME}@latest`),
37145
- join15(getOpenCodeCacheRoot(), "node_modules", PACKAGE_NAME, "package.json")
39013
+ join16(getOpenCodeCacheRoot(), "node_modules", PACKAGE_NAME, "package.json")
37146
39014
  ].filter(isString);
37147
39015
  for (const packageJsonPath of candidates) {
37148
39016
  try {
37149
- if (!existsSync13(packageJsonPath))
39017
+ if (!existsSync14(packageJsonPath))
37150
39018
  continue;
37151
39019
  const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(packageJsonPath, "utf-8")));
37152
39020
  if (pkg.success && pkg.data.version) {
@@ -37191,17 +39059,17 @@ async function getLatestVersion(channel = "latest", options = {}) {
37191
39059
  var pendingSnapshots = new Map;
37192
39060
  var quarantinedInstallDirs = new Set;
37193
39061
  function createAutoUpdateSnapshot(installDir, packageJsonPath, packageName) {
37194
- const packageDir = join16(installDir, "node_modules", packageName);
37195
- const lockfilePath = join16(installDir, "package-lock.json");
37196
- const tempDir = mkdtempSync(join16(tmpdir2(), "aft-auto-update-"));
37197
- const stagedPackageDir = existsSync14(packageDir) ? join16(tempDir, "package") : null;
39062
+ const packageDir = join17(installDir, "node_modules", packageName);
39063
+ const lockfilePath = join17(installDir, "package-lock.json");
39064
+ const tempDir = mkdtempSync(join17(tmpdir2(), "aft-auto-update-"));
39065
+ const stagedPackageDir = existsSync15(packageDir) ? join17(tempDir, "package") : null;
37198
39066
  if (stagedPackageDir)
37199
39067
  cpSync(packageDir, stagedPackageDir, { recursive: true });
37200
39068
  return {
37201
39069
  packageJsonPath,
37202
- packageJson: existsSync14(packageJsonPath) ? readFileSync10(packageJsonPath, "utf-8") : null,
39070
+ packageJson: existsSync15(packageJsonPath) ? readFileSync10(packageJsonPath, "utf-8") : null,
37203
39071
  lockfilePath,
37204
- lockfile: existsSync14(lockfilePath) ? readFileSync10(lockfilePath, "utf-8") : null,
39072
+ lockfile: existsSync15(lockfilePath) ? readFileSync10(lockfilePath, "utf-8") : null,
37205
39073
  packageDir,
37206
39074
  stagedPackageDir,
37207
39075
  tempDir
@@ -37235,8 +39103,8 @@ function stripPackageNameFromPath(pathValue, packageName) {
37235
39103
  return current;
37236
39104
  }
37237
39105
  function removeFromPackageLock(installDir, packageName) {
37238
- const lockPath = join16(installDir, "package-lock.json");
37239
- if (!existsSync14(lockPath))
39106
+ const lockPath = join17(installDir, "package-lock.json");
39107
+ if (!existsSync15(lockPath))
37240
39108
  return false;
37241
39109
  try {
37242
39110
  const lock = import_comment_json3.parse(readFileSync10(lockPath, "utf-8"));
@@ -37262,7 +39130,7 @@ function removeFromPackageLock(installDir, packageName) {
37262
39130
  }
37263
39131
  }
37264
39132
  function ensureDependencyVersion(packageJsonPath, packageName, version) {
37265
- if (!existsSync14(packageJsonPath))
39133
+ if (!existsSync15(packageJsonPath))
37266
39134
  return false;
37267
39135
  try {
37268
39136
  const raw = import_comment_json3.parse(readFileSync10(packageJsonPath, "utf-8"));
@@ -37291,8 +39159,8 @@ function restorePendingSnapshot(installDir) {
37291
39159
  restoreAutoUpdateSnapshot(snapshot);
37292
39160
  }
37293
39161
  function removeInstalledPackage(installDir, packageName) {
37294
- const packageDir = join16(installDir, "node_modules", packageName);
37295
- if (!existsSync14(packageDir))
39162
+ const packageDir = join17(installDir, "node_modules", packageName);
39163
+ if (!existsSync15(packageDir))
37296
39164
  return false;
37297
39165
  rmSync4(packageDir, { recursive: true, force: true });
37298
39166
  log2(`[auto-update-checker] Package removed: ${packageDir}`);
@@ -37304,15 +39172,15 @@ function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackage
37304
39172
  const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME);
37305
39173
  if (nodeModulesDir && basename3(nodeModulesDir) === "node_modules") {
37306
39174
  const installDir = dirname7(nodeModulesDir);
37307
- const packageJsonPath = join16(installDir, "package.json");
37308
- if (existsSync14(packageJsonPath))
39175
+ const packageJsonPath = join17(installDir, "package.json");
39176
+ if (existsSync15(packageJsonPath))
37309
39177
  return { installDir, packageJsonPath };
37310
39178
  }
37311
39179
  return null;
37312
39180
  }
37313
39181
  const cacheRoot = dirname7(cacheDir());
37314
- const legacyPackageJsonPath = join16(cacheRoot, "package.json");
37315
- if (existsSync14(legacyPackageJsonPath)) {
39182
+ const legacyPackageJsonPath = join17(cacheRoot, "package.json");
39183
+ if (existsSync15(legacyPackageJsonPath)) {
37316
39184
  return { installDir: cacheRoot, packageJsonPath: legacyPackageJsonPath };
37317
39185
  }
37318
39186
  return null;
@@ -37535,7 +39403,7 @@ function claimCheckSlot(storageDir, intervalMs) {
37535
39403
  const replacementPath = `${lockPath}.tmp.${process.pid}`;
37536
39404
  writeFileSync7(replacementPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
37537
39405
  try {
37538
- renameSync6(replacementPath, lockPath);
39406
+ renameSync7(replacementPath, lockPath);
37539
39407
  } catch (replaceError) {
37540
39408
  rmSync5(replacementPath, { force: true });
37541
39409
  throw replaceError;
@@ -37603,7 +39471,7 @@ function checkLockIsOwnedBy(lockPath, owner) {
37603
39471
  }
37604
39472
  }
37605
39473
  function hasRecentCheckTimestamp(file, intervalMs) {
37606
- if (!existsSync15(file))
39474
+ if (!existsSync16(file))
37607
39475
  return false;
37608
39476
  try {
37609
39477
  const raw = JSON.parse(readFileSync11(file, "utf-8"));
@@ -37616,7 +39484,7 @@ function hasRecentCheckTimestamp(file, intervalMs) {
37616
39484
  function writeCheckTimestamp(file) {
37617
39485
  const tmp = `${file}.tmp.${process.pid}`;
37618
39486
  writeFileSync7(tmp, JSON.stringify({ lastCheckedMs: Date.now() }), "utf-8");
37619
- renameSync6(tmp, file);
39487
+ renameSync7(tmp, file);
37620
39488
  }
37621
39489
  async function runStartupCheck(ctx, options) {
37622
39490
  if (options.signal.aborted)
@@ -37713,15 +39581,15 @@ import { spawn as spawn5 } from "node:child_process";
37713
39581
  import { createHash as createHash6 } from "node:crypto";
37714
39582
  import {
37715
39583
  createReadStream,
37716
- existsSync as existsSync17,
39584
+ existsSync as existsSync18,
37717
39585
  mkdirSync as mkdirSync8,
37718
39586
  readFileSync as readFileSync14,
37719
- renameSync as renameSync8,
39587
+ renameSync as renameSync9,
37720
39588
  rmSync as rmSync7,
37721
39589
  statSync as statSync10,
37722
39590
  writeFileSync as writeFileSync9
37723
39591
  } from "node:fs";
37724
- import { join as join19 } from "node:path";
39592
+ import { join as join20 } from "node:path";
37725
39593
 
37726
39594
  // src/lsp-cache.ts
37727
39595
  import { randomUUID as randomUUID3 } from "node:crypto";
@@ -37730,13 +39598,13 @@ import {
37730
39598
  mkdirSync as mkdirSync7,
37731
39599
  openSync as openSync6,
37732
39600
  readFileSync as readFileSync12,
37733
- renameSync as renameSync7,
39601
+ renameSync as renameSync8,
37734
39602
  rmSync as rmSync6,
37735
39603
  statSync as statSync9,
37736
39604
  unlinkSync as unlinkSync6,
37737
39605
  writeFileSync as writeFileSync8
37738
39606
  } from "node:fs";
37739
- import { join as join17 } from "node:path";
39607
+ import { join as join18 } from "node:path";
37740
39608
  function aftCacheBase() {
37741
39609
  return getAftCacheRoot();
37742
39610
  }
@@ -37744,18 +39612,18 @@ function lspCacheRoot() {
37744
39612
  return getAftLspPackagesDir();
37745
39613
  }
37746
39614
  function lspPackageDir(npmPackage) {
37747
- return join17(lspCacheRoot(), encodeURIComponent(npmPackage));
39615
+ return join18(lspCacheRoot(), encodeURIComponent(npmPackage));
37748
39616
  }
37749
39617
  function lspBinaryPath(npmPackage, binary) {
37750
- return join17(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
39618
+ return join18(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
37751
39619
  }
37752
39620
  function lspBinDir(npmPackage) {
37753
- return join17(lspPackageDir(npmPackage), "node_modules", ".bin");
39621
+ return join18(lspPackageDir(npmPackage), "node_modules", ".bin");
37754
39622
  }
37755
39623
  function isInstalled(npmPackage, binary) {
37756
39624
  for (const candidate of lspBinaryCandidates(binary)) {
37757
39625
  try {
37758
- if (statSync9(join17(lspBinDir(npmPackage), candidate)).isFile())
39626
+ if (statSync9(join18(lspBinDir(npmPackage), candidate)).isFile())
37759
39627
  return true;
37760
39628
  } catch {}
37761
39629
  }
@@ -37775,13 +39643,13 @@ function writeInstalledMetaIn(installDir, version, sha256) {
37775
39643
  installedAt: new Date().toISOString(),
37776
39644
  ...sha256 ? { sha256 } : {}
37777
39645
  };
37778
- writeFileSync8(join17(installDir, INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
39646
+ writeFileSync8(join18(installDir, INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
37779
39647
  } catch (err) {
37780
39648
  log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
37781
39649
  }
37782
39650
  }
37783
39651
  function readInstalledMetaIn(installDir) {
37784
- const path = join17(installDir, INSTALLED_META_FILE);
39652
+ const path = join18(installDir, INSTALLED_META_FILE);
37785
39653
  try {
37786
39654
  if (!statSync9(path).isFile())
37787
39655
  return null;
@@ -37805,7 +39673,7 @@ function readInstalledMeta(packageKey) {
37805
39673
  return readInstalledMetaIn(lspPackageDir(packageKey));
37806
39674
  }
37807
39675
  function lockPath(npmPackage) {
37808
- return join17(lspPackageDir(npmPackage), ".aft-installing");
39676
+ return join18(lspPackageDir(npmPackage), ".aft-installing");
37809
39677
  }
37810
39678
  var STALE_LOCK_MS2 = 30 * 60 * 1000;
37811
39679
  function acquireInstallLock(lockKey) {
@@ -37936,7 +39804,7 @@ var AUTO_INSTALL_STAMP_FILE = "last-lsp-autoinstall.json";
37936
39804
  var AUTO_INSTALL_WINDOW_MS = 60 * 1000;
37937
39805
  var AUTO_INSTALL_LOCK_STALE_MS = 30 * 60 * 1000;
37938
39806
  function autoInstallStampPath() {
37939
- return join17(aftCacheBase(), AUTO_INSTALL_STAMP_FILE);
39807
+ return join18(aftCacheBase(), AUTO_INSTALL_STAMP_FILE);
37940
39808
  }
37941
39809
  function hasRecentAutoInstallStamp(path) {
37942
39810
  try {
@@ -38022,7 +39890,7 @@ function claimLspAutoInstallPass() {
38022
39890
  encoding: "utf8",
38023
39891
  mode: 384
38024
39892
  });
38025
- renameSync7(tempPath, stampPath);
39893
+ renameSync8(tempPath, stampPath);
38026
39894
  return { release };
38027
39895
  } catch (err) {
38028
39896
  if (claimed) {
@@ -38037,7 +39905,7 @@ function claimLspAutoInstallPass() {
38037
39905
  }
38038
39906
  var VERSION_CHECK_FILE = ".aft-version-check";
38039
39907
  function readVersionCheck(npmPackage) {
38040
- const file = join17(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
39908
+ const file = join18(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
38041
39909
  try {
38042
39910
  const raw = readFileSync12(file, "utf8");
38043
39911
  const parsed = JSON.parse(raw);
@@ -38054,7 +39922,7 @@ function readVersionCheck(npmPackage) {
38054
39922
  }
38055
39923
  function writeVersionCheck(npmPackage, latest) {
38056
39924
  mkdirSync7(lspPackageDir(npmPackage), { recursive: true });
38057
- const file = join17(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
39925
+ const file = join18(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
38058
39926
  const record = {
38059
39927
  last_checked: new Date().toISOString(),
38060
39928
  latest_eligible: latest
@@ -38216,8 +40084,8 @@ var NPM_LSP_TABLE = [
38216
40084
  ];
38217
40085
 
38218
40086
  // src/lsp-project-relevance.ts
38219
- import { existsSync as existsSync16, readdirSync as readdirSync4, readFileSync as readFileSync13 } from "node:fs";
38220
- import { join as join18 } from "node:path";
40087
+ import { existsSync as existsSync17, readdirSync as readdirSync4, readFileSync as readFileSync13 } from "node:fs";
40088
+ import { join as join19 } from "node:path";
38221
40089
  var MAX_WALK_DIRS = 200;
38222
40090
  var MAX_WALK_DEPTH = 4;
38223
40091
  var NOISE_DIRS = new Set([
@@ -38234,7 +40102,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
38234
40102
  if (!rootMarkers)
38235
40103
  return false;
38236
40104
  for (const marker of rootMarkers) {
38237
- if (existsSync16(join18(projectRoot, marker)))
40105
+ if (existsSync17(join19(projectRoot, marker)))
38238
40106
  return true;
38239
40107
  }
38240
40108
  return false;
@@ -38258,7 +40126,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
38258
40126
  }
38259
40127
  function readPackageJson(projectRoot) {
38260
40128
  try {
38261
- const raw = readFileSync13(join18(projectRoot, "package.json"), "utf8");
40129
+ const raw = readFileSync13(join19(projectRoot, "package.json"), "utf8");
38262
40130
  const parsed = JSON.parse(raw);
38263
40131
  if (typeof parsed !== "object" || parsed === null)
38264
40132
  return null;
@@ -38288,7 +40156,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
38288
40156
  for (const entry of entries) {
38289
40157
  if (entry.isDirectory()) {
38290
40158
  if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
38291
- queue.push({ dir: join18(current.dir, entry.name), depth: current.depth + 1 });
40159
+ queue.push({ dir: join19(current.dir, entry.name), depth: current.depth + 1 });
38292
40160
  }
38293
40161
  continue;
38294
40162
  }
@@ -38416,8 +40284,8 @@ async function resolveTargetVersion(spec, config, fetchImpl = fetch) {
38416
40284
  }
38417
40285
  function ensureInstallAnchor(cwd) {
38418
40286
  try {
38419
- const stub = join19(cwd, "package.json");
38420
- if (!existsSync17(stub)) {
40287
+ const stub = join20(cwd, "package.json");
40288
+ if (!existsSync18(stub)) {
38421
40289
  writeFileSync9(stub, `${JSON.stringify({ name: "aft-lsp-cache", version: "0.0.0", private: true })}
38422
40290
  `);
38423
40291
  }
@@ -38643,12 +40511,12 @@ function sha256OfFileSync(path) {
38643
40511
  }
38644
40512
  function quarantineCachedNpmInstall(spec, reason) {
38645
40513
  const packageDir = lspPackageDir(spec.npm);
38646
- const dest = join19(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
40514
+ const dest = join20(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
38647
40515
  warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
38648
40516
  try {
38649
- mkdirSync8(join19(dest, ".."), { recursive: true });
40517
+ mkdirSync8(join20(dest, ".."), { recursive: true });
38650
40518
  rmSync7(dest, { recursive: true, force: true });
38651
- renameSync8(packageDir, dest);
40519
+ renameSync9(packageDir, dest);
38652
40520
  } catch (err) {
38653
40521
  warn2(`[lsp] tofu_mismatch ${spec.npm}: failed to quarantine cache entry: ${err}`);
38654
40522
  }
@@ -38729,26 +40597,26 @@ async function pushLspPathsAfterAutoInstall(pool, projectRoot, cachedBinDirs) {
38729
40597
  }
38730
40598
 
38731
40599
  // src/lsp-github-install.ts
38732
- import { execFileSync as execFileSync2 } from "node:child_process";
40600
+ import { execFileSync as execFileSync3 } from "node:child_process";
38733
40601
  import { createHash as createHash7, randomBytes as randomBytes3 } from "node:crypto";
38734
40602
  import {
38735
40603
  copyFileSync as copyFileSync4,
38736
40604
  createReadStream as createReadStream2,
38737
40605
  createWriteStream as createWriteStream3,
38738
- existsSync as existsSync18,
40606
+ existsSync as existsSync19,
38739
40607
  lstatSync as lstatSync2,
38740
40608
  mkdirSync as mkdirSync9,
38741
40609
  readdirSync as readdirSync5,
38742
40610
  readFileSync as readFileSync15,
38743
40611
  readlinkSync as readlinkSync2,
38744
40612
  realpathSync as realpathSync3,
38745
- renameSync as renameSync9,
40613
+ renameSync as renameSync10,
38746
40614
  rmSync as rmSync8,
38747
40615
  statSync as statSync11,
38748
40616
  unlinkSync as unlinkSync7,
38749
40617
  writeFileSync as writeFileSync10
38750
40618
  } from "node:fs";
38751
- import { dirname as dirname9, join as join20, relative as relative3, resolve as resolve10 } from "node:path";
40619
+ import { dirname as dirname9, join as join21, relative as relative3, resolve as resolve10 } from "node:path";
38752
40620
  import { Readable as Readable3 } from "node:stream";
38753
40621
  import { pipeline as pipeline3 } from "node:stream/promises";
38754
40622
 
@@ -38841,19 +40709,19 @@ function ghCacheRoot() {
38841
40709
  return getAftLspBinariesDir();
38842
40710
  }
38843
40711
  function ghPackageDir(spec) {
38844
- return join20(ghCacheRoot(), spec.id);
40712
+ return join21(ghCacheRoot(), spec.id);
38845
40713
  }
38846
40714
  function ghBinDir(spec) {
38847
- return join20(ghPackageDir(spec), "bin");
40715
+ return join21(ghPackageDir(spec), "bin");
38848
40716
  }
38849
40717
  function ghExtractDir(spec) {
38850
- return join20(ghPackageDir(spec), "extracted");
40718
+ return join21(ghPackageDir(spec), "extracted");
38851
40719
  }
38852
40720
  var INSTALLED_META_FILE2 = ".aft-installed";
38853
40721
  var INSTALL_FAILED_FILE = ".aft-install-failed.json";
38854
40722
  var INSTALL_FAILURE_BACKOFF_MS = 6 * 60 * 60 * 1000;
38855
40723
  function installFailureMarkerPath(spec) {
38856
- return join20(ghPackageDir(spec), INSTALL_FAILED_FILE);
40724
+ return join21(ghPackageDir(spec), INSTALL_FAILED_FILE);
38857
40725
  }
38858
40726
  function readInstallFailureMarker(spec) {
38859
40727
  try {
@@ -38874,7 +40742,7 @@ function writeInstallFailureMarker(spec, release, sha256, installError) {
38874
40742
  mkdirSync9(dirname9(path), { recursive: true });
38875
40743
  writeFileSync10(tempPath, `${JSON.stringify({ release, sha256, error: markerError, at: new Date().toISOString() })}
38876
40744
  `, { encoding: "utf8", mode: 384 });
38877
- renameSync9(tempPath, path);
40745
+ renameSync10(tempPath, path);
38878
40746
  } catch (err) {
38879
40747
  try {
38880
40748
  rmSync8(tempPath, { force: true });
@@ -38895,12 +40763,12 @@ function isFreshInstallFailure(marker) {
38895
40763
  }
38896
40764
  function ghBinaryPath(spec, platform) {
38897
40765
  const ext = platform === "win32" ? ".exe" : "";
38898
- return join20(ghBinDir(spec), `${spec.binary}${ext}`);
40766
+ return join21(ghBinDir(spec), `${spec.binary}${ext}`);
38899
40767
  }
38900
40768
  function isGithubInstalled(spec, platform) {
38901
40769
  for (const candidate of ghBinaryCandidates(spec, platform)) {
38902
40770
  try {
38903
- if (statSync11(join20(ghBinDir(spec), candidate)).isFile())
40771
+ if (statSync11(join21(ghBinDir(spec), candidate)).isFile())
38904
40772
  return true;
38905
40773
  } catch {}
38906
40774
  }
@@ -38913,7 +40781,7 @@ function ghBinaryCandidates(spec, platform) {
38913
40781
  }
38914
40782
  function readGithubInstalledMetaIn(installDir) {
38915
40783
  try {
38916
- const path = join20(installDir, INSTALLED_META_FILE2);
40784
+ const path = join21(installDir, INSTALLED_META_FILE2);
38917
40785
  if (!statSync11(path).isFile())
38918
40786
  return null;
38919
40787
  const parsed = JSON.parse(readFileSync15(path, "utf8"));
@@ -38940,7 +40808,7 @@ function writeGithubInstalledMetaIn(installDir, version, binarySha256, archiveSh
38940
40808
  binarySha256,
38941
40809
  ...archiveSha256 ? { archiveSha256 } : {}
38942
40810
  };
38943
- writeFileSync10(join20(installDir, INSTALLED_META_FILE2), JSON.stringify(meta), "utf8");
40811
+ writeFileSync10(join21(installDir, INSTALLED_META_FILE2), JSON.stringify(meta), "utf8");
38944
40812
  } catch (err) {
38945
40813
  warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
38946
40814
  }
@@ -39189,7 +41057,7 @@ function validateExtraction(stagingRoot) {
39189
41057
  throw new Error(`failed to read staging dir ${dir}: ${err}`);
39190
41058
  }
39191
41059
  for (const entry of entries) {
39192
- const full = join20(dir, entry);
41060
+ const full = join21(dir, entry);
39193
41061
  let lst;
39194
41062
  try {
39195
41063
  lst = lstatSync2(full);
@@ -39235,7 +41103,7 @@ function assertArchiveEntryPath(entry) {
39235
41103
  }
39236
41104
  function precheckWithTar(archivePath, command) {
39237
41105
  let totalBytes = 0;
39238
- const verbose = execFileSync2(command, ["-tvf", archivePath], { encoding: "utf8" });
41106
+ const verbose = execFileSync3(command, ["-tvf", archivePath], { encoding: "utf8" });
39239
41107
  for (const line of verbose.split(`
39240
41108
  `)) {
39241
41109
  if (line.startsWith("h")) {
@@ -39248,7 +41116,7 @@ function precheckWithTar(archivePath, command) {
39248
41116
  totalBytes += Math.max(...numeric);
39249
41117
  }
39250
41118
  }
39251
- const names = execFileSync2(command, ["-tf", archivePath], { encoding: "utf8" });
41119
+ const names = execFileSync3(command, ["-tf", archivePath], { encoding: "utf8" });
39252
41120
  for (const entry of names.split(`
39253
41121
  `)) {
39254
41122
  if (entry.length > 0)
@@ -39259,19 +41127,18 @@ function precheckWithTar(archivePath, command) {
39259
41127
  function precheckArchiveContents(archivePath, archiveType, zipListingMode = "platform") {
39260
41128
  let totalBytes = 0;
39261
41129
  if (archiveType === "zip" && zipListingMode === "platform" && process.platform !== "win32") {
39262
- const out = execFileSync2("unzip", ["-l", archivePath], { encoding: "utf8" });
41130
+ const out = execFileSync3("unzip", ["-l", archivePath], { encoding: "utf8" });
39263
41131
  const match = out.match(/^\s*(\d+)\s+\d+\s+files?\s*$/m);
39264
41132
  if (match)
39265
41133
  totalBytes = Number.parseInt(match[1] ?? "0", 10);
39266
- const names = execFileSync2("unzip", ["-Z1", archivePath], { encoding: "utf8" });
41134
+ const names = execFileSync3("unzip", ["-Z1", archivePath], { encoding: "utf8" });
39267
41135
  for (const entry of names.split(`
39268
41136
  `)) {
39269
41137
  if (entry.length > 0)
39270
41138
  assertArchiveEntryPath(entry);
39271
41139
  }
39272
41140
  } else {
39273
- const command = process.platform === "win32" ? "tar.exe" : "tar";
39274
- totalBytes = precheckWithTar(archivePath, command);
41141
+ totalBytes = precheckWithTar(archivePath, windowsTarExecutable());
39275
41142
  }
39276
41143
  if (totalBytes > MAX_EXTRACT_BYTES2) {
39277
41144
  throw new Error(`archive uncompressed size ${totalBytes} exceeds ${MAX_EXTRACT_BYTES2}`);
@@ -39291,7 +41158,7 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
39291
41158
  try {
39292
41159
  rmSync8(destDir, { recursive: true, force: true });
39293
41160
  } catch {}
39294
- renameSync9(stagingDir, destDir);
41161
+ renameSync10(stagingDir, destDir);
39295
41162
  } catch (err) {
39296
41163
  try {
39297
41164
  rmSync8(stagingDir, { recursive: true, force: true });
@@ -39301,12 +41168,12 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
39301
41168
  }
39302
41169
  function quarantineCachedGithubInstall(spec, reason) {
39303
41170
  const packageDir = ghPackageDir(spec);
39304
- const dest = join20(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
41171
+ const dest = join21(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
39305
41172
  warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
39306
41173
  try {
39307
41174
  mkdirSync9(dirname9(dest), { recursive: true });
39308
41175
  rmSync8(dest, { recursive: true, force: true });
39309
- renameSync9(packageDir, dest);
41176
+ renameSync10(packageDir, dest);
39310
41177
  } catch (err) {
39311
41178
  warn2(`[lsp] tofu_mismatch ${spec.id}: failed to quarantine cache entry: ${err}`);
39312
41179
  }
@@ -39314,7 +41181,7 @@ function quarantineCachedGithubInstall(spec, reason) {
39314
41181
  function validateCachedGithubInstall(spec, platform) {
39315
41182
  const packageDir = ghPackageDir(spec);
39316
41183
  const meta = readGithubInstalledMetaIn(packageDir);
39317
- const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) => join20(ghBinDir(spec), candidate)).find((candidate) => {
41184
+ const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) => join21(ghBinDir(spec), candidate)).find((candidate) => {
39318
41185
  try {
39319
41186
  return statSync11(candidate).isFile();
39320
41187
  } catch {
@@ -39350,30 +41217,21 @@ function validateCachedGithubInstall(spec, platform) {
39350
41217
  function runPlatformExtractor(archivePath, destDir, archiveType) {
39351
41218
  if (archiveType === "zip") {
39352
41219
  if (process.platform === "win32") {
39353
- execFileSync2("tar.exe", ["-xf", archivePath, "-C", destDir], {
39354
- stdio: "pipe",
39355
- timeout: 180000
39356
- });
41220
+ execTarExtractionSync(["-xf", archivePath, "-C", destDir], 180000);
39357
41221
  return;
39358
41222
  }
39359
- execFileSync2("unzip", ["-q", "-o", archivePath, "-d", destDir], {
41223
+ execFileSync3("unzip", ["-q", "-o", archivePath, "-d", destDir], {
39360
41224
  stdio: "pipe",
39361
41225
  timeout: 180000
39362
41226
  });
39363
41227
  return;
39364
41228
  }
39365
41229
  if (archiveType === "tar.gz") {
39366
- execFileSync2("tar", ["-xzf", archivePath, "-C", destDir], {
39367
- stdio: "pipe",
39368
- timeout: 180000
39369
- });
41230
+ execTarExtractionSync(["-xzf", archivePath, "-C", destDir], 180000);
39370
41231
  return;
39371
41232
  }
39372
41233
  if (archiveType === "tar.xz") {
39373
- execFileSync2("tar", ["-xf", archivePath, "-C", destDir], {
39374
- stdio: "pipe",
39375
- timeout: 180000
39376
- });
41234
+ execTarExtractionSync(["-xf", archivePath, "-C", destDir], 180000);
39377
41235
  return;
39378
41236
  }
39379
41237
  throw new Error(`unsupported archive type: ${archiveType}`);
@@ -39394,7 +41252,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
39394
41252
  }
39395
41253
  const pkgDir = ghPackageDir(spec);
39396
41254
  const extractDir = ghExtractDir(spec);
39397
- const archivePath = join20(pkgDir, expected.name);
41255
+ const archivePath = join21(pkgDir, expected.name);
39398
41256
  log2(`[lsp] downloading ${spec.id} ${tag} → ${matchingAsset.url}`);
39399
41257
  try {
39400
41258
  await downloadFile(matchingAsset.url, archivePath, fetchImpl, matchingAsset.size, signal);
@@ -39436,8 +41294,8 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
39436
41294
  unlinkSync7(archivePath);
39437
41295
  } catch {}
39438
41296
  }
39439
- const innerBinaryPath = join20(extractDir, spec.binaryPathInArchive(platform, arch, version));
39440
- if (!existsSync18(innerBinaryPath)) {
41297
+ const innerBinaryPath = join21(extractDir, spec.binaryPathInArchive(platform, arch, version));
41298
+ if (!existsSync19(innerBinaryPath)) {
39441
41299
  const message = `extracted binary not found at ${innerBinaryPath}`;
39442
41300
  error2(`[lsp] ${spec.id}: ${message}`);
39443
41301
  return { ok: false, sha256: archiveSha256, error: message };
@@ -39542,7 +41400,7 @@ function runGithubAutoInstall(relevantServers, config, fetchImpl = fetch) {
39542
41400
  if (!host) {
39543
41401
  for (const spec of GITHUB_LSP_TABLE) {
39544
41402
  try {
39545
- if (existsSync18(ghBinDir(spec))) {
41403
+ if (existsSync19(ghBinDir(spec))) {
39546
41404
  cachedBinDirs.push(ghBinDir(spec));
39547
41405
  }
39548
41406
  } catch {}
@@ -39859,25 +41717,25 @@ function isTuiConnected(sessionId) {
39859
41717
  // src/shared/rpc-server.ts
39860
41718
  import { randomBytes as randomBytes4, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
39861
41719
  import {
39862
- existsSync as existsSync19,
41720
+ existsSync as existsSync20,
39863
41721
  mkdirSync as mkdirSync10,
39864
41722
  readdirSync as readdirSync6,
39865
41723
  readFileSync as readFileSync16,
39866
- renameSync as renameSync10,
41724
+ renameSync as renameSync11,
39867
41725
  unlinkSync as unlinkSync8,
39868
41726
  writeFileSync as writeFileSync11
39869
41727
  } from "node:fs";
39870
41728
  import { createServer } from "node:http";
39871
- import { dirname as dirname10, join as join22 } from "node:path";
41729
+ import { dirname as dirname10, join as join23 } from "node:path";
39872
41730
 
39873
41731
  // src/shared/rpc-utils.ts
39874
- import { join as join21 } from "node:path";
41732
+ import { join as join22 } from "node:path";
39875
41733
  function projectHash(directory) {
39876
41734
  return projectRootKeyHash(directory);
39877
41735
  }
39878
41736
  function rpcPortFileDir(storageDir, directory) {
39879
41737
  const hash = projectHash(directory);
39880
- return join21(storageDir, "rpc", hash, "ports");
41738
+ return join22(storageDir, "rpc", hash, "ports");
39881
41739
  }
39882
41740
  function isPidAlive(pid) {
39883
41741
  if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0)
@@ -39951,7 +41809,7 @@ class AftRpcServer {
39951
41809
  constructor(storageDir, directory) {
39952
41810
  this.portsDir = rpcPortFileDir(storageDir, directory);
39953
41811
  this.instanceId = randomBytes4(8).toString("hex");
39954
- this.portFilePath = join22(this.portsDir, `${this.instanceId}.json`);
41812
+ this.portFilePath = join23(this.portsDir, `${this.instanceId}.json`);
39955
41813
  }
39956
41814
  handle(method, handler) {
39957
41815
  this.handlers.set(method, handler);
@@ -39981,6 +41839,7 @@ class AftRpcServer {
39981
41839
  });
39982
41840
  this.bunServer = server;
39983
41841
  this.port = server.port ?? 0;
41842
+ server.unref?.();
39984
41843
  this.afterServerStarted();
39985
41844
  return this.port;
39986
41845
  }
@@ -40026,7 +41885,7 @@ class AftRpcServer {
40026
41885
  pid: process.pid,
40027
41886
  started_at: Date.now()
40028
41887
  }), { encoding: "utf-8", mode: 384 });
40029
- renameSync10(tmpPath, this.portFilePath);
41888
+ renameSync11(tmpPath, this.portFilePath);
40030
41889
  }
40031
41890
  sweepDeadPortFiles() {
40032
41891
  let entries;
@@ -40038,7 +41897,7 @@ class AftRpcServer {
40038
41897
  for (const entry of entries) {
40039
41898
  if (!entry.endsWith(".json"))
40040
41899
  continue;
40041
- const filePath = join22(this.portsDir, entry);
41900
+ const filePath = join23(this.portsDir, entry);
40042
41901
  if (filePath === this.portFilePath)
40043
41902
  continue;
40044
41903
  try {
@@ -40057,7 +41916,7 @@ class AftRpcServer {
40057
41916
  if (!this.nodeServer && !this.bunServer || this.port <= 0)
40058
41917
  return;
40059
41918
  try {
40060
- if (existsSync19(this.portFilePath))
41919
+ if (existsSync20(this.portFilePath))
40061
41920
  return;
40062
41921
  this.writePortFile();
40063
41922
  log2(`RPC port file was missing; rewrote ${this.portFilePath}`);
@@ -40324,12 +42183,6 @@ function formatCacheRoleLabel(role) {
40324
42183
  }
40325
42184
  return role;
40326
42185
  }
40327
- function formatSemanticIndexStatus(status, stage) {
40328
- if ((status === "loading" || status === "building") && stage === "fingerprint_change") {
40329
- return "Rebuilding (model changed)";
40330
- }
40331
- return status;
40332
- }
40333
42186
  function formatSemanticRefreshing(refreshingCount) {
40334
42187
  if (!Number.isFinite(refreshingCount) || refreshingCount <= 0)
40335
42188
  return null;
@@ -40441,7 +42294,7 @@ function formatStatusMarkdown(status) {
40441
42294
  `- **Cache role:** \`${formatCacheRoleLabel(status.cache_role)}\``
40442
42295
  ];
40443
42296
  appendDegradedStatus(lines, status, true);
40444
- lines.push("", "### Enabled features", `- \`format_on_edit\`: ${formatFlag(status.features.format_on_edit)}`, `- \`search_index\`: ${formatFlag(status.features.search_index)}`, `- \`semantic_search\`: ${formatFlag(status.features.semantic_search)}`, `- \`callgraph_store\`: ${formatFlag(status.features.callgraph_store)}`, "", "### Search index", `- **Status:** \`${status.search_index.status}\``, `- **Files:** ${formatCount(status.search_index.files)}`, `- **Trigrams:** ${formatCount(status.search_index.trigrams)}`, "", "### Semantic index", `- **Status:** \`${formatSemanticIndexStatus(status.semantic_index.status, status.semantic_index.stage)}\``);
42297
+ lines.push("", "### Enabled features", `- \`format_on_edit\`: ${formatFlag(status.features.format_on_edit)}`, `- \`search_index\`: ${formatFlag(status.features.search_index)}`, `- \`semantic_search\`: ${formatFlag(status.features.semantic_search)}`, `- \`callgraph_store\`: ${formatFlag(status.features.callgraph_store)}`, "", "### Search index", `- **Status:** \`${status.search_index.status}\``, `- **Files:** ${formatCount(status.search_index.files)}`, `- **Trigrams:** ${formatCount(status.search_index.trigrams)}`, "", "### Semantic index", `- **Status:** \`${formatSemanticIndexStatus(status.semantic_index.status, status.semantic_index.stage, status.semantic_index.error)}\``);
40445
42298
  const refreshing = formatSemanticRefreshing(status.semantic_index.refreshing_count);
40446
42299
  if (refreshing) {
40447
42300
  lines.push(`- **Refresh:** ${refreshing}`);
@@ -40610,7 +42463,7 @@ function isSyncWatchAborted(sessionID) {
40610
42463
  }
40611
42464
 
40612
42465
  // src/tools/permissions.ts
40613
- import { execFileSync as execFileSync3 } from "node:child_process";
42466
+ import { execFileSync as execFileSync4 } from "node:child_process";
40614
42467
  import * as fs4 from "node:fs";
40615
42468
  import { tmpdir as tmpdir3 } from "node:os";
40616
42469
  import * as path3 from "node:path";
@@ -40865,7 +42718,7 @@ function gitRootForNearestExistingParent(resolved) {
40865
42718
  cwd = path3.dirname(nearest);
40866
42719
  } catch {}
40867
42720
  try {
40868
- const out = execFileSync3("git", ["rev-parse", "--show-toplevel"], {
42721
+ const out = execFileSync4("git", ["rev-parse", "--show-toplevel"], {
40869
42722
  cwd,
40870
42723
  encoding: "utf8",
40871
42724
  stdio: ["ignore", "pipe", "ignore"]
@@ -41178,6 +43031,26 @@ function failure(error) {
41178
43031
  })();
41179
43032
  return new Error(`V2 tool execution rejected with a non-Error value: ${detail}`);
41180
43033
  }
43034
+ function isPlainObject3(value) {
43035
+ if (typeof value !== "object" || value === null)
43036
+ return false;
43037
+ const prototype = Object.getPrototypeOf(value);
43038
+ return prototype === Object.prototype || prototype === null;
43039
+ }
43040
+ function jsonSafeMetadata(value) {
43041
+ if (Array.isArray(value)) {
43042
+ return value.map((entry) => entry === undefined ? null : jsonSafeMetadata(entry));
43043
+ }
43044
+ if (!isPlainObject3(value))
43045
+ return value;
43046
+ const cleaned = {};
43047
+ for (const [key, entry] of Object.entries(value)) {
43048
+ if (entry === undefined)
43049
+ continue;
43050
+ cleaned[key] = jsonSafeMetadata(entry);
43051
+ }
43052
+ return cleaned;
43053
+ }
41181
43054
  function resultContent(result) {
41182
43055
  if (typeof result === "string")
41183
43056
  return { content: result };
@@ -41188,15 +43061,39 @@ function resultContent(result) {
41188
43061
  ...attachment.filename ? { name: attachment.filename } : {}
41189
43062
  }));
41190
43063
  const content = attachments.length ? [{ type: "text", text: result.output }, ...attachments] : result.output;
41191
- const metadata = {
43064
+ const metadata = jsonSafeMetadata({
41192
43065
  ...result.metadata ?? {},
41193
43066
  ...result.title ? { title: result.title } : {}
41194
- };
43067
+ });
41195
43068
  return {
41196
43069
  content,
41197
43070
  ...Object.keys(metadata).length ? { metadata } : {}
41198
43071
  };
41199
43072
  }
43073
+ function failureEnvelopeMessage(result) {
43074
+ const output = typeof result === "string" ? result : result.output;
43075
+ if (typeof output !== "string")
43076
+ return;
43077
+ const trimmed = output.trim();
43078
+ if (!trimmed.startsWith("{") || !trimmed.includes('"success"'))
43079
+ return;
43080
+ let parsed;
43081
+ try {
43082
+ parsed = JSON.parse(trimmed);
43083
+ } catch {
43084
+ return;
43085
+ }
43086
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
43087
+ return;
43088
+ const envelope = parsed;
43089
+ if (envelope.success !== false)
43090
+ return;
43091
+ for (const field of [envelope.message, envelope.error, envelope.code]) {
43092
+ if (typeof field === "string" && field.length > 0)
43093
+ return field;
43094
+ }
43095
+ return "The tool call failed.";
43096
+ }
41200
43097
  function bareToolName3(name) {
41201
43098
  return name.startsWith("aft_") ? name.slice(4) : name;
41202
43099
  }
@@ -41259,15 +43156,15 @@ function runtimeFor(location, context, signal, consumers) {
41259
43156
  abort: signal,
41260
43157
  effectAbort: signal,
41261
43158
  metadata: (update) => {
41262
- Effect.runPromise(context.progress({
43159
+ Effect.runPromise(context.progress(jsonSafeMetadata({
41263
43160
  ...update.metadata ?? {},
41264
43161
  ...update.title ? { title: update.title } : {}
41265
- }));
43162
+ })));
41266
43163
  },
41267
43164
  ask: (request) => {
41268
43165
  if (consumers.requestPermission)
41269
43166
  return consumers.requestPermission(request, context);
41270
- return Promise.reject(new Error(`The "${request.permission}" operation was refused because the OpenCode V2 host did not provide a permission request endpoint.`));
43167
+ return Promise.reject(new Error(`The "${request.permission}" operation was refused because this AFT runtime has no permission evaluator bound, so the host's permission rules for it could not be consulted.`));
41271
43168
  },
41272
43169
  progress: context.progress
41273
43170
  };
@@ -41296,6 +43193,9 @@ function projectV2Tool(name, definition, location, consumers = {}) {
41296
43193
  context: runtime,
41297
43194
  definition
41298
43195
  }) : await definition.execute(input, runtime);
43196
+ const refusal = failureEnvelopeMessage(result);
43197
+ if (refusal)
43198
+ throw new Error(refusal);
41299
43199
  return resultContent(result);
41300
43200
  },
41301
43201
  catch: failure
@@ -42390,7 +44290,7 @@ function createReadTool(ctx) {
42390
44290
  try {
42391
44291
  await runAsk(context.ask({
42392
44292
  permission: "read",
42393
- patterns: [filePath],
44293
+ patterns: [permissionPath(context, filePath)],
42394
44294
  always: ["*"],
42395
44295
  metadata: {}
42396
44296
  }));
@@ -42551,7 +44451,7 @@ function getEditDescription(ctx, writeToolName) {
42551
44451
 
42552
44452
  **Modes** (determined by which parameters you provide):
42553
44453
 
42554
- Provide exactly one mode per call: appendContent, edits[], or symbol plus content. Mixing modes or providing none is rejected — there is no implicit "write" fallback. To edit multiple files, make parallel \`edit\` calls in one response.
44454
+ Provide exactly one mode per call: appendContent, edits[], or symbol plus content. \`symbol\` and \`content\` are only meaningful together; a call carrying one without the other is incomplete. Mixing modes or providing none is rejected — there is no implicit "write" fallback. To edit multiple files, make parallel \`edit\` calls in one response.
42555
44455
 
42556
44456
  1. **Append** — pass \`path\` + \`appendContent\`
42557
44457
  Appends text to the end of a file, creating it if it does not exist.
@@ -42652,8 +44552,8 @@ function createEditTool(ctx, writeToolName = "write") {
42652
44552
  description: getEditDescription(ctx, writeToolName),
42653
44553
  args: {
42654
44554
  filePath: z7.string().describe("Path to the file to edit (absolute or relative to project root)"),
42655
- symbol: z7.string().optional().describe("Named symbol to replace (function, class, type)"),
42656
- content: z7.string().optional().describe("Replacement content for symbol mode. For whole-file writes, use the `write` tool."),
44555
+ symbol: z7.string().optional().describe("Named symbol to replace; only meaningful together with `content`. A call carrying one without the other is incomplete."),
44556
+ content: z7.string().optional().describe("Replacement content for symbol mode; only meaningful together with `symbol`. A call carrying one without the other is incomplete. For whole-file writes, use the `write` tool."),
42657
44557
  appendContent: z7.string().optional().describe("Text to append to the end of path; creates the file if needed"),
42658
44558
  edits: z7.array(z7.object({
42659
44559
  oldString: z7.string().optional().describe("Text to find for a batch find/replace edit"),
@@ -42895,7 +44795,7 @@ function createDeleteTool(ctx) {
42895
44795
  }
42896
44796
  await runAsk(context.ask({
42897
44797
  permission: "edit",
42898
- patterns: absolutePaths,
44798
+ patterns: resolveRelativePatterns(context, absolutePaths),
42899
44799
  always: ["*"],
42900
44800
  metadata: { action: "delete", count: absolutePaths.length }
42901
44801
  }));
@@ -42948,7 +44848,7 @@ function createMoveTool(ctx) {
42948
44848
  }
42949
44849
  await runAsk(context.ask({
42950
44850
  permission: "edit",
42951
- patterns: [filePath, destPath],
44851
+ patterns: resolveRelativePatterns(context, [filePath, destPath]),
42952
44852
  always: ["*"],
42953
44853
  metadata: { action: "move" }
42954
44854
  }));
@@ -43278,7 +45178,7 @@ function inspectTools(ctx) {
43278
45178
  ` + "Treat `dead_code` as a hint, not proof: reachability is call-based, so symbols reached only via method dispatch or referenced only in type position may be false positives — verify before deleting.\n\n" + "When a list is cut, the reply ends with `shown N of M <unit> (<reason>) · narrow: <knobs>`; absence of that line means the list is complete.",
43279
45179
  args: {
43280
45180
  sections: arg(z9.union([z9.string(), z9.array(z9.string())]).optional().describe("Categories to include in detailed drill-down (e.g. 'todos' or ['todos', 'dead_code', 'cycles']). Use 'all' for every active category. Omit for summary-only mode. `sections` changes detail, not the categories verified.")),
43281
- scope: arg(z9.union([z9.string(), z9.array(z9.string())]).optional().describe("Restrict returned results to paths under this scope (file or directory, absolute or relative to project root). `scope=` narrows results and limits Rust LSP startup to owning Cargo workspaces; it does not trigger per-file diagnostic collection. Scoped files no producer has authoritatively analyzed are reported as named gaps (complete: false), never as a clean empty result.")),
45181
+ scope: arg(z9.union([z9.string(), z9.array(z9.string())]).optional().describe("Restrict returned results to paths under this scope (one path, or an array of paths — not a space-separated list; file or directory; absolute or relative to project root). `scope=` narrows results and limits Rust LSP startup to owning Cargo workspaces; it does not trigger per-file diagnostic collection. Scoped files no producer has authoritatively analyzed are reported as named gaps (complete: false), never as a clean empty result.")),
43282
45182
  topK: arg(z9.number().int().positive().max(100).optional().describe("Max drill-down items per category. Default 20, max 100."))
43283
45183
  },
43284
45184
  execute: async (args, context) => {
@@ -43671,7 +45571,7 @@ function safetyTools(ctx) {
43671
45571
  ` + `- 'undo': Undo the entire last tool call when 'path' is omitted (typical), or undo the last edit to one file when 'path' is provided. Note: pops from the undo stack (irreversible, no redo). Use 'history' to inspect per-file history before undoing.
43672
45572
  ` + `- 'history': List all edit snapshots for a file. Requires 'path'.
43673
45573
  ` + `- 'checkpoint': Save a named snapshot. Explicit 'files' may be untracked or gitignored; omit them to snapshot backup-tracked files. Checkpoints are session-scoped and lost on bridge or daemon restart. Requires 'name'.
43674
- ` + `- 'restore': Restore files to a previously saved checkpoint. Requires 'name'.
45574
+ ` + `- 'restore': Restore files to a previously saved checkpoint. Optional 'path'/'files' scopes the restore; omitted scope restores the whole checkpoint. Requires 'name'.
43675
45575
  ` + `- 'list': List all available named checkpoints. No extra params needed.
43676
45576
 
43677
45577
  ` + `Each op requires specific parameters — see parameter descriptions for requirements.
@@ -43679,9 +45579,9 @@ function safetyTools(ctx) {
43679
45579
  ` + "Use checkpoint before risky multi-file changes. Use undo for quick single-file rollback.",
43680
45580
  args: {
43681
45581
  op: z12.enum(["undo", "history", "checkpoint", "restore", "list"]).describe("Safety operation"),
43682
- path: z12.string().optional().describe("File path (required for history, optional for undo). Absolute or relative to project root"),
45582
+ path: z12.string().optional().describe("File path (required for history, optional for undo, optional for restore — restores only that file). Absolute or relative to project root"),
43683
45583
  name: z12.string().optional().describe("Checkpoint name (required for checkpoint, restore)"),
43684
- files: z12.array(z12.string()).optional().describe("Specific files to include in checkpoint (optional, defaults to backup-tracked files; explicit files may be untracked or gitignored)")
45584
+ files: z12.array(z12.string()).optional().describe("Specific files to include in checkpoint, or to restore from a checkpoint (optional; restore without path/files restores the whole checkpoint; explicit checkpoint files may be untracked or gitignored)")
43685
45585
  },
43686
45586
  execute: async (args, context) => {
43687
45587
  const op = args.op;
@@ -44000,7 +45900,7 @@ function semanticTools(ctx) {
44000
45900
  `),
44001
45901
  args: {
44002
45902
  query: arg3(z13.string().describe("Concept, regex, literal text, filename, or capability to find. Examples: 'fuzzy match with whitespace tolerance', '^export', 'Cargo.lock'.")),
44003
- topK: arg3(optionalInt(1, 100).describe("Number of results (default: 10, max: 100)")),
45903
+ topK: arg3(optionalInt(1, 50).describe("Number of results (default: 10, max: 50)")),
44004
45904
  offset: arg3(optionalInt(0, 1e5).describe("Zero-based result offset (default: 0, max: 100000).")),
44005
45905
  includeTests: arg3(z13.boolean().optional().describe("Include test files (*.test.*, *_test.rs, __tests__/, …) plus test-support, fixture, mock, snapshot, and corpus files. Defaults to false.")),
44006
45906
  path: arg3(z13.string().optional().describe("Only set this to search a different Git project (absolute or ~ path). Omit it for the current configured workspace, including non-Git workspace roots; this is not a subdirectory filter. Unindexed external projects use a bounded lexical fallback."))
@@ -44016,9 +45916,9 @@ function semanticTools(ctx) {
44016
45916
  if (denied)
44017
45917
  return permissionDeniedResponse(denied);
44018
45918
  const rawArgs = { query };
44019
- const topK = coerceOptionalInt(args.topK, "topK", 1, 100);
45919
+ const topK = coerceOptionalInt(args.topK, "topK", 1, 50);
44020
45920
  const offset = coerceOptionalInt(args.offset, "offset", 0, 1e5);
44021
- const includeTests = typeof args.includeTests === "boolean" ? args.includeTests : undefined;
45921
+ const includeTests = !isEmptyParam(args.includeTests) ? coerceBoolean(args.includeTests) : undefined;
44022
45922
  if (topK !== undefined)
44023
45923
  rawArgs.topK = topK;
44024
45924
  if (offset !== undefined)
@@ -44258,11 +46158,11 @@ function throwSentinel(command) {
44258
46158
  throw sentinel;
44259
46159
  }
44260
46160
  var PLUGIN_VERSION = resolvePluginVersion(import.meta.url);
44261
- var ANNOUNCEMENT_VERSION = "0.56.0";
46161
+ var ANNOUNCEMENT_VERSION = "0.57.0";
44262
46162
  var ANNOUNCEMENT_FEATURES = [
44263
- "Callgraph stays consistent under load: edits arriving mid-rebuild can no longer be silently lost from navigation results.",
44264
- "aft_zoom handles real-world .jsonc: files with comment banners above the opening brace now resolve, and not-found errors point at the segment that actually failed (thanks @iceteaSA).",
44265
- "Disk hygiene: stale per-checkout inspect caches from old worktrees are now swept automatically — one machine reclaimed 21 GB."
46163
+ "OpenCode 2 is supported: tools, permission prompts, the sidebar and cancellation all work on the GA host, and an end-to-end matrix guards them.",
46164
+ "`doctor` configures a machine that has only OpenCode 2 installed, and `--fix` no longer skips unrelated repairs when it cannot decide the generation.",
46165
+ "A code-health scan no longer starts while the same project is still building its call graph, which cost about 90 MB of peak memory on large repositories."
44266
46166
  ];
44267
46167
  var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
44268
46168
  var plugin = async (input) => initializePluginForDirectory(input);
@@ -44934,7 +46834,7 @@ Install: ${getManualInstallHint()}`).catch(() => {});
44934
46834
  var src_default = plugin;
44935
46835
 
44936
46836
  // src/entry/server-runtime.mjs
44937
- import { Effect as Effect5 } from "effect";
46837
+ import { Effect as Effect6 } from "effect";
44938
46838
 
44939
46839
  // src/rpc/register.ts
44940
46840
  import { Effect as Effect2 } from "effect";
@@ -45137,6 +47037,8 @@ function registerAftRpc(context, location, pool) {
45137
47037
  }
45138
47038
 
45139
47039
  // src/permissions/v2.ts
47040
+ import { Effect as Effect3 } from "effect";
47041
+
45140
47042
  class PermissionDeniedError extends Error {
45141
47043
  name = "PermissionDeniedError";
45142
47044
  }
@@ -45144,6 +47046,107 @@ class PermissionDeniedError extends Error {
45144
47046
  class PermissionRejectedError extends Error {
45145
47047
  name = "PermissionRejectedError";
45146
47048
  }
47049
+
47050
+ class PermissionPromptUnavailableError extends Error {
47051
+ name = "PermissionPromptUnavailableError";
47052
+ }
47053
+
47054
+ class PermissionPromptUnansweredError extends Error {
47055
+ name = "PermissionPromptUnansweredError";
47056
+ }
47057
+
47058
+ class PermissionRulesUnavailableError extends Error {
47059
+ name = "PermissionRulesUnavailableError";
47060
+ }
47061
+ var V2_PROMPT_REPLY_TIMEOUT_MS = 10 * 60000;
47062
+ var V2_PROMPT_LISTEN_TIMEOUT_MS = 5000;
47063
+ function wildcardMatch(input, pattern) {
47064
+ const normalized = input.replaceAll("\\", "/");
47065
+ let escaped = pattern.replaceAll("\\", "/").replaceAll(/[.+^${}()|[\]\\]/g, "\\$&").replaceAll(/\*/g, ".*").replaceAll(/\?/g, ".");
47066
+ if (escaped.endsWith(" .*"))
47067
+ escaped = `${escaped.slice(0, -3)}( .*)?`;
47068
+ return new RegExp(`^${escaped}$`, process.platform === "win32" ? "si" : "s").test(normalized);
47069
+ }
47070
+ function matchingRule(action, resource, rules) {
47071
+ for (let index = rules.length - 1;index >= 0; index -= 1) {
47072
+ const rule = rules[index];
47073
+ if (rule && wildcardMatch(action, rule.action) && wildcardMatch(resource, rule.resource)) {
47074
+ return rule;
47075
+ }
47076
+ }
47077
+ return { action, resource: "*", effect: "ask" };
47078
+ }
47079
+ function decidePermission(request, rules) {
47080
+ for (const resource of request.patterns) {
47081
+ const rule = matchingRule(request.permission, resource, rules);
47082
+ if (rule.effect === "deny")
47083
+ return { effect: "deny", resource, rule };
47084
+ }
47085
+ for (const resource of request.patterns) {
47086
+ const rule = matchingRule(request.permission, resource, rules);
47087
+ if (rule.effect === "ask")
47088
+ return { effect: "ask", resource, rule };
47089
+ }
47090
+ return { effect: "allow" };
47091
+ }
47092
+ function detail(error) {
47093
+ return error instanceof Error ? error.message : String(error);
47094
+ }
47095
+ async function runHostEffect(effect) {
47096
+ return await Effect3.runPromise(effect);
47097
+ }
47098
+ async function sessionRecord(host, sessionID) {
47099
+ if (!sessionID)
47100
+ return;
47101
+ try {
47102
+ return await runHostEffect(host.session.get({ sessionID }));
47103
+ } catch (error) {
47104
+ throw new PermissionRulesUnavailableError(`reading session ${JSON.stringify(sessionID)} failed: ${detail(error)}`);
47105
+ }
47106
+ }
47107
+ async function agentRules(host, agentID) {
47108
+ let record;
47109
+ try {
47110
+ record = (await runHostEffect(host.agent.get({ agentID }))).data;
47111
+ } catch (error) {
47112
+ throw new PermissionRulesUnavailableError(`reading agent ${JSON.stringify(agentID)} failed: ${detail(error)}`);
47113
+ }
47114
+ if (!record.permissions) {
47115
+ throw new PermissionRulesUnavailableError(`agent ${JSON.stringify(agentID)} reported no permission rules`);
47116
+ }
47117
+ return record.permissions;
47118
+ }
47119
+ async function configuredRules(host, context) {
47120
+ const session = await sessionRecord(host, context.sessionID);
47121
+ const agentID = context.agent ?? session?.agent;
47122
+ if (!agentID) {
47123
+ throw new PermissionRulesUnavailableError("the tool call carried no agent identifier and its session named none");
47124
+ }
47125
+ return [...await agentRules(host, agentID), ...session?.permissions ?? []];
47126
+ }
47127
+ function describeRule(rule) {
47128
+ if (!rule)
47129
+ return "no matching rule";
47130
+ return `${JSON.stringify(rule.action)} on ${JSON.stringify(rule.resource)} is ${JSON.stringify(rule.effect)}`;
47131
+ }
47132
+ function deniedMessage(request, decision) {
47133
+ return `Permission denied: this session's permission rules deny ${JSON.stringify(request.permission)}` + `${decision.resource === undefined ? "" : ` for ${JSON.stringify(decision.resource)}`}` + ` (${describeRule(decision.rule)}).`;
47134
+ }
47135
+ function promptUnavailableMessage(request, decision, observed) {
47136
+ const resource = decision.resource ?? "*";
47137
+ return `The ${JSON.stringify(request.permission)} operation needs interactive approval: this ` + `session's permission rules resolve it to "ask" for ${JSON.stringify(resource)}, and AFT ` + `could not reach the OpenCode service to raise a prompt (${observed}). Start OpenCode's ` + "background service and retry, or run it without a prompt by adding " + `{"action": ${JSON.stringify(request.permission)}, "resource": ${JSON.stringify(resource)}, ` + '"effect": "allow"} to the "permissions" list of the agent or session in your OpenCode config.';
47138
+ }
47139
+ function promptUnansweredMessage(request, decision, observed) {
47140
+ const resource = decision.resource ?? "*";
47141
+ return `The ${JSON.stringify(request.permission)} operation was refused: this session's permission ` + `rules resolve it to "ask" for ${JSON.stringify(resource)}, AFT raised a prompt and received ` + `no reply (${observed}), so nothing was permitted. Answer the prompt and run the operation ` + "again, or run it without a prompt by adding " + `{"action": ${JSON.stringify(request.permission)}, "resource": ${JSON.stringify(resource)}, ` + '"effect": "allow"} to the "permissions" list of the agent or session in your OpenCode config.';
47142
+ }
47143
+ function waitDuration(ms) {
47144
+ if (ms >= 60000 && ms % 60000 === 0)
47145
+ return `${ms / 60000}m`;
47146
+ if (ms >= 1000 && ms % 1000 === 0)
47147
+ return `${ms / 1000}s`;
47148
+ return `${ms}ms`;
47149
+ }
45147
47150
  function requiredContextID(context, key) {
45148
47151
  const value = context[key];
45149
47152
  if (typeof value !== "string" || value.length === 0) {
@@ -45168,43 +47171,117 @@ function repliedEvent(event) {
45168
47171
  const candidate = envelope.payload ?? event;
45169
47172
  if (candidate.type !== "permission.replied")
45170
47173
  return;
45171
- if (!candidate.properties || typeof candidate.properties !== "object")
47174
+ if (!candidate.data || typeof candidate.data !== "object")
45172
47175
  return;
45173
- return candidate;
47176
+ return candidate.data;
45174
47177
  }
45175
47178
  async function closeStream(iterator) {
45176
47179
  if (typeof iterator.return === "function")
45177
47180
  await iterator.return();
45178
47181
  }
45179
- async function waitForReply(stream, sessionID, requestID) {
45180
- const iterator = stream[Symbol.asyncIterator]();
47182
+ function pull(iterator) {
47183
+ return iterator.next().then((result) => ({ kind: "event", result }), (error) => ({ kind: "failed", error }));
47184
+ }
47185
+ function countdown(ms) {
47186
+ let handle;
47187
+ const expired = new Promise((resolve) => {
47188
+ handle = setTimeout(resolve, ms);
47189
+ });
47190
+ return {
47191
+ expired,
47192
+ cancel: () => {
47193
+ if (handle !== undefined)
47194
+ clearTimeout(handle);
47195
+ }
47196
+ };
47197
+ }
47198
+ function cancellation(signal) {
47199
+ if (!signal)
47200
+ return { cancelled: new Promise(() => {}), dispose: () => {} };
47201
+ if (signal.aborted)
47202
+ return { cancelled: Promise.resolve(), dispose: () => {} };
47203
+ let listener;
47204
+ const cancelled = new Promise((resolve) => {
47205
+ listener = () => resolve();
47206
+ signal.addEventListener("abort", listener, { once: true });
47207
+ });
47208
+ return {
47209
+ cancelled,
47210
+ dispose: () => {
47211
+ if (listener)
47212
+ signal.removeEventListener("abort", listener);
47213
+ }
47214
+ };
47215
+ }
47216
+ async function startListening(client, listenTimeoutMs) {
47217
+ let iterator;
47218
+ try {
47219
+ const subscription = await client.event.subscribe();
47220
+ iterator = subscription.stream[Symbol.asyncIterator]();
47221
+ } catch (error) {
47222
+ return { unavailable: `subscribing to the event stream failed: ${detail(error)}` };
47223
+ }
47224
+ const first = pull(iterator);
47225
+ const ready = countdown(listenTimeoutMs);
47226
+ try {
47227
+ const settled = await Promise.race([first, ready.expired.then(() => {
47228
+ return;
47229
+ })]);
47230
+ if (settled?.kind === "failed") {
47231
+ await closeStream(iterator);
47232
+ return { unavailable: `reading the event stream failed: ${detail(settled.error)}` };
47233
+ }
47234
+ } finally {
47235
+ ready.cancel();
47236
+ }
47237
+ return { iterator, first };
47238
+ }
47239
+ async function waitForReply(iterator, first, sessionID, requestID, limits) {
47240
+ const deadline = countdown(limits.replyTimeoutMs);
47241
+ const abort = cancellation(limits.signal);
47242
+ let pending = first;
45181
47243
  try {
45182
47244
  while (true) {
45183
- const next = await iterator.next();
45184
- if (next.done)
45185
- throw new Error("Permission event stream ended before a reply arrived");
45186
- const event = repliedEvent(next.value);
45187
- if (!event || event.properties.sessionID !== sessionID || event.properties.requestID !== requestID) {
47245
+ const next = pending ?? pull(iterator);
47246
+ pending = undefined;
47247
+ const settled = await Promise.race([
47248
+ next,
47249
+ deadline.expired.then(() => ({ kind: "unanswered" })),
47250
+ abort.cancelled.then(() => ({ kind: "cancelled" }))
47251
+ ]);
47252
+ if (settled.kind === "unanswered") {
47253
+ throw new PermissionPromptUnansweredError(`waited ${waitDuration(limits.replyTimeoutMs)} after raising it`);
47254
+ }
47255
+ if (settled.kind === "cancelled") {
47256
+ throw new PermissionPromptUnansweredError("the operation was cancelled while the prompt was still open");
47257
+ }
47258
+ if (settled.kind === "failed") {
47259
+ throw new PermissionPromptUnansweredError(`reading the event stream failed: ${detail(settled.error)}`);
47260
+ }
47261
+ if (settled.result.done) {
47262
+ throw new PermissionPromptUnansweredError("the event stream ended before a reply arrived");
47263
+ }
47264
+ const event = repliedEvent(settled.result.value);
47265
+ if (!event || event.sessionID !== sessionID || event.requestID !== requestID)
45188
47266
  continue;
45189
- }
45190
- if (event.properties.reply === "reject") {
47267
+ if (event.reply === "reject")
45191
47268
  throw new PermissionRejectedError("Permission denied.");
45192
- }
45193
47269
  return;
45194
47270
  }
45195
47271
  } finally {
47272
+ deadline.cancel();
47273
+ abort.dispose();
45196
47274
  await closeStream(iterator);
45197
47275
  }
45198
47276
  }
45199
- async function requestPermission(host, request, context) {
47277
+ async function raisePrompt(client, request, decision, context, limits) {
45200
47278
  const sessionID = requiredContextID(context, "sessionID");
45201
47279
  const messageID = requiredContextID(context, "messageID");
45202
47280
  const id = requiredContextID(context, "id");
45203
- const subscription = await host.client.event.subscribe();
45204
- const iterator = subscription.stream[Symbol.asyncIterator]();
47281
+ const listening = await startListening(client, limits.listenTimeoutMs);
45205
47282
  let streamClaimed = false;
45206
47283
  try {
45207
- const result = createResult(await host.client.permission.create({
47284
+ const result = createResult(await client.permission.create({
45208
47285
  sessionID,
45209
47286
  action: request.permission,
45210
47287
  resources: [...request.patterns],
@@ -45216,25 +47293,343 @@ async function requestPermission(host, request, context) {
45216
47293
  return;
45217
47294
  if (result.effect === "deny")
45218
47295
  throw new PermissionDeniedError("Permission denied.");
47296
+ if ("unavailable" in listening) {
47297
+ throw new PermissionPromptUnavailableError(promptUnavailableMessage(request, decision, listening.unavailable));
47298
+ }
45219
47299
  streamClaimed = true;
45220
- await waitForReply({ [Symbol.asyncIterator]: () => iterator }, sessionID, result.id);
47300
+ try {
47301
+ await waitForReply(listening.iterator, listening.first, sessionID, result.id, limits);
47302
+ } catch (error) {
47303
+ if (!(error instanceof PermissionPromptUnansweredError))
47304
+ throw error;
47305
+ throw new PermissionPromptUnansweredError(promptUnansweredMessage(request, decision, error.message));
47306
+ }
45221
47307
  } finally {
45222
- if (!streamClaimed)
45223
- await closeStream(iterator);
47308
+ if (!streamClaimed && "iterator" in listening)
47309
+ await closeStream(listening.iterator);
47310
+ }
47311
+ }
47312
+ function contextAbortSignal(context) {
47313
+ const candidate = context.abort;
47314
+ return candidate instanceof AbortSignal ? candidate : undefined;
47315
+ }
47316
+ function resolveLimits(context, limits) {
47317
+ return {
47318
+ replyTimeoutMs: limits.replyTimeoutMs ?? V2_PROMPT_REPLY_TIMEOUT_MS,
47319
+ listenTimeoutMs: limits.listenTimeoutMs ?? V2_PROMPT_LISTEN_TIMEOUT_MS,
47320
+ signal: limits.signal ?? contextAbortSignal(context)
47321
+ };
47322
+ }
47323
+ async function requestPermission(host, request, context, prompt, limits = {}) {
47324
+ let rules;
47325
+ try {
47326
+ rules = await configuredRules(host, context);
47327
+ } catch (error) {
47328
+ if (!(error instanceof PermissionRulesUnavailableError))
47329
+ throw error;
47330
+ throw new PermissionRulesUnavailableError(`The ${JSON.stringify(request.permission)} operation was refused because AFT could not ` + `read this session's OpenCode permission rules (${error.message}), so it cannot tell ` + "whether the operation is permitted.");
47331
+ }
47332
+ const decision = decidePermission(request, rules);
47333
+ if (decision.effect === "allow")
47334
+ return;
47335
+ if (decision.effect === "deny")
47336
+ throw new PermissionDeniedError(deniedMessage(request, decision));
47337
+ const channel = await prompt.client();
47338
+ if (!channel.client) {
47339
+ throw new PermissionPromptUnavailableError(promptUnavailableMessage(request, decision, channel.unavailable));
47340
+ }
47341
+ await raisePrompt(channel.client, request, decision, context, resolveLimits(context, limits));
47342
+ }
47343
+
47344
+ // src/permissions/v2-service.ts
47345
+ init_promise();
47346
+
47347
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-txckps9j.js
47348
+ var stderrLimit = 8 * 1024;
47349
+
47350
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-xgnj2w4v.js
47351
+ var timings = new WeakMap;
47352
+ var defaultEnsureTiming2 = {
47353
+ pollInterval: 25,
47354
+ requestTimeout: 2000,
47355
+ spawnDelay: 5000,
47356
+ maxSpawnDelay: 30000,
47357
+ promiseTimeout: 120000,
47358
+ stopPollInterval: 50,
47359
+ stopPollAttempts: 100
47360
+ };
47361
+
47362
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-sxt88q69.js
47363
+ function matchesVersion2(version, options) {
47364
+ if (options.version === undefined)
47365
+ return true;
47366
+ if (version === undefined)
47367
+ return false;
47368
+ if (typeof options.version === "function")
47369
+ return options.version(version);
47370
+ return version === options.version;
47371
+ }
47372
+
47373
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/chunks/service-rg0h87gt.js
47374
+ init_service_9rqn6x4v();
47375
+ import { readFile, rename as rename2, rm as rm2, writeFile } from "node:fs/promises";
47376
+ var exports_pty_handoff = {};
47377
+ __export2(exports_pty_handoff, {
47378
+ PtyHandoff: () => exports_pty_handoff,
47379
+ clear: () => clear2,
47380
+ complete: () => complete2,
47381
+ environment: () => environment2,
47382
+ prepare: () => prepare2
47383
+ });
47384
+ async function prepare2(file, info, timeout) {
47385
+ const existing = await read(file);
47386
+ if (existing !== undefined && existing.expiresAt > Date.now() && same(existing.source, info))
47387
+ return;
47388
+ await Promise.resolve().then(() => init_promise());
47389
+ const client = exports_client.make({
47390
+ baseUrl: info.url,
47391
+ headers: info.password === undefined ? undefined : { authorization: "Basic " + Buffer.from(`opencode:${info.password}`).toString("base64") }
47392
+ });
47393
+ const missing = (error) => error instanceof ClientError2 && error.reason === "UnexpectedStatus" && typeof error.cause === "object" && error.cause !== null && ("status" in error.cause) && error.cause.status === 404;
47394
+ const result = await client.experimental.persistentPty.handoff({ signal: AbortSignal.timeout(timeout) }).then((value) => ({ value }), (cause) => ({ cause }));
47395
+ if ("cause" in result) {
47396
+ const concurrent = await read(file);
47397
+ if (concurrent !== undefined && concurrent.expiresAt > Date.now() && same(concurrent.source, info))
47398
+ return;
47399
+ if (!missing(result.cause))
47400
+ throw new Error("Failed to prepare persistent terminals for service replacement", { cause: result.cause });
47401
+ console.warn("Background service cannot hand off persistent terminals; shutting them down before replacement");
47402
+ await client.experimental.persistentPty.shutdown({ signal: AbortSignal.timeout(timeout) }).catch((cause) => {
47403
+ if (missing(cause))
47404
+ return;
47405
+ throw new Error("Failed to shut down persistent terminals before service replacement", { cause });
47406
+ });
47407
+ await publish(file, info, null);
47408
+ return;
47409
+ }
47410
+ const body = result.value;
47411
+ if (typeof body !== "object" || body === null || !("handoff" in body))
47412
+ throw new Error("Invalid persistent terminal handoff response");
47413
+ if (body.handoff === null) {
47414
+ await publish(file, info, null);
47415
+ return;
47416
+ }
47417
+ if (!isHandoff(body.handoff) || body.handoff.expiresAt <= Date.now())
47418
+ throw new Error("Invalid or expired persistent terminal handoff");
47419
+ await publish(file, info, body.handoff);
47420
+ }
47421
+ async function publish(file, info, handoff) {
47422
+ const temporary = `${file}.pty-handoff.${crypto.randomUUID()}.tmp`;
47423
+ await writeFile(temporary, JSON.stringify({
47424
+ source: { id: info.id, pid: info.pid, url: info.url },
47425
+ handoff,
47426
+ expiresAt: handoff?.expiresAt ?? Date.now() + 30000
47427
+ }), { mode: 384, flag: "wx" });
47428
+ await rename2(temporary, file + ".pty-handoff").finally(() => rm2(temporary, { force: true }));
47429
+ }
47430
+ async function environment2(file, env) {
47431
+ const record = await read(file);
47432
+ const current = await readFile(file, "utf8").then((text) => JSON.parse(text)).catch(() => {
47433
+ return;
47434
+ });
47435
+ const handoff = record !== undefined && record.expiresAt > Date.now() && (current === undefined || same(record.source, current)) ? record.handoff : undefined;
47436
+ return { ...env, OPENCODE_PTY_HANDOFF: handoff == null ? undefined : JSON.stringify(handoff) };
47437
+ }
47438
+ async function complete2(file, info) {
47439
+ const record = await read(file);
47440
+ if (record !== undefined && !same(record.source, info))
47441
+ await clear2(file);
47442
+ }
47443
+ async function clear2(file) {
47444
+ await rm2(file + ".pty-handoff", { force: true });
47445
+ }
47446
+ async function read(file) {
47447
+ const value = await readFile(file + ".pty-handoff", "utf8").then((text) => JSON.parse(text)).catch(() => {
47448
+ return;
47449
+ });
47450
+ if (typeof value !== "object" || value === null || !("source" in value) || !("handoff" in value))
47451
+ return;
47452
+ if (typeof value.source !== "object" || value.source === null)
47453
+ return;
47454
+ if (!("pid" in value.source) || typeof value.source.pid !== "number")
47455
+ return;
47456
+ if (!("url" in value.source) || typeof value.source.url !== "string")
47457
+ return;
47458
+ if ("id" in value.source && typeof value.source.id !== "string")
47459
+ return;
47460
+ if (value.handoff !== null && !isHandoff(value.handoff))
47461
+ return;
47462
+ if (!("expiresAt" in value) || typeof value.expiresAt !== "number" || !Number.isFinite(value.expiresAt))
47463
+ return;
47464
+ return {
47465
+ source: {
47466
+ id: "id" in value.source && typeof value.source.id === "string" ? value.source.id : undefined,
47467
+ pid: value.source.pid,
47468
+ url: value.source.url
47469
+ },
47470
+ handoff: value.handoff,
47471
+ expiresAt: value.expiresAt
47472
+ };
47473
+ }
47474
+ function same(left, right) {
47475
+ return left.id === right.id && left.pid === right.pid && left.url === right.url;
47476
+ }
47477
+ function isHandoff(value) {
47478
+ 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);
47479
+ }
47480
+ // ../../node_modules/.bun/@opencode+client@2.0.11+bdc4bbd92cece36b/node_modules/@opencode/client/dist/promise/service.js
47481
+ import { readFile as readFile2, rm as rm3 } from "node:fs/promises";
47482
+ import { homedir as homedir13 } from "node:os";
47483
+ import { join as join25 } from "node:path";
47484
+ async function discover(options = {}) {
47485
+ const found = (await registered(options.file)).service;
47486
+ if (found?.state !== "ready")
47487
+ return;
47488
+ if (!found.compatible)
47489
+ return;
47490
+ if (!matchesVersion2(found.version, options))
47491
+ return;
47492
+ return found.endpoint;
47493
+ }
47494
+ function fallback() {
47495
+ return join25(process.env["XDG_STATE_HOME"] ?? join25(homedir13(), ".local", "state"), "opencode", "service.json");
47496
+ }
47497
+ function headers(endpoint) {
47498
+ if (endpoint.auth === undefined)
47499
+ return;
47500
+ return {
47501
+ authorization: "Basic " + Buffer.from(endpoint.auth.username + ":" + endpoint.auth.password).toString("base64")
47502
+ };
47503
+ }
47504
+ async function read2(file) {
47505
+ const text = await readFile2(file ?? fallback(), "utf8").catch(() => {
47506
+ return;
47507
+ });
47508
+ if (text === undefined)
47509
+ return;
47510
+ try {
47511
+ return JSON.parse(text);
47512
+ } catch {
47513
+ return;
45224
47514
  }
45225
47515
  }
47516
+ async function probeResult(info, timeout = defaultEnsureTiming2.requestTimeout) {
47517
+ const endpoint = {
47518
+ url: info.url,
47519
+ auth: info.password === undefined ? undefined : { type: "basic", username: "opencode", password: info.password }
47520
+ };
47521
+ const signal = AbortSignal.timeout(timeout);
47522
+ const result = await fetch(new URL("/api/info", info.url), { headers: headers(endpoint), signal }).then(async (response) => ({
47523
+ response,
47524
+ body: response.status === 404 ? undefined : await response.json()
47525
+ })).then((value) => ({ value }), (cause) => ({ cause }));
47526
+ if ("cause" in result)
47527
+ return { service: undefined, timedOut: signal.aborted };
47528
+ const response = result.value.response;
47529
+ if (response.status === 404)
47530
+ return {
47531
+ service: {
47532
+ info,
47533
+ endpoint,
47534
+ version: info.version,
47535
+ state: "ready",
47536
+ compatible: false
47537
+ },
47538
+ timedOut: false
47539
+ };
47540
+ const serverInfo = decodeInfo(result.value.body);
47541
+ if (serverInfo !== undefined) {
47542
+ if (serverInfo.pid !== info.pid)
47543
+ return { service: undefined, timedOut: false };
47544
+ if (info.version !== undefined && serverInfo.version !== info.version)
47545
+ return { service: undefined, timedOut: false };
47546
+ return {
47547
+ service: {
47548
+ info,
47549
+ endpoint,
47550
+ version: serverInfo.version,
47551
+ state: response.ok ? "ready" : response.status === 500 ? "failed" : "waiting",
47552
+ compatible: true
47553
+ },
47554
+ timedOut: false
47555
+ };
47556
+ }
47557
+ return { service: undefined, timedOut: false };
47558
+ }
47559
+ function decodeInfo(input) {
47560
+ if (typeof input !== "object" || input === null)
47561
+ return;
47562
+ if (!("version" in input) || typeof input.version !== "string")
47563
+ return;
47564
+ if (!("pid" in input) || typeof input.pid !== "number" || !Number.isInteger(input.pid) || input.pid < 0)
47565
+ return;
47566
+ return { version: input.version, pid: input.pid };
47567
+ }
47568
+ async function registered(file, timeout) {
47569
+ const info = await read2(file);
47570
+ if (info === undefined)
47571
+ return { info: undefined, service: undefined, timedOut: false };
47572
+ return { info, ...await probeResult(info, timeout) };
47573
+ }
47574
+
47575
+ // src/permissions/v2-service.ts
47576
+ function detail2(error) {
47577
+ return error instanceof Error ? error.message : String(error);
47578
+ }
47579
+ function promptClient(endpoint) {
47580
+ const client = exports_client.make({ baseUrl: endpoint.url, headers: headers(endpoint) });
47581
+ return {
47582
+ permission: {
47583
+ create: (input) => client.permission.create(input)
47584
+ },
47585
+ event: {
47586
+ subscribe: async () => ({ stream: client.event.subscribe() })
47587
+ }
47588
+ };
47589
+ }
47590
+ async function discoverPromptClient() {
47591
+ let endpoint;
47592
+ try {
47593
+ endpoint = await discover();
47594
+ } catch (error) {
47595
+ return { unavailable: `looking up the local OpenCode service failed: ${detail2(error)}` };
47596
+ }
47597
+ if (!endpoint) {
47598
+ return { unavailable: "no healthy, compatible local OpenCode service is registered" };
47599
+ }
47600
+ return { client: promptClient(endpoint) };
47601
+ }
47602
+ function createV2PromptChannel(discovery = discoverPromptClient) {
47603
+ let cached;
47604
+ return {
47605
+ async client() {
47606
+ if (cached)
47607
+ return { client: cached };
47608
+ const result = await discovery();
47609
+ if (result.client)
47610
+ cached = result.client;
47611
+ return result;
47612
+ }
47613
+ };
47614
+ }
45226
47615
 
45227
47616
  // src/tools/hoisted/v2.ts
45228
- function hoistedV2ToolConsumers(host) {
45229
- if (!("client" in host))
47617
+ function domainMethod(host, domain, method) {
47618
+ const value = host[domain];
47619
+ if (!value || typeof value !== "object")
47620
+ return false;
47621
+ return typeof value[method] === "function";
47622
+ }
47623
+ function hoistedV2ToolConsumers(host, prompt = createV2PromptChannel()) {
47624
+ if (!domainMethod(host, "agent", "get") || !domainMethod(host, "session", "get"))
45230
47625
  return {};
45231
47626
  return {
45232
- requestPermission: (request, context) => requestPermission(host, request, context)
47627
+ requestPermission: (request, context) => requestPermission(host, request, context, prompt)
45233
47628
  };
45234
47629
  }
45235
47630
 
45236
47631
  // src/wakes/runtime-consumer.ts
45237
- import { Effect as Effect4 } from "effect";
47632
+ import { Effect as Effect5 } from "effect";
45238
47633
 
45239
47634
  // src/cancellation/effect-abort.ts
45240
47635
  function forwardEffectAbort(signal, send) {
@@ -45283,7 +47678,7 @@ async function executeV2Bash(execution) {
45283
47678
  }
45284
47679
 
45285
47680
  // src/wakes/session-delivery.ts
45286
- import { Effect as Effect3 } from "effect";
47681
+ import { Effect as Effect4 } from "effect";
45287
47682
 
45288
47683
  class V2SessionDelivery {
45289
47684
  session;
@@ -45293,12 +47688,12 @@ class V2SessionDelivery {
45293
47688
  this.session = session;
45294
47689
  }
45295
47690
  completion(input) {
45296
- return Effect3.suspend(() => {
47691
+ return Effect4.suspend(() => {
45297
47692
  if (this.disposed)
45298
- return Effect3.succeed(false);
47693
+ return Effect4.succeed(false);
45299
47694
  const keys = [...new Set(input.taskIDs)].map((taskID) => `${input.sessionID}\x00${taskID}`);
45300
47695
  if (keys.length === 0 || keys.every((key) => this.admittedCompletions.has(key))) {
45301
- return Effect3.succeed(false);
47696
+ return Effect4.succeed(false);
45302
47697
  }
45303
47698
  for (const key of keys)
45304
47699
  this.admittedCompletions.add(key);
@@ -45310,20 +47705,20 @@ class V2SessionDelivery {
45310
47705
  ...input.metadata,
45311
47706
  task_ids: [...new Set(input.taskIDs)]
45312
47707
  }
45313
- }).pipe(Effect3.map(() => true));
47708
+ }).pipe(Effect4.map(() => true));
45314
47709
  });
45315
47710
  }
45316
47711
  status(input) {
45317
- return Effect3.suspend(() => {
47712
+ return Effect4.suspend(() => {
45318
47713
  if (this.disposed)
45319
- return Effect3.succeed(undefined);
47714
+ return Effect4.succeed(undefined);
45320
47715
  return this.session.synthetic({
45321
47716
  sessionID: input.sessionID,
45322
47717
  text: input.text,
45323
47718
  description: input.description,
45324
47719
  metadata: input.metadata,
45325
47720
  resume: false
45326
- }).pipe(Effect3.asVoid);
47721
+ }).pipe(Effect4.asVoid);
45327
47722
  });
45328
47723
  }
45329
47724
  dispose() {
@@ -45340,7 +47735,7 @@ async function routeCompletion(completion, bridge) {
45340
47735
  const route = sessionRoutes.get(completion.session_id);
45341
47736
  if (!route)
45342
47737
  return;
45343
- const admitted = await Effect4.runPromise(route.delivery.completion({
47738
+ const admitted = await Effect5.runPromise(route.delivery.completion({
45344
47739
  sessionID: completion.session_id,
45345
47740
  taskIDs: [completion.task_id],
45346
47741
  text: formatSystemReminder([completion]),
@@ -45362,7 +47757,7 @@ async function routeLongRunning(reminder, _bridge) {
45362
47757
  const route = sessionRoutes.get(reminder.session_id);
45363
47758
  if (!route)
45364
47759
  return;
45365
- await Effect4.runPromise(route.delivery.status({
47760
+ await Effect5.runPromise(route.delivery.status({
45366
47761
  sessionID: reminder.session_id,
45367
47762
  text: formatLongRunningReminder([reminder]),
45368
47763
  description: "Background bash status",
@@ -45460,16 +47855,21 @@ function makeServerEffect(overrides = {}) {
45460
47855
  const dependencies = { ...defaults, ...overrides };
45461
47856
  return (context) => {
45462
47857
  const location = context.location;
45463
- return Effect5.gen(function* () {
45464
- const runtime = yield* Effect5.promise(() => bootLocation(context, location, dependencies));
47858
+ if (typeof location?.directory !== "string") {
47859
+ debug2("V2 effect skipped: host context has no location");
47860
+ return Effect6.void;
47861
+ }
47862
+ log2("AFT V2 runtime starting");
47863
+ return Effect6.gen(function* () {
47864
+ const runtime = yield* Effect6.promise(() => bootLocation(context, location, dependencies));
45465
47865
  if (!runtime)
45466
47866
  return;
45467
- yield* Effect5.addFinalizer(() => Effect5.promise(async () => {
47867
+ yield* Effect6.addFinalizer(() => Effect6.promise(async () => {
45468
47868
  runtime.consumers.dispose?.();
45469
47869
  await dependencies.releaseBridge(runtime.pool);
45470
47870
  }));
45471
47871
  const rpc = yield* dependencies.registerRpc(context, location, runtime.pool);
45472
- yield* Effect5.addFinalizer(() => Effect5.promise(() => rpc.dispose()));
47872
+ yield* Effect6.addFinalizer(() => Effect6.promise(() => rpc.dispose()));
45473
47873
  yield* dependencies.registerTools(context, location, runtime.tools, runtime.consumers);
45474
47874
  });
45475
47875
  };