@cortexkit/aft-opencode 0.13.1 → 0.14.1

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.
package/dist/pool.d.ts CHANGED
@@ -4,11 +4,23 @@ export interface PoolOptions extends BridgeOptions {
4
4
  idleTimeoutMs?: number;
5
5
  }
6
6
  /**
7
- * Manages a pool of BinaryBridge instances, one per session.
8
- * Each session gets its own binary process with isolated backup/undo history.
9
- * Handles idle cleanup and LRU eviction when at capacity.
7
+ * Manages a pool of BinaryBridge instances, keyed by **canonical project root**.
8
+ *
9
+ * Prior to issue #14, the pool spawned one binary process per OpenCode session,
10
+ * which duplicated every heavy in-memory structure (ONNX runtime, trigram and
11
+ * semantic indexes, LSP state, symbol caches) N times for N sessions in the
12
+ * same project. That produced an effective "leak" the user saw as many aft
13
+ * processes consuming gigabytes of RAM on large repositories.
14
+ *
15
+ * The current design spawns **one bridge per project** and relies on the Rust
16
+ * side to partition the small amount of truly session-scoped state (undo
17
+ * history, named checkpoints) via the `session_id` envelope field attached by
18
+ * the `callBridge()` helper. Sessions sharing a bridge still share the
19
+ * latency of a single request pipeline; the trade-off is acceptable because
20
+ * it removes the real RAM multiplier.
10
21
  */
11
22
  export declare class BridgePool {
23
+ /** Project-root → bridge. Key is a normalized canonical path. */
12
24
  private readonly bridges;
13
25
  private binaryPath;
14
26
  private readonly maxPoolSize;
@@ -18,13 +30,23 @@ export declare class BridgePool {
18
30
  private cleanupTimer;
19
31
  constructor(binaryPath: string, options?: PoolOptions, configOverrides?: Record<string, unknown>);
20
32
  /**
21
- * Get or create a bridge for the given session.
22
- * Each session gets its own binary process with isolated backup/undo history.
23
- * The bridge's working directory is set to `directory`.
33
+ * Get any existing bridge that is configured and alive, preferring one that
34
+ * matches the given project root.
35
+ *
36
+ * Used by `/aft-status` and similar read-only paths that want to reuse a
37
+ * warm bridge (with loaded semantic indexes etc.) instead of paying the
38
+ * cold-start cost on a cheap query.
24
39
  */
25
- /** Get any existing bridge that is configured and alive, preferring the given directory. */
26
- getAnyActiveBridge(_directory: string): BinaryBridge | null;
27
- getBridge(directory: string, sessionID: string): BinaryBridge;
40
+ getAnyActiveBridge(projectRoot: string): BinaryBridge | null;
41
+ /**
42
+ * Get or create the bridge for `projectRoot`.
43
+ *
44
+ * Callers should always pass a **canonical** project root (see
45
+ * `projectRootFor()` in `tools/_shared.ts`). All sessions operating on the
46
+ * same project share one bridge; their undo/checkpoint state is still
47
+ * isolated by `session_id` on the Rust side.
48
+ */
49
+ getBridge(projectRoot: string): BinaryBridge;
28
50
  /** Shut down idle bridges that haven't been used within the timeout. */
29
51
  private cleanup;
30
52
  /** Evict the least recently used bridge to make room. */
@@ -1 +1 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAY5D,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;IAC1D,OAAO,CAAC,YAAY,CAA+C;gBAGjE,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,WAAgB,EACzB,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAmB/C;;;;OAIG;IACH,4FAA4F;IAC5F,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAW3D,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY;IAwB7D,wEAAwE;IACxE,OAAO,CAAC,OAAO;IAUf,yDAAyD;IACzD,OAAO,CAAC,QAAQ;IAgBhB,wDAAwD;IAClD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAU/B;;;OAGG;IACG,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBnD,4CAA4C;IAC5C,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAY5D,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,UAAU;IACrB,iEAAiE;IACjE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;IAC1D,OAAO,CAAC,YAAY,CAA+C;gBAGjE,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,WAAgB,EACzB,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAmB/C;;;;;;;OAOG;IACH,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAgB5D;;;;;;;OAOG;IACH,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY;IAmB5C,wEAAwE;IACxE,OAAO,CAAC,OAAO;IAUf,yDAAyD;IACzD,OAAO,CAAC,QAAQ;IAgBhB,wDAAwD;IAClD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAU/B;;;OAGG;IACG,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBnD,4CAA4C;IAC5C,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
@@ -36,6 +36,14 @@ export interface AftStatusSnapshot {
36
36
  warm_entries: number;
37
37
  };
38
38
  storage_dir: string | null;
39
+ /** Total checkpoints across all sessions sharing this bridge. */
40
+ checkpoints_total: number;
41
+ /** Current session's own slice of undo/checkpoint state. */
42
+ session: {
43
+ id: string;
44
+ tracked_files: number;
45
+ checkpoints: number;
46
+ };
39
47
  }
40
48
  export declare function formatBytes(bytes: number): string;
41
49
  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,QAAQ,EAAE;QACR,cAAc,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,wBAAwB,EAAE,OAAO,CAAC;QAClC,yBAAyB,EAAE,OAAO,CAAC;QACnC,4BAA4B,EAAE,OAAO,CAAC;KACvC,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;CAC5B;AAkCD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAajD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iBAAiB,CAkDpF;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CA6D3E;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CA+DtE"}
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,QAAQ,EAAE;QACR,cAAc,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,wBAAwB,EAAE,OAAO,CAAC;QAClC,yBAAyB,EAAE,OAAO,CAAC;QACnC,4BAA4B,EAAE,OAAO,CAAC;KACvC,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,CAyDpF;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAsE3E;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAwEtE"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Process-level shutdown handlers.
3
+ *
4
+ * OpenCode does not reliably await plugin `dispose()` before Node exits, and
5
+ * host-level SIGTERM/SIGINT propagate to our `aft` children through the process
6
+ * group. Without explicit cleanup, children see SIGTERM, their `exit` handler
7
+ * fires, and (before the sibling fix in bridge.ts) they would auto-restart into
8
+ * orphaned processes. Even with that fixed, we still want orderly shutdown so
9
+ * pending requests get rejected and the bridges terminate before Node is gone.
10
+ *
11
+ * Each plugin instance (and there can be several per Node process when OpenCode
12
+ * loads the plugin from multiple contexts) registers its cleanup callback here.
13
+ * We install the OS-level signal handlers exactly once per Node process via a
14
+ * `globalThis` guard — otherwise each plugin reload would stack another SIGTERM
15
+ * listener and fire duplicate shutdowns.
16
+ */
17
+ type Cleanup = () => Promise<void> | void;
18
+ /**
19
+ * Register a shutdown cleanup. Call from plugin initialization; returned
20
+ * function unregisters (use in `dispose` so plugin reloads don't leak).
21
+ */
22
+ export declare function registerShutdownCleanup(fn: Cleanup): () => void;
23
+ export {};
24
+ //# sourceMappingURL=shutdown-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown-hooks.d.ts","sourceRoot":"","sources":["../src/shutdown-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,KAAK,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AA+D1C;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,IAAI,CAO/D"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Shared helpers for plugin tool handlers.
3
+ *
4
+ * Every tool that talks to the Rust binary should use `callBridge()` instead
5
+ * of calling `ctx.pool.getBridge(...).send(...)` directly. The helper:
6
+ *
7
+ * 1. Resolves the project root from `context.worktree ?? context.directory`
8
+ * (canonical path), so two tool calls in the same project always reach
9
+ * the same bridge even if the agent's cwd momentarily differs.
10
+ * 2. Injects `session_id` from `context.sessionID` into every request so the
11
+ * Rust side can partition undo/checkpoint state per OpenCode session
12
+ * (issue #14 — one shared bridge per project, N sessions per bridge).
13
+ *
14
+ * Tools that specifically need the raw `BinaryBridge` (for example to call
15
+ * `bridge.send()` multiple times with shared state) should use `bridgeFor()`
16
+ * and still pass `session_id` explicitly.
17
+ */
18
+ import type { BinaryBridge } from "../bridge.js";
19
+ import type { PluginContext } from "../types.js";
20
+ /**
21
+ * Minimum shape of the per-tool-call context provided by the OpenCode SDK.
22
+ *
23
+ * We only depend on a few fields so any similar context (including the Pi
24
+ * plugin's `ExtensionContext`) can be passed through the same helpers once
25
+ * they adopt session-aware calls.
26
+ */
27
+ export interface ToolRuntime {
28
+ /** Worktree root (preferred); falls back to `directory` when absent. */
29
+ worktree?: string;
30
+ /** Agent's working directory for this tool call. */
31
+ directory: string;
32
+ /** Opaque OpenCode session identifier. Missing in CLI tests / some hosts. */
33
+ sessionID?: string;
34
+ }
35
+ /**
36
+ * Resolve the canonical project root for a runtime.
37
+ *
38
+ * Prefers `worktree` because that stays stable across OpenCode sessions in
39
+ * the same project; falls back to `directory` when unavailable (standalone
40
+ * CLI use, older hosts). Normalizes trailing slashes and resolves symlinks
41
+ * via `realpath` so `/repo` and `/repo/` and `/Users/.../repo -> /Volumes/...`
42
+ * collapse to the same key.
43
+ */
44
+ export declare function projectRootFor(runtime: ToolRuntime): string;
45
+ /**
46
+ * Get the BinaryBridge for the runtime's project root.
47
+ *
48
+ * Prefer `callBridge()` unless you need to send multiple requests yourself.
49
+ */
50
+ export declare function bridgeFor(ctx: PluginContext, runtime: ToolRuntime): BinaryBridge;
51
+ /**
52
+ * Send a single command to the Rust binary with `session_id` injected.
53
+ *
54
+ * This is the canonical way for a tool handler to call AFT: the helper picks
55
+ * the right bridge (project-keyed), attaches the session namespace from
56
+ * `context.sessionID`, and returns whatever the binary responds.
57
+ *
58
+ * The Rust side falls back to a shared default namespace when `session_id`
59
+ * is absent (see `RawRequest::session()`), so hosts that don't expose a
60
+ * session identifier still work — they just share undo/checkpoint state.
61
+ */
62
+ export declare function callBridge(ctx: PluginContext, runtime: ToolRuntime, command: string, params?: Record<string, unknown>): ReturnType<BinaryBridge["send"]>;
63
+ //# sourceMappingURL=_shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../src/tools/_shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAa3D;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,YAAY,CAEhF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAMlC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/tools/ast.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAwCjD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAuM3E"}
1
+ {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/tools/ast.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAyCjD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAqM3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"conflicts.d.ts","sourceRoot":"","sources":["../../src/tools/conflicts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAgBhF"}
1
+ {"version":3,"file":"conflicts.d.ts","sourceRoot":"","sources":["../../src/tools/conflicts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAehF"}
@@ -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;AA4EjD;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CA6IjE;AAwqBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAS/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAuBnF"}
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;AA6EjD;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CA4IjE;AAkqBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAS/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAuBnF"}
@@ -1 +1 @@
1
- {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../src/tools/imports.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAUjD;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAoF9E"}
1
+ {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../src/tools/imports.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAWjD;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAmF9E"}
@@ -1 +1 @@
1
- {"version":3,"file":"lsp.d.ts","sourceRoot":"","sources":["../../src/tools/lsp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA2D3E"}
1
+ {"version":3,"file":"lsp.d.ts","sourceRoot":"","sources":["../../src/tools/lsp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA0D3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/tools/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAsDlF"}
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/tools/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAqDlF"}
@@ -1 +1 @@
1
- {"version":3,"file":"reading.d.ts","sourceRoot":"","sources":["../../src/tools/reading.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA0CjD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAuK/E"}
1
+ {"version":3,"file":"reading.d.ts","sourceRoot":"","sources":["../../src/tools/reading.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA2CjD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAmK/E"}
@@ -1 +1 @@
1
- {"version":3,"file":"refactoring.d.ts","sourceRoot":"","sources":["../../src/tools/refactoring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAYjD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA4HnF"}
1
+ {"version":3,"file":"refactoring.d.ts","sourceRoot":"","sources":["../../src/tools/refactoring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAajD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA2HnF"}
@@ -1 +1 @@
1
- {"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../../src/tools/safety.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAWjD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAgF9E"}
1
+ {"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../../src/tools/safety.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAYjD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA6F9E"}
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuDjD;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAyF9E"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAwDjD;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAsF9E"}
@@ -1 +1 @@
1
- {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../src/tools/semantic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAQjD,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAqChF"}
1
+ {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../src/tools/semantic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AASjD,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAoChF"}
@@ -1 +1 @@
1
- {"version":3,"file":"structure.d.ts","sourceRoot":"","sources":["../../src/tools/structure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAUjD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAkKjF"}
1
+ {"version":3,"file":"structure.d.ts","sourceRoot":"","sources":["../../src/tools/structure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAWjD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAiKjF"}
package/dist/tui.js CHANGED
@@ -164,6 +164,7 @@ function coerceAftStatus(response) {
164
164
  };
165
165
  const disk = asRecord(response.disk);
166
166
  const symbolCache = asRecord(response.symbol_cache);
167
+ const session = asRecord(response.session);
167
168
  return {
168
169
  version: readString(response.version, "unknown"),
169
170
  project_root: readNullableString(response.project_root),
@@ -201,7 +202,13 @@ function coerceAftStatus(response) {
201
202
  local_entries: readNumber(symbolCache.local_entries),
202
203
  warm_entries: readNumber(symbolCache.warm_entries)
203
204
  },
204
- storage_dir: readNullableString(response.storage_dir)
205
+ storage_dir: readNullableString(response.storage_dir),
206
+ checkpoints_total: readNumber(response.checkpoints_total),
207
+ session: {
208
+ id: readString(session.id, "__default__"),
209
+ tracked_files: readNumber(session.tracked_files),
210
+ checkpoints: readNumber(session.checkpoints)
211
+ }
205
212
  };
206
213
  }
207
214
  function formatStatusDialogMessage(status) {
@@ -236,6 +243,7 @@ function formatStatusDialogMessage(status) {
236
243
  if (status.storage_dir ?? status.disk.storage_dir) {
237
244
  lines.push(`- storage dir: ${status.storage_dir ?? status.disk.storage_dir}`);
238
245
  }
246
+ lines.push("", "Current session", `- id: ${status.session.id}`, `- tracked files: ${formatCount(status.session.tracked_files)}`, `- checkpoints: ${formatCount(status.session.checkpoints)}`, `- project checkpoints (all sessions): ${formatCount(status.checkpoints_total)}`);
239
247
  if (status.semantic_index.stage) {
240
248
  lines.push("", "Semantic stage", status.semantic_index.stage);
241
249
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-opencode",
3
- "version": "0.13.1",
3
+ "version": "0.14.1",
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",
@@ -35,11 +35,11 @@
35
35
  "zod": "^4.1.8"
36
36
  },
37
37
  "optionalDependencies": {
38
- "@cortexkit/aft-darwin-arm64": "0.13.1",
39
- "@cortexkit/aft-darwin-x64": "0.13.1",
40
- "@cortexkit/aft-linux-arm64": "0.13.1",
41
- "@cortexkit/aft-linux-x64": "0.13.1",
42
- "@cortexkit/aft-win32-x64": "0.13.1"
38
+ "@cortexkit/aft-darwin-arm64": "0.14.1",
39
+ "@cortexkit/aft-darwin-x64": "0.14.1",
40
+ "@cortexkit/aft-linux-arm64": "0.14.1",
41
+ "@cortexkit/aft-linux-x64": "0.14.1",
42
+ "@cortexkit/aft-win32-x64": "0.14.1"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/node": "^22.0.0",
@@ -36,6 +36,14 @@ export interface AftStatusSnapshot {
36
36
  warm_entries: number;
37
37
  };
38
38
  storage_dir: string | null;
39
+ /** Total checkpoints across all sessions sharing this bridge. */
40
+ checkpoints_total: number;
41
+ /** Current session's own slice of undo/checkpoint state. */
42
+ session: {
43
+ id: string;
44
+ tracked_files: number;
45
+ checkpoints: number;
46
+ };
39
47
  }
40
48
 
41
49
  function asRecord(value: unknown): Record<string, unknown> {
@@ -95,6 +103,7 @@ export function coerceAftStatus(response: Record<string, unknown>): AftStatusSna
95
103
  };
96
104
  const disk = asRecord(response.disk);
97
105
  const symbolCache = asRecord(response.symbol_cache);
106
+ const session = asRecord(response.session);
98
107
 
99
108
  return {
100
109
  version: readString(response.version, "unknown"),
@@ -134,6 +143,12 @@ export function coerceAftStatus(response: Record<string, unknown>): AftStatusSna
134
143
  warm_entries: readNumber(symbolCache.warm_entries),
135
144
  },
136
145
  storage_dir: readNullableString(response.storage_dir),
146
+ checkpoints_total: readNumber(response.checkpoints_total),
147
+ session: {
148
+ id: readString(session.id, "__default__"),
149
+ tracked_files: readNumber(session.tracked_files),
150
+ checkpoints: readNumber(session.checkpoints),
151
+ },
137
152
  };
138
153
  }
139
154
 
@@ -182,6 +197,15 @@ export function formatStatusDialogMessage(status: AftStatusSnapshot): string {
182
197
  lines.push(`- storage dir: ${status.storage_dir ?? status.disk.storage_dir}`);
183
198
  }
184
199
 
200
+ lines.push(
201
+ "",
202
+ "Current session",
203
+ `- id: ${status.session.id}`,
204
+ `- tracked files: ${formatCount(status.session.tracked_files)}`,
205
+ `- checkpoints: ${formatCount(status.session.checkpoints)}`,
206
+ `- project checkpoints (all sessions): ${formatCount(status.checkpoints_total)}`,
207
+ );
208
+
185
209
  if (status.semantic_index.stage) {
186
210
  lines.push("", "Semantic stage", status.semantic_index.stage);
187
211
  }
@@ -262,5 +286,14 @@ export function formatStatusMarkdown(status: AftStatusSnapshot): string {
262
286
  lines.push(`- **Storage dir:** \`${status.storage_dir ?? status.disk.storage_dir}\``);
263
287
  }
264
288
 
289
+ lines.push(
290
+ "",
291
+ "### Current session",
292
+ `- **ID:** \`${status.session.id}\``,
293
+ `- **Tracked files:** ${formatCount(status.session.tracked_files)}`,
294
+ `- **Checkpoints:** ${formatCount(status.session.checkpoints)}`,
295
+ `- **Project checkpoints (all sessions):** ${formatCount(status.checkpoints_total)}`,
296
+ );
297
+
265
298
  return lines.join("\n");
266
299
  }