diff --git a/clients/example-vscode-lsp/.gitattributes b/clients/example-vscode-lsp/.gitattributes new file mode 100644 index 000000000..c091529f3 --- /dev/null +++ b/clients/example-vscode-lsp/.gitattributes @@ -0,0 +1 @@ +*.png filter=lfs diff=lfs merge=lfs -text \ No newline at end of file diff --git a/clients/example-vscode-lsp/.gitignore b/clients/example-vscode-lsp/.gitignore new file mode 100644 index 000000000..d2703e4fe --- /dev/null +++ b/clients/example-vscode-lsp/.gitignore @@ -0,0 +1,3 @@ +node_modules +dist +*.vsix diff --git a/clients/example-vscode-lsp/README.md b/clients/example-vscode-lsp/README.md new file mode 100644 index 000000000..4573d6e41 --- /dev/null +++ b/clients/example-vscode-lsp/README.md @@ -0,0 +1,9 @@ +# Example VSCode client for Tabby agent (LSP) + +This is an example of a VSCode extension for the Tabby agent. It runs the Tabby agent as a language server and creates a client connecting to it. + +![Demo](./demo.png) + +For more information about Tabby agent, please refer to [Tabby agent](https://github.com/TabbyML/tabby/tree/main/clients/tabby-agent). + +For more information about developing a VSCode LSP extension, please refer to [VSCode Language Extensions Guide](https://code.visualstudio.com/api/language-extensions/overview). diff --git a/clients/example-vscode-lsp/demo.png b/clients/example-vscode-lsp/demo.png new file mode 100644 index 000000000..2bec01380 --- /dev/null +++ b/clients/example-vscode-lsp/demo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:542a3e013ee260fc455eeae21c374f98fa2471186f737c6b535f147eb10ffe6f +size 66601 diff --git a/clients/example-vscode-lsp/package.json b/clients/example-vscode-lsp/package.json new file mode 100644 index 000000000..0993d6169 --- /dev/null +++ b/clients/example-vscode-lsp/package.json @@ -0,0 +1,25 @@ +{ + "name": "example-vscode-tabby-lsp-client", + "description": "Example VSCode client for Tabby agent (LSP).", + "publisher": "TabbyML", + "version": "0.0.1", + "engines": { + "vscode": "^1.82.0" + }, + "main": "./dist/extension.js", + "activationEvents": [ + "onLanguage" + ], + "scripts": { + "build": "tsup --minify", + "watch": "tsup --watch ./ --ignore-watch ./dist" + }, + "devDependencies": { + "@types/vscode": "^1.82.0", + "esbuild-plugin-copy": "^2.1.1", + "tabby-agent": "1.2.0" + }, + "dependencies": { + "vscode-languageclient": "^9.0.1" + } +} diff --git a/clients/example-vscode-lsp/src/extension.ts b/clients/example-vscode-lsp/src/extension.ts new file mode 100644 index 000000000..675cbee3e --- /dev/null +++ b/clients/example-vscode-lsp/src/extension.ts @@ -0,0 +1,37 @@ +import { ExtensionContext } from "vscode"; +import { LanguageClient, ServerOptions, TransportKind } from "vscode-languageclient/node"; + +let client: LanguageClient; + +export async function activate(context: ExtensionContext): Promise { + console.debug("Tabby LSP Example: activate"); + + const serverModulePath = context.asAbsolutePath("dist/server/tabby-agent.js"); + const serverOptions: ServerOptions = { + run: { + module: serverModulePath, + args: ["--lsp"], + transport: TransportKind.ipc, + }, + debug: { + module: serverModulePath, + args: ["--lsp"], + transport: TransportKind.ipc, + }, + }; + const clientOptions = { + documentSelector: [{ pattern: "**/*" }], + }; + if (!client) { + client = new LanguageClient("Tabby LSP Example", serverOptions, clientOptions); + } + return await client.start(); +} + +export async function deactivate(): Promise { + console.debug("Tabby LSP Example: deactivate"); + + if (client) { + return await client.stop(); + } +} diff --git a/clients/example-vscode-lsp/tsconfig.json b/clients/example-vscode-lsp/tsconfig.json new file mode 100644 index 000000000..954a4cc3f --- /dev/null +++ b/clients/example-vscode-lsp/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "ES2020", + "lib": ["ES2020"], + "sourceMap": true, + "strict": true + }, + "include": ["./src"] +} diff --git a/clients/example-vscode-lsp/tsup.config.ts b/clients/example-vscode-lsp/tsup.config.ts new file mode 100644 index 000000000..1efa0a2b4 --- /dev/null +++ b/clients/example-vscode-lsp/tsup.config.ts @@ -0,0 +1,30 @@ +import { defineConfig } from "tsup"; +import { copy } from "esbuild-plugin-copy"; +import { dependencies } from "./package.json"; + +export default () => [ + defineConfig({ + name: "node", + entry: ["src/extension.ts"], + outDir: "dist", + platform: "node", + target: "node18", + external: ["vscode"], + noExternal: Object.keys(dependencies), + clean: true, + esbuildPlugins: [ + copy({ + assets: [ + { + from: "../tabby-agent/dist/cli.js", + to: "./server/tabby-agent.js", + }, + { + from: "../tabby-agent/dist/wasm/*", + to: "./server/wasm", + }, + ], + }), + ], + }), +]; diff --git a/package.json b/package.json index 713d46074..b7e93fc5c 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "clients/tabby-agent", "clients/vscode", "clients/vim", - "clients/intellij" + "clients/intellij", + "clients/example-vscode-lsp" ], "engines": { "node": ">=18" diff --git a/yarn.lock b/yarn.lock index 0406f8fbd..0fe9230f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2843,6 +2843,13 @@ minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatc dependencies: brace-expansion "^1.1.7" +minimatch@^5.1.0: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + minimatch@^9.0.1: version "9.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" @@ -3638,7 +3645,7 @@ semver@^6.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.4, semver@^7.3.5, semver@^7.5.2, semver@^7.5.4: +semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.5.2, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -4214,6 +4221,15 @@ vscode-jsonrpc@8.2.0: resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz#f43dfa35fb51e763d17cd94dcca0c9458f35abf9" integrity sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA== +vscode-languageclient@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz#cdfe20267726c8d4db839dc1e9d1816e1296e854" + integrity sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA== + dependencies: + minimatch "^5.1.0" + semver "^7.3.7" + vscode-languageserver-protocol "3.17.5" + vscode-languageserver-protocol@3.17.5: version "3.17.5" resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz#864a8b8f390835572f4e13bd9f8313d0e3ac4bea"