@cortexkit/aft-opencode 0.25.2 → 0.26.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA8JlD;;;;;;;;;;;;;;;;;;GAkBG;AAQH,QAAA,MAAM,MAAM,EAAE,MAA6D,CAAC;AA4vB5E,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA8JlD;;;;;;;;;;;;;;;;;;GAkBG;AAQH,QAAA,MAAM,MAAM,EAAE,MAA6D,CAAC;AAuvB5E,eAAe,MAAM,CAAC"}
package/dist/index.js CHANGED
@@ -7931,6 +7931,15 @@ function clampSemanticTimeout(configOverrides, bridgeTimeoutMs) {
7931
7931
  };
7932
7932
  }
7933
7933
 
7934
+ class BridgeReplacedDuringVersionCheck extends Error {
7935
+ newBinaryPath;
7936
+ constructor(newBinaryPath) {
7937
+ super(`Bridge binary replaced during version check: ${newBinaryPath}`);
7938
+ this.newBinaryPath = newBinaryPath;
7939
+ this.name = "BridgeReplacedDuringVersionCheck";
7940
+ }
7941
+ }
7942
+
7934
7943
  class BinaryBridge {
7935
7944
  static RESTART_RESET_MS = 5 * 60 * 1000;
7936
7945
  static STDERR_TAIL_MAX = 20;
@@ -8019,97 +8028,108 @@ class BinaryBridge {
8019
8028
  this.cachedStatus = snapshot;
8020
8029
  }
8021
8030
  async send(command, params = {}, options) {
8022
- if (this._shuttingDown) {
8023
- throw new Error(`${this.errorPrefix} Bridge is shutting down, cannot send "${command}"`);
8024
- }
8025
- if (Object.hasOwn(params, "id")) {
8026
- throw new Error("params cannot contain reserved key 'id'");
8027
- }
8028
- const requestSessionId = typeof params.session_id === "string" && params.session_id.length > 0 ? params.session_id : undefined;
8029
- this.ensureSpawned(requestSessionId);
8030
- if (requestSessionId && options?.configureWarningClient !== undefined) {
8031
- this.configureWarningClients.set(requestSessionId, options.configureWarningClient);
8032
- }
8033
- if (!this.configured) {
8034
- if (command !== "configure" && command !== "version") {
8035
- if (!this._configurePromise) {
8036
- const sessionIdForConfigure = typeof params.session_id === "string" ? params.session_id : undefined;
8037
- this._configurePromise = (async () => {
8038
- try {
8039
- const configResult = await this.send("configure", {
8040
- project_root: this.cwd,
8041
- ...this.configOverrides,
8042
- ...sessionIdForConfigure ? { session_id: sessionIdForConfigure } : {}
8043
- });
8044
- if (configResult.success === false) {
8045
- throw new Error(`${this.errorPrefix} Configure failed: ${configResult.message ?? "unknown error"}`);
8046
- }
8047
- await this.deliverConfigureWarnings(configResult, params, options);
8048
- await this.checkVersion();
8049
- if (!this.isAlive()) {
8050
- throw new Error(`${this.errorPrefix} Bridge died during version check. Check logs: ${getLogFilePath()}`);
8031
+ return this.sendWithVersionMismatchRetry(command, params, options, true);
8032
+ }
8033
+ async sendWithVersionMismatchRetry(command, params, options, canRetryAfterVersionSwap) {
8034
+ try {
8035
+ if (this._shuttingDown) {
8036
+ throw new Error(`${this.errorPrefix} Bridge is shutting down, cannot send "${command}"`);
8037
+ }
8038
+ if (Object.hasOwn(params, "id")) {
8039
+ throw new Error("params cannot contain reserved key 'id'");
8040
+ }
8041
+ const requestSessionId = typeof params.session_id === "string" && params.session_id.length > 0 ? params.session_id : undefined;
8042
+ this.ensureSpawned(requestSessionId);
8043
+ if (requestSessionId && options?.configureWarningClient !== undefined) {
8044
+ this.configureWarningClients.set(requestSessionId, options.configureWarningClient);
8045
+ }
8046
+ if (!this.configured) {
8047
+ if (command !== "configure" && command !== "version") {
8048
+ if (!this._configurePromise) {
8049
+ const sessionIdForConfigure = typeof params.session_id === "string" ? params.session_id : undefined;
8050
+ this._configurePromise = (async () => {
8051
+ try {
8052
+ const configResult = await this.send("configure", {
8053
+ project_root: this.cwd,
8054
+ ...this.configOverrides,
8055
+ ...sessionIdForConfigure ? { session_id: sessionIdForConfigure } : {}
8056
+ });
8057
+ if (configResult.success === false) {
8058
+ throw new Error(`${this.errorPrefix} Configure failed: ${configResult.message ?? "unknown error"}`);
8059
+ }
8060
+ await this.deliverConfigureWarnings(configResult, params, options);
8061
+ await this.checkVersion();
8062
+ if (!this.isAlive()) {
8063
+ throw new Error(`${this.errorPrefix} Bridge died during version check. Check logs: ${getLogFilePath()}`);
8064
+ }
8065
+ this.configured = true;
8066
+ } finally {
8067
+ this._configurePromise = null;
8051
8068
  }
8052
- this.configured = true;
8053
- } finally {
8054
- this._configurePromise = null;
8055
- }
8056
- })();
8057
- }
8058
- await this._configurePromise;
8059
- }
8060
- }
8061
- const id = String(this.nextId++);
8062
- let request;
8063
- if (Object.hasOwn(params, "command") || Object.hasOwn(params, "method")) {
8064
- const nested = { ...params };
8065
- const reserved = {};
8066
- for (const key of ["session_id", "lsp_hints"]) {
8067
- if (Object.hasOwn(nested, key)) {
8068
- reserved[key] = nested[key];
8069
- delete nested[key];
8069
+ })();
8070
+ }
8071
+ await this._configurePromise;
8072
+ }
8073
+ }
8074
+ const id = String(this.nextId++);
8075
+ let request;
8076
+ if (Object.hasOwn(params, "command") || Object.hasOwn(params, "method")) {
8077
+ const nested = { ...params };
8078
+ const reserved = {};
8079
+ for (const key of ["session_id", "lsp_hints"]) {
8080
+ if (Object.hasOwn(nested, key)) {
8081
+ reserved[key] = nested[key];
8082
+ delete nested[key];
8083
+ }
8070
8084
  }
8085
+ request = { id, command, ...reserved, params: nested };
8086
+ } else {
8087
+ request = { id, command, ...params };
8071
8088
  }
8072
- request = { id, command, ...reserved, params: nested };
8073
- } else {
8074
- request = { id, command, ...params };
8075
- }
8076
- const line = `${JSON.stringify(request)}
8089
+ const line = `${JSON.stringify(request)}
8077
8090
  `;
8078
- const effectiveTimeoutMs = options?.transportTimeoutMs ?? options?.timeoutMs ?? this.timeoutMs;
8079
- const keepBridgeOnTimeout = options?.keepBridgeOnTimeout === true;
8080
- return new Promise((resolve, reject) => {
8081
- const timer = setTimeout(() => {
8082
- this.pending.delete(id);
8083
- const restartSuffix = keepBridgeOnTimeout ? "" : " \u2014 restarting bridge";
8084
- const timeoutMsg = `Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms${restartSuffix}`;
8085
- if (requestSessionId) {
8086
- sessionWarn(requestSessionId, timeoutMsg);
8087
- } else {
8088
- warn(timeoutMsg);
8089
- }
8090
- reject(new Error(`${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
8091
- if (!keepBridgeOnTimeout) {
8092
- this.handleTimeout(requestSessionId);
8093
- }
8094
- }, effectiveTimeoutMs);
8095
- this.pending.set(id, { resolve, reject, timer, onProgress: options?.onProgress });
8096
- if (!this.process?.stdin?.writable) {
8097
- this.pending.delete(id);
8098
- clearTimeout(timer);
8099
- reject(new Error(`${this.errorPrefix} stdin not writable for command "${command}"`));
8100
- return;
8101
- }
8102
- this.process.stdin.write(line, (err) => {
8103
- if (err) {
8104
- const entry = this.pending.get(id);
8105
- if (entry) {
8106
- this.pending.delete(id);
8107
- clearTimeout(entry.timer);
8108
- entry.reject(new Error(`${this.errorPrefix} Failed to write to stdin: ${err.message}`));
8091
+ const effectiveTimeoutMs = options?.transportTimeoutMs ?? options?.timeoutMs ?? this.timeoutMs;
8092
+ const keepBridgeOnTimeout = options?.keepBridgeOnTimeout === true;
8093
+ return new Promise((resolve, reject) => {
8094
+ const timer = setTimeout(() => {
8095
+ this.pending.delete(id);
8096
+ const restartSuffix = keepBridgeOnTimeout ? "" : " \u2014 restarting bridge";
8097
+ const timeoutMsg = `Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms${restartSuffix}`;
8098
+ if (requestSessionId) {
8099
+ sessionWarn(requestSessionId, timeoutMsg);
8100
+ } else {
8101
+ warn(timeoutMsg);
8109
8102
  }
8103
+ reject(new Error(`${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
8104
+ if (!keepBridgeOnTimeout) {
8105
+ this.handleTimeout(requestSessionId);
8106
+ }
8107
+ }, effectiveTimeoutMs);
8108
+ this.pending.set(id, { resolve, reject, timer, onProgress: options?.onProgress });
8109
+ if (!this.process?.stdin?.writable) {
8110
+ this.pending.delete(id);
8111
+ clearTimeout(timer);
8112
+ reject(new Error(`${this.errorPrefix} stdin not writable for command "${command}"`));
8113
+ return;
8110
8114
  }
8115
+ this.process.stdin.write(line, (err) => {
8116
+ if (err) {
8117
+ const entry = this.pending.get(id);
8118
+ if (entry) {
8119
+ this.pending.delete(id);
8120
+ clearTimeout(entry.timer);
8121
+ entry.reject(new Error(`${this.errorPrefix} Failed to write to stdin: ${err.message}`));
8122
+ }
8123
+ }
8124
+ });
8111
8125
  });
8112
- });
8126
+ } catch (err) {
8127
+ if (err instanceof BridgeReplacedDuringVersionCheck && canRetryAfterVersionSwap && command !== "configure" && command !== "version") {
8128
+ log(`Retrying request "${command}" once after coordinated binary replacement: ${err.newBinaryPath}`);
8129
+ return this.sendWithVersionMismatchRetry(command, params, options, false);
8130
+ }
8131
+ throw err;
8132
+ }
8113
8133
  }
8114
8134
  async deliverConfigureWarnings(configResult, params, options) {
8115
8135
  if (!this.onConfigureWarnings || !Array.isArray(configResult.warnings))
@@ -8208,13 +8228,43 @@ class BinaryBridge {
8208
8228
  log(`Binary version: ${binaryVersion}`);
8209
8229
  if (compareSemver(binaryVersion, this.minVersion) < 0) {
8210
8230
  warn(`Binary version ${binaryVersion} is older than required ${this.minVersion}`);
8211
- this.onVersionMismatch?.(binaryVersion, this.minVersion);
8231
+ const replacementPath = await this.onVersionMismatch?.(binaryVersion, this.minVersion);
8232
+ if (replacementPath === undefined) {
8233
+ return;
8234
+ }
8235
+ if (replacementPath === null || replacementPath.length === 0) {
8236
+ throw new Error(`Binary version ${binaryVersion} is older than required ${this.minVersion}; no compatible replacement binary was provided`);
8237
+ }
8238
+ await this.replaceCurrentBinary(replacementPath);
8239
+ throw new BridgeReplacedDuringVersionCheck(replacementPath);
8212
8240
  }
8213
8241
  } catch (err) {
8214
8242
  warn(`Version check failed: ${err.message}`);
8215
8243
  throw err;
8216
8244
  }
8217
8245
  }
8246
+ async replaceCurrentBinary(newBinaryPath) {
8247
+ this.binaryPath = newBinaryPath;
8248
+ this.configured = false;
8249
+ this.clearRestartResetTimer();
8250
+ this.rejectAllPending(new Error(`${this.errorPrefix} Bridge restarting with updated binary: ${newBinaryPath}`));
8251
+ if (!this.process)
8252
+ return;
8253
+ const proc = this.process;
8254
+ this.process = null;
8255
+ await new Promise((resolve) => {
8256
+ const forceKillTimer = setTimeout(() => {
8257
+ proc.kill("SIGKILL");
8258
+ resolve();
8259
+ }, 5000);
8260
+ proc.once("exit", () => {
8261
+ clearTimeout(forceKillTimer);
8262
+ log("Process exited during coordinated binary replacement");
8263
+ resolve();
8264
+ });
8265
+ proc.kill("SIGTERM");
8266
+ });
8267
+ }
8218
8268
  ensureSpawned(triggeringSessionId) {
8219
8269
  if (this.isAlive())
8220
8270
  return;
@@ -9302,6 +9352,7 @@ class BridgePool {
9302
9352
  this.bridges.clear();
9303
9353
  await Promise.allSettled(shutdowns);
9304
9354
  this.log(`Binary path updated to ${newPath}. All bridges cleared \u2014 next calls will use the new binary.`);
9355
+ return newPath;
9305
9356
  }
9306
9357
  log(message, meta) {
9307
9358
  const logger = this.logger ?? getActiveLogger();
@@ -9352,7 +9403,9 @@ function readBinaryVersion(binaryPath) {
9352
9403
  stdio: ["pipe", "pipe", "pipe"],
9353
9404
  timeout: 5000
9354
9405
  });
9355
- const rawVersion = result.stdout?.trim();
9406
+ const stdoutVersion = result.stdout?.trim();
9407
+ const stderrVersion = result.stderr?.trim();
9408
+ const rawVersion = stdoutVersion || stderrVersion;
9356
9409
  if (!rawVersion)
9357
9410
  return null;
9358
9411
  return rawVersion.replace(/^aft\s+/, "");
@@ -9688,6 +9741,7 @@ async function fetchUrlToTempFile(url, storageDir, options = {}) {
9688
9741
  throw new Error(`Only http:// and https:// URLs are supported, got: ${parsed.protocol}`);
9689
9742
  }
9690
9743
  const allowPrivate = options.allowPrivate === true;
9744
+ await assertPublicUrl(parsed, allowPrivate, options.lookup);
9691
9745
  const dir = cacheDir(storageDir);
9692
9746
  mkdirSync4(dir, { recursive: true });
9693
9747
  const hash = hashUrl(url);
@@ -27044,7 +27098,7 @@ async function getSessionDirectory(client, sessionId, fallbackDirectory) {
27044
27098
  }
27045
27099
  let dir = null;
27046
27100
  try {
27047
- const result = await sessionApi.get({ sessionID: sessionId, directory: fallbackDirectory });
27101
+ const result = await sessionApi.get({ path: { id: sessionId } });
27048
27102
  const session = result?.data ?? result;
27049
27103
  if (session && typeof session.directory === "string" && session.directory.length > 0) {
27050
27104
  dir = session.directory;
@@ -29040,8 +29094,11 @@ function createEditTool(ctx, writeToolName = "write") {
29040
29094
  ...op,
29041
29095
  file: path4.isAbsolute(op.file) ? op.file : path4.resolve(context.directory, op.file)
29042
29096
  }));
29043
- const data2 = await callBridge(ctx, context, "transaction", { operations: resolvedOps });
29044
- return JSON.stringify(data2);
29097
+ const response = await callBridge(ctx, context, "transaction", { operations: resolvedOps });
29098
+ if (response.success === false) {
29099
+ throw new Error(response.message ?? "transaction failed");
29100
+ }
29101
+ return JSON.stringify(response);
29045
29102
  }
29046
29103
  const file2 = args.filePath;
29047
29104
  if (!file2)
@@ -29520,6 +29577,9 @@ function createDeleteTool(ctx) {
29520
29577
  files: absolutePaths,
29521
29578
  recursive
29522
29579
  });
29580
+ if (response.success === false) {
29581
+ throw new Error(response.message ?? "delete failed");
29582
+ }
29523
29583
  const deletedEntries = response.deleted ?? [];
29524
29584
  const skipped = response.skipped_files ?? [];
29525
29585
  const deleted = deletedEntries.map((entry) => entry.file);
@@ -29603,7 +29663,7 @@ function formatError2(error50) {
29603
29663
  }
29604
29664
  function aftPrefixedTools(ctx) {
29605
29665
  const aftEditTool = createEditTool(ctx, "aft_write");
29606
- return {
29666
+ const tools = {
29607
29667
  aft_read: createReadTool(ctx),
29608
29668
  aft_write: createWriteTool(ctx, "aft_edit"),
29609
29669
  aft_edit: {
@@ -29632,8 +29692,11 @@ function aftPrefixedTools(ctx) {
29632
29692
  create_dirs: normalizedArgs.create_dirs !== false,
29633
29693
  diagnostics: true
29634
29694
  };
29635
- const data = await callBridge(ctx, context, "write", writeParams);
29636
- return JSON.stringify(data);
29695
+ const response = await callBridge(ctx, context, "write", writeParams);
29696
+ if (response.success === false) {
29697
+ throw new Error(response.message ?? "write failed");
29698
+ }
29699
+ return JSON.stringify(response);
29637
29700
  }
29638
29701
  return aftEditTool.execute(normalizedArgs, context);
29639
29702
  }
@@ -29642,6 +29705,16 @@ function aftPrefixedTools(ctx) {
29642
29705
  aft_delete: createDeleteTool(ctx),
29643
29706
  aft_move: createMoveTool(ctx)
29644
29707
  };
29708
+ const bashRewrite = ctx.config.experimental?.bash?.rewrite === true;
29709
+ const bashCompress = ctx.config.experimental?.bash?.compress === true;
29710
+ const bashBackground = ctx.config.experimental?.bash?.background === true;
29711
+ const anyBashExperimental = bashRewrite || bashCompress || bashBackground;
29712
+ if (anyBashExperimental) {
29713
+ tools.aft_bash = createBashTool(ctx);
29714
+ tools.bash_status = createBashStatusTool(ctx);
29715
+ tools.bash_kill = createBashKillTool(ctx);
29716
+ }
29717
+ return tools;
29645
29718
  }
29646
29719
 
29647
29720
  // src/tools/imports.ts
@@ -30818,25 +30891,27 @@ ${lines}
30818
30891
  const poolOptions = {
30819
30892
  errorPrefix: "[aft-plugin]",
30820
30893
  minVersion: PLUGIN_VERSION,
30821
- onVersionMismatch: (binaryVersion, minVersion) => {
30894
+ onVersionMismatch: async (binaryVersion, minVersion) => {
30822
30895
  if (versionUpgradeAttempted === binaryVersion) {
30823
30896
  log2(`Version ${binaryVersion} < ${minVersion} but upgrade already attempted \u2014 continuing`);
30824
- return;
30897
+ return null;
30825
30898
  }
30826
30899
  versionUpgradeAttempted = binaryVersion;
30827
30900
  warn2(`WARNING: aft binary v${binaryVersion} is older than plugin v${minVersion}. ` + "Some features may not work. Attempting to download a compatible binary...");
30828
- ensureBinary(`v${minVersion}`).then((path7) => {
30829
- if (path7) {
30830
- log2(`Found/downloaded compatible binary at ${path7}. Replacing running bridges...`);
30831
- pool.replaceBinary(path7).then(() => {
30832
- log2("Binary replaced successfully. New bridges will use the updated binary.");
30833
- }, (err) => error2("Failed to replace binary:", err));
30834
- } else {
30901
+ try {
30902
+ const path7 = await ensureBinary(`v${minVersion}`);
30903
+ if (!path7) {
30835
30904
  warn2(`Could not find or download v${minVersion}. Continuing with v${binaryVersion}.`);
30905
+ return null;
30836
30906
  }
30837
- }, (err) => {
30907
+ log2(`Found/downloaded compatible binary at ${path7}. Replacing running bridges...`);
30908
+ const replaced = await pool.replaceBinary(path7);
30909
+ log2("Binary replaced successfully. New bridges will use the updated binary.");
30910
+ return replaced;
30911
+ } catch (err) {
30838
30912
  error2(`Auto-download failed: ${err.message}. Install manually: cargo install agent-file-tools@${minVersion}`);
30839
- });
30913
+ return null;
30914
+ }
30840
30915
  },
30841
30916
  onConfigureWarnings: async ({ projectRoot, sessionId, client, warnings }) => {
30842
30917
  const pendingWarnings = sessionId ? drainPendingEagerWarnings(projectRoot) : [];
@@ -1,7 +1,8 @@
1
1
  /**
2
- * Resolve the project directory the session was created with. Returns
3
- * `null` when the lookup is unavailable or fails callers should fall
4
- * back to the runtime's directory in that case.
2
+ * Resolve the project directory the session was created with from the SDK's
3
+ * session object. Returns the SDK-reported directory, or `null` when the
4
+ * lookup is unavailable/fails — callers should fall back to the runtime's
5
+ * directory in that case.
5
6
  *
6
7
  * This function is best-effort: any error (missing `client.session.get`,
7
8
  * network failure, malformed response) is logged and recorded as a
@@ -1 +1 @@
1
- {"version":3,"file":"session-directory.d.ts","sourceRoot":"","sources":["../../src/shared/session-directory.ts"],"names":[],"mappings":"AA8CA;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0CxB;AAWD;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,GAAG,IAAI,GAAG,SAAS,CAK3B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,iBAAiB,EAAE,MAAM,GACxB,IAAI,CAIN;AAED,qDAAqD;AACrD,wBAAgB,kCAAkC,IAAI,IAAI,CAEzD"}
1
+ {"version":3,"file":"session-directory.d.ts","sourceRoot":"","sources":["../../src/shared/session-directory.ts"],"names":[],"mappings":"AA+CA;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA8CxB;AAWD;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,GAAG,IAAI,GAAG,SAAS,CAK3B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,iBAAiB,EAAE,MAAM,GACxB,IAAI,CAIN;AAED,qDAAqD;AACrD,wBAAgB,kCAAkC,IAAI,IAAI,CAEzD"}
@@ -1 +1 @@
1
- {"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuEjD,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,EAAE,OAAO,MAAM,KAAG,MAChD,CAAC;AAqRtC;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CA+JjE;AAukCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAwB/E;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA6EnF"}
1
+ {"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuEjD,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,EAAE,OAAO,MAAM,KAAG,MAChD,CAAC;AAqRtC;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CA+JjE;AA8kCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAwB/E;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAgGnF"}
package/dist/tui.js CHANGED
@@ -4,7 +4,7 @@ import { createMemo as createMemo2, createSignal as createSignal2, onCleanup as
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "@cortexkit/aft-opencode",
7
- version: "0.25.2",
7
+ version: "0.26.0",
8
8
  type: "module",
9
9
  description: "OpenCode plugin for Agent File Tools (AFT) \u2014 tree-sitter and lsp powered code analysis",
10
10
  main: "dist/index.js",
@@ -32,7 +32,7 @@ var package_default = {
32
32
  },
33
33
  dependencies: {
34
34
  "@clack/prompts": "^1.2.0",
35
- "@cortexkit/aft-bridge": "0.25.2",
35
+ "@cortexkit/aft-bridge": "0.26.0",
36
36
  "@opencode-ai/plugin": "^1.14.39",
37
37
  "@opencode-ai/sdk": "^1.14.39",
38
38
  "comment-json": "^4.6.2",
@@ -40,11 +40,11 @@ var package_default = {
40
40
  zod: "^4.1.8"
41
41
  },
42
42
  optionalDependencies: {
43
- "@cortexkit/aft-darwin-arm64": "0.25.2",
44
- "@cortexkit/aft-darwin-x64": "0.25.2",
45
- "@cortexkit/aft-linux-arm64": "0.25.2",
46
- "@cortexkit/aft-linux-x64": "0.25.2",
47
- "@cortexkit/aft-win32-x64": "0.25.2"
43
+ "@cortexkit/aft-darwin-arm64": "0.26.0",
44
+ "@cortexkit/aft-darwin-x64": "0.26.0",
45
+ "@cortexkit/aft-linux-arm64": "0.26.0",
46
+ "@cortexkit/aft-linux-x64": "0.26.0",
47
+ "@cortexkit/aft-win32-x64": "0.26.0"
48
48
  },
49
49
  devDependencies: {
50
50
  "@types/node": "^22.0.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-opencode",
3
- "version": "0.25.2",
3
+ "version": "0.26.0",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Agent File Tools (AFT) — tree-sitter and lsp powered code analysis",
6
6
  "main": "dist/index.js",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@clack/prompts": "^1.2.0",
31
- "@cortexkit/aft-bridge": "0.25.2",
31
+ "@cortexkit/aft-bridge": "0.26.0",
32
32
  "@opencode-ai/plugin": "^1.14.39",
33
33
  "@opencode-ai/sdk": "^1.14.39",
34
34
  "comment-json": "^4.6.2",
@@ -36,11 +36,11 @@
36
36
  "zod": "^4.1.8"
37
37
  },
38
38
  "optionalDependencies": {
39
- "@cortexkit/aft-darwin-arm64": "0.25.2",
40
- "@cortexkit/aft-darwin-x64": "0.25.2",
41
- "@cortexkit/aft-linux-arm64": "0.25.2",
42
- "@cortexkit/aft-linux-x64": "0.25.2",
43
- "@cortexkit/aft-win32-x64": "0.25.2"
39
+ "@cortexkit/aft-darwin-arm64": "0.26.0",
40
+ "@cortexkit/aft-darwin-x64": "0.26.0",
41
+ "@cortexkit/aft-linux-arm64": "0.26.0",
42
+ "@cortexkit/aft-linux-x64": "0.26.0",
43
+ "@cortexkit/aft-win32-x64": "0.26.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^22.0.0",
@@ -28,8 +28,9 @@ interface SessionInfo {
28
28
  interface OpenCodeClientShape {
29
29
  session?: {
30
30
  get?: (input: {
31
- sessionID: string;
32
- directory?: string;
31
+ path: { id: string };
32
+ query?: { directory?: string };
33
+ throwOnError?: boolean;
33
34
  }) => Promise<{ data?: SessionInfo } | SessionInfo | undefined>;
34
35
  };
35
36
  }
@@ -45,9 +46,10 @@ const CACHE_MAX_ENTRIES = 200;
45
46
  const cache = new Map<string, CacheEntry>();
46
47
 
47
48
  /**
48
- * Resolve the project directory the session was created with. Returns
49
- * `null` when the lookup is unavailable or fails callers should fall
50
- * back to the runtime's directory in that case.
49
+ * Resolve the project directory the session was created with from the SDK's
50
+ * session object. Returns the SDK-reported directory, or `null` when the
51
+ * lookup is unavailable/fails — callers should fall back to the runtime's
52
+ * directory in that case.
51
53
  *
52
54
  * This function is best-effort: any error (missing `client.session.get`,
53
55
  * network failure, malformed response) is logged and recorded as a
@@ -81,7 +83,11 @@ export async function getSessionDirectory(
81
83
  // Call as a method so the SDK's `this._client` reference resolves
82
84
  // correctly. Extracting `c.session.get` into a local would lose the
83
85
  // binding and crash the SDK with "undefined is not an object".
84
- const result = await sessionApi.get({ sessionID: sessionId, directory: fallbackDirectory });
86
+ // SDK schema: SessionGetData uses `path: { id }`, NOT a flat
87
+ // `sessionID`. Do NOT pass `directory` — looking up a session by ID is an
88
+ // identity query, and newer SDKs don't accept a top-level directory here.
89
+ void fallbackDirectory;
90
+ const result = await sessionApi.get({ path: { id: sessionId } });
85
91
  // SDK responses come either as `{ data: Session }` or directly as `Session`
86
92
  // depending on `ThrowOnError`. Handle both shapes.
87
93
  const session: SessionInfo | undefined =