@cortexkit/aft-opencode 0.29.1 → 0.30.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.
@@ -0,0 +1,18 @@
1
+ import * as fs from "node:fs/promises";
2
+ import { Terminal } from "@xterm/headless";
3
+ export interface PtyTerminalState {
4
+ terminal: Terminal;
5
+ fileHandle: fs.FileHandle;
6
+ offset: number;
7
+ rows: number;
8
+ cols: number;
9
+ lastAccessMs: number;
10
+ }
11
+ export declare function getOrCreatePtyTerminal(key: string, outputPath: string, rows?: number, cols?: number): Promise<PtyTerminalState>;
12
+ export declare function readPtyBytes(state: PtyTerminalState): Promise<Buffer>;
13
+ export declare function disposePtyTerminal(key: string): Promise<void>;
14
+ export declare function disposeAllPtyTerminals(): Promise<void>;
15
+ export declare function renderScreen(state: PtyTerminalState, rows?: number, cols?: number): string;
16
+ export declare function __resetPtyCacheForTests(): void;
17
+ export declare function __ptyCacheSizeForTests(): number;
18
+ //# sourceMappingURL=pty-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty-cache.d.ts","sourceRoot":"","sources":["../../src/shared/pty-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAM3C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAID,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,IAAI,SAAe,EACnB,IAAI,SAAe,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAuB3B;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAa3E;AAED,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMnE;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,gBAAgB,EACvB,IAAI,SAAa,EACjB,IAAI,SAAa,GAChB,MAAM,CAiBR;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAM9C;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C"}
@@ -17,6 +17,45 @@
17
17
  */
18
18
  import type { BinaryBridge, BridgeRequestOptions } from "@cortexkit/aft-bridge";
19
19
  import type { PluginContext } from "../types.js";
20
+ /**
21
+ * Optional integer with bounds.
22
+ *
23
+ * MUST be JSON-Schema-representable for OpenCode tool registration to
24
+ * succeed: OpenCode wraps plugin args in a host `z.object()` and runs
25
+ * `z.toJSONSchema(args, { io: "input" })` at session start. Any node
26
+ * the host's Zod can't convert (e.g. `.transform()`, `.preprocess()`)
27
+ * throws "Transforms cannot be represented in JSON Schema" and the
28
+ * entire plugin fails to load. Keep this a plain schema — no
29
+ * transforms. Empty-sentinel coercion (null/""/0 → undefined) belongs
30
+ * in tool handlers via `coerceOptionalInt`, not in the schema.
31
+ *
32
+ * Regression guard: `tool-schemas-json-convertible.test.ts` runs
33
+ * `z.toJSONSchema(z.object(args), { io: "input" })` on every plugin
34
+ * tool. If anyone reintroduces a `.transform()` here it fails before
35
+ * shipping.
36
+ *
37
+ * Return type is `any` to suppress TS2742 — Zod's inferred type leaks
38
+ * `.bun/zod@...` paths that aren't portable across the host SDK and
39
+ * our zod version. The type annotation has no runtime effect; the
40
+ * contract test is the real invariant.
41
+ */
42
+ export declare const optionalInt: (min: number, max: number) => any;
43
+ /**
44
+ * Runtime coercion for agent-friendly sentinel handling.
45
+ *
46
+ * Some agents emit null / "" / 0 when they mean "param not provided".
47
+ * Use this inside tool handlers BEFORE relying on the value. Returns
48
+ * `undefined` for all empty sentinels; rejects out-of-bounds with a
49
+ * clear message.
50
+ *
51
+ * Tool handlers that want sentinel tolerance must pass args through
52
+ * this AFTER Zod validation has accepted the value (or for fields
53
+ * declared as `z.unknown().optional()` that bypass type validation).
54
+ * With `optionalInt`'s bounded `z.number().int()` schema, Zod already
55
+ * rejects the sentinels — call this for defense in depth or for fields
56
+ * declared more permissively.
57
+ */
58
+ export declare function coerceOptionalInt(v: unknown, paramName: string, min: number, max: number): number | undefined;
20
59
  /**
21
60
  * Per-command timeout overrides (milliseconds).
22
61
  *
@@ -1 +1 @@
1
- {"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../src/tools/_shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAOhF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQlE,CAAC;AAEF,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAErE;AAED;;;;;;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;AAkBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAW3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,YAAY,CAEhF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA0BlC;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAE9F"}
1
+ {"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../src/tools/_shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAQhF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,GACR,CAAC;AAEhD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,OAAO,EACV,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAWpB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQlE,CAAC;AAEF,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAErE;AAED;;;;;;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;AAkBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAW3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,YAAY,CAEhF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA0BlC;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAE9F"}
@@ -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;AAkDjD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA6S3E"}
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;AAkDjD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA4S3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAMvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA0EjD,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAuOjE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAqCvE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAmBrE"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAavE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA0EjD,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAkQjE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAyBvE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAuBrE"}
@@ -0,0 +1,24 @@
1
+ import type { ToolContext, ToolDefinition } from "@opencode-ai/plugin";
2
+ import type { PluginContext } from "../types.js";
3
+ export type BashWaitPattern = {
4
+ kind: "substring";
5
+ value: string;
6
+ } | {
7
+ kind: "regex";
8
+ value: RegExp;
9
+ source: string;
10
+ };
11
+ export type BashStatusWaited = {
12
+ reason: "matched" | "exited" | "timeout";
13
+ elapsed_ms: number;
14
+ match?: string;
15
+ match_offset?: number;
16
+ };
17
+ type BashStatusWithWait = Record<string, unknown> & {
18
+ waited?: BashStatusWaited;
19
+ };
20
+ export declare function createBashWatchTool(ctx: PluginContext): ToolDefinition;
21
+ export declare function waitForBashStatus(ctx: PluginContext, runtime: ToolContext, taskId: string, outputMode: string | undefined, waitFor: BashWaitPattern | undefined, effectiveWaitMs: number): Promise<BashStatusWithWait>;
22
+ export declare function parseWaitPattern(value: unknown): BashWaitPattern | undefined;
23
+ export {};
24
+ //# sourceMappingURL=bash_watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash_watch.d.ts","sourceRoot":"","sources":["../../src/tools/bash_watch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAavE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AASjD,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACrD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AACF,KAAK,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAElF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAyFtE;AAiDD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAmD7B;AAsCD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAK5E"}
@@ -0,0 +1,38 @@
1
+ import type { ToolDefinition } from "@opencode-ai/plugin";
2
+ import type { PluginContext } from "../types.js";
3
+ /**
4
+ * Write bytes to a running PTY background task.
5
+ *
6
+ * Two input shapes:
7
+ *
8
+ * - **String** — verbatim bytes written to the PTY. Use this for plain text
9
+ * such as REPL commands (`"print(1)\n"`) or when the agent specifically
10
+ * wants the literal characters `\u001b` (e.g. writing source code).
11
+ *
12
+ * - **Sequence array** — mix plain strings (text) with `{ key: "<name>" }`
13
+ * objects (named control keys). Items concatenate into one atomic write
14
+ * so the PTY sees the whole sequence as one input chunk. The agent never
15
+ * has to JSON-encode escape characters.
16
+ *
17
+ * Allowed key names: `enter`, `return`, `tab`, `space`, `backspace`,
18
+ * `esc`, `escape`, `up`, `down`, `left`, `right`, `home`, `end`,
19
+ * `page-up`, `page-down`, `delete`, `insert`, `f1`..`f12`,
20
+ * `ctrl-a`..`ctrl-z`. Names are case-insensitive.
21
+ *
22
+ * The vim "type text, exit insert, save and quit" idiom:
23
+ *
24
+ * ```ts
25
+ * bash_write({ taskId, input: [
26
+ * "iHello",
27
+ * { key: "esc" },
28
+ * ":wq",
29
+ * { key: "enter" },
30
+ * ]})
31
+ * ```
32
+ *
33
+ * Rust enforces a 1 MiB maximum on the EXPANDED byte stream. Agents should
34
+ * check `bash_status` first and only call `bash_write` when the task reports
35
+ * `mode: "pty"`.
36
+ */
37
+ export declare function createBashWriteTool(ctx: PluginContext): ToolDefinition;
38
+ //# sourceMappingURL=bash_write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash_write.d.ts","sourceRoot":"","sources":["../../src/tools/bash_write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CA6CtE"}
@@ -20,7 +20,7 @@ export declare function createReadTool(ctx: PluginContext): ToolDefinition;
20
20
  * Returns hoisted tools keyed by opencode's built-in names.
21
21
  * Overrides: read, write, edit, apply_patch (always when hoisting is on).
22
22
  *
23
- * Bash hoisting is opt-in: `bash`, `bash_status`, and `bash_kill` are
23
+ * Bash hoisting is opt-in: `bash`, `bash_status`, `bash_write`, and `bash_kill` are
24
24
  * registered together when at least one `experimental.bash.*` flag is
25
25
  * enabled (rewrite, compress, or background). When all flags are off,
26
26
  * opencode's native bash stays in place — users without bash experimentals
@@ -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;AAK1D,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;AAmmCD;;;;;;;;;;;;;;;;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,CA4FnF"}
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;AAK1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAyEjD,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,CAkKjE;AAkmCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA0B/E;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA8FnF"}
@@ -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;AAIjD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAkF3E"}
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,CA+E3E"}
@@ -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;AAKjD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAqDlF"}
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,CAkDlF"}
@@ -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;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA2J/E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GACnC,eAAe,CAyBjB"}
1
+ {"version":3,"file":"reading.d.ts","sourceRoot":"","sources":["../../src/tools/reading.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA0J/E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GACnC,eAAe,CAyBjB"}
@@ -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;AASjD,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAyDhF"}
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;AAWjD,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAyDhF"}
package/dist/tui.js CHANGED
@@ -3,7 +3,7 @@ import { createMemo as createMemo2, createSignal as createSignal2, onCleanup as
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@cortexkit/aft-opencode",
6
- version: "0.29.1",
6
+ version: "0.30.1",
7
7
  type: "module",
8
8
  description: "OpenCode plugin for Agent File Tools (AFT) — tree-sitter and lsp powered code analysis",
9
9
  main: "dist/index.js",
@@ -32,20 +32,21 @@ var package_default = {
32
32
  },
33
33
  dependencies: {
34
34
  "@clack/prompts": "^1.2.0",
35
- "@cortexkit/aft-bridge": "0.29.1",
35
+ "@cortexkit/aft-bridge": "0.30.1",
36
36
  "@opencode-ai/plugin": "^1.15.5",
37
37
  "@opencode-ai/sdk": "^1.15.5",
38
+ "@xterm/headless": "^5.5.0",
38
39
  "comment-json": "^4.6.2",
39
40
  undici: "^7.25.0",
40
41
  zod: "^4.1.8"
41
42
  },
42
43
  optionalDependencies: {
43
- "@cortexkit/aft-darwin-arm64": "0.29.1",
44
- "@cortexkit/aft-darwin-x64": "0.29.1",
45
- "@cortexkit/aft-linux-arm64": "0.29.1",
46
- "@cortexkit/aft-linux-x64": "0.29.1",
47
- "@cortexkit/aft-win32-arm64": "0.29.1",
48
- "@cortexkit/aft-win32-x64": "0.29.1"
44
+ "@cortexkit/aft-darwin-arm64": "0.30.1",
45
+ "@cortexkit/aft-darwin-x64": "0.30.1",
46
+ "@cortexkit/aft-linux-arm64": "0.30.1",
47
+ "@cortexkit/aft-linux-x64": "0.30.1",
48
+ "@cortexkit/aft-win32-arm64": "0.30.1",
49
+ "@cortexkit/aft-win32-x64": "0.30.1"
49
50
  },
50
51
  devDependencies: {
51
52
  "@types/node": "^22.0.0",
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-hints.d.ts","sourceRoot":"","sources":["../src/workflow-hints.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,oEAAoE;IACpE,WAAW,EAAE,SAAS,GAAG,aAAa,GAAG,KAAK,CAAC;IAC/C,4EAA4E;IAC5E,aAAa,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,eAAe,EAAE,OAAO,CAAC;IACzB,wEAAwE;IACxE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,4DAA4D;IAC5D,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC5B;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAmEzE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAQjG"}
1
+ {"version":3,"file":"workflow-hints.d.ts","sourceRoot":"","sources":["../src/workflow-hints.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,oEAAoE;IACpE,WAAW,EAAE,SAAS,GAAG,aAAa,GAAG,KAAK,CAAC;IAC/C,4EAA4E;IAC5E,aAAa,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,eAAe,EAAE,OAAO,CAAC;IACzB,wEAAwE;IACxE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,4DAA4D;IAC5D,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC5B;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAuEzE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAQjG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-opencode",
3
- "version": "0.29.1",
3
+ "version": "0.30.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",
@@ -29,20 +29,21 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@clack/prompts": "^1.2.0",
32
- "@cortexkit/aft-bridge": "0.29.1",
32
+ "@cortexkit/aft-bridge": "0.30.1",
33
33
  "@opencode-ai/plugin": "^1.15.5",
34
34
  "@opencode-ai/sdk": "^1.15.5",
35
+ "@xterm/headless": "^5.5.0",
35
36
  "comment-json": "^4.6.2",
36
37
  "undici": "^7.25.0",
37
38
  "zod": "^4.1.8"
38
39
  },
39
40
  "optionalDependencies": {
40
- "@cortexkit/aft-darwin-arm64": "0.29.1",
41
- "@cortexkit/aft-darwin-x64": "0.29.1",
42
- "@cortexkit/aft-linux-arm64": "0.29.1",
43
- "@cortexkit/aft-linux-x64": "0.29.1",
44
- "@cortexkit/aft-win32-arm64": "0.29.1",
45
- "@cortexkit/aft-win32-x64": "0.29.1"
41
+ "@cortexkit/aft-darwin-arm64": "0.30.1",
42
+ "@cortexkit/aft-darwin-x64": "0.30.1",
43
+ "@cortexkit/aft-linux-arm64": "0.30.1",
44
+ "@cortexkit/aft-linux-x64": "0.30.1",
45
+ "@cortexkit/aft-win32-arm64": "0.30.1",
46
+ "@cortexkit/aft-win32-x64": "0.30.1"
46
47
  },
47
48
  "devDependencies": {
48
49
  "@types/node": "^22.0.0",
@@ -0,0 +1,113 @@
1
+ import * as fs from "node:fs/promises";
2
+ import { Terminal } from "@xterm/headless";
3
+
4
+ const DEFAULT_COLS = 80;
5
+ const DEFAULT_ROWS = 24;
6
+ const READ_CHUNK_SIZE = 64 * 1024;
7
+
8
+ export interface PtyTerminalState {
9
+ terminal: Terminal;
10
+ fileHandle: fs.FileHandle;
11
+ offset: number;
12
+ rows: number;
13
+ cols: number;
14
+ lastAccessMs: number;
15
+ }
16
+
17
+ const terminals = new Map<string, PtyTerminalState>();
18
+
19
+ export async function getOrCreatePtyTerminal(
20
+ key: string,
21
+ outputPath: string,
22
+ rows = DEFAULT_ROWS,
23
+ cols = DEFAULT_COLS,
24
+ ): Promise<PtyTerminalState> {
25
+ const existing = terminals.get(key);
26
+ if (existing) {
27
+ existing.lastAccessMs = Date.now();
28
+ if (existing.rows === rows && existing.cols === cols) {
29
+ return existing;
30
+ }
31
+ terminals.delete(key);
32
+ existing.terminal.dispose();
33
+ await existing.fileHandle.close().catch(() => undefined);
34
+ }
35
+
36
+ const fileHandle = await fs.open(outputPath, "r");
37
+ const state: PtyTerminalState = {
38
+ terminal: new Terminal({ cols, rows, allowProposedApi: true }),
39
+ fileHandle,
40
+ offset: 0,
41
+ rows,
42
+ cols,
43
+ lastAccessMs: Date.now(),
44
+ };
45
+ terminals.set(key, state);
46
+ return state;
47
+ }
48
+
49
+ export async function readPtyBytes(state: PtyTerminalState): Promise<Buffer> {
50
+ const chunks: Buffer[] = [];
51
+ while (true) {
52
+ const buffer = Buffer.allocUnsafe(READ_CHUNK_SIZE);
53
+ const { bytesRead } = await state.fileHandle.read(buffer, 0, buffer.length, state.offset);
54
+ if (bytesRead === 0) break;
55
+ const chunk = buffer.subarray(0, bytesRead);
56
+ chunks.push(Buffer.from(chunk));
57
+ await writeTerminal(state.terminal, chunk);
58
+ state.offset += bytesRead;
59
+ }
60
+ state.lastAccessMs = Date.now();
61
+ return Buffer.concat(chunks);
62
+ }
63
+
64
+ export async function disposePtyTerminal(key: string): Promise<void> {
65
+ const state = terminals.get(key);
66
+ if (!state) return;
67
+ terminals.delete(key);
68
+ state.terminal.dispose();
69
+ await state.fileHandle.close().catch(() => undefined);
70
+ }
71
+
72
+ export async function disposeAllPtyTerminals(): Promise<void> {
73
+ await Promise.all([...terminals.keys()].map((key) => disposePtyTerminal(key)));
74
+ }
75
+
76
+ export function renderScreen(
77
+ state: PtyTerminalState,
78
+ rows = state.rows,
79
+ cols = state.cols,
80
+ ): string {
81
+ const active = state.terminal.buffer.active;
82
+ const lines: string[] = [];
83
+ for (let y = 0; y < rows; y++) {
84
+ const line = active.getLine(active.baseY + y);
85
+ if (!line) {
86
+ lines.push("");
87
+ continue;
88
+ }
89
+ let text = "";
90
+ for (let x = 0; x < cols; x++) {
91
+ text += line.getCell(x)?.getChars() || " ";
92
+ }
93
+ lines.push(text.trimEnd());
94
+ }
95
+ while (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
96
+ return lines.join("\n");
97
+ }
98
+
99
+ export function __resetPtyCacheForTests(): void {
100
+ for (const state of terminals.values()) {
101
+ state.terminal.dispose();
102
+ void state.fileHandle.close().catch(() => undefined);
103
+ }
104
+ terminals.clear();
105
+ }
106
+
107
+ export function __ptyCacheSizeForTests(): number {
108
+ return terminals.size;
109
+ }
110
+
111
+ function writeTerminal(terminal: Terminal, data: Uint8Array): Promise<void> {
112
+ return new Promise((resolve) => terminal.write(data, resolve));
113
+ }