@cortexkit/aft-opencode 0.9.1 → 0.11.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 (94) hide show
  1. package/dist/bridge.d.ts.map +1 -1
  2. package/dist/config.d.ts +1 -0
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +25413 -182
  6. package/dist/notifications.d.ts +48 -0
  7. package/dist/notifications.d.ts.map +1 -0
  8. package/dist/onnx-runtime.d.ts +35 -0
  9. package/dist/onnx-runtime.d.ts.map +1 -0
  10. package/dist/pool.d.ts +2 -0
  11. package/dist/pool.d.ts.map +1 -1
  12. package/dist/resolver.d.ts.map +1 -1
  13. package/dist/shared/opencode-config-dir.d.ts +16 -0
  14. package/dist/shared/opencode-config-dir.d.ts.map +1 -0
  15. package/dist/shared/rpc-client.d.ts +16 -0
  16. package/dist/shared/rpc-client.d.ts.map +1 -0
  17. package/dist/shared/rpc-server.d.ts +17 -0
  18. package/dist/shared/rpc-server.d.ts.map +1 -0
  19. package/dist/shared/rpc-utils.d.ts +11 -0
  20. package/dist/shared/rpc-utils.d.ts.map +1 -0
  21. package/dist/shared/runtime.d.ts +10 -0
  22. package/dist/shared/runtime.d.ts.map +1 -0
  23. package/dist/shared/status.d.ts +37 -0
  24. package/dist/shared/status.d.ts.map +1 -0
  25. package/dist/shared/tui-config.d.ts +2 -0
  26. package/dist/shared/tui-config.d.ts.map +1 -0
  27. package/dist/shared/url-fetch.d.ts +11 -0
  28. package/dist/shared/url-fetch.d.ts.map +1 -0
  29. package/dist/tools/reading.d.ts.map +1 -1
  30. package/dist/tools/search.d.ts.map +1 -1
  31. package/dist/tools/semantic.d.ts +4 -0
  32. package/dist/tools/semantic.d.ts.map +1 -0
  33. package/dist/types.d.ts +2 -0
  34. package/dist/types.d.ts.map +1 -1
  35. package/package.json +29 -9
  36. package/src/shared/opencode-config-dir.ts +46 -0
  37. package/src/shared/rpc-client.ts +123 -0
  38. package/src/shared/rpc-server.ts +135 -0
  39. package/src/shared/rpc-utils.ts +21 -0
  40. package/src/shared/runtime.ts +26 -0
  41. package/src/shared/status.ts +206 -0
  42. package/src/shared/tui-config.ts +58 -0
  43. package/src/shared/url-fetch.ts +237 -0
  44. package/src/tui/index.tsx +209 -0
  45. package/src/tui/types/opencode-plugin-tui.d.ts +232 -0
  46. package/dist/bridge.js +0 -311
  47. package/dist/bridge.js.map +0 -1
  48. package/dist/config.js +0 -302
  49. package/dist/config.js.map +0 -1
  50. package/dist/downloader.js +0 -198
  51. package/dist/downloader.js.map +0 -1
  52. package/dist/index.js.map +0 -1
  53. package/dist/logger.js +0 -78
  54. package/dist/logger.js.map +0 -1
  55. package/dist/lsp.js +0 -79
  56. package/dist/lsp.js.map +0 -1
  57. package/dist/metadata-store.js +0 -53
  58. package/dist/metadata-store.js.map +0 -1
  59. package/dist/normalize-schemas.js +0 -45
  60. package/dist/normalize-schemas.js.map +0 -1
  61. package/dist/patch-parser.js +0 -247
  62. package/dist/patch-parser.js.map +0 -1
  63. package/dist/platform.js +0 -31
  64. package/dist/platform.js.map +0 -1
  65. package/dist/pool.js +0 -111
  66. package/dist/pool.js.map +0 -1
  67. package/dist/resolver.js +0 -168
  68. package/dist/resolver.js.map +0 -1
  69. package/dist/tools/ast.js +0 -200
  70. package/dist/tools/ast.js.map +0 -1
  71. package/dist/tools/conflicts.js +0 -20
  72. package/dist/tools/conflicts.js.map +0 -1
  73. package/dist/tools/hoisted.js +0 -870
  74. package/dist/tools/hoisted.js.map +0 -1
  75. package/dist/tools/imports.js +0 -90
  76. package/dist/tools/imports.js.map +0 -1
  77. package/dist/tools/lsp.js +0 -58
  78. package/dist/tools/lsp.js.map +0 -1
  79. package/dist/tools/navigation.js +0 -58
  80. package/dist/tools/navigation.js.map +0 -1
  81. package/dist/tools/permissions.js +0 -50
  82. package/dist/tools/permissions.js.map +0 -1
  83. package/dist/tools/reading.js +0 -229
  84. package/dist/tools/reading.js.map +0 -1
  85. package/dist/tools/refactoring.js +0 -129
  86. package/dist/tools/refactoring.js.map +0 -1
  87. package/dist/tools/safety.js +0 -83
  88. package/dist/tools/safety.js.map +0 -1
  89. package/dist/tools/search.js +0 -88
  90. package/dist/tools/search.js.map +0 -1
  91. package/dist/tools/structure.js +0 -157
  92. package/dist/tools/structure.js.map +0 -1
  93. package/dist/types.js +0 -2
  94. package/dist/types.js.map +0 -1
@@ -0,0 +1,48 @@
1
+ /**
2
+ * User-visible notifications for AFT plugin.
3
+ *
4
+ * Two delivery paths based on the OpenCode client:
5
+ * - Desktop: Sends ignored messages to the active session (appears in chat, hidden from LLM)
6
+ * - TUI: Uses client.tui.showToast() for transient toast notifications
7
+ *
8
+ * Use cases:
9
+ * - Feature announcements (new version, new experimental features)
10
+ * - Warnings (ONNX Runtime not found, stale binary)
11
+ * - Status updates (semantic search ready, index built)
12
+ *
13
+ * Messages are identified by markers and cleaned up on subsequent startups
14
+ * when no longer relevant (Desktop only — TUI toasts are inherently transient).
15
+ */
16
+ export interface NotificationOptions {
17
+ /** The OpenCode SDK client */
18
+ client: unknown;
19
+ /** Project directory for Desktop state lookup */
20
+ directory: string;
21
+ /** Server URL for message deletion (optional — from ctx.serverUrl) */
22
+ serverUrl?: string;
23
+ }
24
+ /**
25
+ * Send a persistent warning notification.
26
+ * Desktop: ignored message, cleaned up on next startup when resolved.
27
+ * TUI: toast with warning variant (inherently transient).
28
+ */
29
+ export declare function sendWarning(opts: NotificationOptions, message: string): Promise<void>;
30
+ /**
31
+ * Send a transient status notification.
32
+ * Desktop: ignored message, auto-deletes after 3 seconds.
33
+ * TUI: toast with success variant, auto-dismissed by the TUI.
34
+ */
35
+ export declare function sendStatus(opts: NotificationOptions, message: string): Promise<void>;
36
+ /**
37
+ * Send a feature announcement for a new version.
38
+ * Tracked via a version file in storageDir — only fires once per version across all sessions.
39
+ * Desktop: ignored message in the active session.
40
+ * TUI: toast with info variant.
41
+ */
42
+ export declare function sendFeatureAnnouncement(opts: NotificationOptions, version: string, features: string[], storageDir?: string): Promise<void>;
43
+ /**
44
+ * Clean up stale AFT warning messages from previous runs.
45
+ * Desktop only — TUI toasts are inherently transient and don't need cleanup.
46
+ */
47
+ export declare function cleanupWarnings(opts: NotificationOptions): Promise<void>;
48
+ //# sourceMappingURL=notifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA+NH,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;;;;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;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C9E"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Auto-download and manage ONNX Runtime shared library for semantic search.
3
+ *
4
+ * Downloads the CPU-only ONNX Runtime from Microsoft's GitHub releases.
5
+ * The library is cached in the storage directory alongside semantic index data.
6
+ *
7
+ * Supported platforms:
8
+ * - macOS ARM64 (osx-arm64)
9
+ * - Linux x64 (linux-x64)
10
+ * - Linux ARM64 (linux-aarch64)
11
+ * - Windows x64 (win-x64)
12
+ * - Windows ARM64 (win-arm64)
13
+ *
14
+ * macOS x64 (Intel) is not provided by Microsoft — users must install via:
15
+ * brew install onnxruntime
16
+ */
17
+ /** Check if this platform can auto-download ONNX Runtime */
18
+ export declare function isOrtAutoDownloadSupported(): boolean;
19
+ /** Get the install hint for platforms where auto-download isn't available */
20
+ export declare function getManualInstallHint(): string;
21
+ /**
22
+ * Ensure ONNX Runtime is available. Returns the directory containing the library,
23
+ * or null if unavailable.
24
+ *
25
+ * Resolution order:
26
+ * 1. Cached in storageDir/onnxruntime/<version>/
27
+ * 2. Auto-download from GitHub releases (if platform supported)
28
+ * 3. null (user needs manual install)
29
+ */
30
+ export declare function ensureOnnxRuntime(storageDir: string): Promise<string | null>;
31
+ /**
32
+ * Remove ONNX Runtime from temp files. Cleanup helper for test isolation.
33
+ */
34
+ export declare function cleanupOnnxRuntime(storageDir: string): void;
35
+ //# sourceMappingURL=onnx-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onnx-runtime.d.ts","sourceRoot":"","sources":["../src/onnx-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA0DH,4DAA4D;AAC5D,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAED,6EAA6E;AAC7E,wBAAgB,oBAAoB,IAAI,MAAM,CAQ7C;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA4BlF;AAuGD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAU3D"}
package/dist/pool.d.ts CHANGED
@@ -22,6 +22,8 @@ export declare class BridgePool {
22
22
  * Each session gets its own binary process with isolated backup/undo history.
23
23
  * The bridge's working directory is set to `directory`.
24
24
  */
25
+ /** Get any existing bridge that is configured and alive, preferring the given directory. */
26
+ getAnyActiveBridge(_directory: string): BinaryBridge | null;
25
27
  getBridge(directory: string, sessionID: string): BinaryBridge;
26
28
  /** Shut down idle bridges that haven't been used within the timeout. */
27
29
  private cleanup;
@@ -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,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;IAUnD,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;;;;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 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAqDA;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,QAAQ,GAAE,MAAyB,EACnC,IAAI,GAAE,MAAqB,GAC1B,MAAM,CAgBR;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAuC9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAiClD"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAqDA;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,QAAQ,GAAE,MAAyB,EACnC,IAAI,GAAE,MAAqB,GAC1B,MAAM,CAgBR;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAiD9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAiClD"}
@@ -0,0 +1,16 @@
1
+ export type OpenCodeBinaryType = "opencode" | "opencode-desktop";
2
+ export interface OpenCodeConfigDirOptions {
3
+ binary: OpenCodeBinaryType;
4
+ version?: string | null;
5
+ checkExisting?: boolean;
6
+ }
7
+ export interface OpenCodeConfigPaths {
8
+ configDir: string;
9
+ configJson: string;
10
+ configJsonc: string;
11
+ packageJson: string;
12
+ omoConfig: string;
13
+ }
14
+ export declare function getOpenCodeConfigDir(_options: OpenCodeConfigDirOptions): string;
15
+ export declare function getOpenCodeConfigPaths(options: OpenCodeConfigDirOptions): OpenCodeConfigPaths;
16
+ //# sourceMappingURL=opencode-config-dir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-config-dir.d.ts","sourceRoot":"","sources":["../../src/shared/opencode-config-dir.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,kBAAkB,CAAC;AAEjE,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAeD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM,CAE/E;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,wBAAwB,GAAG,mBAAmB,CAS7F"}
@@ -0,0 +1,16 @@
1
+ export declare class AftRpcClient {
2
+ private port;
3
+ private portFilePath;
4
+ private healthChecked;
5
+ constructor(storageDir: string, directory: string);
6
+ /** Call an RPC method. Retries port resolution if the server isn't ready yet. */
7
+ call<T = Record<string, unknown>>(method: string, params?: Record<string, unknown>): Promise<T>;
8
+ /** Check if the RPC server is reachable. */
9
+ isAvailable(): Promise<boolean>;
10
+ private resolvePort;
11
+ private readPortFile;
12
+ private healthCheck;
13
+ private fetchWithTimeout;
14
+ reset(): void;
15
+ }
16
+ //# sourceMappingURL=rpc-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-client.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-client.ts"],"names":[],"mappings":"AAOA,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,aAAa,CAAS;gBAElB,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAIjD,iFAAiF;IAC3E,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,OAAO,CAAC,CAAC,CAAC;IAoBb,4CAA4C;IACtC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;YASvB,WAAW;IAkCzB,OAAO,CAAC,YAAY;YAaN,WAAW;YAWX,gBAAgB;IAU9B,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,17 @@
1
+ type RpcHandler = (params: Record<string, unknown>) => Promise<Record<string, unknown>>;
2
+ export declare class AftRpcServer {
3
+ private server;
4
+ private port;
5
+ private handlers;
6
+ private portFilePath;
7
+ constructor(storageDir: string, directory: string);
8
+ /** Register an RPC method handler. */
9
+ handle(method: string, handler: RpcHandler): void;
10
+ /** Start the server on a random port, write port to disk. */
11
+ start(): Promise<number>;
12
+ /** Stop the server and clean up port file. */
13
+ stop(): void;
14
+ private dispatch;
15
+ }
16
+ export {};
17
+ //# sourceMappingURL=rpc-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-server.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-server.ts"],"names":[],"mappings":"AAMA,KAAK,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAExF,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,YAAY,CAAS;gBAEjB,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAIjD,sCAAsC;IACtC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAIjD,6DAA6D;IACvD,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAsC9B,8CAA8C;IAC9C,IAAI,IAAI,IAAI;IAYZ,OAAO,CAAC,QAAQ;CA2DjB"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Compute a stable hash for a project directory.
3
+ * Used to scope RPC port files per-project so multiple
4
+ * OpenCode Desktop instances don't overwrite each other.
5
+ */
6
+ export declare function projectHash(directory: string): string;
7
+ /**
8
+ * Get the per-project RPC port file path.
9
+ */
10
+ export declare function rpcPortFilePath(storageDir: string, directory: string): string;
11
+ //# sourceMappingURL=rpc-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-utils.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-utils.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAIrD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG7E"}
@@ -0,0 +1,10 @@
1
+ type BridgeLike = {
2
+ getBridge: (directory: string, sessionID: string) => {
3
+ send: (command: string, params?: Record<string, unknown>) => Promise<Record<string, unknown>>;
4
+ };
5
+ };
6
+ export declare function setSharedBridgePool(pool: BridgeLike): void;
7
+ export declare function getSharedBridgePool(): BridgeLike | null;
8
+ export declare function clearSharedBridgePool(): void;
9
+ export {};
10
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/shared/runtime.ts"],"names":[],"mappings":"AAAA,KAAK,UAAU,GAAG;IAChB,SAAS,EAAE,CACT,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,KACd;QACH,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;KAC/F,CAAC;CACH,CAAC;AAQF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAE1D;AAED,wBAAgB,mBAAmB,IAAI,UAAU,GAAG,IAAI,CAEvD;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
@@ -0,0 +1,37 @@
1
+ export interface AftStatusSnapshot {
2
+ version: string;
3
+ project_root: string | null;
4
+ features: {
5
+ format_on_edit: boolean;
6
+ validate_on_edit: string;
7
+ restrict_to_project_root: boolean;
8
+ experimental_search_index: boolean;
9
+ experimental_semantic_search: boolean;
10
+ };
11
+ search_index: {
12
+ status: string;
13
+ files: number | null;
14
+ trigrams: number | null;
15
+ };
16
+ semantic_index: {
17
+ status: string;
18
+ entries: number | null;
19
+ dimension: number | null;
20
+ };
21
+ disk: {
22
+ storage_dir: string | null;
23
+ trigram_disk_bytes: number;
24
+ semantic_disk_bytes: number;
25
+ };
26
+ lsp_servers: number;
27
+ symbol_cache: {
28
+ local_entries: number;
29
+ warm_entries: number;
30
+ };
31
+ storage_dir: string | null;
32
+ }
33
+ export declare function formatBytes(bytes: number): string;
34
+ export declare function coerceAftStatus(response: Record<string, unknown>): AftStatusSnapshot;
35
+ export declare function formatStatusDialogMessage(status: AftStatusSnapshot): string;
36
+ export declare function formatStatusMarkdown(status: AftStatusSnapshot): string;
37
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +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,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,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,CAuCpF;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAwC3E;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CA0CtE"}
@@ -0,0 +1,2 @@
1
+ export declare function ensureTuiPluginEntry(): boolean;
2
+ //# sourceMappingURL=tui-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui-config.d.ts","sourceRoot":"","sources":["../../src/shared/tui-config.ts"],"names":[],"mappings":"AAmBA,wBAAgB,oBAAoB,IAAI,OAAO,CAsC9C"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Fetch a URL to a cached temp file. Uses disk cache with 1-day TTL.
3
+ * Returns the cached file path the Rust outline/zoom command can read.
4
+ * Throws on errors (invalid URL, network failure, unsupported content type, oversized body).
5
+ */
6
+ export declare function fetchUrlToTempFile(url: string, storageDir: string): Promise<string>;
7
+ /**
8
+ * Remove cache entries older than TTL. Called periodically at plugin startup.
9
+ */
10
+ export declare function cleanupUrlCache(storageDir: string): void;
11
+ //# sourceMappingURL=url-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-fetch.d.ts","sourceRoot":"","sources":["../../src/shared/url-fetch.ts"],"names":[],"mappings":"AA4EA;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoHzF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAkCxD"}
@@ -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;AA0CjD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAiJ/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;AA0CjD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAuK/E"}
@@ -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,CAkE9E"}
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"}
@@ -0,0 +1,4 @@
1
+ import type { ToolDefinition } from "@opencode-ai/plugin";
2
+ import type { PluginContext } from "../types.js";
3
+ export declare function semanticTools(ctx: PluginContext): Record<string, ToolDefinition>;
4
+ //# sourceMappingURL=semantic.d.ts.map
@@ -0,0 +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"}
package/dist/types.d.ts CHANGED
@@ -9,5 +9,7 @@ export interface PluginContext {
9
9
  pool: BridgePool;
10
10
  client: PluginInput["client"];
11
11
  config: AftConfig;
12
+ /** Absolute path to AFT's storage dir (e.g. ~/.local/share/opencode/storage/plugin/aft) */
13
+ storageDir: string;
12
14
  }
13
15
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,EAAE,SAAS,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,EAAE,SAAS,CAAC;IAClB,2FAA2F;IAC3F,UAAU,EAAE,MAAM,CAAC;CACpB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-opencode",
3
- "version": "0.9.1",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Agent File Tools (AFT) — tree-sitter and lsp powered code analysis",
6
6
  "main": "dist/index.js",
@@ -12,30 +12,50 @@
12
12
  },
13
13
  "files": [
14
14
  "dist",
15
+ "src/tui",
16
+ "src/shared",
15
17
  "README.md"
16
18
  ],
17
19
  "scripts": {
18
- "build": "tsc",
20
+ "build": "bun build src/index.ts --outdir dist --target bun --format esm --external @opencode-ai/plugin && tsc --emitDeclarationOnly",
19
21
  "typecheck": "tsc --noEmit",
20
22
  "pretest": "cd ../.. && cargo build",
21
23
  "test": "bun test",
22
24
  "test:e2e": "bun test src/__tests__/e2e/",
23
- "prepublishOnly": "tsc"
25
+ "prepublishOnly": "bun run build"
24
26
  },
25
27
  "dependencies": {
26
28
  "@opencode-ai/plugin": "^1.2.26",
27
- "jsonc-parser": "^3.3.1",
29
+ "@opencode-ai/sdk": "^1.2.26",
28
30
  "zod": "^4.1.8"
29
31
  },
30
32
  "optionalDependencies": {
31
- "@cortexkit/aft-darwin-arm64": "0.9.1",
32
- "@cortexkit/aft-darwin-x64": "0.9.1",
33
- "@cortexkit/aft-linux-arm64": "0.9.1",
34
- "@cortexkit/aft-linux-x64": "0.9.1",
35
- "@cortexkit/aft-win32-x64": "0.9.1"
33
+ "@cortexkit/aft-darwin-arm64": "0.11.0",
34
+ "@cortexkit/aft-darwin-x64": "0.11.0",
35
+ "@cortexkit/aft-linux-arm64": "0.11.0",
36
+ "@cortexkit/aft-linux-x64": "0.11.0",
37
+ "@cortexkit/aft-win32-x64": "0.11.0"
36
38
  },
37
39
  "devDependencies": {
38
40
  "@types/node": "^22.0.0",
41
+ "comment-json": "^4.6.2",
39
42
  "typescript": "^5.8.0"
43
+ },
44
+ "exports": {
45
+ ".": {
46
+ "types": "./dist/index.d.ts",
47
+ "import": "./dist/index.js"
48
+ },
49
+ "./tui": {
50
+ "types": "./src/tui/index.tsx",
51
+ "import": "./src/tui/index.tsx"
52
+ }
53
+ },
54
+ "oc-plugin": [
55
+ "server",
56
+ "tui"
57
+ ],
58
+ "peerDependencies": {
59
+ "@opencode-ai/plugin": ">=1.2.0"
40
60
  }
41
61
  }
@@ -0,0 +1,46 @@
1
+ import { homedir } from "node:os";
2
+ import { join, resolve } from "node:path";
3
+
4
+ export type OpenCodeBinaryType = "opencode" | "opencode-desktop";
5
+
6
+ export interface OpenCodeConfigDirOptions {
7
+ binary: OpenCodeBinaryType;
8
+ version?: string | null;
9
+ checkExisting?: boolean;
10
+ }
11
+
12
+ export interface OpenCodeConfigPaths {
13
+ configDir: string;
14
+ configJson: string;
15
+ configJsonc: string;
16
+ packageJson: string;
17
+ omoConfig: string;
18
+ }
19
+
20
+ function getCliConfigDir(): string {
21
+ const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
22
+ if (envConfigDir) {
23
+ return resolve(envConfigDir);
24
+ }
25
+
26
+ if (process.platform === "win32") {
27
+ return join(homedir(), ".config", "opencode");
28
+ }
29
+
30
+ return join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "opencode");
31
+ }
32
+
33
+ export function getOpenCodeConfigDir(_options: OpenCodeConfigDirOptions): string {
34
+ return getCliConfigDir();
35
+ }
36
+
37
+ export function getOpenCodeConfigPaths(options: OpenCodeConfigDirOptions): OpenCodeConfigPaths {
38
+ const configDir = getOpenCodeConfigDir(options);
39
+ return {
40
+ configDir,
41
+ configJson: join(configDir, "opencode.json"),
42
+ configJsonc: join(configDir, "opencode.jsonc"),
43
+ packageJson: join(configDir, "package.json"),
44
+ omoConfig: join(configDir, "magic-context.jsonc"),
45
+ };
46
+ }
@@ -0,0 +1,123 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { rpcPortFilePath } from "./rpc-utils.js";
3
+
4
+ const MAX_RETRIES = 10;
5
+ const RETRY_DELAY_MS = 500;
6
+ const REQUEST_TIMEOUT_MS = 5000;
7
+
8
+ export class AftRpcClient {
9
+ private port: number | null = null;
10
+ private portFilePath: string;
11
+ private healthChecked = false;
12
+
13
+ constructor(storageDir: string, directory: string) {
14
+ this.portFilePath = rpcPortFilePath(storageDir, directory);
15
+ }
16
+
17
+ /** Call an RPC method. Retries port resolution if the server isn't ready yet. */
18
+ async call<T = Record<string, unknown>>(
19
+ method: string,
20
+ params: Record<string, unknown> = {},
21
+ ): Promise<T> {
22
+ const port = await this.resolvePort();
23
+ if (!port) {
24
+ throw new Error("AFT RPC server not available");
25
+ }
26
+
27
+ const response = await this.fetchWithTimeout(`http://127.0.0.1:${port}/rpc/${method}`, {
28
+ method: "POST",
29
+ headers: { "Content-Type": "application/json" },
30
+ body: JSON.stringify(params),
31
+ });
32
+
33
+ if (!response.ok) {
34
+ const text = await response.text();
35
+ throw new Error(`RPC ${method} failed (${response.status}): ${text}`);
36
+ }
37
+
38
+ return (await response.json()) as T;
39
+ }
40
+
41
+ /** Check if the RPC server is reachable. */
42
+ async isAvailable(): Promise<boolean> {
43
+ try {
44
+ const port = await this.resolvePort();
45
+ return port !== null;
46
+ } catch {
47
+ return false;
48
+ }
49
+ }
50
+
51
+ private async resolvePort(): Promise<number | null> {
52
+ if (this.port && this.healthChecked) {
53
+ return this.port;
54
+ }
55
+
56
+ if (this.port) {
57
+ const alive = await this.healthCheck(this.port);
58
+ if (alive) {
59
+ this.healthChecked = true;
60
+ return this.port;
61
+ }
62
+ this.port = null;
63
+ this.healthChecked = false;
64
+ }
65
+
66
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
67
+ const port = this.readPortFile();
68
+ if (port) {
69
+ const alive = await this.healthCheck(port);
70
+ if (alive) {
71
+ this.port = port;
72
+ this.healthChecked = true;
73
+ return port;
74
+ }
75
+ }
76
+
77
+ if (attempt < MAX_RETRIES - 1) {
78
+ await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));
79
+ }
80
+ }
81
+
82
+ return null;
83
+ }
84
+
85
+ private readPortFile(): number | null {
86
+ try {
87
+ const content = readFileSync(this.portFilePath, "utf-8").trim();
88
+ const port = Number.parseInt(content, 10);
89
+ if (Number.isNaN(port) || port <= 0 || port > 65535) {
90
+ return null;
91
+ }
92
+ return port;
93
+ } catch {
94
+ return null;
95
+ }
96
+ }
97
+
98
+ private async healthCheck(port: number): Promise<boolean> {
99
+ try {
100
+ const response = await this.fetchWithTimeout(`http://127.0.0.1:${port}/health`, {
101
+ method: "GET",
102
+ });
103
+ return response.ok;
104
+ } catch {
105
+ return false;
106
+ }
107
+ }
108
+
109
+ private async fetchWithTimeout(url: string, options: RequestInit): Promise<Response> {
110
+ const controller = new AbortController();
111
+ const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
112
+ try {
113
+ return await fetch(url, { ...options, signal: controller.signal });
114
+ } finally {
115
+ clearTimeout(timeout);
116
+ }
117
+ }
118
+
119
+ reset(): void {
120
+ this.port = null;
121
+ this.healthChecked = false;
122
+ }
123
+ }