@cortexkit/aft-opencode 0.56.2 → 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 (39) hide show
  1. package/dist/bg-notifications.d.ts +1 -0
  2. package/dist/bg-notifications.d.ts.map +1 -1
  3. package/dist/entry/server.js +2650 -267
  4. package/dist/index.js +420 -228
  5. package/dist/lsp-github-install.d.ts.map +1 -1
  6. package/dist/permissions/v2-service.d.ts +30 -0
  7. package/dist/permissions/v2-service.d.ts.map +1 -0
  8. package/dist/permissions/v2.d.ts +121 -9
  9. package/dist/permissions/v2.d.ts.map +1 -1
  10. package/dist/shared/rpc-server.d.ts.map +1 -1
  11. package/dist/shared/status.d.ts +8 -1
  12. package/dist/shared/status.d.ts.map +1 -1
  13. package/dist/subc-tool-schemas.d.ts +11 -0
  14. package/dist/subc-tool-schemas.d.ts.map +1 -1
  15. package/dist/tool-registration.d.ts.map +1 -1
  16. package/dist/tools/definitions/v2.d.ts +6 -0
  17. package/dist/tools/definitions/v2.d.ts.map +1 -1
  18. package/dist/tools/hoisted/v2.d.ts +12 -2
  19. package/dist/tools/hoisted/v2.d.ts.map +1 -1
  20. package/dist/tools/hoisted.d.ts.map +1 -1
  21. package/dist/tools/semantic.d.ts.map +1 -1
  22. package/dist/tui/v2-status.d.ts +8 -0
  23. package/dist/tui/v2-status.d.ts.map +1 -1
  24. package/index.js +14 -0
  25. package/package.json +14 -10
  26. package/server.js +8 -0
  27. package/src/shared/rpc-server.ts +5 -0
  28. package/src/shared/status.ts +16 -9
  29. package/src/tui/index.tsx +1 -0
  30. package/src/tui/sidebar-view.tsx +722 -0
  31. package/src/tui/sidebar.tsx +42 -560
  32. package/src/tui/v2-status.ts +8 -1
  33. package/src/tui/v2.tsx +173 -30
  34. package/src/tui-compiled/index.tsx +1 -1
  35. package/src/tui-compiled/sidebar-view.tsx +815 -0
  36. package/src/tui-compiled/sidebar.tsx +45 -693
  37. package/src/tui-compiled/v2-status.ts +8 -1
  38. package/src/tui-compiled/v2.tsx +163 -54
  39. 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() {
@@ -15543,12 +17250,36 @@ function isNpmAvailable(deps = defaultDeps()) {
15543
17250
  return resolveNpm(deps) !== null;
15544
17251
  }
15545
17252
  // ../aft-bridge/dist/onnx-runtime.js
15546
- import { execFileSync } from "node:child_process";
17253
+ import { execFileSync as execFileSync2 } from "node:child_process";
15547
17254
  import { createHash as createHash4 } from "node:crypto";
15548
- 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";
15549
- 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";
15550
17257
  import { Readable as Readable2 } from "node:stream";
15551
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
15552
17283
  var ORT_VERSION = "1.24.4";
15553
17284
  var ORT_REPO = "microsoft/onnxruntime";
15554
17285
  var MAX_DOWNLOAD_BYTES2 = 256 * 1024 * 1024;
@@ -15612,11 +17343,11 @@ function getManualInstallHint() {
15612
17343
  }
15613
17344
  async function ensureOnnxRuntime(storageDir) {
15614
17345
  const info = getPlatformInfo();
15615
- const ortVersionDir = join12(storageDir, "onnxruntime", ORT_VERSION);
17346
+ const ortVersionDir = join13(storageDir, "onnxruntime", ORT_VERSION);
15616
17347
  const libName = info?.libName ?? "libonnxruntime.dylib";
15617
17348
  const resolvedOrtDir = resolveCachedOnnxRuntimeDir(ortVersionDir, libName);
15618
- const libPath = join12(resolvedOrtDir, libName);
15619
- if (existsSync9(libPath)) {
17349
+ const libPath = join13(resolvedOrtDir, libName);
17350
+ if (existsSync10(libPath)) {
15620
17351
  const meta = readOnnxInstalledMeta(ortVersionDir);
15621
17352
  if (meta?.sha256) {
15622
17353
  try {
@@ -15645,9 +17376,9 @@ async function ensureOnnxRuntime(storageDir) {
15645
17376
  warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
15646
17377
  return null;
15647
17378
  }
15648
- const onnxBaseDir = join12(storageDir, "onnxruntime");
17379
+ const onnxBaseDir = join13(storageDir, "onnxruntime");
15649
17380
  mkdirSync5(onnxBaseDir, { recursive: true });
15650
- const lockPath = join12(onnxBaseDir, ONNX_LOCK_FILE);
17381
+ const lockPath = join13(onnxBaseDir, ONNX_LOCK_FILE);
15651
17382
  cleanupAbandonedStagingDirs(onnxBaseDir);
15652
17383
  if (!acquireLock(lockPath)) {
15653
17384
  warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
@@ -15666,7 +17397,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
15666
17397
  for (const entry of entries) {
15667
17398
  if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
15668
17399
  continue;
15669
- const stagingDir = join12(onnxBaseDir, entry);
17400
+ const stagingDir = join13(onnxBaseDir, entry);
15670
17401
  const parts = entry.split(".");
15671
17402
  const pidStr = parts[parts.length - 2];
15672
17403
  const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
@@ -15703,7 +17434,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
15703
17434
  }
15704
17435
  function cleanupIncompleteTargetIfUnowned(ortDir) {
15705
17436
  try {
15706
- if (existsSync9(ortDir) && !existsSync9(join12(ortDir, ONNX_INSTALLED_META_FILE))) {
17437
+ if (existsSync10(ortDir) && !existsSync10(join13(ortDir, ONNX_INSTALLED_META_FILE))) {
15707
17438
  log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
15708
17439
  rmSync3(ortDir, { recursive: true, force: true });
15709
17440
  }
@@ -15747,8 +17478,8 @@ function detectOnnxVersion(libDir, libName) {
15747
17478
  if (version)
15748
17479
  return version;
15749
17480
  }
15750
- const base = join12(libDir, libName);
15751
- if (existsSync9(base)) {
17481
+ const base = join13(libDir, libName);
17482
+ if (existsSync10(base)) {
15752
17483
  try {
15753
17484
  const real = realpathSync2(base);
15754
17485
  const version = parseOnnxVersionFromPath(real) ?? parseOnnxVersionFromDirectoryPath(real);
@@ -15814,10 +17545,10 @@ function directoryContainsLibrary(dir, libName) {
15814
17545
  }
15815
17546
  }
15816
17547
  function resolveCachedOnnxRuntimeDir(ortVersionDir, libName) {
15817
- if (existsSync9(join12(ortVersionDir, libName)))
17548
+ if (existsSync10(join13(ortVersionDir, libName)))
15818
17549
  return ortVersionDir;
15819
- const libSubdir = join12(ortVersionDir, "lib");
15820
- if (existsSync9(join12(libSubdir, libName)))
17550
+ const libSubdir = join13(ortVersionDir, "lib");
17551
+ if (existsSync10(join13(libSubdir, libName)))
15821
17552
  return libSubdir;
15822
17553
  return ortVersionDir;
15823
17554
  }
@@ -15832,13 +17563,13 @@ function findSystemOnnxRuntime(libName) {
15832
17563
  } else if (process.platform === "win32") {
15833
17564
  const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
15834
17565
  const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
15835
- 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"), ...(() => {
15836
17567
  const nugetPaths = [];
15837
17568
  const userProfile = process.env.USERPROFILE ?? "";
15838
17569
  if (!userProfile)
15839
17570
  return nugetPaths;
15840
- const nugetPackageDir = join12(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
15841
- if (!existsSync9(nugetPackageDir))
17571
+ const nugetPackageDir = join13(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
17572
+ if (!existsSync10(nugetPackageDir))
15842
17573
  return nugetPaths;
15843
17574
  try {
15844
17575
  for (const entry of readdirSync3(nugetPackageDir, { withFileTypes: true })) {
@@ -15846,7 +17577,7 @@ function findSystemOnnxRuntime(libName) {
15846
17577
  continue;
15847
17578
  if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
15848
17579
  continue;
15849
- 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"));
15850
17581
  }
15851
17582
  } catch (err) {
15852
17583
  warn(`Failed to scan NuGet ONNX Runtime cache ${nugetPackageDir}: ${err instanceof Error ? err.message : String(err)}`);
@@ -15868,11 +17599,11 @@ function findSystemOnnxRuntime(libName) {
15868
17599
  });
15869
17600
  const unknownVersionPaths = [];
15870
17601
  for (const dir of uniquePaths) {
15871
- const libPath = join12(dir, libName);
17602
+ const libPath = join13(dir, libName);
15872
17603
  if (process.platform === "win32") {
15873
17604
  if (!directoryContainsLibrary(dir, libName))
15874
17605
  continue;
15875
- } else if (!existsSync9(libPath)) {
17606
+ } else if (!existsSync10(libPath)) {
15876
17607
  continue;
15877
17608
  }
15878
17609
  const version = detectOnnxVersion(dir, libName);
@@ -15938,7 +17669,7 @@ function validateExtractedTree(stagingRoot) {
15938
17669
  const walk = (dir) => {
15939
17670
  const entries = readdirSync3(dir);
15940
17671
  for (const entry of entries) {
15941
- const fullPath = join12(dir, entry);
17672
+ const fullPath = join13(dir, entry);
15942
17673
  const lst = lstatSync(fullPath);
15943
17674
  if (lst.isSymbolicLink()) {
15944
17675
  const linkTarget = readlinkSync(fullPath);
@@ -15971,34 +17702,32 @@ async function downloadOnnxRuntime(info, targetDir) {
15971
17702
  const url = `https://github.com/${ORT_REPO}/releases/download/v${ORT_VERSION}/${info.assetName}.${info.archiveType === "tgz" ? "tgz" : "zip"}`;
15972
17703
  log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
15973
17704
  const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
17705
+ const extractionRoot = join13(tmpDir, "extract");
17706
+ const stagedInstallDir = join13(tmpDir, "install");
15974
17707
  try {
15975
- mkdirSync5(tmpDir, { recursive: true });
15976
- const archivePath = join12(tmpDir, `onnxruntime.${info.archiveType}`);
17708
+ mkdirSync5(extractionRoot, { recursive: true });
17709
+ const archivePath = join13(tmpDir, `onnxruntime.${info.archiveType}`);
15977
17710
  await downloadFileWithCap(url, archivePath);
15978
17711
  const archiveSha256 = sha256File(archivePath);
15979
17712
  log(`ONNX Runtime archive sha256=${archiveSha256}`);
15980
17713
  if (info.archiveType === "tgz") {
15981
- execFileSync("tar", ["xzf", archivePath, "-C", tmpDir], {
15982
- stdio: "pipe",
15983
- timeout: 120000
15984
- });
17714
+ execTarExtractionSync(["xzf", archivePath, "-C", extractionRoot], 120000);
15985
17715
  } else {
15986
- await extractZipArchive(archivePath, tmpDir);
17716
+ await extractZipArchive(archivePath, extractionRoot);
15987
17717
  }
15988
17718
  try {
15989
17719
  unlinkSync4(archivePath);
15990
17720
  } catch {}
15991
- validateExtractedTree(tmpDir);
15992
- const extractedDir = join12(tmpDir, info.assetName, "lib");
15993
- if (!existsSync9(extractedDir)) {
17721
+ validateExtractedTree(extractionRoot);
17722
+ const extractedDir = join13(extractionRoot, info.assetName, "lib");
17723
+ if (!existsSync10(extractedDir)) {
15994
17724
  throw new Error(`Expected directory not found: ${extractedDir}`);
15995
17725
  }
15996
- mkdirSync5(targetDir, { recursive: true });
15997
17726
  const libFiles = readdirSync3(extractedDir).filter((f) => f.startsWith("libonnxruntime") || f.startsWith("onnxruntime"));
15998
17727
  const realFiles = [];
15999
17728
  const symlinks = [];
16000
17729
  for (const libFile of libFiles) {
16001
- const src = join12(extractedDir, libFile);
17730
+ const src = join13(extractedDir, libFile);
16002
17731
  try {
16003
17732
  const stat = lstatSync(src);
16004
17733
  log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
@@ -16012,15 +17741,11 @@ async function downloadOnnxRuntime(info, targetDir) {
16012
17741
  realFiles.push(libFile);
16013
17742
  }
16014
17743
  }
16015
- copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks);
16016
- const libPath = join12(targetDir, info.libName);
16017
- let libHash = null;
16018
- try {
16019
- libHash = sha256File(libPath);
16020
- } catch (err) {
16021
- warn(`Could not hash newly-installed ONNX library at ${libPath}: ${err}`);
16022
- }
16023
- 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);
16024
17749
  rmSync3(tmpDir, { recursive: true, force: true });
16025
17750
  log(`ONNX Runtime v${ORT_VERSION} installed to ${targetDir}`);
16026
17751
  return targetDir;
@@ -16029,17 +17754,39 @@ async function downloadOnnxRuntime(info, targetDir) {
16029
17754
  try {
16030
17755
  rmSync3(tmpDir, { recursive: true, force: true });
16031
17756
  } catch {}
16032
- try {
16033
- rmSync3(targetDir, { recursive: true, force: true });
16034
- } catch {}
16035
17757
  return null;
16036
17758
  }
16037
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
+ }
16038
17785
  function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync3) {
16039
17786
  const requiredLibs = new Set([info.libName]);
16040
17787
  for (const libFile of realFiles) {
16041
- const src = join12(extractedDir, libFile);
16042
- const dst = join12(targetDir, libFile);
17788
+ const src = join13(extractedDir, libFile);
17789
+ const dst = join13(targetDir, libFile);
16043
17790
  try {
16044
17791
  copyFile(src, dst);
16045
17792
  if (process.platform !== "win32") {
@@ -16055,11 +17802,11 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
16055
17802
  }
16056
17803
  const targetRoot = realpathSync2(targetDir);
16057
17804
  for (const link of symlinks) {
16058
- const dst = join12(targetDir, link.name);
17805
+ const dst = join13(targetDir, link.name);
16059
17806
  try {
16060
17807
  unlinkSync4(dst);
16061
17808
  } catch {}
16062
- const dstForContainment = join12(targetRoot, link.name);
17809
+ const dstForContainment = join13(targetRoot, link.name);
16063
17810
  const resolvedTarget = resolve7(dirname5(dstForContainment), link.target);
16064
17811
  if (!isPathInsideRoot(targetRoot, resolvedTarget)) {
16065
17812
  const message = `ONNX Runtime symlink ${link.name} points outside install dir: ${link.target}`;
@@ -16080,21 +17827,18 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
16080
17827
  log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
16081
17828
  }
16082
17829
  }
16083
- const requiredPath = join12(targetDir, info.libName);
16084
- if (!existsSync9(requiredPath)) {
17830
+ const requiredPath = join13(targetDir, info.libName);
17831
+ if (!existsSync10(requiredPath)) {
16085
17832
  rmSync3(targetDir, { recursive: true, force: true });
16086
17833
  throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
16087
17834
  }
16088
17835
  }
16089
17836
  async function extractZipArchive(archivePath, destinationDir) {
16090
17837
  if (process.platform === "win32") {
16091
- execFileSync("tar.exe", ["-xf", archivePath, "-C", destinationDir], {
16092
- stdio: "pipe",
16093
- timeout: 120000
16094
- });
17838
+ execTarExtractionSync(["-xf", archivePath, "-C", destinationDir], 120000);
16095
17839
  return;
16096
17840
  }
16097
- execFileSync("unzip", ["-q", archivePath, "-d", destinationDir], {
17841
+ execFileSync2("unzip", ["-q", archivePath, "-d", destinationDir], {
16098
17842
  stdio: "pipe",
16099
17843
  timeout: 120000
16100
17844
  });
@@ -16107,13 +17851,13 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
16107
17851
  ...sha256 ? { sha256 } : {},
16108
17852
  archiveSha256
16109
17853
  };
16110
- writeFileSync3(join12(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
17854
+ writeFileSync3(join13(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
16111
17855
  } catch (err) {
16112
17856
  log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
16113
17857
  }
16114
17858
  }
16115
17859
  function readOnnxInstalledMeta(installDir) {
16116
- const path = join12(installDir, ONNX_INSTALLED_META_FILE);
17860
+ const path = join13(installDir, ONNX_INSTALLED_META_FILE);
16117
17861
  try {
16118
17862
  if (!statSync6(path).isFile())
16119
17863
  return null;
@@ -16225,7 +17969,7 @@ function isWindowsProcessAlive(pid) {
16225
17969
  if (!Number.isInteger(pid) || pid <= 0)
16226
17970
  return false;
16227
17971
  try {
16228
- 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"], {
16229
17973
  encoding: "utf8",
16230
17974
  timeout: 2000,
16231
17975
  windowsHide: true
@@ -16446,10 +18190,8 @@ function prepareCanonicalEditArguments(toolName, rawArguments) {
16446
18190
  if (unknownRootKeys.length > 0) {
16447
18191
  throw new InvalidRequestError(formatUnknownKeys(unknownRootKeys));
16448
18192
  }
18193
+ validateSymbolModePair(record);
16449
18194
  const modes = editModesPresent(record);
16450
- if (hasOrphanedSymbolContent(record)) {
16451
- throw new InvalidRequestError("edit: 'content' requires a non-empty string 'symbol' when symbol mode is selected");
16452
- }
16453
18195
  if (modes.length > 1) {
16454
18196
  throw new InvalidRequestError(`edit: conflicting modes: ${modes.join(", ")}. ${OMIT_OPTIONAL_FIELDS_STEERING}`);
16455
18197
  }
@@ -16469,7 +18211,7 @@ function prepareCanonicalEditArguments(toolName, rawArguments) {
16469
18211
  throw new InvalidRequestError("edit: 'symbol' must be a string when symbol mode is selected");
16470
18212
  }
16471
18213
  if (!hasOwn(record, "content") || typeof record.content !== "string") {
16472
- 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[]`.");
16473
18215
  }
16474
18216
  } else {
16475
18217
  const item = {};
@@ -16522,6 +18264,29 @@ function validateEditPath(record) {
16522
18264
  function formatUnknownKeys(keys) {
16523
18265
  return `Unrecognized keys: ${keys.map((key) => `"${key}"`).join(", ")}`;
16524
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
+ }
16525
18290
  function editModesPresent(record) {
16526
18291
  const hasAppendContent = isNonEmptyString(record.appendContent);
16527
18292
  if (!hasAppendContent)
@@ -16607,9 +18372,6 @@ function normalizeEditArraySentinels(record) {
16607
18372
  return true;
16608
18373
  }
16609
18374
  }
16610
- function hasOrphanedSymbolContent(record) {
16611
- return isNonEmptyString(record.content) && !isNonEmptyString(record.symbol);
16612
- }
16613
18375
  function parseEditArray(value) {
16614
18376
  if (typeof value === "string") {
16615
18377
  let parsed;
@@ -16792,8 +18554,50 @@ function copyOwnProperties(source) {
16792
18554
  copy[key] = source[key];
16793
18555
  return copy;
16794
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
+ }
16795
18599
  // src/config.ts
16796
- 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";
16797
18601
  import { homedir as homedir10 } from "node:os";
16798
18602
  import { isAbsolute as isAbsolute6, parse as parsePath, resolve as resolvePath } from "node:path";
16799
18603
  var import_comment_json = __toESM(require_src2(), 1);
@@ -22024,7 +23828,7 @@ function migrateExperimentalBashBlock(rawConfig, configPath, logger) {
22024
23828
  return movedKeys;
22025
23829
  }
22026
23830
  function migrateAftConfigFile2(configPath, logger = { log: log2, warn: warn2 }) {
22027
- if (!existsSync10(configPath)) {
23831
+ if (!existsSync11(configPath)) {
22028
23832
  return { migrated: false, oldKeys: [] };
22029
23833
  }
22030
23834
  let tmpPath = null;
@@ -22048,7 +23852,7 @@ function migrateAftConfigFile2(configPath, logger = { log: log2, warn: warn2 })
22048
23852
  ${serialized}` : serialized;
22049
23853
  tmpPath = `${configPath}.tmp.${process.pid}`;
22050
23854
  writeFileSync4(tmpPath, nextContent, "utf-8");
22051
- renameSync5(tmpPath, configPath);
23855
+ renameSync6(tmpPath, configPath);
22052
23856
  logger.log(`Migrated config at ${configPath}: removed ${oldKeys.join(", ")}`);
22053
23857
  return { migrated: true, oldKeys };
22054
23858
  } catch (err) {
@@ -22109,7 +23913,7 @@ function recordConfigParseFailure(configPath, errorMessage) {
22109
23913
  }
22110
23914
  function loadConfigFromPath(configPath) {
22111
23915
  try {
22112
- if (!existsSync10(configPath)) {
23916
+ if (!existsSync11(configPath)) {
22113
23917
  return null;
22114
23918
  }
22115
23919
  const content = readFileSync7(configPath, "utf-8");
@@ -22449,7 +24253,7 @@ function loadAftConfig(projectDirectory) {
22449
24253
  }
22450
24254
 
22451
24255
  // src/tools/_shared.ts
22452
- import { existsSync as existsSync11 } from "node:fs";
24256
+ import { existsSync as existsSync12 } from "node:fs";
22453
24257
  import * as os2 from "node:os";
22454
24258
  import * as path2 from "node:path";
22455
24259
 
@@ -34862,6 +36666,7 @@ var DEBOUNCE_STEP_MS = 200;
34862
36666
  var DEBOUNCE_CAP_MS = 1000;
34863
36667
  var MAX_WAKE_SEND_ATTEMPTS = 5;
34864
36668
  var DEFAULT_WAKE_CONFIRMATION_WINDOW_MS = 5000;
36669
+ var BUSY_WAKE_DEFER_CEILING_MS = 60000;
34865
36670
  var UNKNOWN_COMPLETION_TTL_MS = 5000;
34866
36671
  var UNKNOWN_COMPLETION_CAP = 32;
34867
36672
  var DEFAULT_SESSION_ID2 = "__default__";
@@ -34893,10 +36698,12 @@ function logDroppedForeignSessionFrame(drainContext, droppedSessionId, liveSessi
34893
36698
  var DEFAULT_BG_HOP_TIMEOUT_MS = 15000;
34894
36699
  var bgHopTimeoutMs = DEFAULT_BG_HOP_TIMEOUT_MS;
34895
36700
  var wakeConfirmationWindowMs = DEFAULT_WAKE_CONFIRMATION_WINDOW_MS;
36701
+ var busyWakeDeferCeilingMs = BUSY_WAKE_DEFER_CEILING_MS;
34896
36702
  var lastWakeMessageTimestamp = 0;
34897
36703
  var wakeMessageCounter = 0;
34898
36704
  var subcNudgesInFlight = new Map;
34899
36705
  var subcNudgeLogState = new Map;
36706
+ var deferredBusyWakes = new Map;
34900
36707
  function consumeBgCompletion(sessionID, taskId) {
34901
36708
  const state = stateFor(sessionID);
34902
36709
  state.pendingCompletions = state.pendingCompletions.filter((c) => c.task_id !== taskId);
@@ -34911,6 +36718,9 @@ function consumeBgCompletion(sessionID, taskId) {
34911
36718
  }
34912
36719
  }
34913
36720
  clearWakeTimerIfNoPending(state);
36721
+ if (state.pendingCompletions.length === 0 && state.pendingLongRunning.length === 0 && state.pendingPatternMatches.length === 0) {
36722
+ clearDeferredBusyWake(sessionID || DEFAULT_SESSION_ID2);
36723
+ }
34914
36724
  }
34915
36725
  async function markBgCompletionDelivered(drainContext, taskId) {
34916
36726
  const state = stateFor(drainContext.sessionID);
@@ -35016,7 +36826,7 @@ async function handlePushedPatternMatch(drainContext, frame) {
35016
36826
  }
35017
36827
  const state = stateFor(drainContext.sessionID);
35018
36828
  queuePendingPatternMatch(state, { ...frame, ackCompletionOnDelivery: true });
35019
- await triggerWakeIfPending(drainContext, true);
36829
+ await triggerWakeIfPending(drainContext, true, true, false, true);
35020
36830
  }
35021
36831
  function ingestBgCompletions(sessionID, completions) {
35022
36832
  if (!Array.isArray(completions) || completions.length === 0)
@@ -35054,11 +36864,11 @@ function ingestBgCompletions(sessionID, completions) {
35054
36864
  }
35055
36865
  async function handlePushedBgCompletion(drainContext, completion) {
35056
36866
  ingestBgCompletions(drainContext.sessionID, [completion]);
35057
- await triggerWakeIfPending(drainContext, true, false);
36867
+ await triggerWakeIfPending(drainContext, true, false, false, true);
35058
36868
  }
35059
36869
  async function handlePushedBgLongRunning(drainContext, reminder) {
35060
36870
  stateFor(drainContext.sessionID).pendingLongRunning.push(reminder);
35061
- await triggerWakeIfPending(drainContext, true);
36871
+ await triggerWakeIfPending(drainContext, true, true, false, true);
35062
36872
  }
35063
36873
  async function appendInTurnBgCompletions(drainContext, output) {
35064
36874
  if (!output)
@@ -35103,6 +36913,7 @@ async function appendInTurnBgCompletions(drainContext, output) {
35103
36913
  if (inTurnAcked)
35104
36914
  confirmAcked(state, inTurnAckIds);
35105
36915
  clearWakeTimerIfNoPending(state);
36916
+ clearDeferredBusyWake(drainContext.sessionID);
35106
36917
  }
35107
36918
  async function handleIdleBgCompletions(drainContext) {
35108
36919
  stateFor(drainContext.sessionID).wakeDeferredTaskIds.clear();
@@ -35130,7 +36941,7 @@ async function handleSubcBgEventsNudgeOnce(drainContext) {
35130
36941
  const state = stateFor(drainContext.sessionID);
35131
36942
  state.wakeDeferredTaskIds.clear();
35132
36943
  rearmHardStoppedWake(state, drainContext);
35133
- await triggerWakeIfPending(drainContext, false, true, true);
36944
+ await triggerWakeIfPending(drainContext, false, true, true, true);
35134
36945
  }
35135
36946
  function logSubcNudgeLifecycle(drainContext, kind, message) {
35136
36947
  logDeliveryHop(drainContext, kind, message, {
@@ -35345,6 +37156,42 @@ function registerWakeAdmission(state, admission) {
35345
37156
  }, wakeConfirmationWindowMs);
35346
37157
  tracked.confirmationTimer.unref?.();
35347
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
+ }
35348
37195
  function observeOpenCodeBgNotificationEvent(event) {
35349
37196
  try {
35350
37197
  if (!event || typeof event !== "object")
@@ -35393,12 +37240,17 @@ function observeOpenCodeBgNotificationEvent(event) {
35393
37240
  return;
35394
37241
  }
35395
37242
  if (nextStatus === "idle") {
37243
+ const deferred = clearDeferredBusyWake(sessionID);
37244
+ if (deferred)
37245
+ triggerWakeIfPending(deferred.context, true).catch(() => {
37246
+ return;
37247
+ });
35396
37248
  for (const admission of state.wakeAdmissions.values())
35397
37249
  queueWakeRefire(state, admission);
35398
37250
  }
35399
37251
  } catch {}
35400
37252
  }
35401
- async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredCompletions = true, forceDrain = false) {
37253
+ async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredCompletions = true, forceDrain = false, deferWhileBusy = false) {
35402
37254
  const state = stateFor(drainContext.sessionID);
35403
37255
  if (!skipDrain && (forceDrain || state.outstandingTaskIds.size > 0 || !state.forcedDrainCompleted)) {
35404
37256
  await drainCompletions(drainContext);
@@ -35406,6 +37258,10 @@ async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredComp
35406
37258
  routeExplicitControlCompletions(state);
35407
37259
  if (!hasWakeEligiblePending(state, includeDeferredCompletions))
35408
37260
  return;
37261
+ if (deferWhileBusy && state.hostStatus === "busy") {
37262
+ deferBusyWake(drainContext);
37263
+ return;
37264
+ }
35409
37265
  scheduleWake(state, async (reminder, deliveredCompletions, deliveredPatternMatches) => {
35410
37266
  const liveSession = getActiveSessionId() ?? drainContext.sessionID;
35411
37267
  if (liveSession && drainContext.sessionID && drainContext.sessionID !== liveSession) {
@@ -36247,7 +38103,7 @@ function bridgeFor(ctx, runtime) {
36247
38103
  if (ctx.isProjectEnabled?.(projectRoot) === false) {
36248
38104
  throw new Error(`AFT disabled by config for ${projectRoot}`);
36249
38105
  }
36250
- if (!existsSync11(projectRoot)) {
38106
+ if (!existsSync12(projectRoot)) {
36251
38107
  throw new Error(`project directory no longer exists: ${projectRoot} (stale restored session?)`);
36252
38108
  }
36253
38109
  return ctx.pool.getBridge(projectRoot);
@@ -36404,9 +38260,9 @@ async function signalBashWaitDetachForProject(pool, projectRoot, sessionID) {
36404
38260
  }
36405
38261
 
36406
38262
  // src/notifications.ts
36407
- import { existsSync as existsSync12, readFileSync as readFileSync8 } from "node:fs";
38263
+ import { existsSync as existsSync13, readFileSync as readFileSync8 } from "node:fs";
36408
38264
  import { homedir as homedir12, platform } from "node:os";
36409
- import { join as join13 } from "node:path";
38265
+ import { join as join14 } from "node:path";
36410
38266
  function isTuiMode() {
36411
38267
  return process.env.OPENCODE_CLIENT === "cli";
36412
38268
  }
@@ -36428,21 +38284,21 @@ function getDesktopStatePath() {
36428
38284
  const os = platform();
36429
38285
  const home = homedir12();
36430
38286
  if (os === "darwin") {
36431
- 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");
36432
38288
  }
36433
38289
  if (os === "linux") {
36434
- const xdgConfig = process.env.XDG_CONFIG_HOME || join13(home, ".config");
36435
- 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");
36436
38292
  }
36437
38293
  if (os === "win32") {
36438
- const appData = process.env.APPDATA || join13(home, "AppData", "Roaming");
36439
- 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");
36440
38296
  }
36441
38297
  return null;
36442
38298
  }
36443
38299
  function readDesktopState() {
36444
38300
  const statePath = getDesktopStatePath();
36445
- if (!statePath || !existsSync12(statePath)) {
38301
+ if (!statePath || !existsSync13(statePath)) {
36446
38302
  return { serverUrl: null };
36447
38303
  }
36448
38304
  try {
@@ -36942,11 +38798,11 @@ async function flushConfigureWarningsOnIdle(sessionId) {
36942
38798
  // src/hooks/auto-update-checker/index.ts
36943
38799
  import {
36944
38800
  closeSync as closeSync5,
36945
- existsSync as existsSync15,
38801
+ existsSync as existsSync16,
36946
38802
  mkdirSync as mkdirSync6,
36947
38803
  openSync as openSync5,
36948
38804
  readFileSync as readFileSync11,
36949
- renameSync as renameSync6,
38805
+ renameSync as renameSync7,
36950
38806
  rmSync as rmSync5,
36951
38807
  statSync as statSync8,
36952
38808
  writeFileSync as writeFileSync7
@@ -36955,30 +38811,30 @@ import { dirname as dirname8 } from "node:path";
36955
38811
 
36956
38812
  // src/hooks/auto-update-checker/cache.ts
36957
38813
  import { spawn as spawn4 } from "node:child_process";
36958
- 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";
36959
38815
  import { tmpdir as tmpdir2 } from "node:os";
36960
- 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";
36961
38817
  var import_comment_json3 = __toESM(require_src2(), 1);
36962
38818
 
36963
38819
  // src/hooks/auto-update-checker/checker.ts
36964
- import { existsSync as existsSync13, readFileSync as readFileSync9, statSync as statSync7, writeFileSync as writeFileSync5 } from "node:fs";
36965
- 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";
36966
38822
  import { fileURLToPath } from "node:url";
36967
38823
  var import_comment_json2 = __toESM(require_src2(), 1);
36968
38824
 
36969
38825
  // src/hooks/auto-update-checker/constants.ts
36970
- import { join as join14 } from "node:path";
38826
+ import { join as join15 } from "node:path";
36971
38827
  var PACKAGE_NAME = "@cortexkit/aft-opencode";
36972
38828
  var NPM_REGISTRY_URL = "https://registry.npmjs.org";
36973
38829
  var NPM_FETCH_TIMEOUT = 1e4;
36974
38830
  function cacheDir() {
36975
- return join14(getOpenCodeCacheRoot(), "packages");
38831
+ return join15(getOpenCodeCacheRoot(), "packages");
36976
38832
  }
36977
38833
  function userOpenCodeConfig() {
36978
- return join14(getOpenCodeConfigRoot(), "opencode.json");
38834
+ return join15(getOpenCodeConfigRoot(), "opencode.json");
36979
38835
  }
36980
38836
  function userOpenCodeConfigJsonc() {
36981
- return join14(getOpenCodeConfigRoot(), "opencode.jsonc");
38837
+ return join15(getOpenCodeConfigRoot(), "opencode.jsonc");
36982
38838
  }
36983
38839
 
36984
38840
  // src/hooks/auto-update-checker/types.ts
@@ -37037,8 +38893,8 @@ function extractChannel(version) {
37037
38893
  }
37038
38894
  function getConfigPaths(directory) {
37039
38895
  return [
37040
- join15(directory, ".opencode", "opencode.json"),
37041
- join15(directory, ".opencode", "opencode.jsonc"),
38896
+ join16(directory, ".opencode", "opencode.json"),
38897
+ join16(directory, ".opencode", "opencode.jsonc"),
37042
38898
  userOpenCodeConfig(),
37043
38899
  userOpenCodeConfigJsonc()
37044
38900
  ];
@@ -37058,7 +38914,7 @@ function resolvePathPluginSpec(spec, configPath) {
37058
38914
  function getLocalDevPath(directory) {
37059
38915
  for (const configPath of getConfigPaths(directory)) {
37060
38916
  try {
37061
- if (!existsSync13(configPath))
38917
+ if (!existsSync14(configPath))
37062
38918
  continue;
37063
38919
  const rawConfig = parseJsonConfig(readFileSync9(configPath, "utf-8"));
37064
38920
  const plugins = getPluginEntries(rawConfig);
@@ -37084,8 +38940,8 @@ function findPackageJsonUp(startPath) {
37084
38940
  const stat = statSync7(startPath);
37085
38941
  let dir = stat.isDirectory() ? startPath : dirname6(startPath);
37086
38942
  for (let i = 0;i < 10; i++) {
37087
- const pkgPath = join15(dir, "package.json");
37088
- if (existsSync13(pkgPath)) {
38943
+ const pkgPath = join16(dir, "package.json");
38944
+ if (existsSync14(pkgPath)) {
37089
38945
  try {
37090
38946
  const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(pkgPath, "utf-8")));
37091
38947
  if (pkg.success && pkg.data.name === PACKAGE_NAME)
@@ -37125,7 +38981,7 @@ function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
37125
38981
  function findPluginEntry(directory) {
37126
38982
  for (const configPath of getConfigPaths(directory)) {
37127
38983
  try {
37128
- if (!existsSync13(configPath))
38984
+ if (!existsSync14(configPath))
37129
38985
  continue;
37130
38986
  const rawConfig = parseJsonConfig(readFileSync9(configPath, "utf-8"));
37131
38987
  const plugins = getPluginEntries(rawConfig);
@@ -37145,7 +39001,7 @@ function findPluginEntry(directory) {
37145
39001
  }
37146
39002
  var cachedPackageVersion = null;
37147
39003
  function getSpecCachePackageJsonPath(spec) {
37148
- return join15(cacheDir(), spec, "node_modules", PACKAGE_NAME, "package.json");
39004
+ return join16(cacheDir(), spec, "node_modules", PACKAGE_NAME, "package.json");
37149
39005
  }
37150
39006
  function getCachedVersion(spec) {
37151
39007
  if (!spec && cachedPackageVersion)
@@ -37154,11 +39010,11 @@ function getCachedVersion(spec) {
37154
39010
  getCurrentRuntimePackageJsonPath(),
37155
39011
  spec ? getSpecCachePackageJsonPath(spec) : null,
37156
39012
  getSpecCachePackageJsonPath(`${PACKAGE_NAME}@latest`),
37157
- join15(getOpenCodeCacheRoot(), "node_modules", PACKAGE_NAME, "package.json")
39013
+ join16(getOpenCodeCacheRoot(), "node_modules", PACKAGE_NAME, "package.json")
37158
39014
  ].filter(isString);
37159
39015
  for (const packageJsonPath of candidates) {
37160
39016
  try {
37161
- if (!existsSync13(packageJsonPath))
39017
+ if (!existsSync14(packageJsonPath))
37162
39018
  continue;
37163
39019
  const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(packageJsonPath, "utf-8")));
37164
39020
  if (pkg.success && pkg.data.version) {
@@ -37203,17 +39059,17 @@ async function getLatestVersion(channel = "latest", options = {}) {
37203
39059
  var pendingSnapshots = new Map;
37204
39060
  var quarantinedInstallDirs = new Set;
37205
39061
  function createAutoUpdateSnapshot(installDir, packageJsonPath, packageName) {
37206
- const packageDir = join16(installDir, "node_modules", packageName);
37207
- const lockfilePath = join16(installDir, "package-lock.json");
37208
- const tempDir = mkdtempSync(join16(tmpdir2(), "aft-auto-update-"));
37209
- 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;
37210
39066
  if (stagedPackageDir)
37211
39067
  cpSync(packageDir, stagedPackageDir, { recursive: true });
37212
39068
  return {
37213
39069
  packageJsonPath,
37214
- packageJson: existsSync14(packageJsonPath) ? readFileSync10(packageJsonPath, "utf-8") : null,
39070
+ packageJson: existsSync15(packageJsonPath) ? readFileSync10(packageJsonPath, "utf-8") : null,
37215
39071
  lockfilePath,
37216
- lockfile: existsSync14(lockfilePath) ? readFileSync10(lockfilePath, "utf-8") : null,
39072
+ lockfile: existsSync15(lockfilePath) ? readFileSync10(lockfilePath, "utf-8") : null,
37217
39073
  packageDir,
37218
39074
  stagedPackageDir,
37219
39075
  tempDir
@@ -37247,8 +39103,8 @@ function stripPackageNameFromPath(pathValue, packageName) {
37247
39103
  return current;
37248
39104
  }
37249
39105
  function removeFromPackageLock(installDir, packageName) {
37250
- const lockPath = join16(installDir, "package-lock.json");
37251
- if (!existsSync14(lockPath))
39106
+ const lockPath = join17(installDir, "package-lock.json");
39107
+ if (!existsSync15(lockPath))
37252
39108
  return false;
37253
39109
  try {
37254
39110
  const lock = import_comment_json3.parse(readFileSync10(lockPath, "utf-8"));
@@ -37274,7 +39130,7 @@ function removeFromPackageLock(installDir, packageName) {
37274
39130
  }
37275
39131
  }
37276
39132
  function ensureDependencyVersion(packageJsonPath, packageName, version) {
37277
- if (!existsSync14(packageJsonPath))
39133
+ if (!existsSync15(packageJsonPath))
37278
39134
  return false;
37279
39135
  try {
37280
39136
  const raw = import_comment_json3.parse(readFileSync10(packageJsonPath, "utf-8"));
@@ -37303,8 +39159,8 @@ function restorePendingSnapshot(installDir) {
37303
39159
  restoreAutoUpdateSnapshot(snapshot);
37304
39160
  }
37305
39161
  function removeInstalledPackage(installDir, packageName) {
37306
- const packageDir = join16(installDir, "node_modules", packageName);
37307
- if (!existsSync14(packageDir))
39162
+ const packageDir = join17(installDir, "node_modules", packageName);
39163
+ if (!existsSync15(packageDir))
37308
39164
  return false;
37309
39165
  rmSync4(packageDir, { recursive: true, force: true });
37310
39166
  log2(`[auto-update-checker] Package removed: ${packageDir}`);
@@ -37316,15 +39172,15 @@ function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackage
37316
39172
  const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME);
37317
39173
  if (nodeModulesDir && basename3(nodeModulesDir) === "node_modules") {
37318
39174
  const installDir = dirname7(nodeModulesDir);
37319
- const packageJsonPath = join16(installDir, "package.json");
37320
- if (existsSync14(packageJsonPath))
39175
+ const packageJsonPath = join17(installDir, "package.json");
39176
+ if (existsSync15(packageJsonPath))
37321
39177
  return { installDir, packageJsonPath };
37322
39178
  }
37323
39179
  return null;
37324
39180
  }
37325
39181
  const cacheRoot = dirname7(cacheDir());
37326
- const legacyPackageJsonPath = join16(cacheRoot, "package.json");
37327
- if (existsSync14(legacyPackageJsonPath)) {
39182
+ const legacyPackageJsonPath = join17(cacheRoot, "package.json");
39183
+ if (existsSync15(legacyPackageJsonPath)) {
37328
39184
  return { installDir: cacheRoot, packageJsonPath: legacyPackageJsonPath };
37329
39185
  }
37330
39186
  return null;
@@ -37547,7 +39403,7 @@ function claimCheckSlot(storageDir, intervalMs) {
37547
39403
  const replacementPath = `${lockPath}.tmp.${process.pid}`;
37548
39404
  writeFileSync7(replacementPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
37549
39405
  try {
37550
- renameSync6(replacementPath, lockPath);
39406
+ renameSync7(replacementPath, lockPath);
37551
39407
  } catch (replaceError) {
37552
39408
  rmSync5(replacementPath, { force: true });
37553
39409
  throw replaceError;
@@ -37615,7 +39471,7 @@ function checkLockIsOwnedBy(lockPath, owner) {
37615
39471
  }
37616
39472
  }
37617
39473
  function hasRecentCheckTimestamp(file, intervalMs) {
37618
- if (!existsSync15(file))
39474
+ if (!existsSync16(file))
37619
39475
  return false;
37620
39476
  try {
37621
39477
  const raw = JSON.parse(readFileSync11(file, "utf-8"));
@@ -37628,7 +39484,7 @@ function hasRecentCheckTimestamp(file, intervalMs) {
37628
39484
  function writeCheckTimestamp(file) {
37629
39485
  const tmp = `${file}.tmp.${process.pid}`;
37630
39486
  writeFileSync7(tmp, JSON.stringify({ lastCheckedMs: Date.now() }), "utf-8");
37631
- renameSync6(tmp, file);
39487
+ renameSync7(tmp, file);
37632
39488
  }
37633
39489
  async function runStartupCheck(ctx, options) {
37634
39490
  if (options.signal.aborted)
@@ -37725,15 +39581,15 @@ import { spawn as spawn5 } from "node:child_process";
37725
39581
  import { createHash as createHash6 } from "node:crypto";
37726
39582
  import {
37727
39583
  createReadStream,
37728
- existsSync as existsSync17,
39584
+ existsSync as existsSync18,
37729
39585
  mkdirSync as mkdirSync8,
37730
39586
  readFileSync as readFileSync14,
37731
- renameSync as renameSync8,
39587
+ renameSync as renameSync9,
37732
39588
  rmSync as rmSync7,
37733
39589
  statSync as statSync10,
37734
39590
  writeFileSync as writeFileSync9
37735
39591
  } from "node:fs";
37736
- import { join as join19 } from "node:path";
39592
+ import { join as join20 } from "node:path";
37737
39593
 
37738
39594
  // src/lsp-cache.ts
37739
39595
  import { randomUUID as randomUUID3 } from "node:crypto";
@@ -37742,13 +39598,13 @@ import {
37742
39598
  mkdirSync as mkdirSync7,
37743
39599
  openSync as openSync6,
37744
39600
  readFileSync as readFileSync12,
37745
- renameSync as renameSync7,
39601
+ renameSync as renameSync8,
37746
39602
  rmSync as rmSync6,
37747
39603
  statSync as statSync9,
37748
39604
  unlinkSync as unlinkSync6,
37749
39605
  writeFileSync as writeFileSync8
37750
39606
  } from "node:fs";
37751
- import { join as join17 } from "node:path";
39607
+ import { join as join18 } from "node:path";
37752
39608
  function aftCacheBase() {
37753
39609
  return getAftCacheRoot();
37754
39610
  }
@@ -37756,18 +39612,18 @@ function lspCacheRoot() {
37756
39612
  return getAftLspPackagesDir();
37757
39613
  }
37758
39614
  function lspPackageDir(npmPackage) {
37759
- return join17(lspCacheRoot(), encodeURIComponent(npmPackage));
39615
+ return join18(lspCacheRoot(), encodeURIComponent(npmPackage));
37760
39616
  }
37761
39617
  function lspBinaryPath(npmPackage, binary) {
37762
- return join17(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
39618
+ return join18(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
37763
39619
  }
37764
39620
  function lspBinDir(npmPackage) {
37765
- return join17(lspPackageDir(npmPackage), "node_modules", ".bin");
39621
+ return join18(lspPackageDir(npmPackage), "node_modules", ".bin");
37766
39622
  }
37767
39623
  function isInstalled(npmPackage, binary) {
37768
39624
  for (const candidate of lspBinaryCandidates(binary)) {
37769
39625
  try {
37770
- if (statSync9(join17(lspBinDir(npmPackage), candidate)).isFile())
39626
+ if (statSync9(join18(lspBinDir(npmPackage), candidate)).isFile())
37771
39627
  return true;
37772
39628
  } catch {}
37773
39629
  }
@@ -37787,13 +39643,13 @@ function writeInstalledMetaIn(installDir, version, sha256) {
37787
39643
  installedAt: new Date().toISOString(),
37788
39644
  ...sha256 ? { sha256 } : {}
37789
39645
  };
37790
- writeFileSync8(join17(installDir, INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
39646
+ writeFileSync8(join18(installDir, INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
37791
39647
  } catch (err) {
37792
39648
  log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
37793
39649
  }
37794
39650
  }
37795
39651
  function readInstalledMetaIn(installDir) {
37796
- const path = join17(installDir, INSTALLED_META_FILE);
39652
+ const path = join18(installDir, INSTALLED_META_FILE);
37797
39653
  try {
37798
39654
  if (!statSync9(path).isFile())
37799
39655
  return null;
@@ -37817,7 +39673,7 @@ function readInstalledMeta(packageKey) {
37817
39673
  return readInstalledMetaIn(lspPackageDir(packageKey));
37818
39674
  }
37819
39675
  function lockPath(npmPackage) {
37820
- return join17(lspPackageDir(npmPackage), ".aft-installing");
39676
+ return join18(lspPackageDir(npmPackage), ".aft-installing");
37821
39677
  }
37822
39678
  var STALE_LOCK_MS2 = 30 * 60 * 1000;
37823
39679
  function acquireInstallLock(lockKey) {
@@ -37948,7 +39804,7 @@ var AUTO_INSTALL_STAMP_FILE = "last-lsp-autoinstall.json";
37948
39804
  var AUTO_INSTALL_WINDOW_MS = 60 * 1000;
37949
39805
  var AUTO_INSTALL_LOCK_STALE_MS = 30 * 60 * 1000;
37950
39806
  function autoInstallStampPath() {
37951
- return join17(aftCacheBase(), AUTO_INSTALL_STAMP_FILE);
39807
+ return join18(aftCacheBase(), AUTO_INSTALL_STAMP_FILE);
37952
39808
  }
37953
39809
  function hasRecentAutoInstallStamp(path) {
37954
39810
  try {
@@ -38034,7 +39890,7 @@ function claimLspAutoInstallPass() {
38034
39890
  encoding: "utf8",
38035
39891
  mode: 384
38036
39892
  });
38037
- renameSync7(tempPath, stampPath);
39893
+ renameSync8(tempPath, stampPath);
38038
39894
  return { release };
38039
39895
  } catch (err) {
38040
39896
  if (claimed) {
@@ -38049,7 +39905,7 @@ function claimLspAutoInstallPass() {
38049
39905
  }
38050
39906
  var VERSION_CHECK_FILE = ".aft-version-check";
38051
39907
  function readVersionCheck(npmPackage) {
38052
- const file = join17(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
39908
+ const file = join18(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
38053
39909
  try {
38054
39910
  const raw = readFileSync12(file, "utf8");
38055
39911
  const parsed = JSON.parse(raw);
@@ -38066,7 +39922,7 @@ function readVersionCheck(npmPackage) {
38066
39922
  }
38067
39923
  function writeVersionCheck(npmPackage, latest) {
38068
39924
  mkdirSync7(lspPackageDir(npmPackage), { recursive: true });
38069
- const file = join17(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
39925
+ const file = join18(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
38070
39926
  const record = {
38071
39927
  last_checked: new Date().toISOString(),
38072
39928
  latest_eligible: latest
@@ -38228,8 +40084,8 @@ var NPM_LSP_TABLE = [
38228
40084
  ];
38229
40085
 
38230
40086
  // src/lsp-project-relevance.ts
38231
- import { existsSync as existsSync16, readdirSync as readdirSync4, readFileSync as readFileSync13 } from "node:fs";
38232
- 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";
38233
40089
  var MAX_WALK_DIRS = 200;
38234
40090
  var MAX_WALK_DEPTH = 4;
38235
40091
  var NOISE_DIRS = new Set([
@@ -38246,7 +40102,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
38246
40102
  if (!rootMarkers)
38247
40103
  return false;
38248
40104
  for (const marker of rootMarkers) {
38249
- if (existsSync16(join18(projectRoot, marker)))
40105
+ if (existsSync17(join19(projectRoot, marker)))
38250
40106
  return true;
38251
40107
  }
38252
40108
  return false;
@@ -38270,7 +40126,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
38270
40126
  }
38271
40127
  function readPackageJson(projectRoot) {
38272
40128
  try {
38273
- const raw = readFileSync13(join18(projectRoot, "package.json"), "utf8");
40129
+ const raw = readFileSync13(join19(projectRoot, "package.json"), "utf8");
38274
40130
  const parsed = JSON.parse(raw);
38275
40131
  if (typeof parsed !== "object" || parsed === null)
38276
40132
  return null;
@@ -38300,7 +40156,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
38300
40156
  for (const entry of entries) {
38301
40157
  if (entry.isDirectory()) {
38302
40158
  if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
38303
- 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 });
38304
40160
  }
38305
40161
  continue;
38306
40162
  }
@@ -38428,8 +40284,8 @@ async function resolveTargetVersion(spec, config, fetchImpl = fetch) {
38428
40284
  }
38429
40285
  function ensureInstallAnchor(cwd) {
38430
40286
  try {
38431
- const stub = join19(cwd, "package.json");
38432
- if (!existsSync17(stub)) {
40287
+ const stub = join20(cwd, "package.json");
40288
+ if (!existsSync18(stub)) {
38433
40289
  writeFileSync9(stub, `${JSON.stringify({ name: "aft-lsp-cache", version: "0.0.0", private: true })}
38434
40290
  `);
38435
40291
  }
@@ -38655,12 +40511,12 @@ function sha256OfFileSync(path) {
38655
40511
  }
38656
40512
  function quarantineCachedNpmInstall(spec, reason) {
38657
40513
  const packageDir = lspPackageDir(spec.npm);
38658
- const dest = join19(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
40514
+ const dest = join20(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
38659
40515
  warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
38660
40516
  try {
38661
- mkdirSync8(join19(dest, ".."), { recursive: true });
40517
+ mkdirSync8(join20(dest, ".."), { recursive: true });
38662
40518
  rmSync7(dest, { recursive: true, force: true });
38663
- renameSync8(packageDir, dest);
40519
+ renameSync9(packageDir, dest);
38664
40520
  } catch (err) {
38665
40521
  warn2(`[lsp] tofu_mismatch ${spec.npm}: failed to quarantine cache entry: ${err}`);
38666
40522
  }
@@ -38741,26 +40597,26 @@ async function pushLspPathsAfterAutoInstall(pool, projectRoot, cachedBinDirs) {
38741
40597
  }
38742
40598
 
38743
40599
  // src/lsp-github-install.ts
38744
- import { execFileSync as execFileSync2 } from "node:child_process";
40600
+ import { execFileSync as execFileSync3 } from "node:child_process";
38745
40601
  import { createHash as createHash7, randomBytes as randomBytes3 } from "node:crypto";
38746
40602
  import {
38747
40603
  copyFileSync as copyFileSync4,
38748
40604
  createReadStream as createReadStream2,
38749
40605
  createWriteStream as createWriteStream3,
38750
- existsSync as existsSync18,
40606
+ existsSync as existsSync19,
38751
40607
  lstatSync as lstatSync2,
38752
40608
  mkdirSync as mkdirSync9,
38753
40609
  readdirSync as readdirSync5,
38754
40610
  readFileSync as readFileSync15,
38755
40611
  readlinkSync as readlinkSync2,
38756
40612
  realpathSync as realpathSync3,
38757
- renameSync as renameSync9,
40613
+ renameSync as renameSync10,
38758
40614
  rmSync as rmSync8,
38759
40615
  statSync as statSync11,
38760
40616
  unlinkSync as unlinkSync7,
38761
40617
  writeFileSync as writeFileSync10
38762
40618
  } from "node:fs";
38763
- 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";
38764
40620
  import { Readable as Readable3 } from "node:stream";
38765
40621
  import { pipeline as pipeline3 } from "node:stream/promises";
38766
40622
 
@@ -38853,19 +40709,19 @@ function ghCacheRoot() {
38853
40709
  return getAftLspBinariesDir();
38854
40710
  }
38855
40711
  function ghPackageDir(spec) {
38856
- return join20(ghCacheRoot(), spec.id);
40712
+ return join21(ghCacheRoot(), spec.id);
38857
40713
  }
38858
40714
  function ghBinDir(spec) {
38859
- return join20(ghPackageDir(spec), "bin");
40715
+ return join21(ghPackageDir(spec), "bin");
38860
40716
  }
38861
40717
  function ghExtractDir(spec) {
38862
- return join20(ghPackageDir(spec), "extracted");
40718
+ return join21(ghPackageDir(spec), "extracted");
38863
40719
  }
38864
40720
  var INSTALLED_META_FILE2 = ".aft-installed";
38865
40721
  var INSTALL_FAILED_FILE = ".aft-install-failed.json";
38866
40722
  var INSTALL_FAILURE_BACKOFF_MS = 6 * 60 * 60 * 1000;
38867
40723
  function installFailureMarkerPath(spec) {
38868
- return join20(ghPackageDir(spec), INSTALL_FAILED_FILE);
40724
+ return join21(ghPackageDir(spec), INSTALL_FAILED_FILE);
38869
40725
  }
38870
40726
  function readInstallFailureMarker(spec) {
38871
40727
  try {
@@ -38886,7 +40742,7 @@ function writeInstallFailureMarker(spec, release, sha256, installError) {
38886
40742
  mkdirSync9(dirname9(path), { recursive: true });
38887
40743
  writeFileSync10(tempPath, `${JSON.stringify({ release, sha256, error: markerError, at: new Date().toISOString() })}
38888
40744
  `, { encoding: "utf8", mode: 384 });
38889
- renameSync9(tempPath, path);
40745
+ renameSync10(tempPath, path);
38890
40746
  } catch (err) {
38891
40747
  try {
38892
40748
  rmSync8(tempPath, { force: true });
@@ -38907,12 +40763,12 @@ function isFreshInstallFailure(marker) {
38907
40763
  }
38908
40764
  function ghBinaryPath(spec, platform) {
38909
40765
  const ext = platform === "win32" ? ".exe" : "";
38910
- return join20(ghBinDir(spec), `${spec.binary}${ext}`);
40766
+ return join21(ghBinDir(spec), `${spec.binary}${ext}`);
38911
40767
  }
38912
40768
  function isGithubInstalled(spec, platform) {
38913
40769
  for (const candidate of ghBinaryCandidates(spec, platform)) {
38914
40770
  try {
38915
- if (statSync11(join20(ghBinDir(spec), candidate)).isFile())
40771
+ if (statSync11(join21(ghBinDir(spec), candidate)).isFile())
38916
40772
  return true;
38917
40773
  } catch {}
38918
40774
  }
@@ -38925,7 +40781,7 @@ function ghBinaryCandidates(spec, platform) {
38925
40781
  }
38926
40782
  function readGithubInstalledMetaIn(installDir) {
38927
40783
  try {
38928
- const path = join20(installDir, INSTALLED_META_FILE2);
40784
+ const path = join21(installDir, INSTALLED_META_FILE2);
38929
40785
  if (!statSync11(path).isFile())
38930
40786
  return null;
38931
40787
  const parsed = JSON.parse(readFileSync15(path, "utf8"));
@@ -38952,7 +40808,7 @@ function writeGithubInstalledMetaIn(installDir, version, binarySha256, archiveSh
38952
40808
  binarySha256,
38953
40809
  ...archiveSha256 ? { archiveSha256 } : {}
38954
40810
  };
38955
- writeFileSync10(join20(installDir, INSTALLED_META_FILE2), JSON.stringify(meta), "utf8");
40811
+ writeFileSync10(join21(installDir, INSTALLED_META_FILE2), JSON.stringify(meta), "utf8");
38956
40812
  } catch (err) {
38957
40813
  warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
38958
40814
  }
@@ -39201,7 +41057,7 @@ function validateExtraction(stagingRoot) {
39201
41057
  throw new Error(`failed to read staging dir ${dir}: ${err}`);
39202
41058
  }
39203
41059
  for (const entry of entries) {
39204
- const full = join20(dir, entry);
41060
+ const full = join21(dir, entry);
39205
41061
  let lst;
39206
41062
  try {
39207
41063
  lst = lstatSync2(full);
@@ -39247,7 +41103,7 @@ function assertArchiveEntryPath(entry) {
39247
41103
  }
39248
41104
  function precheckWithTar(archivePath, command) {
39249
41105
  let totalBytes = 0;
39250
- const verbose = execFileSync2(command, ["-tvf", archivePath], { encoding: "utf8" });
41106
+ const verbose = execFileSync3(command, ["-tvf", archivePath], { encoding: "utf8" });
39251
41107
  for (const line of verbose.split(`
39252
41108
  `)) {
39253
41109
  if (line.startsWith("h")) {
@@ -39260,7 +41116,7 @@ function precheckWithTar(archivePath, command) {
39260
41116
  totalBytes += Math.max(...numeric);
39261
41117
  }
39262
41118
  }
39263
- const names = execFileSync2(command, ["-tf", archivePath], { encoding: "utf8" });
41119
+ const names = execFileSync3(command, ["-tf", archivePath], { encoding: "utf8" });
39264
41120
  for (const entry of names.split(`
39265
41121
  `)) {
39266
41122
  if (entry.length > 0)
@@ -39271,19 +41127,18 @@ function precheckWithTar(archivePath, command) {
39271
41127
  function precheckArchiveContents(archivePath, archiveType, zipListingMode = "platform") {
39272
41128
  let totalBytes = 0;
39273
41129
  if (archiveType === "zip" && zipListingMode === "platform" && process.platform !== "win32") {
39274
- const out = execFileSync2("unzip", ["-l", archivePath], { encoding: "utf8" });
41130
+ const out = execFileSync3("unzip", ["-l", archivePath], { encoding: "utf8" });
39275
41131
  const match = out.match(/^\s*(\d+)\s+\d+\s+files?\s*$/m);
39276
41132
  if (match)
39277
41133
  totalBytes = Number.parseInt(match[1] ?? "0", 10);
39278
- const names = execFileSync2("unzip", ["-Z1", archivePath], { encoding: "utf8" });
41134
+ const names = execFileSync3("unzip", ["-Z1", archivePath], { encoding: "utf8" });
39279
41135
  for (const entry of names.split(`
39280
41136
  `)) {
39281
41137
  if (entry.length > 0)
39282
41138
  assertArchiveEntryPath(entry);
39283
41139
  }
39284
41140
  } else {
39285
- const command = process.platform === "win32" ? "tar.exe" : "tar";
39286
- totalBytes = precheckWithTar(archivePath, command);
41141
+ totalBytes = precheckWithTar(archivePath, windowsTarExecutable());
39287
41142
  }
39288
41143
  if (totalBytes > MAX_EXTRACT_BYTES2) {
39289
41144
  throw new Error(`archive uncompressed size ${totalBytes} exceeds ${MAX_EXTRACT_BYTES2}`);
@@ -39303,7 +41158,7 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
39303
41158
  try {
39304
41159
  rmSync8(destDir, { recursive: true, force: true });
39305
41160
  } catch {}
39306
- renameSync9(stagingDir, destDir);
41161
+ renameSync10(stagingDir, destDir);
39307
41162
  } catch (err) {
39308
41163
  try {
39309
41164
  rmSync8(stagingDir, { recursive: true, force: true });
@@ -39313,12 +41168,12 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
39313
41168
  }
39314
41169
  function quarantineCachedGithubInstall(spec, reason) {
39315
41170
  const packageDir = ghPackageDir(spec);
39316
- const dest = join20(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
41171
+ const dest = join21(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
39317
41172
  warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
39318
41173
  try {
39319
41174
  mkdirSync9(dirname9(dest), { recursive: true });
39320
41175
  rmSync8(dest, { recursive: true, force: true });
39321
- renameSync9(packageDir, dest);
41176
+ renameSync10(packageDir, dest);
39322
41177
  } catch (err) {
39323
41178
  warn2(`[lsp] tofu_mismatch ${spec.id}: failed to quarantine cache entry: ${err}`);
39324
41179
  }
@@ -39326,7 +41181,7 @@ function quarantineCachedGithubInstall(spec, reason) {
39326
41181
  function validateCachedGithubInstall(spec, platform) {
39327
41182
  const packageDir = ghPackageDir(spec);
39328
41183
  const meta = readGithubInstalledMetaIn(packageDir);
39329
- 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) => {
39330
41185
  try {
39331
41186
  return statSync11(candidate).isFile();
39332
41187
  } catch {
@@ -39362,30 +41217,21 @@ function validateCachedGithubInstall(spec, platform) {
39362
41217
  function runPlatformExtractor(archivePath, destDir, archiveType) {
39363
41218
  if (archiveType === "zip") {
39364
41219
  if (process.platform === "win32") {
39365
- execFileSync2("tar.exe", ["-xf", archivePath, "-C", destDir], {
39366
- stdio: "pipe",
39367
- timeout: 180000
39368
- });
41220
+ execTarExtractionSync(["-xf", archivePath, "-C", destDir], 180000);
39369
41221
  return;
39370
41222
  }
39371
- execFileSync2("unzip", ["-q", "-o", archivePath, "-d", destDir], {
41223
+ execFileSync3("unzip", ["-q", "-o", archivePath, "-d", destDir], {
39372
41224
  stdio: "pipe",
39373
41225
  timeout: 180000
39374
41226
  });
39375
41227
  return;
39376
41228
  }
39377
41229
  if (archiveType === "tar.gz") {
39378
- execFileSync2("tar", ["-xzf", archivePath, "-C", destDir], {
39379
- stdio: "pipe",
39380
- timeout: 180000
39381
- });
41230
+ execTarExtractionSync(["-xzf", archivePath, "-C", destDir], 180000);
39382
41231
  return;
39383
41232
  }
39384
41233
  if (archiveType === "tar.xz") {
39385
- execFileSync2("tar", ["-xf", archivePath, "-C", destDir], {
39386
- stdio: "pipe",
39387
- timeout: 180000
39388
- });
41234
+ execTarExtractionSync(["-xf", archivePath, "-C", destDir], 180000);
39389
41235
  return;
39390
41236
  }
39391
41237
  throw new Error(`unsupported archive type: ${archiveType}`);
@@ -39406,7 +41252,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
39406
41252
  }
39407
41253
  const pkgDir = ghPackageDir(spec);
39408
41254
  const extractDir = ghExtractDir(spec);
39409
- const archivePath = join20(pkgDir, expected.name);
41255
+ const archivePath = join21(pkgDir, expected.name);
39410
41256
  log2(`[lsp] downloading ${spec.id} ${tag} → ${matchingAsset.url}`);
39411
41257
  try {
39412
41258
  await downloadFile(matchingAsset.url, archivePath, fetchImpl, matchingAsset.size, signal);
@@ -39448,8 +41294,8 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
39448
41294
  unlinkSync7(archivePath);
39449
41295
  } catch {}
39450
41296
  }
39451
- const innerBinaryPath = join20(extractDir, spec.binaryPathInArchive(platform, arch, version));
39452
- if (!existsSync18(innerBinaryPath)) {
41297
+ const innerBinaryPath = join21(extractDir, spec.binaryPathInArchive(platform, arch, version));
41298
+ if (!existsSync19(innerBinaryPath)) {
39453
41299
  const message = `extracted binary not found at ${innerBinaryPath}`;
39454
41300
  error2(`[lsp] ${spec.id}: ${message}`);
39455
41301
  return { ok: false, sha256: archiveSha256, error: message };
@@ -39554,7 +41400,7 @@ function runGithubAutoInstall(relevantServers, config, fetchImpl = fetch) {
39554
41400
  if (!host) {
39555
41401
  for (const spec of GITHUB_LSP_TABLE) {
39556
41402
  try {
39557
- if (existsSync18(ghBinDir(spec))) {
41403
+ if (existsSync19(ghBinDir(spec))) {
39558
41404
  cachedBinDirs.push(ghBinDir(spec));
39559
41405
  }
39560
41406
  } catch {}
@@ -39871,25 +41717,25 @@ function isTuiConnected(sessionId) {
39871
41717
  // src/shared/rpc-server.ts
39872
41718
  import { randomBytes as randomBytes4, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
39873
41719
  import {
39874
- existsSync as existsSync19,
41720
+ existsSync as existsSync20,
39875
41721
  mkdirSync as mkdirSync10,
39876
41722
  readdirSync as readdirSync6,
39877
41723
  readFileSync as readFileSync16,
39878
- renameSync as renameSync10,
41724
+ renameSync as renameSync11,
39879
41725
  unlinkSync as unlinkSync8,
39880
41726
  writeFileSync as writeFileSync11
39881
41727
  } from "node:fs";
39882
41728
  import { createServer } from "node:http";
39883
- import { dirname as dirname10, join as join22 } from "node:path";
41729
+ import { dirname as dirname10, join as join23 } from "node:path";
39884
41730
 
39885
41731
  // src/shared/rpc-utils.ts
39886
- import { join as join21 } from "node:path";
41732
+ import { join as join22 } from "node:path";
39887
41733
  function projectHash(directory) {
39888
41734
  return projectRootKeyHash(directory);
39889
41735
  }
39890
41736
  function rpcPortFileDir(storageDir, directory) {
39891
41737
  const hash = projectHash(directory);
39892
- return join21(storageDir, "rpc", hash, "ports");
41738
+ return join22(storageDir, "rpc", hash, "ports");
39893
41739
  }
39894
41740
  function isPidAlive(pid) {
39895
41741
  if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0)
@@ -39963,7 +41809,7 @@ class AftRpcServer {
39963
41809
  constructor(storageDir, directory) {
39964
41810
  this.portsDir = rpcPortFileDir(storageDir, directory);
39965
41811
  this.instanceId = randomBytes4(8).toString("hex");
39966
- this.portFilePath = join22(this.portsDir, `${this.instanceId}.json`);
41812
+ this.portFilePath = join23(this.portsDir, `${this.instanceId}.json`);
39967
41813
  }
39968
41814
  handle(method, handler) {
39969
41815
  this.handlers.set(method, handler);
@@ -39993,6 +41839,7 @@ class AftRpcServer {
39993
41839
  });
39994
41840
  this.bunServer = server;
39995
41841
  this.port = server.port ?? 0;
41842
+ server.unref?.();
39996
41843
  this.afterServerStarted();
39997
41844
  return this.port;
39998
41845
  }
@@ -40038,7 +41885,7 @@ class AftRpcServer {
40038
41885
  pid: process.pid,
40039
41886
  started_at: Date.now()
40040
41887
  }), { encoding: "utf-8", mode: 384 });
40041
- renameSync10(tmpPath, this.portFilePath);
41888
+ renameSync11(tmpPath, this.portFilePath);
40042
41889
  }
40043
41890
  sweepDeadPortFiles() {
40044
41891
  let entries;
@@ -40050,7 +41897,7 @@ class AftRpcServer {
40050
41897
  for (const entry of entries) {
40051
41898
  if (!entry.endsWith(".json"))
40052
41899
  continue;
40053
- const filePath = join22(this.portsDir, entry);
41900
+ const filePath = join23(this.portsDir, entry);
40054
41901
  if (filePath === this.portFilePath)
40055
41902
  continue;
40056
41903
  try {
@@ -40069,7 +41916,7 @@ class AftRpcServer {
40069
41916
  if (!this.nodeServer && !this.bunServer || this.port <= 0)
40070
41917
  return;
40071
41918
  try {
40072
- if (existsSync19(this.portFilePath))
41919
+ if (existsSync20(this.portFilePath))
40073
41920
  return;
40074
41921
  this.writePortFile();
40075
41922
  log2(`RPC port file was missing; rewrote ${this.portFilePath}`);
@@ -40336,12 +42183,6 @@ function formatCacheRoleLabel(role) {
40336
42183
  }
40337
42184
  return role;
40338
42185
  }
40339
- function formatSemanticIndexStatus(status, stage) {
40340
- if ((status === "loading" || status === "building") && stage === "fingerprint_change") {
40341
- return "Rebuilding (model changed)";
40342
- }
40343
- return status;
40344
- }
40345
42186
  function formatSemanticRefreshing(refreshingCount) {
40346
42187
  if (!Number.isFinite(refreshingCount) || refreshingCount <= 0)
40347
42188
  return null;
@@ -40453,7 +42294,7 @@ function formatStatusMarkdown(status) {
40453
42294
  `- **Cache role:** \`${formatCacheRoleLabel(status.cache_role)}\``
40454
42295
  ];
40455
42296
  appendDegradedStatus(lines, status, true);
40456
- 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)}\``);
40457
42298
  const refreshing = formatSemanticRefreshing(status.semantic_index.refreshing_count);
40458
42299
  if (refreshing) {
40459
42300
  lines.push(`- **Refresh:** ${refreshing}`);
@@ -40622,7 +42463,7 @@ function isSyncWatchAborted(sessionID) {
40622
42463
  }
40623
42464
 
40624
42465
  // src/tools/permissions.ts
40625
- import { execFileSync as execFileSync3 } from "node:child_process";
42466
+ import { execFileSync as execFileSync4 } from "node:child_process";
40626
42467
  import * as fs4 from "node:fs";
40627
42468
  import { tmpdir as tmpdir3 } from "node:os";
40628
42469
  import * as path3 from "node:path";
@@ -40877,7 +42718,7 @@ function gitRootForNearestExistingParent(resolved) {
40877
42718
  cwd = path3.dirname(nearest);
40878
42719
  } catch {}
40879
42720
  try {
40880
- const out = execFileSync3("git", ["rev-parse", "--show-toplevel"], {
42721
+ const out = execFileSync4("git", ["rev-parse", "--show-toplevel"], {
40881
42722
  cwd,
40882
42723
  encoding: "utf8",
40883
42724
  stdio: ["ignore", "pipe", "ignore"]
@@ -41190,6 +43031,26 @@ function failure(error) {
41190
43031
  })();
41191
43032
  return new Error(`V2 tool execution rejected with a non-Error value: ${detail}`);
41192
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
+ }
41193
43054
  function resultContent(result) {
41194
43055
  if (typeof result === "string")
41195
43056
  return { content: result };
@@ -41200,15 +43061,39 @@ function resultContent(result) {
41200
43061
  ...attachment.filename ? { name: attachment.filename } : {}
41201
43062
  }));
41202
43063
  const content = attachments.length ? [{ type: "text", text: result.output }, ...attachments] : result.output;
41203
- const metadata = {
43064
+ const metadata = jsonSafeMetadata({
41204
43065
  ...result.metadata ?? {},
41205
43066
  ...result.title ? { title: result.title } : {}
41206
- };
43067
+ });
41207
43068
  return {
41208
43069
  content,
41209
43070
  ...Object.keys(metadata).length ? { metadata } : {}
41210
43071
  };
41211
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
+ }
41212
43097
  function bareToolName3(name) {
41213
43098
  return name.startsWith("aft_") ? name.slice(4) : name;
41214
43099
  }
@@ -41271,15 +43156,15 @@ function runtimeFor(location, context, signal, consumers) {
41271
43156
  abort: signal,
41272
43157
  effectAbort: signal,
41273
43158
  metadata: (update) => {
41274
- Effect.runPromise(context.progress({
43159
+ Effect.runPromise(context.progress(jsonSafeMetadata({
41275
43160
  ...update.metadata ?? {},
41276
43161
  ...update.title ? { title: update.title } : {}
41277
- }));
43162
+ })));
41278
43163
  },
41279
43164
  ask: (request) => {
41280
43165
  if (consumers.requestPermission)
41281
43166
  return consumers.requestPermission(request, context);
41282
- 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.`));
41283
43168
  },
41284
43169
  progress: context.progress
41285
43170
  };
@@ -41308,6 +43193,9 @@ function projectV2Tool(name, definition, location, consumers = {}) {
41308
43193
  context: runtime,
41309
43194
  definition
41310
43195
  }) : await definition.execute(input, runtime);
43196
+ const refusal = failureEnvelopeMessage(result);
43197
+ if (refusal)
43198
+ throw new Error(refusal);
41311
43199
  return resultContent(result);
41312
43200
  },
41313
43201
  catch: failure
@@ -42402,7 +44290,7 @@ function createReadTool(ctx) {
42402
44290
  try {
42403
44291
  await runAsk(context.ask({
42404
44292
  permission: "read",
42405
- patterns: [filePath],
44293
+ patterns: [permissionPath(context, filePath)],
42406
44294
  always: ["*"],
42407
44295
  metadata: {}
42408
44296
  }));
@@ -42563,7 +44451,7 @@ function getEditDescription(ctx, writeToolName) {
42563
44451
 
42564
44452
  **Modes** (determined by which parameters you provide):
42565
44453
 
42566
- 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.
42567
44455
 
42568
44456
  1. **Append** — pass \`path\` + \`appendContent\`
42569
44457
  Appends text to the end of a file, creating it if it does not exist.
@@ -42664,8 +44552,8 @@ function createEditTool(ctx, writeToolName = "write") {
42664
44552
  description: getEditDescription(ctx, writeToolName),
42665
44553
  args: {
42666
44554
  filePath: z7.string().describe("Path to the file to edit (absolute or relative to project root)"),
42667
- symbol: z7.string().optional().describe("Named symbol to replace (function, class, type)"),
42668
- 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."),
42669
44557
  appendContent: z7.string().optional().describe("Text to append to the end of path; creates the file if needed"),
42670
44558
  edits: z7.array(z7.object({
42671
44559
  oldString: z7.string().optional().describe("Text to find for a batch find/replace edit"),
@@ -42907,7 +44795,7 @@ function createDeleteTool(ctx) {
42907
44795
  }
42908
44796
  await runAsk(context.ask({
42909
44797
  permission: "edit",
42910
- patterns: absolutePaths,
44798
+ patterns: resolveRelativePatterns(context, absolutePaths),
42911
44799
  always: ["*"],
42912
44800
  metadata: { action: "delete", count: absolutePaths.length }
42913
44801
  }));
@@ -42960,7 +44848,7 @@ function createMoveTool(ctx) {
42960
44848
  }
42961
44849
  await runAsk(context.ask({
42962
44850
  permission: "edit",
42963
- patterns: [filePath, destPath],
44851
+ patterns: resolveRelativePatterns(context, [filePath, destPath]),
42964
44852
  always: ["*"],
42965
44853
  metadata: { action: "move" }
42966
44854
  }));
@@ -43290,7 +45178,7 @@ function inspectTools(ctx) {
43290
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.",
43291
45179
  args: {
43292
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.")),
43293
- 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.")),
43294
45182
  topK: arg(z9.number().int().positive().max(100).optional().describe("Max drill-down items per category. Default 20, max 100."))
43295
45183
  },
43296
45184
  execute: async (args, context) => {
@@ -43683,7 +45571,7 @@ function safetyTools(ctx) {
43683
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.
43684
45572
  ` + `- 'history': List all edit snapshots for a file. Requires 'path'.
43685
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'.
43686
- ` + `- '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'.
43687
45575
  ` + `- 'list': List all available named checkpoints. No extra params needed.
43688
45576
 
43689
45577
  ` + `Each op requires specific parameters — see parameter descriptions for requirements.
@@ -43691,9 +45579,9 @@ function safetyTools(ctx) {
43691
45579
  ` + "Use checkpoint before risky multi-file changes. Use undo for quick single-file rollback.",
43692
45580
  args: {
43693
45581
  op: z12.enum(["undo", "history", "checkpoint", "restore", "list"]).describe("Safety operation"),
43694
- 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"),
43695
45583
  name: z12.string().optional().describe("Checkpoint name (required for checkpoint, restore)"),
43696
- 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)")
43697
45585
  },
43698
45586
  execute: async (args, context) => {
43699
45587
  const op = args.op;
@@ -44030,7 +45918,7 @@ function semanticTools(ctx) {
44030
45918
  const rawArgs = { query };
44031
45919
  const topK = coerceOptionalInt(args.topK, "topK", 1, 50);
44032
45920
  const offset = coerceOptionalInt(args.offset, "offset", 0, 1e5);
44033
- const includeTests = typeof args.includeTests === "boolean" ? args.includeTests : undefined;
45921
+ const includeTests = !isEmptyParam(args.includeTests) ? coerceBoolean(args.includeTests) : undefined;
44034
45922
  if (topK !== undefined)
44035
45923
  rawArgs.topK = topK;
44036
45924
  if (offset !== undefined)
@@ -44270,11 +46158,11 @@ function throwSentinel(command) {
44270
46158
  throw sentinel;
44271
46159
  }
44272
46160
  var PLUGIN_VERSION = resolvePluginVersion(import.meta.url);
44273
- var ANNOUNCEMENT_VERSION = "0.56.0";
46161
+ var ANNOUNCEMENT_VERSION = "0.57.0";
44274
46162
  var ANNOUNCEMENT_FEATURES = [
44275
- "Callgraph stays consistent under load: edits arriving mid-rebuild can no longer be silently lost from navigation results.",
44276
- "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).",
44277
- "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."
44278
46166
  ];
44279
46167
  var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
44280
46168
  var plugin = async (input) => initializePluginForDirectory(input);
@@ -44946,7 +46834,7 @@ Install: ${getManualInstallHint()}`).catch(() => {});
44946
46834
  var src_default = plugin;
44947
46835
 
44948
46836
  // src/entry/server-runtime.mjs
44949
- import { Effect as Effect5 } from "effect";
46837
+ import { Effect as Effect6 } from "effect";
44950
46838
 
44951
46839
  // src/rpc/register.ts
44952
46840
  import { Effect as Effect2 } from "effect";
@@ -45149,6 +47037,8 @@ function registerAftRpc(context, location, pool) {
45149
47037
  }
45150
47038
 
45151
47039
  // src/permissions/v2.ts
47040
+ import { Effect as Effect3 } from "effect";
47041
+
45152
47042
  class PermissionDeniedError extends Error {
45153
47043
  name = "PermissionDeniedError";
45154
47044
  }
@@ -45156,6 +47046,107 @@ class PermissionDeniedError extends Error {
45156
47046
  class PermissionRejectedError extends Error {
45157
47047
  name = "PermissionRejectedError";
45158
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
+ }
45159
47150
  function requiredContextID(context, key) {
45160
47151
  const value = context[key];
45161
47152
  if (typeof value !== "string" || value.length === 0) {
@@ -45180,43 +47171,117 @@ function repliedEvent(event) {
45180
47171
  const candidate = envelope.payload ?? event;
45181
47172
  if (candidate.type !== "permission.replied")
45182
47173
  return;
45183
- if (!candidate.properties || typeof candidate.properties !== "object")
47174
+ if (!candidate.data || typeof candidate.data !== "object")
45184
47175
  return;
45185
- return candidate;
47176
+ return candidate.data;
45186
47177
  }
45187
47178
  async function closeStream(iterator) {
45188
47179
  if (typeof iterator.return === "function")
45189
47180
  await iterator.return();
45190
47181
  }
45191
- async function waitForReply(stream, sessionID, requestID) {
45192
- 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;
45193
47243
  try {
45194
47244
  while (true) {
45195
- const next = await iterator.next();
45196
- if (next.done)
45197
- throw new Error("Permission event stream ended before a reply arrived");
45198
- const event = repliedEvent(next.value);
45199
- 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)
45200
47266
  continue;
45201
- }
45202
- if (event.properties.reply === "reject") {
47267
+ if (event.reply === "reject")
45203
47268
  throw new PermissionRejectedError("Permission denied.");
45204
- }
45205
47269
  return;
45206
47270
  }
45207
47271
  } finally {
47272
+ deadline.cancel();
47273
+ abort.dispose();
45208
47274
  await closeStream(iterator);
45209
47275
  }
45210
47276
  }
45211
- async function requestPermission(host, request, context) {
47277
+ async function raisePrompt(client, request, decision, context, limits) {
45212
47278
  const sessionID = requiredContextID(context, "sessionID");
45213
47279
  const messageID = requiredContextID(context, "messageID");
45214
47280
  const id = requiredContextID(context, "id");
45215
- const subscription = await host.client.event.subscribe();
45216
- const iterator = subscription.stream[Symbol.asyncIterator]();
47281
+ const listening = await startListening(client, limits.listenTimeoutMs);
45217
47282
  let streamClaimed = false;
45218
47283
  try {
45219
- const result = createResult(await host.client.permission.create({
47284
+ const result = createResult(await client.permission.create({
45220
47285
  sessionID,
45221
47286
  action: request.permission,
45222
47287
  resources: [...request.patterns],
@@ -45228,25 +47293,343 @@ async function requestPermission(host, request, context) {
45228
47293
  return;
45229
47294
  if (result.effect === "deny")
45230
47295
  throw new PermissionDeniedError("Permission denied.");
47296
+ if ("unavailable" in listening) {
47297
+ throw new PermissionPromptUnavailableError(promptUnavailableMessage(request, decision, listening.unavailable));
47298
+ }
45231
47299
  streamClaimed = true;
45232
- 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
+ }
45233
47307
  } finally {
45234
- if (!streamClaimed)
45235
- 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;
47514
+ }
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
+ };
45236
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
+ };
45237
47614
  }
45238
47615
 
45239
47616
  // src/tools/hoisted/v2.ts
45240
- function hoistedV2ToolConsumers(host) {
45241
- 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"))
45242
47625
  return {};
45243
47626
  return {
45244
- requestPermission: (request, context) => requestPermission(host, request, context)
47627
+ requestPermission: (request, context) => requestPermission(host, request, context, prompt)
45245
47628
  };
45246
47629
  }
45247
47630
 
45248
47631
  // src/wakes/runtime-consumer.ts
45249
- import { Effect as Effect4 } from "effect";
47632
+ import { Effect as Effect5 } from "effect";
45250
47633
 
45251
47634
  // src/cancellation/effect-abort.ts
45252
47635
  function forwardEffectAbort(signal, send) {
@@ -45295,7 +47678,7 @@ async function executeV2Bash(execution) {
45295
47678
  }
45296
47679
 
45297
47680
  // src/wakes/session-delivery.ts
45298
- import { Effect as Effect3 } from "effect";
47681
+ import { Effect as Effect4 } from "effect";
45299
47682
 
45300
47683
  class V2SessionDelivery {
45301
47684
  session;
@@ -45305,12 +47688,12 @@ class V2SessionDelivery {
45305
47688
  this.session = session;
45306
47689
  }
45307
47690
  completion(input) {
45308
- return Effect3.suspend(() => {
47691
+ return Effect4.suspend(() => {
45309
47692
  if (this.disposed)
45310
- return Effect3.succeed(false);
47693
+ return Effect4.succeed(false);
45311
47694
  const keys = [...new Set(input.taskIDs)].map((taskID) => `${input.sessionID}\x00${taskID}`);
45312
47695
  if (keys.length === 0 || keys.every((key) => this.admittedCompletions.has(key))) {
45313
- return Effect3.succeed(false);
47696
+ return Effect4.succeed(false);
45314
47697
  }
45315
47698
  for (const key of keys)
45316
47699
  this.admittedCompletions.add(key);
@@ -45322,20 +47705,20 @@ class V2SessionDelivery {
45322
47705
  ...input.metadata,
45323
47706
  task_ids: [...new Set(input.taskIDs)]
45324
47707
  }
45325
- }).pipe(Effect3.map(() => true));
47708
+ }).pipe(Effect4.map(() => true));
45326
47709
  });
45327
47710
  }
45328
47711
  status(input) {
45329
- return Effect3.suspend(() => {
47712
+ return Effect4.suspend(() => {
45330
47713
  if (this.disposed)
45331
- return Effect3.succeed(undefined);
47714
+ return Effect4.succeed(undefined);
45332
47715
  return this.session.synthetic({
45333
47716
  sessionID: input.sessionID,
45334
47717
  text: input.text,
45335
47718
  description: input.description,
45336
47719
  metadata: input.metadata,
45337
47720
  resume: false
45338
- }).pipe(Effect3.asVoid);
47721
+ }).pipe(Effect4.asVoid);
45339
47722
  });
45340
47723
  }
45341
47724
  dispose() {
@@ -45352,7 +47735,7 @@ async function routeCompletion(completion, bridge) {
45352
47735
  const route = sessionRoutes.get(completion.session_id);
45353
47736
  if (!route)
45354
47737
  return;
45355
- const admitted = await Effect4.runPromise(route.delivery.completion({
47738
+ const admitted = await Effect5.runPromise(route.delivery.completion({
45356
47739
  sessionID: completion.session_id,
45357
47740
  taskIDs: [completion.task_id],
45358
47741
  text: formatSystemReminder([completion]),
@@ -45374,7 +47757,7 @@ async function routeLongRunning(reminder, _bridge) {
45374
47757
  const route = sessionRoutes.get(reminder.session_id);
45375
47758
  if (!route)
45376
47759
  return;
45377
- await Effect4.runPromise(route.delivery.status({
47760
+ await Effect5.runPromise(route.delivery.status({
45378
47761
  sessionID: reminder.session_id,
45379
47762
  text: formatLongRunningReminder([reminder]),
45380
47763
  description: "Background bash status",
@@ -45474,19 +47857,19 @@ function makeServerEffect(overrides = {}) {
45474
47857
  const location = context.location;
45475
47858
  if (typeof location?.directory !== "string") {
45476
47859
  debug2("V2 effect skipped: host context has no location");
45477
- return Effect5.void;
47860
+ return Effect6.void;
45478
47861
  }
45479
47862
  log2("AFT V2 runtime starting");
45480
- return Effect5.gen(function* () {
45481
- const runtime = yield* Effect5.promise(() => bootLocation(context, location, dependencies));
47863
+ return Effect6.gen(function* () {
47864
+ const runtime = yield* Effect6.promise(() => bootLocation(context, location, dependencies));
45482
47865
  if (!runtime)
45483
47866
  return;
45484
- yield* Effect5.addFinalizer(() => Effect5.promise(async () => {
47867
+ yield* Effect6.addFinalizer(() => Effect6.promise(async () => {
45485
47868
  runtime.consumers.dispose?.();
45486
47869
  await dependencies.releaseBridge(runtime.pool);
45487
47870
  }));
45488
47871
  const rpc = yield* dependencies.registerRpc(context, location, runtime.pool);
45489
- yield* Effect5.addFinalizer(() => Effect5.promise(() => rpc.dispose()));
47872
+ yield* Effect6.addFinalizer(() => Effect6.promise(() => rpc.dispose()));
45490
47873
  yield* dependencies.registerTools(context, location, runtime.tools, runtime.consumers);
45491
47874
  });
45492
47875
  };