@cortexkit/aft-opencode 0.25.1 → 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);
8102
+ }
8103
+ reject(new Error(`${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
8104
+ if (!keepBridgeOnTimeout) {
8105
+ this.handleTimeout(requestSessionId);
8109
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;
@@ -8519,11 +8569,12 @@ async function downloadBinary(version) {
8519
8569
  error(`Unsupported platform: ${process.platform}-${process.arch}`);
8520
8570
  return null;
8521
8571
  }
8522
- const tag = version ?? await fetchLatestTag();
8523
- if (!tag) {
8572
+ const rawTag = version ?? await fetchLatestTag();
8573
+ if (!rawTag) {
8524
8574
  error("Could not determine latest release version.");
8525
8575
  return null;
8526
8576
  }
8577
+ const tag = rawTag.startsWith("v") ? rawTag : `v${rawTag}`;
8527
8578
  const versionedCacheDir = join2(getCacheDir(), tag);
8528
8579
  const binaryName = getBinaryName();
8529
8580
  const binaryPath = join2(versionedCacheDir, binaryName);
@@ -8585,13 +8636,14 @@ async function downloadBinary(version) {
8585
8636
  }
8586
8637
  async function ensureBinary(version) {
8587
8638
  if (version) {
8588
- const versionCached = getCachedBinaryPath(version);
8639
+ const tag = version.startsWith("v") ? version : `v${version}`;
8640
+ const versionCached = getCachedBinaryPath(tag);
8589
8641
  if (versionCached) {
8590
- log(`Found cached binary for ${version}: ${versionCached}`);
8642
+ log(`Found cached binary for ${tag}: ${versionCached}`);
8591
8643
  return versionCached;
8592
8644
  }
8593
- log(`No cached binary for ${version}, downloading...`);
8594
- return downloadBinary(version);
8645
+ log(`No cached binary for ${tag}, downloading...`);
8646
+ return downloadBinary(tag);
8595
8647
  }
8596
8648
  log("No cached binary found, downloading latest...");
8597
8649
  return downloadBinary();
@@ -9300,6 +9352,7 @@ class BridgePool {
9300
9352
  this.bridges.clear();
9301
9353
  await Promise.allSettled(shutdowns);
9302
9354
  this.log(`Binary path updated to ${newPath}. All bridges cleared \u2014 next calls will use the new binary.`);
9355
+ return newPath;
9303
9356
  }
9304
9357
  log(message, meta) {
9305
9358
  const logger = this.logger ?? getActiveLogger();
@@ -9350,7 +9403,9 @@ function readBinaryVersion(binaryPath) {
9350
9403
  stdio: ["pipe", "pipe", "pipe"],
9351
9404
  timeout: 5000
9352
9405
  });
9353
- const rawVersion = result.stdout?.trim();
9406
+ const stdoutVersion = result.stdout?.trim();
9407
+ const stderrVersion = result.stderr?.trim();
9408
+ const rawVersion = stdoutVersion || stderrVersion;
9354
9409
  if (!rawVersion)
9355
9410
  return null;
9356
9411
  return rawVersion.replace(/^aft\s+/, "");
@@ -9686,6 +9741,7 @@ async function fetchUrlToTempFile(url, storageDir, options = {}) {
9686
9741
  throw new Error(`Only http:// and https:// URLs are supported, got: ${parsed.protocol}`);
9687
9742
  }
9688
9743
  const allowPrivate = options.allowPrivate === true;
9744
+ await assertPublicUrl(parsed, allowPrivate, options.lookup);
9689
9745
  const dir = cacheDir(storageDir);
9690
9746
  mkdirSync4(dir, { recursive: true });
9691
9747
  const hash = hashUrl(url);
@@ -27042,7 +27098,7 @@ async function getSessionDirectory(client, sessionId, fallbackDirectory) {
27042
27098
  }
27043
27099
  let dir = null;
27044
27100
  try {
27045
- const result = await sessionApi.get({ sessionID: sessionId, directory: fallbackDirectory });
27101
+ const result = await sessionApi.get({ path: { id: sessionId } });
27046
27102
  const session = result?.data ?? result;
27047
27103
  if (session && typeof session.directory === "string" && session.directory.length > 0) {
27048
27104
  dir = session.directory;
@@ -29038,8 +29094,11 @@ function createEditTool(ctx, writeToolName = "write") {
29038
29094
  ...op,
29039
29095
  file: path4.isAbsolute(op.file) ? op.file : path4.resolve(context.directory, op.file)
29040
29096
  }));
29041
- const data2 = await callBridge(ctx, context, "transaction", { operations: resolvedOps });
29042
- 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);
29043
29102
  }
29044
29103
  const file2 = args.filePath;
29045
29104
  if (!file2)
@@ -29518,6 +29577,9 @@ function createDeleteTool(ctx) {
29518
29577
  files: absolutePaths,
29519
29578
  recursive
29520
29579
  });
29580
+ if (response.success === false) {
29581
+ throw new Error(response.message ?? "delete failed");
29582
+ }
29521
29583
  const deletedEntries = response.deleted ?? [];
29522
29584
  const skipped = response.skipped_files ?? [];
29523
29585
  const deleted = deletedEntries.map((entry) => entry.file);
@@ -29601,7 +29663,7 @@ function formatError2(error50) {
29601
29663
  }
29602
29664
  function aftPrefixedTools(ctx) {
29603
29665
  const aftEditTool = createEditTool(ctx, "aft_write");
29604
- return {
29666
+ const tools = {
29605
29667
  aft_read: createReadTool(ctx),
29606
29668
  aft_write: createWriteTool(ctx, "aft_edit"),
29607
29669
  aft_edit: {
@@ -29630,8 +29692,11 @@ function aftPrefixedTools(ctx) {
29630
29692
  create_dirs: normalizedArgs.create_dirs !== false,
29631
29693
  diagnostics: true
29632
29694
  };
29633
- const data = await callBridge(ctx, context, "write", writeParams);
29634
- 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);
29635
29700
  }
29636
29701
  return aftEditTool.execute(normalizedArgs, context);
29637
29702
  }
@@ -29640,6 +29705,16 @@ function aftPrefixedTools(ctx) {
29640
29705
  aft_delete: createDeleteTool(ctx),
29641
29706
  aft_move: createMoveTool(ctx)
29642
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;
29643
29718
  }
29644
29719
 
29645
29720
  // src/tools/imports.ts
@@ -30816,25 +30891,27 @@ ${lines}
30816
30891
  const poolOptions = {
30817
30892
  errorPrefix: "[aft-plugin]",
30818
30893
  minVersion: PLUGIN_VERSION,
30819
- onVersionMismatch: (binaryVersion, minVersion) => {
30894
+ onVersionMismatch: async (binaryVersion, minVersion) => {
30820
30895
  if (versionUpgradeAttempted === binaryVersion) {
30821
30896
  log2(`Version ${binaryVersion} < ${minVersion} but upgrade already attempted \u2014 continuing`);
30822
- return;
30897
+ return null;
30823
30898
  }
30824
30899
  versionUpgradeAttempted = binaryVersion;
30825
30900
  warn2(`WARNING: aft binary v${binaryVersion} is older than plugin v${minVersion}. ` + "Some features may not work. Attempting to download a compatible binary...");
30826
- ensureBinary(`v${minVersion}`).then((path7) => {
30827
- if (path7) {
30828
- log2(`Found/downloaded compatible binary at ${path7}. Replacing running bridges...`);
30829
- pool.replaceBinary(path7).then(() => {
30830
- log2("Binary replaced successfully. New bridges will use the updated binary.");
30831
- }, (err) => error2("Failed to replace binary:", err));
30832
- } else {
30901
+ try {
30902
+ const path7 = await ensureBinary(`v${minVersion}`);
30903
+ if (!path7) {
30833
30904
  warn2(`Could not find or download v${minVersion}. Continuing with v${binaryVersion}.`);
30905
+ return null;
30834
30906
  }
30835
- }, (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) {
30836
30912
  error2(`Auto-download failed: ${err.message}. Install manually: cargo install agent-file-tools@${minVersion}`);
30837
- });
30913
+ return null;
30914
+ }
30838
30915
  },
30839
30916
  onConfigureWarnings: async ({ projectRoot, sessionId, client, warnings }) => {
30840
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.1",
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.1",
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.1",
44
- "@cortexkit/aft-darwin-x64": "0.25.1",
45
- "@cortexkit/aft-linux-arm64": "0.25.1",
46
- "@cortexkit/aft-linux-x64": "0.25.1",
47
- "@cortexkit/aft-win32-x64": "0.25.1"
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.1",
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.1",
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.1",
40
- "@cortexkit/aft-darwin-x64": "0.25.1",
41
- "@cortexkit/aft-linux-arm64": "0.25.1",
42
- "@cortexkit/aft-linux-x64": "0.25.1",
43
- "@cortexkit/aft-win32-x64": "0.25.1"
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 =