@cortexkit/aft-opencode 0.2.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.
Files changed (69) hide show
  1. package/dist/bridge.d.ts +43 -0
  2. package/dist/bridge.d.ts.map +1 -0
  3. package/dist/bridge.js +194 -0
  4. package/dist/bridge.js.map +1 -0
  5. package/dist/config.d.ts +42 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +180 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/downloader.d.ts +32 -0
  10. package/dist/downloader.d.ts.map +1 -0
  11. package/dist/downloader.js +140 -0
  12. package/dist/downloader.js.map +1 -0
  13. package/dist/index.d.ts +21 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +62 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/lsp.d.ts +32 -0
  18. package/dist/lsp.d.ts.map +1 -0
  19. package/dist/lsp.js +71 -0
  20. package/dist/lsp.js.map +1 -0
  21. package/dist/pool.d.ts +33 -0
  22. package/dist/pool.d.ts.map +1 -0
  23. package/dist/pool.js +86 -0
  24. package/dist/pool.js.map +1 -0
  25. package/dist/resolver.d.ts +36 -0
  26. package/dist/resolver.d.ts.map +1 -0
  27. package/dist/resolver.js +122 -0
  28. package/dist/resolver.js.map +1 -0
  29. package/dist/tools/ast.d.ts +9 -0
  30. package/dist/tools/ast.d.ts.map +1 -0
  31. package/dist/tools/ast.js +102 -0
  32. package/dist/tools/ast.js.map +1 -0
  33. package/dist/tools/editing.d.ts +7 -0
  34. package/dist/tools/editing.d.ts.map +1 -0
  35. package/dist/tools/editing.js +150 -0
  36. package/dist/tools/editing.js.map +1 -0
  37. package/dist/tools/imports.d.ts +7 -0
  38. package/dist/tools/imports.d.ts.map +1 -0
  39. package/dist/tools/imports.js +67 -0
  40. package/dist/tools/imports.js.map +1 -0
  41. package/dist/tools/lsp.d.ts +8 -0
  42. package/dist/tools/lsp.d.ts.map +1 -0
  43. package/dist/tools/lsp.js +120 -0
  44. package/dist/tools/lsp.js.map +1 -0
  45. package/dist/tools/navigation.d.ts +7 -0
  46. package/dist/tools/navigation.d.ts.map +1 -0
  47. package/dist/tools/navigation.js +46 -0
  48. package/dist/tools/navigation.js.map +1 -0
  49. package/dist/tools/reading.d.ts +7 -0
  50. package/dist/tools/reading.d.ts.map +1 -0
  51. package/dist/tools/reading.js +103 -0
  52. package/dist/tools/reading.js.map +1 -0
  53. package/dist/tools/refactoring.d.ts +7 -0
  54. package/dist/tools/refactoring.d.ts.map +1 -0
  55. package/dist/tools/refactoring.js +80 -0
  56. package/dist/tools/refactoring.js.map +1 -0
  57. package/dist/tools/safety.d.ts +8 -0
  58. package/dist/tools/safety.d.ts.map +1 -0
  59. package/dist/tools/safety.js +53 -0
  60. package/dist/tools/safety.js.map +1 -0
  61. package/dist/tools/structure.d.ts +8 -0
  62. package/dist/tools/structure.d.ts.map +1 -0
  63. package/dist/tools/structure.js +107 -0
  64. package/dist/tools/structure.js.map +1 -0
  65. package/dist/types.d.ts +13 -0
  66. package/dist/types.d.ts.map +1 -0
  67. package/dist/types.js +2 -0
  68. package/dist/types.js.map +1 -0
  69. package/package.json +40 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"downloader.js","sourceRoot":"","sources":["../src/downloader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ /**
3
+ * AFT (Agent File Toolkit) plugin for OpenCode.
4
+ *
5
+ * Config is loaded from two levels (project overrides user):
6
+ * - User: ~/.config/opencode/aft.jsonc (or .json)
7
+ * - Project: <project>/.opencode/aft.jsonc (or .json)
8
+ *
9
+ * Tools organized into groups:
10
+ * - Reading: aft_outline, aft_zoom
11
+ * - Editing: aft_edit
12
+ * - Safety: aft_safety
13
+ * - Imports: aft_import
14
+ * - Structure: aft_transform
15
+ * - Navigation: aft_navigate
16
+ * - Refactoring: aft_refactor
17
+ * - AST Search: aft_ast_search, aft_ast_replace\n * - LSP: aft_lsp_diagnostics, aft_lsp_hover, aft_lsp_goto_definition, aft_lsp_find_references, aft_lsp_prepare_rename, aft_lsp_rename
18
+ */
19
+ declare const plugin: Plugin;
20
+ export default plugin;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAelD;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,MAAM,EAAE,MAgCb,CAAC;AAEF,eAAe,MAAM,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,62 @@
1
+ import { loadAftConfig } from "./config.js";
2
+ import { BridgePool } from "./pool.js";
3
+ import { findBinary } from "./resolver.js";
4
+ import { astTools } from "./tools/ast.js";
5
+ import { editingTools } from "./tools/editing.js";
6
+ import { importTools } from "./tools/imports.js";
7
+ import { lspTools } from "./tools/lsp.js";
8
+ import { navigationTools } from "./tools/navigation.js";
9
+ import { readingTools } from "./tools/reading.js";
10
+ import { refactoringTools } from "./tools/refactoring.js";
11
+ import { safetyTools } from "./tools/safety.js";
12
+ import { structureTools } from "./tools/structure.js";
13
+ /**
14
+ * AFT (Agent File Toolkit) plugin for OpenCode.
15
+ *
16
+ * Config is loaded from two levels (project overrides user):
17
+ * - User: ~/.config/opencode/aft.jsonc (or .json)
18
+ * - Project: <project>/.opencode/aft.jsonc (or .json)
19
+ *
20
+ * Tools organized into groups:
21
+ * - Reading: aft_outline, aft_zoom
22
+ * - Editing: aft_edit
23
+ * - Safety: aft_safety
24
+ * - Imports: aft_import
25
+ * - Structure: aft_transform
26
+ * - Navigation: aft_navigate
27
+ * - Refactoring: aft_refactor
28
+ * - AST Search: aft_ast_search, aft_ast_replace\n * - LSP: aft_lsp_diagnostics, aft_lsp_hover, aft_lsp_goto_definition, aft_lsp_find_references, aft_lsp_prepare_rename, aft_lsp_rename
29
+ */
30
+ const plugin = async (input) => {
31
+ const binaryPath = await findBinary();
32
+ // Load config: ~/.config/opencode/aft.jsonc → <project>/.opencode/aft.jsonc
33
+ const aftConfig = loadAftConfig(input.directory);
34
+ // Build config overrides for the Rust binary (strip undefined values)
35
+ const configOverrides = {};
36
+ if (aftConfig.format_on_edit !== undefined)
37
+ configOverrides.format_on_edit = aftConfig.format_on_edit;
38
+ if (aftConfig.validate_on_edit !== undefined)
39
+ configOverrides.validate_on_edit = aftConfig.validate_on_edit;
40
+ if (aftConfig.formatter !== undefined)
41
+ configOverrides.formatter = aftConfig.formatter;
42
+ if (aftConfig.checker !== undefined)
43
+ configOverrides.checker = aftConfig.checker;
44
+ const pool = new BridgePool(binaryPath, {}, configOverrides);
45
+ const ctx = { pool, client: input.client, config: aftConfig };
46
+ return {
47
+ tool: {
48
+ ...readingTools(ctx),
49
+ ...editingTools(ctx),
50
+ ...safetyTools(ctx),
51
+ ...importTools(ctx),
52
+ ...structureTools(ctx),
53
+ ...navigationTools(ctx),
54
+ ...astTools(ctx),
55
+ ...refactoringTools(ctx),
56
+ ...lspTools(ctx),
57
+ },
58
+ dispose: () => pool.shutdown(),
59
+ };
60
+ };
61
+ export default plugin;
62
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,GAAW,KAAK,EAAE,KAAK,EAAE,EAAE;IACrC,MAAM,UAAU,GAAG,MAAM,UAAU,EAAE,CAAC;IAEtC,4EAA4E;IAC5E,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEjD,sEAAsE;IACtE,MAAM,eAAe,GAA4B,EAAE,CAAC;IACpD,IAAI,SAAS,CAAC,cAAc,KAAK,SAAS;QACxC,eAAe,CAAC,cAAc,GAAG,SAAS,CAAC,cAAc,CAAC;IAC5D,IAAI,SAAS,CAAC,gBAAgB,KAAK,SAAS;QAC1C,eAAe,CAAC,gBAAgB,GAAG,SAAS,CAAC,gBAAgB,CAAC;IAChE,IAAI,SAAS,CAAC,SAAS,KAAK,SAAS;QAAE,eAAe,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;IACvF,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS;QAAE,eAAe,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;IAEjF,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,EAAE,EAAE,eAAe,CAAC,CAAC;IAC7D,MAAM,GAAG,GAAkB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAE7E,OAAO;QACL,IAAI,EAAE;YACJ,GAAG,YAAY,CAAC,GAAG,CAAC;YACpB,GAAG,YAAY,CAAC,GAAG,CAAC;YACpB,GAAG,WAAW,CAAC,GAAG,CAAC;YACnB,GAAG,WAAW,CAAC,GAAG,CAAC;YACnB,GAAG,cAAc,CAAC,GAAG,CAAC;YACtB,GAAG,eAAe,CAAC,GAAG,CAAC;YACvB,GAAG,QAAQ,CAAC,GAAG,CAAC;YAChB,GAAG,gBAAgB,CAAC,GAAG,CAAC;YACxB,GAAG,QAAQ,CAAC,GAAG,CAAC;SACjB;QACD,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE;KAC/B,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,MAAM,CAAC"}
package/dist/lsp.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ /** Wire format for a single LSP symbol hint sent to the binary. */
3
+ interface LspSymbolHint {
4
+ name: string;
5
+ file: string;
6
+ line: number;
7
+ kind?: string;
8
+ }
9
+ /** Wire format for the lsp_hints field in bridge requests. */
10
+ export interface LspHints {
11
+ symbols: LspSymbolHint[];
12
+ }
13
+ /**
14
+ * Maps LSP SymbolKind numbers to AFT kind strings.
15
+ * Only kinds relevant to AFT disambiguation are included.
16
+ * @see https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#symbolKind
17
+ */
18
+ export declare const LSP_SYMBOL_KIND_MAP: Record<number, string>;
19
+ /**
20
+ * Query the OpenCode LSP for workspace symbols matching `symbolName`.
21
+ *
22
+ * Returns formatted hints for the binary's `lsp_hints` field, or `undefined` if:
23
+ * - No LSP server is connected
24
+ * - The API call fails
25
+ * - No symbols match
26
+ *
27
+ * Failures are silent at the caller level — the binary falls back to
28
+ * tree-sitter-only disambiguation when `lsp_hints` is absent.
29
+ */
30
+ export declare function queryLspHints(client: PluginInput["client"], symbolName: string, directory?: string): Promise<LspHints | undefined>;
31
+ export {};
32
+ //# sourceMappingURL=lsp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp.d.ts","sourceRoot":"","sources":["../src/lsp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKvD,mEAAmE;AACnE,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,8DAA8D;AAC9D,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOtD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,EAC7B,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAgD/B"}
package/dist/lsp.js ADDED
@@ -0,0 +1,71 @@
1
+ /** Prefix for diagnostic messages. */
2
+ const TAG = "[aft-plugin]";
3
+ /**
4
+ * Maps LSP SymbolKind numbers to AFT kind strings.
5
+ * Only kinds relevant to AFT disambiguation are included.
6
+ * @see https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#symbolKind
7
+ */
8
+ export const LSP_SYMBOL_KIND_MAP = {
9
+ 5: "class",
10
+ 6: "method",
11
+ 10: "enum",
12
+ 11: "interface",
13
+ 12: "function",
14
+ 23: "struct",
15
+ };
16
+ /**
17
+ * Query the OpenCode LSP for workspace symbols matching `symbolName`.
18
+ *
19
+ * Returns formatted hints for the binary's `lsp_hints` field, or `undefined` if:
20
+ * - No LSP server is connected
21
+ * - The API call fails
22
+ * - No symbols match
23
+ *
24
+ * Failures are silent at the caller level — the binary falls back to
25
+ * tree-sitter-only disambiguation when `lsp_hints` is absent.
26
+ */
27
+ export async function queryLspHints(client, symbolName, directory) {
28
+ try {
29
+ // Check if any LSP server is connected
30
+ const statusResult = await client.lsp.status();
31
+ const servers = statusResult.data;
32
+ if (!servers || !servers.some((s) => s.status === "connected")) {
33
+ return undefined;
34
+ }
35
+ // Query workspace symbols
36
+ const query = { query: symbolName };
37
+ if (directory) {
38
+ query.directory = directory;
39
+ }
40
+ const symbolsResult = await client.find.symbols({ query });
41
+ const symbols = symbolsResult.data;
42
+ if (!symbols || symbols.length === 0) {
43
+ return undefined;
44
+ }
45
+ // Map to wire format
46
+ const hints = [];
47
+ for (const sym of symbols) {
48
+ // Strip file:// prefix from URIs
49
+ let file = sym.location.uri;
50
+ if (file.startsWith("file://")) {
51
+ file = file.slice(7);
52
+ }
53
+ const hint = {
54
+ name: sym.name,
55
+ file,
56
+ line: sym.location.range.start.line,
57
+ };
58
+ const kind = LSP_SYMBOL_KIND_MAP[sym.kind];
59
+ if (kind) {
60
+ hint.kind = kind;
61
+ }
62
+ hints.push(hint);
63
+ }
64
+ return { symbols: hints };
65
+ }
66
+ catch (err) {
67
+ console.warn(`${TAG} LSP query failed for "${symbolName}": ${err.message}`);
68
+ return undefined;
69
+ }
70
+ }
71
+ //# sourceMappingURL=lsp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp.js","sourceRoot":"","sources":["../src/lsp.ts"],"names":[],"mappings":"AAEA,sCAAsC;AACtC,MAAM,GAAG,GAAG,cAAc,CAAC;AAe3B;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAA2B;IACzD,CAAC,EAAE,OAAO;IACV,CAAC,EAAE,QAAQ;IACX,EAAE,EAAE,MAAM;IACV,EAAE,EAAE,WAAW;IACf,EAAE,EAAE,UAAU;IACd,EAAE,EAAE,QAAQ;CACb,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA6B,EAC7B,UAAkB,EAClB,SAAkB;IAElB,IAAI,CAAC;QACH,uCAAuC;QACvC,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC;QAClC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,EAAE,CAAC;YAC/D,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,0BAA0B;QAC1B,MAAM,KAAK,GAA0C,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QAC3E,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;QAC9B,CAAC;QACD,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC;QACnC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,qBAAqB;QACrB,MAAM,KAAK,GAAoB,EAAE,CAAC;QAClC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,iCAAiC;YACjC,IAAI,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;YAC5B,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC/B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;YAED,MAAM,IAAI,GAAkB;gBAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI;gBACJ,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI;aACpC,CAAC;YAEF,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACnB,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,0BAA0B,UAAU,MAAO,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACvF,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
package/dist/pool.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ import { BinaryBridge, type BridgeOptions } from "./bridge";
2
+ export interface PoolOptions extends BridgeOptions {
3
+ maxPoolSize?: number;
4
+ idleTimeoutMs?: number;
5
+ }
6
+ /**
7
+ * Manages a pool of BinaryBridge instances, one per project directory.
8
+ * Handles idle cleanup and LRU eviction when at capacity.
9
+ */
10
+ export declare class BridgePool {
11
+ private readonly bridges;
12
+ private readonly binaryPath;
13
+ private readonly maxPoolSize;
14
+ private readonly idleTimeoutMs;
15
+ private readonly bridgeOptions;
16
+ private readonly configOverrides;
17
+ private cleanupTimer;
18
+ constructor(binaryPath: string, options?: PoolOptions, configOverrides?: Record<string, unknown>);
19
+ /**
20
+ * Get or create a bridge for the given directory.
21
+ * Each directory gets its own binary process that auto-configures on first use.
22
+ */
23
+ getBridge(directory: string): BinaryBridge;
24
+ /** Shut down idle bridges that haven't been used within the timeout. */
25
+ private cleanup;
26
+ /** Evict the least recently used bridge to make room. */
27
+ private evictLRU;
28
+ /** Shut down all bridges and stop the cleanup timer. */
29
+ shutdown(): Promise<void>;
30
+ /** Number of active bridges in the pool. */
31
+ get size(): number;
32
+ }
33
+ //# sourceMappingURL=pool.d.ts.map
@@ -0,0 +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;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,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;IAU/C;;;OAGG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY;IAuB1C,wEAAwE;IACxE,OAAO,CAAC,OAAO;IAUf,yDAAyD;IACzD,OAAO,CAAC,QAAQ;IAgBhB,wDAAwD;IAClD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAU/B,4CAA4C;IAC5C,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
package/dist/pool.js ADDED
@@ -0,0 +1,86 @@
1
+ import { BinaryBridge } from "./bridge";
2
+ const _TAG = "[BridgePool]";
3
+ const DEFAULT_IDLE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
4
+ const DEFAULT_MAX_POOL_SIZE = 8;
5
+ const CLEANUP_INTERVAL_MS = 60 * 1000; // check every minute
6
+ /**
7
+ * Manages a pool of BinaryBridge instances, one per project directory.
8
+ * Handles idle cleanup and LRU eviction when at capacity.
9
+ */
10
+ export class BridgePool {
11
+ bridges = new Map();
12
+ binaryPath;
13
+ maxPoolSize;
14
+ idleTimeoutMs;
15
+ bridgeOptions;
16
+ configOverrides;
17
+ cleanupTimer = null;
18
+ constructor(binaryPath, options = {}, configOverrides = {}) {
19
+ this.binaryPath = binaryPath;
20
+ this.maxPoolSize = options.maxPoolSize ?? DEFAULT_MAX_POOL_SIZE;
21
+ this.idleTimeoutMs = options.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
22
+ this.bridgeOptions = { timeoutMs: options.timeoutMs, maxRestarts: options.maxRestarts };
23
+ this.configOverrides = configOverrides;
24
+ this.cleanupTimer = setInterval(() => this.cleanup(), CLEANUP_INTERVAL_MS);
25
+ }
26
+ /**
27
+ * Get or create a bridge for the given directory.
28
+ * Each directory gets its own binary process that auto-configures on first use.
29
+ */
30
+ getBridge(directory) {
31
+ const normalized = directory.replace(/\/+$/, "");
32
+ const existing = this.bridges.get(normalized);
33
+ if (existing) {
34
+ existing.lastUsed = Date.now();
35
+ return existing.bridge;
36
+ }
37
+ // Evict LRU if at capacity
38
+ if (this.bridges.size >= this.maxPoolSize) {
39
+ this.evictLRU();
40
+ }
41
+ const bridge = new BinaryBridge(this.binaryPath, normalized, this.bridgeOptions, this.configOverrides);
42
+ this.bridges.set(normalized, { bridge, lastUsed: Date.now() });
43
+ return bridge;
44
+ }
45
+ /** Shut down idle bridges that haven't been used within the timeout. */
46
+ cleanup() {
47
+ const now = Date.now();
48
+ for (const [dir, entry] of this.bridges) {
49
+ if (now - entry.lastUsed > this.idleTimeoutMs) {
50
+ entry.bridge.shutdown().catch(() => { });
51
+ this.bridges.delete(dir);
52
+ }
53
+ }
54
+ }
55
+ /** Evict the least recently used bridge to make room. */
56
+ evictLRU() {
57
+ let oldestDir = null;
58
+ let oldestTime = Infinity;
59
+ for (const [dir, entry] of this.bridges) {
60
+ if (entry.lastUsed < oldestTime) {
61
+ oldestTime = entry.lastUsed;
62
+ oldestDir = dir;
63
+ }
64
+ }
65
+ if (oldestDir) {
66
+ const entry = this.bridges.get(oldestDir);
67
+ entry?.bridge.shutdown().catch(() => { });
68
+ this.bridges.delete(oldestDir);
69
+ }
70
+ }
71
+ /** Shut down all bridges and stop the cleanup timer. */
72
+ async shutdown() {
73
+ if (this.cleanupTimer) {
74
+ clearInterval(this.cleanupTimer);
75
+ this.cleanupTimer = null;
76
+ }
77
+ const shutdowns = Array.from(this.bridges.values()).map((e) => e.bridge.shutdown());
78
+ this.bridges.clear();
79
+ await Promise.allSettled(shutdowns);
80
+ }
81
+ /** Number of active bridges in the pool. */
82
+ get size() {
83
+ return this.bridges.size;
84
+ }
85
+ }
86
+ //# sourceMappingURL=pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Map the current `process.platform` and `process.arch` to the npm platform
3
+ * package suffix (e.g. `"darwin-arm64"`, `"linux-x64"`).
4
+ *
5
+ * Exported for testability — agents and scripts can call this directly to
6
+ * verify the platform mapping without running the full resolver.
7
+ *
8
+ * @throws {Error} with the exact `process.platform` and `process.arch` values
9
+ * when the combination is unsupported.
10
+ */
11
+ export declare function platformKey(platform?: string, arch?: string): string;
12
+ /**
13
+ * Locate the `aft` binary synchronously by checking (in order):
14
+ * 1. Cached binary from previous auto-download (~/.cache/aft/bin/)
15
+ * 2. npm platform package via `require.resolve(@cortexkit/aft-<platform>/bin/aft)`
16
+ * 3. PATH lookup via `which aft` (or `where aft` on Windows)
17
+ * 4. ~/.cargo/bin/aft (Rust cargo install location)
18
+ *
19
+ * Returns the absolute path to the first binary found, or null if none found.
20
+ */
21
+ export declare function findBinarySync(): string | null;
22
+ /**
23
+ * Locate the `aft` binary, with auto-download as a last resort.
24
+ *
25
+ * Resolution order:
26
+ * 1. Cached binary (~/.cache/aft/bin/)
27
+ * 2. npm platform package (@cortexkit/aft-<platform>)
28
+ * 3. PATH lookup (which aft)
29
+ * 4. ~/.cargo/bin/aft
30
+ * 5. Auto-download from GitHub releases
31
+ *
32
+ * Returns the absolute path to the binary.
33
+ * Throws a descriptive error with install instructions if all sources fail.
34
+ */
35
+ export declare function findBinary(): Promise<string>;
36
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAaA;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,QAAQ,GAAE,MAAyB,EACnC,IAAI,GAAE,MAAqB,GAC1B,MAAM,CAgBR;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAkC9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CA8BlD"}
@@ -0,0 +1,122 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { ensureBinary, getCachedBinaryPath } from "./downloader.js";
6
+ /** Supported platform package mapping: `process.platform`-`process.arch` → npm package suffix. */
7
+ const PLATFORM_MAP = {
8
+ darwin: { arm64: "darwin-arm64", x64: "darwin-x64" },
9
+ linux: { arm64: "linux-arm64", x64: "linux-x64" },
10
+ win32: { x64: "win32-x64" },
11
+ };
12
+ /**
13
+ * Map the current `process.platform` and `process.arch` to the npm platform
14
+ * package suffix (e.g. `"darwin-arm64"`, `"linux-x64"`).
15
+ *
16
+ * Exported for testability — agents and scripts can call this directly to
17
+ * verify the platform mapping without running the full resolver.
18
+ *
19
+ * @throws {Error} with the exact `process.platform` and `process.arch` values
20
+ * when the combination is unsupported.
21
+ */
22
+ export function platformKey(platform = process.platform, arch = process.arch) {
23
+ const archMap = PLATFORM_MAP[platform];
24
+ if (!archMap) {
25
+ throw new Error(`Unsupported platform: ${platform} (arch: ${arch}). ` +
26
+ `Supported platforms: ${Object.keys(PLATFORM_MAP).join(", ")}`);
27
+ }
28
+ const key = archMap[arch];
29
+ if (!key) {
30
+ throw new Error(`Unsupported architecture: ${arch} on platform ${platform}. ` +
31
+ `Supported architectures for ${platform}: ${Object.keys(archMap).join(", ")}`);
32
+ }
33
+ return key;
34
+ }
35
+ /**
36
+ * Locate the `aft` binary synchronously by checking (in order):
37
+ * 1. Cached binary from previous auto-download (~/.cache/aft/bin/)
38
+ * 2. npm platform package via `require.resolve(@cortexkit/aft-<platform>/bin/aft)`
39
+ * 3. PATH lookup via `which aft` (or `where aft` on Windows)
40
+ * 4. ~/.cargo/bin/aft (Rust cargo install location)
41
+ *
42
+ * Returns the absolute path to the first binary found, or null if none found.
43
+ */
44
+ export function findBinarySync() {
45
+ const ext = process.platform === "win32" ? ".exe" : "";
46
+ // 1. Check cached binary from auto-download
47
+ const cached = getCachedBinaryPath();
48
+ if (cached)
49
+ return cached;
50
+ // 2. Check npm platform package
51
+ try {
52
+ const key = platformKey();
53
+ const packageBin = `@cortexkit/aft-${key}/bin/aft${ext}`;
54
+ const resolved = require.resolve(packageBin);
55
+ if (existsSync(resolved))
56
+ return resolved;
57
+ }
58
+ catch {
59
+ // npm package not installed or resolution failed
60
+ }
61
+ // 3. Check PATH
62
+ try {
63
+ const whichCmd = process.platform === "win32" ? "where aft" : "which aft";
64
+ const result = execSync(whichCmd, {
65
+ encoding: "utf-8",
66
+ stdio: ["pipe", "pipe", "pipe"],
67
+ }).trim();
68
+ if (result)
69
+ return result;
70
+ }
71
+ catch {
72
+ // not in PATH
73
+ }
74
+ // 4. Check ~/.cargo/bin/aft
75
+ const cargoPath = join(homedir(), ".cargo", "bin", `aft${ext}`);
76
+ if (existsSync(cargoPath))
77
+ return cargoPath;
78
+ return null;
79
+ }
80
+ /**
81
+ * Locate the `aft` binary, with auto-download as a last resort.
82
+ *
83
+ * Resolution order:
84
+ * 1. Cached binary (~/.cache/aft/bin/)
85
+ * 2. npm platform package (@cortexkit/aft-<platform>)
86
+ * 3. PATH lookup (which aft)
87
+ * 4. ~/.cargo/bin/aft
88
+ * 5. Auto-download from GitHub releases
89
+ *
90
+ * Returns the absolute path to the binary.
91
+ * Throws a descriptive error with install instructions if all sources fail.
92
+ */
93
+ export async function findBinary() {
94
+ // Try synchronous resolution first (fast path)
95
+ const syncResult = findBinarySync();
96
+ if (syncResult)
97
+ return syncResult;
98
+ // 5. Auto-download from GitHub releases
99
+ console.error("[aft-plugin] Binary not found locally, attempting auto-download...");
100
+ const downloaded = await ensureBinary();
101
+ if (downloaded)
102
+ return downloaded;
103
+ // All sources exhausted
104
+ throw new Error([
105
+ "Could not find the `aft` binary.",
106
+ "",
107
+ "Attempted sources:",
108
+ " - Cache directory (~/.cache/aft/bin/)",
109
+ " - npm platform package (@cortexkit/aft-<platform>)",
110
+ " - PATH lookup (which aft)",
111
+ " - ~/.cargo/bin/aft",
112
+ " - Auto-download from GitHub releases (failed)",
113
+ "",
114
+ "Install it using one of these methods:",
115
+ " npm install @cortexkit/aft-opencode # installs platform-specific binary via npm",
116
+ " cargo install aft # from crates.io",
117
+ " cargo build --release # from source (binary at target/release/aft)",
118
+ "",
119
+ "Or add the aft directory to your PATH.",
120
+ ].join("\n"));
121
+ }
122
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEpE,kGAAkG;AAClG,MAAM,YAAY,GAA2C;IAC3D,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,YAAY,EAAE;IACpD,KAAK,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,WAAW,EAAE;IACjD,KAAK,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE;CAC5B,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CACzB,WAAmB,OAAO,CAAC,QAAQ,EACnC,OAAe,OAAO,CAAC,IAAI;IAE3B,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,yBAAyB,QAAQ,WAAW,IAAI,KAAK;YACnD,wBAAwB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACjE,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,6BAA6B,IAAI,gBAAgB,QAAQ,IAAI;YAC3D,+BAA+B,QAAQ,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAChF,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAEvD,4CAA4C;IAC5C,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;IACrC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,gCAAgC;IAChC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,kBAAkB,GAAG,WAAW,GAAG,EAAE,CAAC;QACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,QAAQ,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;IACnD,CAAC;IAED,gBAAgB;IAChB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;QAC1E,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,EAAE;YAChC,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;IAED,4BAA4B;IAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;IAChE,IAAI,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAE5C,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,+CAA+C;IAC/C,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAElC,wCAAwC;IACxC,OAAO,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACpF,MAAM,UAAU,GAAG,MAAM,YAAY,EAAE,CAAC;IACxC,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAElC,wBAAwB;IACxB,MAAM,IAAI,KAAK,CACb;QACE,kCAAkC;QAClC,EAAE;QACF,oBAAoB;QACpB,yCAAyC;QACzC,sDAAsD;QACtD,6BAA6B;QAC7B,sBAAsB;QACtB,iDAAiD;QACjD,EAAE;QACF,wCAAwC;QACxC,0FAA0F;QAC1F,kDAAkD;QAClD,8EAA8E;QAC9E,EAAE;QACF,wCAAwC;KACzC,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Tool definitions for AST pattern search and replace using ast-grep.
3
+ * Supports meta-variables ($VAR for single node, $$$ for multiple nodes).
4
+ * Patterns must be complete AST nodes (valid code fragments).
5
+ */
6
+ import type { ToolDefinition } from "@opencode-ai/plugin";
7
+ import type { PluginContext } from "../types.js";
8
+ export declare function astTools(ctx: PluginContext): Record<string, ToolDefinition>;
9
+ //# sourceMappingURL=ast.d.ts.map
@@ -0,0 +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;AA8BjD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAgE3E"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Tool definitions for AST pattern search and replace using ast-grep.
3
+ * Supports meta-variables ($VAR for single node, $$$ for multiple nodes).
4
+ * Patterns must be complete AST nodes (valid code fragments).
5
+ */
6
+ import { tool } from "@opencode-ai/plugin";
7
+ const z = tool.schema;
8
+ const SUPPORTED_LANGS = [
9
+ "bash",
10
+ "c",
11
+ "cpp",
12
+ "csharp",
13
+ "css",
14
+ "elixir",
15
+ "go",
16
+ "haskell",
17
+ "html",
18
+ "java",
19
+ "javascript",
20
+ "json",
21
+ "kotlin",
22
+ "lua",
23
+ "nix",
24
+ "php",
25
+ "python",
26
+ "ruby",
27
+ "rust",
28
+ "scala",
29
+ "solidity",
30
+ "swift",
31
+ "typescript",
32
+ "tsx",
33
+ "yaml",
34
+ ];
35
+ export function astTools(ctx) {
36
+ return {
37
+ aft_ast_search: {
38
+ description: "Search code patterns across filesystem using AST-aware matching. Supports 25 languages. " +
39
+ "Use meta-variables: $VAR (single node), $$$ (multiple nodes). " +
40
+ "IMPORTANT: Patterns must be complete AST nodes (valid code). " +
41
+ "For functions, include params and body: 'export async function $NAME($$$) { $$$ }' not 'export async function $NAME'. " +
42
+ "Examples: 'console.log($MSG)', 'def $FUNC($$$):', 'async function $NAME($$$)'",
43
+ args: {
44
+ pattern: z
45
+ .string()
46
+ .describe("AST pattern with meta-variables ($VAR, $$$). Must be complete AST node."),
47
+ lang: z.enum(SUPPORTED_LANGS).describe("Target language"),
48
+ paths: z.array(z.string()).optional().describe("Paths to search (default: ['.'])"),
49
+ globs: z
50
+ .array(z.string())
51
+ .optional()
52
+ .describe("Include/exclude globs (prefix ! to exclude)"),
53
+ context: z.number().optional().describe("Context lines around match"),
54
+ },
55
+ execute: async (args, context) => {
56
+ const bridge = ctx.pool.getBridge(context.directory);
57
+ const params = {
58
+ pattern: args.pattern,
59
+ lang: args.lang,
60
+ };
61
+ if (args.paths)
62
+ params.paths = args.paths;
63
+ if (args.globs)
64
+ params.globs = args.globs;
65
+ if (args.context !== undefined)
66
+ params.context = Number(args.context);
67
+ const response = await bridge.send("ast_search", params);
68
+ return JSON.stringify(response);
69
+ },
70
+ },
71
+ aft_ast_replace: {
72
+ description: "Replace code patterns across filesystem with AST-aware rewriting. Dry-run by default. " +
73
+ "Use meta-variables in rewrite to preserve matched content. " +
74
+ "Example: pattern='console.log($MSG)' rewrite='logger.info($MSG)'",
75
+ args: {
76
+ pattern: z.string().describe("AST pattern to match"),
77
+ rewrite: z.string().describe("Replacement pattern (can use $VAR from pattern)"),
78
+ lang: z.enum(SUPPORTED_LANGS).describe("Target language"),
79
+ paths: z.array(z.string()).optional().describe("Paths to search"),
80
+ globs: z.array(z.string()).optional().describe("Include/exclude globs"),
81
+ dryRun: z.boolean().optional().describe("Preview changes without applying (default: true)"),
82
+ },
83
+ execute: async (args, context) => {
84
+ const bridge = ctx.pool.getBridge(context.directory);
85
+ const params = {
86
+ pattern: args.pattern,
87
+ rewrite: args.rewrite,
88
+ lang: args.lang,
89
+ };
90
+ if (args.paths)
91
+ params.paths = args.paths;
92
+ if (args.globs)
93
+ params.globs = args.globs;
94
+ // Default to dry_run=true for safety
95
+ params.dry_run = args.dryRun !== false;
96
+ const response = await bridge.send("ast_replace", params);
97
+ return JSON.stringify(response);
98
+ },
99
+ },
100
+ };
101
+ }
102
+ //# sourceMappingURL=ast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/tools/ast.ts"],"names":[],"mappings":"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"}