@cortexkit/aft-opencode 0.26.3 → 0.26.4

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;AA8vB5E,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA8JlD;;;;;;;;;;;;;;;;;;GAkBG;AAQH,QAAA,MAAM,MAAM,EAAE,MAA6D,CAAC;AA+sB5E,eAAe,MAAM,CAAC"}
package/dist/index.js CHANGED
@@ -7805,7 +7805,7 @@ var require_src2 = __commonJS((exports, module) => {
7805
7805
  // src/index.ts
7806
7806
  import { existsSync as existsSync14, mkdirSync as mkdirSync12, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
7807
7807
  import { createRequire as createRequire2 } from "module";
7808
- import { homedir as homedir11 } from "os";
7808
+ import { homedir as homedir10 } from "os";
7809
7809
  import { join as join21 } from "path";
7810
7810
 
7811
7811
  // ../aft-bridge/dist/active-logger.js
@@ -9378,31 +9378,9 @@ function isProcessAlive(pid) {
9378
9378
  }
9379
9379
  // ../aft-bridge/dist/pool.js
9380
9380
  import { realpathSync as realpathSync2 } from "fs";
9381
- import { homedir as homedir3 } from "os";
9382
9381
  var DEFAULT_IDLE_TIMEOUT_MS = Infinity;
9383
9382
  var DEFAULT_MAX_POOL_SIZE = 8;
9384
9383
  var CLEANUP_INTERVAL_MS = 60 * 1000;
9385
- function canonicalHomeDir() {
9386
- try {
9387
- const home = homedir3();
9388
- if (!home)
9389
- return null;
9390
- try {
9391
- return realpathSync2(home);
9392
- } catch {
9393
- return home.replace(/[/\\]+$/, "");
9394
- }
9395
- } catch {
9396
- return null;
9397
- }
9398
- }
9399
- function isHomeDirectoryRoot(normalizedKey) {
9400
- const home = canonicalHomeDir();
9401
- if (!home)
9402
- return false;
9403
- return normalizedKey === home;
9404
- }
9405
-
9406
9384
  class BridgePool {
9407
9385
  bridges = new Map;
9408
9386
  binaryPath;
@@ -9549,7 +9527,7 @@ function normalizeKey(projectRoot) {
9549
9527
  import { execSync, spawnSync } from "child_process";
9550
9528
  import { chmodSync as chmodSync3, copyFileSync as copyFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync3, renameSync as renameSync2 } from "fs";
9551
9529
  import { createRequire } from "module";
9552
- import { homedir as homedir4 } from "os";
9530
+ import { homedir as homedir3 } from "os";
9553
9531
  import { join as join4 } from "path";
9554
9532
  function readBinaryVersion(binaryPath) {
9555
9533
  try {
@@ -9602,7 +9580,7 @@ function normalizeBareVersion(version) {
9602
9580
  return version.startsWith("v") ? version.slice(1) : version;
9603
9581
  }
9604
9582
  function homeDirFromEnv(env) {
9605
- return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir4();
9583
+ return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir3();
9606
9584
  }
9607
9585
  function cacheDirFromEnv(env) {
9608
9586
  if (process.platform === "win32") {
@@ -10218,6 +10196,7 @@ function mergeContexts(base, patch) {
10218
10196
  function isComplete(ctx) {
10219
10197
  return Boolean(ctx.agent && ctx.model && ctx.variant);
10220
10198
  }
10199
+ var PROMPT_CONTEXT_MESSAGE_LIMIT = 50;
10221
10200
  async function resolvePromptContext(client, sessionId) {
10222
10201
  if (!client || !sessionId)
10223
10202
  return null;
@@ -10226,7 +10205,10 @@ async function resolvePromptContext(client, sessionId) {
10226
10205
  return null;
10227
10206
  let messages = [];
10228
10207
  try {
10229
- const response = await c.session.messages({ path: { id: sessionId } });
10208
+ const response = await c.session.messages({
10209
+ path: { id: sessionId },
10210
+ query: { limit: PROMPT_CONTEXT_MESSAGE_LIMIT }
10211
+ });
10230
10212
  messages = extractMessages(response);
10231
10213
  } catch {
10232
10214
  return null;
@@ -10645,7 +10627,7 @@ function formatDuration(completion) {
10645
10627
  // src/config.ts
10646
10628
  var import_comment_json = __toESM(require_src2(), 1);
10647
10629
  import { existsSync as existsSync5, readFileSync as readFileSync3, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "fs";
10648
- import { homedir as homedir5 } from "os";
10630
+ import { homedir as homedir4 } from "os";
10649
10631
  import { join as join7 } from "path";
10650
10632
 
10651
10633
  // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
@@ -24623,7 +24605,7 @@ function getOpenCodeConfigDir() {
24623
24605
  if (envDir) {
24624
24606
  return envDir;
24625
24607
  }
24626
- const xdgConfig = process.env.XDG_CONFIG_HOME || join7(homedir5(), ".config");
24608
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join7(homedir4(), ".config");
24627
24609
  return join7(xdgConfig, "opencode");
24628
24610
  }
24629
24611
  function loadAftConfig(projectDirectory) {
@@ -24671,27 +24653,27 @@ import { basename, dirname as dirname3, join as join10 } from "path";
24671
24653
  // src/hooks/auto-update-checker/checker.ts
24672
24654
  var import_comment_json2 = __toESM(require_src2(), 1);
24673
24655
  import { existsSync as existsSync6, readFileSync as readFileSync4, statSync as statSync3, writeFileSync as writeFileSync4 } from "fs";
24674
- import { homedir as homedir7 } from "os";
24656
+ import { homedir as homedir6 } from "os";
24675
24657
  import { dirname as dirname2, isAbsolute, join as join9, resolve as resolve2 } from "path";
24676
24658
  import { fileURLToPath } from "url";
24677
24659
 
24678
24660
  // src/hooks/auto-update-checker/constants.ts
24679
- import { homedir as homedir6, platform } from "os";
24661
+ import { homedir as homedir5, platform } from "os";
24680
24662
  import { join as join8 } from "path";
24681
24663
  var PACKAGE_NAME = "@cortexkit/aft-opencode";
24682
24664
  var NPM_REGISTRY_URL = "https://registry.npmjs.org";
24683
24665
  var NPM_FETCH_TIMEOUT = 1e4;
24684
24666
  function getOpenCodeCacheRoot() {
24685
24667
  if (platform() === "win32") {
24686
- return join8(process.env.LOCALAPPDATA ?? homedir6(), "opencode");
24668
+ return join8(process.env.LOCALAPPDATA ?? homedir5(), "opencode");
24687
24669
  }
24688
- return join8(homedir6(), ".cache", "opencode");
24670
+ return join8(homedir5(), ".cache", "opencode");
24689
24671
  }
24690
24672
  function getOpenCodeConfigRoot() {
24691
24673
  if (platform() === "win32") {
24692
- return join8(process.env.APPDATA ?? join8(homedir6(), "AppData", "Roaming"), "opencode");
24674
+ return join8(process.env.APPDATA ?? join8(homedir5(), "AppData", "Roaming"), "opencode");
24693
24675
  }
24694
- return join8(process.env.XDG_CONFIG_HOME ?? join8(homedir6(), ".config"), "opencode");
24676
+ return join8(process.env.XDG_CONFIG_HOME ?? join8(homedir5(), ".config"), "opencode");
24695
24677
  }
24696
24678
  var CACHE_DIR = join8(getOpenCodeCacheRoot(), "packages");
24697
24679
  var USER_OPENCODE_CONFIG = join8(getOpenCodeConfigRoot(), "opencode.json");
@@ -24870,7 +24852,7 @@ function getCachedVersion(spec) {
24870
24852
  getCurrentRuntimePackageJsonPath(),
24871
24853
  spec ? getSpecCachePackageJsonPath(spec) : null,
24872
24854
  getSpecCachePackageJsonPath(`${PACKAGE_NAME}@latest`),
24873
- join9(homedir7(), ".cache", "opencode", "node_modules", PACKAGE_NAME, "package.json")
24855
+ join9(homedir6(), ".cache", "opencode", "node_modules", PACKAGE_NAME, "package.json")
24874
24856
  ].filter(isString);
24875
24857
  for (const packageJsonPath of candidates) {
24876
24858
  try {
@@ -25284,7 +25266,7 @@ import {
25284
25266
  unlinkSync as unlinkSync5,
25285
25267
  writeFileSync as writeFileSync7
25286
25268
  } from "fs";
25287
- import { homedir as homedir8 } from "os";
25269
+ import { homedir as homedir7 } from "os";
25288
25270
  import { join as join12 } from "path";
25289
25271
  function aftCacheBase() {
25290
25272
  const override = process.env.AFT_CACHE_DIR;
@@ -25292,10 +25274,10 @@ function aftCacheBase() {
25292
25274
  return override;
25293
25275
  if (process.platform === "win32") {
25294
25276
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
25295
- const base2 = localAppData || join12(homedir8(), "AppData", "Local");
25277
+ const base2 = localAppData || join12(homedir7(), "AppData", "Local");
25296
25278
  return join12(base2, "aft");
25297
25279
  }
25298
- const base = process.env.XDG_CACHE_HOME || join12(homedir8(), ".cache");
25280
+ const base = process.env.XDG_CACHE_HOME || join12(homedir7(), ".cache");
25299
25281
  return join12(base, "aft");
25300
25282
  }
25301
25283
  function lspCacheRoot() {
@@ -26941,7 +26923,7 @@ function normalizeToolMap(tools) {
26941
26923
 
26942
26924
  // src/notifications.ts
26943
26925
  import { existsSync as existsSync11, mkdirSync as mkdirSync9, readFileSync as readFileSync10, renameSync as renameSync7, rmSync as rmSync6, writeFileSync as writeFileSync9 } from "fs";
26944
- import { homedir as homedir9, platform as platform2 } from "os";
26926
+ import { homedir as homedir8, platform as platform2 } from "os";
26945
26927
  import { join as join16 } from "path";
26946
26928
  function isTuiMode() {
26947
26929
  return process.env.OPENCODE_CLIENT === "cli";
@@ -26964,7 +26946,7 @@ var STATUS_MARKER = `${AFT_MARKER} \u2705`;
26964
26946
  var WARNED_TOOLS_FILE = "warned_tools.json";
26965
26947
  function getDesktopStatePath() {
26966
26948
  const os2 = platform2();
26967
- const home = homedir9();
26949
+ const home = homedir8();
26968
26950
  if (os2 === "darwin") {
26969
26951
  return join16(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
26970
26952
  }
@@ -27018,11 +27000,15 @@ function getServerAuth() {
27018
27000
  const username = process.env.OPENCODE_SERVER_USERNAME ?? "opencode";
27019
27001
  return `Basic ${Buffer.from(`${username}:${password}`, "utf8").toString("base64")}`;
27020
27002
  }
27003
+ var SESSION_MESSAGES_LIMIT = 50;
27021
27004
  async function getSessionMessages(client, sessionId) {
27022
27005
  try {
27023
27006
  const c = client;
27024
27007
  if (typeof c.session?.messages === "function") {
27025
- const result = await c.session.messages({ path: { id: sessionId } });
27008
+ const result = await c.session.messages({
27009
+ path: { id: sessionId },
27010
+ query: { limit: SESSION_MESSAGES_LIMIT }
27011
+ });
27026
27012
  return result?.data ?? [];
27027
27013
  }
27028
27014
  } catch {}
@@ -27537,7 +27523,8 @@ function coerceAftStatus(response) {
27537
27523
  id: readString(session.id, "__default__"),
27538
27524
  tracked_files: readNumber(session.tracked_files),
27539
27525
  checkpoints: readNumber(session.checkpoints)
27540
- }
27526
+ },
27527
+ message: readString(response.message, "")
27541
27528
  };
27542
27529
  }
27543
27530
  function formatStatusMarkdown(status) {
@@ -27599,7 +27586,7 @@ import { existsSync as existsSync12, mkdirSync as mkdirSync11, readFileSync as r
27599
27586
  import { dirname as dirname7, join as join19 } from "path";
27600
27587
 
27601
27588
  // src/shared/opencode-config-dir.ts
27602
- import { homedir as homedir10 } from "os";
27589
+ import { homedir as homedir9 } from "os";
27603
27590
  import { join as join18, resolve as resolve4 } from "path";
27604
27591
  function getCliConfigDir() {
27605
27592
  const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
@@ -27607,9 +27594,9 @@ function getCliConfigDir() {
27607
27594
  return resolve4(envConfigDir);
27608
27595
  }
27609
27596
  if (process.platform === "win32") {
27610
- return join18(homedir10(), ".config", "opencode");
27597
+ return join18(homedir9(), ".config", "opencode");
27611
27598
  }
27612
- return join18(process.env.XDG_CONFIG_HOME || join18(homedir10(), ".config"), "opencode");
27599
+ return join18(process.env.XDG_CONFIG_HOME || join18(homedir9(), ".config"), "opencode");
27613
27600
  }
27614
27601
  function getOpenCodeConfigDir2(_options) {
27615
27602
  return getCliConfigDir();
@@ -31117,7 +31104,7 @@ async function initializePluginForDirectory(input) {
31117
31104
  if (aftConfig.max_callgraph_files !== undefined)
31118
31105
  configOverrides.max_callgraph_files = aftConfig.max_callgraph_files;
31119
31106
  const isFastembedSemanticBackend = (aftConfig.semantic?.backend ?? "fastembed") === "fastembed";
31120
- const dataHome = process.env.XDG_DATA_HOME || join21(homedir11(), ".local", "share");
31107
+ const dataHome = process.env.XDG_DATA_HOME || join21(homedir10(), ".local", "share");
31121
31108
  configOverrides.storage_dir = join21(dataHome, "opencode", "storage", "plugin", "aft");
31122
31109
  let onnxRuntimePromise = null;
31123
31110
  if (aftConfig.semantic_search && isFastembedSemanticBackend) {
@@ -31276,27 +31263,6 @@ ${lines}
31276
31263
  warn2(`ONNX Runtime resolution rejected unexpectedly: ${err}`);
31277
31264
  });
31278
31265
  }
31279
- (async () => {
31280
- try {
31281
- if (isHomeDirectoryRoot(input.directory)) {
31282
- log2(`Eager configure skipped: input.directory=${input.directory} is the user home directory. ` + `The first real tool call from a session will warm the correct project bridge.`);
31283
- return;
31284
- }
31285
- if (onnxRuntimePromise) {
31286
- await Promise.race([
31287
- onnxRuntimePromise,
31288
- new Promise((resolve11) => setTimeout(() => resolve11(null), 60000))
31289
- ]);
31290
- }
31291
- const bridge = pool.getBridge(input.directory);
31292
- const response = await bridge.send("status", {}, { configureWarningClient: input.client });
31293
- if (response.success !== false) {
31294
- bridge.cacheStatusSnapshot(response);
31295
- }
31296
- } catch (err) {
31297
- log2(`eager configure failed: ${err instanceof Error ? err.message : String(err)}`);
31298
- }
31299
- })();
31300
31266
  const rpcServer = new AftRpcServer(configOverrides.storage_dir, input.directory);
31301
31267
  const unregisterShutdown = registerShutdownCleanup(async () => {
31302
31268
  await Promise.allSettled([abortInFlightAutoInstalls(), abortInFlightGithubInstalls()]);
@@ -31323,7 +31289,7 @@ ${lines}
31323
31289
  return {
31324
31290
  success: true,
31325
31291
  status: "not_initialized",
31326
- message: "AFT bridge has not been initialized for this project yet. Status will populate after the first tool call."
31292
+ message: "Waiting for first tool call to populate"
31327
31293
  };
31328
31294
  }
31329
31295
  const cached2 = bridge.getCachedStatus();
@@ -13,6 +13,24 @@
13
13
  * Messages are identified by markers and cleaned up on subsequent startups
14
14
  * when no longer relevant (Desktop only — TUI toasts are inherently transient).
15
15
  */
16
+ type SdkMessage = {
17
+ info?: {
18
+ id?: string;
19
+ role?: string;
20
+ };
21
+ parts?: Array<{
22
+ type?: string;
23
+ text?: string;
24
+ ignored?: boolean;
25
+ }>;
26
+ };
27
+ export declare const SESSION_MESSAGES_LIMIT = 50;
28
+ /**
29
+ * @internal — exported only so tests can pin the bounded-call contract.
30
+ * Production callers go through `sendStatus` / `cleanupWarnings`, both of
31
+ * which gate on a real `readDesktopState()` before reaching this helper.
32
+ */
33
+ export declare function getSessionMessages(client: unknown, sessionId: string): Promise<SdkMessage[]>;
16
34
  export interface NotificationOptions {
17
35
  /** The OpenCode SDK client */
18
36
  client: unknown;
@@ -61,4 +79,5 @@ export declare function deliverConfigureWarnings(opts: ConfigureWarningOptions,
61
79
  * Desktop only — TUI toasts are inherently transient and don't need cleanup.
62
80
  */
63
81
  export declare function cleanupWarnings(opts: NotificationOptions): Promise<void>;
82
+ export {};
64
83
  //# sourceMappingURL=notifications.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAyOH,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,yBAAyB,GAAG,uBAAuB,GAAG,oBAAoB,CAAC;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW3F;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C1F;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAqCf;AA8FD,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,uBAAuB,EAC7B,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C9E"}
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAyIH,KAAK,UAAU,GAAG;IAChB,IAAI,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACpE,CAAC;AAyBF,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,EAAE,CAAC,CAqBvB;AAqED,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,yBAAyB,GAAG,uBAAuB,GAAG,oBAAoB,CAAC;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW3F;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C1F;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAqCf;AA8FD,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,uBAAuB,EAC7B,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C9E"}
@@ -31,15 +31,6 @@ export interface ResolvedPromptContext {
31
31
  };
32
32
  variant?: string;
33
33
  }
34
- /**
35
- * Read recent messages from the OpenCode session and resolve the most
36
- * recent assistant prompt context. Falls back to user messages if no
37
- * assistant has the field. Merges across messages so partial fields are
38
- * filled in. Returns null if no usable context is found.
39
- *
40
- * Mirrors `resolveSessionPromptParams` in `opencode-xtra` (the working
41
- * reference implementation).
42
- */
43
34
  export declare function resolvePromptContext(client: unknown, sessionId: string): Promise<ResolvedPromptContext | null>;
44
35
  export interface LastAssistantModel {
45
36
  providerID: string;
@@ -1 +1 @@
1
- {"version":3,"file":"last-assistant-model.d.ts","sourceRoot":"","sources":["../../src/shared/last-assistant-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA0ED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAwCvC;AAID,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,6EAA6E;AAC7E,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAQpC"}
1
+ {"version":3,"file":"last-assistant-model.d.ts","sourceRoot":"","sources":["../../src/shared/last-assistant-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAkGD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CA8CvC;AAID,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,6EAA6E;AAC7E,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAQpC"}
@@ -57,6 +57,14 @@ export interface AftStatusSnapshot {
57
57
  tracked_files: number;
58
58
  checkpoints: number;
59
59
  };
60
+ /**
61
+ * Human-readable explanation for a synthetic snapshot (e.g.
62
+ * `cache_role === "not_initialized"`). When the plugin returns a placeholder
63
+ * because no bridge has been spawned yet, this message tells the user what
64
+ * to expect; the TUI dialog renders it instead of an empty grid of zeros.
65
+ * Empty string when the snapshot is real bridge data.
66
+ */
67
+ message: string;
60
68
  }
61
69
  export declare function formatBytes(bytes: number): string;
62
70
  export declare function coerceAftStatus(response: Record<string, unknown>): AftStatusSnapshot;
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/shared/status.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,+EAA+E;IAC/E,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE;QACR,cAAc,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,wBAAwB,EAAE,OAAO,CAAC;QAClC,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,OAAO,CAAC;KAC1B,CAAC;IACF,YAAY,EAAE;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;IACF,cAAc,EAAE;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;IACF,IAAI,EAAE;QACJ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iEAAiE;IACjE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAkCD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAajD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iBAAiB,CAiEpF;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAuE3E;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CA0EtE"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/shared/status.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,+EAA+E;IAC/E,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE;QACR,cAAc,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,wBAAwB,EAAE,OAAO,CAAC;QAClC,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,OAAO,CAAC;KAC1B,CAAC;IACF,YAAY,EAAE;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;IACF,cAAc,EAAE;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;IACF,IAAI,EAAE;QACJ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iEAAiE;IACjE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAkCD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAajD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iBAAiB,CAkEpF;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAuE3E;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CA0EtE"}
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.26.3",
7
+ version: "0.26.4",
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.26.3",
35
+ "@cortexkit/aft-bridge": "0.26.4",
36
36
  "@opencode-ai/plugin": "^1.15.5",
37
37
  "@opencode-ai/sdk": "^1.15.5",
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.26.3",
44
- "@cortexkit/aft-darwin-x64": "0.26.3",
45
- "@cortexkit/aft-linux-arm64": "0.26.3",
46
- "@cortexkit/aft-linux-x64": "0.26.3",
47
- "@cortexkit/aft-win32-x64": "0.26.3"
43
+ "@cortexkit/aft-darwin-arm64": "0.26.4",
44
+ "@cortexkit/aft-darwin-x64": "0.26.4",
45
+ "@cortexkit/aft-linux-arm64": "0.26.4",
46
+ "@cortexkit/aft-linux-x64": "0.26.4",
47
+ "@cortexkit/aft-win32-x64": "0.26.4"
48
48
  },
49
49
  devDependencies: {
50
50
  "@types/node": "^22.0.0",
@@ -375,7 +375,8 @@ function coerceAftStatus(response) {
375
375
  id: readString(session.id, "__default__"),
376
376
  tracked_files: readNumber(session.tracked_files),
377
377
  checkpoints: readNumber(session.checkpoints)
378
- }
378
+ },
379
+ message: readString(response.message, "")
379
380
  };
380
381
  }
381
382
 
@@ -644,6 +645,14 @@ var SidebarContent = (props) => {
644
645
  ]
645
646
  }, undefined, true, undefined, this)
646
647
  }, undefined, false, undefined, this),
648
+ s()?.cache_role === "not_initialized" && /* @__PURE__ */ jsxDEV("box", {
649
+ marginTop: 1,
650
+ width: "100%",
651
+ children: /* @__PURE__ */ jsxDEV("text", {
652
+ fg: props.theme.textMuted,
653
+ children: s().message || "Waiting for first tool call to populate"
654
+ }, undefined, false, undefined, this)
655
+ }, undefined, false, undefined, this),
647
656
  /* @__PURE__ */ jsxDEV(SectionHeader, {
648
657
  theme: props.theme,
649
658
  title: "Search Index"
@@ -863,7 +872,16 @@ var StatusDialog = (props) => {
863
872
  children: error()
864
873
  }, undefined, false, undefined, this)
865
874
  }, undefined, false, undefined, this) : null,
866
- status() ? /* @__PURE__ */ jsxDEV2("box", {
875
+ status()?.cache_role === "not_initialized" ? /* @__PURE__ */ jsxDEV2("box", {
876
+ width: "100%",
877
+ marginTop: 1,
878
+ justifyContent: "center",
879
+ children: /* @__PURE__ */ jsxDEV2("text", {
880
+ fg: t().textMuted,
881
+ children: status().message || "Waiting for first tool call to populate"
882
+ }, undefined, false, undefined, this)
883
+ }, undefined, false, undefined, this) : null,
884
+ status() && status().cache_role !== "not_initialized" ? /* @__PURE__ */ jsxDEV2("box", {
867
885
  flexDirection: "column",
868
886
  width: "100%",
869
887
  marginBottom: 1,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-opencode",
3
- "version": "0.26.3",
3
+ "version": "0.26.4",
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.26.3",
31
+ "@cortexkit/aft-bridge": "0.26.4",
32
32
  "@opencode-ai/plugin": "^1.15.5",
33
33
  "@opencode-ai/sdk": "^1.15.5",
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.26.3",
40
- "@cortexkit/aft-darwin-x64": "0.26.3",
41
- "@cortexkit/aft-linux-arm64": "0.26.3",
42
- "@cortexkit/aft-linux-x64": "0.26.3",
43
- "@cortexkit/aft-win32-x64": "0.26.3"
39
+ "@cortexkit/aft-darwin-arm64": "0.26.4",
40
+ "@cortexkit/aft-darwin-x64": "0.26.4",
41
+ "@cortexkit/aft-linux-arm64": "0.26.4",
42
+ "@cortexkit/aft-linux-x64": "0.26.4",
43
+ "@cortexkit/aft-win32-x64": "0.26.4"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^22.0.0",
@@ -110,7 +110,22 @@ function isComplete(ctx: ResolvedPromptContext): boolean {
110
110
  *
111
111
  * Mirrors `resolveSessionPromptParams` in `opencode-xtra` (the working
112
112
  * reference implementation).
113
+ *
114
+ * Bounded via `query.limit` — without it, OpenCode's legacy
115
+ * `/session/{id}/message` endpoint hydrates the ENTIRE session. Large
116
+ * sessions can carry 30k-45k messages / 100k+ parts and blow the host's
117
+ * memory just to find the last assistant turn. We only need the most
118
+ * recent prompt context, so 50 is plenty (the very last assistant
119
+ * usually has everything; the merge fallback rarely needs more).
120
+ *
121
+ * Future v2 migration: once `@opencode-ai/sdk` exposes `client.v2.session.messages`
122
+ * with projected shapes (user / assistant / agent-switched / model-switched / ...),
123
+ * prefer that with `{ limit: 50, order: "desc" }` and fall back to this bounded
124
+ * legacy call when v2 returns no items (older sessions aren't backfilled into v2).
125
+ * See https://github.com/cortexkit/aft notes for tracking.
113
126
  */
127
+ const PROMPT_CONTEXT_MESSAGE_LIMIT = 50;
128
+
114
129
  export async function resolvePromptContext(
115
130
  client: unknown,
116
131
  sessionId: string,
@@ -118,14 +133,20 @@ export async function resolvePromptContext(
118
133
  if (!client || !sessionId) return null;
119
134
  const c = client as {
120
135
  session?: {
121
- messages?: (input: { path: { id: string } }) => Promise<{ data?: unknown[] } | unknown[]>;
136
+ messages?: (input: {
137
+ path: { id: string };
138
+ query?: { limit?: number };
139
+ }) => Promise<{ data?: unknown[] } | unknown[]>;
122
140
  };
123
141
  };
124
142
  if (typeof c.session?.messages !== "function") return null;
125
143
 
126
144
  let messages: unknown[] = [];
127
145
  try {
128
- const response = await c.session.messages({ path: { id: sessionId } });
146
+ const response = await c.session.messages({
147
+ path: { id: sessionId },
148
+ query: { limit: PROMPT_CONTEXT_MESSAGE_LIMIT },
149
+ });
129
150
  messages = extractMessages(response);
130
151
  } catch {
131
152
  return null;
@@ -57,6 +57,14 @@ export interface AftStatusSnapshot {
57
57
  tracked_files: number;
58
58
  checkpoints: number;
59
59
  };
60
+ /**
61
+ * Human-readable explanation for a synthetic snapshot (e.g.
62
+ * `cache_role === "not_initialized"`). When the plugin returns a placeholder
63
+ * because no bridge has been spawned yet, this message tells the user what
64
+ * to expect; the TUI dialog renders it instead of an empty grid of zeros.
65
+ * Empty string when the snapshot is real bridge data.
66
+ */
67
+ message: string;
60
68
  }
61
69
 
62
70
  function asRecord(value: unknown): Record<string, unknown> {
@@ -170,6 +178,7 @@ export function coerceAftStatus(response: Record<string, unknown>): AftStatusSna
170
178
  tracked_files: readNumber(session.tracked_files),
171
179
  checkpoints: readNumber(session.checkpoints),
172
180
  },
181
+ message: readString(response.message, ""),
173
182
  };
174
183
  }
175
184
 
package/src/tui/index.tsx CHANGED
@@ -178,8 +178,21 @@ const StatusDialog = (props: StatusDialogProps) => {
178
178
  </box>
179
179
  ) : null}
180
180
 
181
+ {/* Lazy-bridge placeholder: when no bridge has spawned for this project
182
+ yet (because the user has not made any tool call since opening
183
+ OpenCode), the RPC server returns a synthetic snapshot with
184
+ cache_role === "not_initialized". Show the explanatory message
185
+ instead of an empty grid of zeros and "unknown" rows. */}
186
+ {status()?.cache_role === "not_initialized" ? (
187
+ <box width="100%" marginTop={1} justifyContent="center">
188
+ <text fg={t().textMuted}>
189
+ {status()!.message || "Waiting for first tool call to populate"}
190
+ </text>
191
+ </box>
192
+ ) : null}
193
+
181
194
  {/* Header rows — paths span full width since they can be long */}
182
- {status() ? (
195
+ {status() && status()!.cache_role !== "not_initialized" ? (
183
196
  <box flexDirection="column" width="100%" marginBottom={1}>
184
197
  <R
185
198
  theme={t()}
@@ -292,6 +292,21 @@ const SidebarContent = (props: {
292
292
  </box>
293
293
  )}
294
294
 
295
+ {/* Lazy-bridge placeholder. AFT skips spawning the `aft` binary at
296
+ plugin init to keep memory/CPU low on OpenCode Desktop sessions
297
+ that have many projects pinned in the sidebar. The RPC server
298
+ returns a synthetic `cache_role === "not_initialized"` snapshot
299
+ until the first tool call routes through `callBridge()` and warms
300
+ the bridge. Show the explanatory message instead of empty status
301
+ rows so users understand why metrics are blank. */}
302
+ {s()?.cache_role === "not_initialized" && (
303
+ <box marginTop={1} width="100%">
304
+ <text fg={props.theme.textMuted}>
305
+ {s()!.message || "Waiting for first tool call to populate"}
306
+ </text>
307
+ </box>
308
+ )}
309
+
295
310
  {/* Search index */}
296
311
  <SectionHeader theme={props.theme} title="Search Index" />
297
312
  <StatRow