Skip to content

Commit d1a4701

Browse files
amirbiluclaude
andcommitted
Add node server architecture with ports management and webview
Introduces a Node.js server layer for improved chat functionality: - Add node_server.lua to manage Node runtime and server lifecycle - Add ports.lua for dynamic port allocation to avoid conflicts - Reorganize chat binary from chat/ to webview/ directory - Add plugin/tabnine.lua for early port initialization - Include bundled node installers and server dependencies - Remove unused example files and lift imports to module top Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 6d209e5 commit d1a4701

65 files changed

Lines changed: 517476 additions & 1310 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ Tabnine client for Neovim
1212
- [Windows](#windows)
1313
- [Activate (mandatory)](#activate-mandatory)
1414
- [Activate Tabnine Pro](#activate-tabnine-pro)
15-
- [Tabnine Chat](#tabnine-chat)
15+
- [Tabnine Agent](#tabnine-agent)
1616
- [Commands](#commands)
17-
- [Tabnine Chat commands](#tabnine-chat-commands)
17+
- [Tabnine Agent commands](#tabnine-agent-commands)
1818
- [`<Tab>` and `nvim-cmp`](#tab-and-nvim-cmp)
1919
- [lualine integration](#lualine-integration)
2020
- [Other statusline integrations](#other-statusline-integrations)
@@ -168,16 +168,44 @@ end, { expr = true })
168168

169169
Sometimes Tabnine may fail to open the browser on Tabnine Hub, in this case use `:TabnineHubUrl` to get Tabnine Hub URL
170170

171-
## Tabnine Chat
171+
## Tabnine Agent
172172
![Tabnine Neovim chat](https://github.com/codota/tabnine-nvim/blob/master/examples/lua-chat.gif)
173-
Tabnine chat needs a webview to run, to use it:
174-
- You will need to build the chat from source, by executing: `cargo build --release` inside `chat/` directory.
175-
- You may be missing some dependencies to build the chat. To fix this, run the following command:
173+
174+
Tabnine Agent requires a webview component and a Node.js server to run.
175+
176+
### Building the Webview
177+
178+
1. Install the required dependencies:
179+
```shell
180+
# Debian/Ubuntu
181+
sudo apt-get install -y libgtk-3-dev libglib2.0-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev libwebkit2gtk-4.1-dev
182+
183+
# Arch
184+
pacman -S --needed gtk3 glib2 webkit2gtk-4.1 libsoup3
185+
186+
# macOS (dependencies included with system)
187+
```
188+
189+
2. Build the webview binary (requires Rust stable):
176190
```shell
177-
$ # Debian/Ubuntu
178-
$ sudo apt-get install -y libgtk-3-dev libglib2.0-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev libwebkit2gtk-4.1-dev
179-
$ # Arch
180-
$ pacman -S --needed gtk3 glib2 webkit2gtk-4.1 libsoup3
191+
cd webview/
192+
cargo build --release
193+
# Or if using nightly by default:
194+
rustup run stable cargo build --release
195+
```
196+
197+
This creates the `tabnine_webview` binary in `webview/target/release/`.
198+
199+
### Project Structure
200+
201+
```
202+
tabnine-nvim/
203+
├── node/
204+
│ ├── installer/ # Node.js runtime installer (per-platform binaries)
205+
│ └── server/ # Node.js proxy server for chat communication
206+
├── webview/ # Rust webview binary source (wry-based)
207+
├── binaries/ # TabNine completion engine (downloaded)
208+
└── lua/tabnine/ # Neovim plugin Lua code
181209
```
182210

183211
## Commands
@@ -186,19 +214,24 @@ $ pacman -S --needed gtk3 glib2 webkit2gtk-4.1 libsoup3
186214
- `:TabnineDisable` - to disable Tabnine
187215
- `:TabnineEnable` - to enable Tabnine
188216
- `:TabnineToggle` - to toggle enable/disable
189-
- `:TabnineChat` - to launch Tabnine chat
217+
- `:TabnineAgent` - to launch Tabnine Agent
190218
- `:TabnineLoginWithAuthToken` - to log in using auth token (for headless environments, where no browser is available)
191219
- `:TabnineAccept` - accept apply changes
192220
- `:TabnineReject` - reject apply changes
193221

194-
### Tabnine Chat commands
195-
- `:TabnineChat` - to open Tabnine Chat
222+
### Tabnine Agent commands
223+
- `:TabnineAgent` - to open Tabnine Agent
224+
- `:TabnineAgentClose` - to close Tabnine Agent
225+
- `:TabnineAgentClear` - to clear the current conversation
226+
- `:TabnineAgentNew` - to start a new conversation
196227
- `:TabnineFix` - to fix the function in scope
197228
- `:TabnineTest` - to generate tests for function in scope
198229
- `:TabnineExplain` - to explain the function in scope
199230
- `:TabnineAccept` - accept apply changes
200231
- `:TabnineReject` - reject apply changes
201232

233+
> **Note:** The old `TabnineChat*` commands are deprecated and will show a warning. Please use the new `TabnineAgent*` commands instead.
234+
202235
## `<Tab>` and `nvim-cmp`
203236

204237
`nvim-cmp` maps `<Tab>` to navigating through pop menu items (see [here](https://github.com/hrsh7th/nvim-cmp/blob/777450fd0ae289463a14481673e26246b5e38bf2/lua/cmp/config/mapping.lua#L86)) This conflicts with Tabnine `<Tab>` for inline completion. To get this sorted you can either:

chat/index.html

Lines changed: 0 additions & 466 deletions
This file was deleted.

dl_binaries.ps1

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
# This script downloads the binaries for the most recent version of TabNine.
44

55
$TABNINE_UPDATE_SERVICE="https://update.tabnine.com"
6+
$NODE_VERSION="v24.12.0"
7+
68
if ($args.count -gt 0) {
79
$TABNINE_UPDATE_SERVICE=$args[0]
810
}
@@ -14,15 +16,24 @@ else {
1416
$version = invoke-webrequest -uri "$TABNINE_UPDATE_SERVICE/bundles/version" -usebasicparsing
1517
}
1618

19+
# Get script directory
20+
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
21+
1722
if ([Environment]::Is64BitOperatingSystem) {
1823
$targets = @(
1924
'x86_64-pc-windows-gnu'
2025
)
26+
if ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -eq "Arm64") {
27+
$node_installer_platform = "windows-arm64"
28+
} else {
29+
$node_installer_platform = "windows-x64"
30+
}
2131
}
2232
else {
2333
$targets = @(
2434
'i686-pc-windows-gnu'
2535
)
36+
$node_installer_platform = "windows-x64"
2637
}
2738

2839
if (test-path -path "binaries/$version") {
@@ -36,12 +47,30 @@ $targets | foreach-object {
3647

3748
if (!(test-path -path "binaries/$version/$target")) { New-Item -Path "binaries/$version/$target" -ItemType Directory -force | out-null }
3849

39-
Write-Output "downloading $path"
50+
Write-Output "downloading $path"
4051
invoke-webrequest -uri "$TABNINE_UPDATE_SERVICE/bundles/$path/TabNine.zip" -outfile "binaries/$path/TabNine.zip"
4152
# Stop this iteration if the download failed
4253
if (!(Test-Path "binaries/$path/TabNine.zip" -PathType Leaf)) {return}
4354

44-
expand-archive "binaries/$path/TabNine.zip" "binaries/$path"
55+
expand-archive "binaries/$path/TabNine.zip" "binaries/$path"
4556

4657
remove-item -path "binaries/$path/TabNine.zip"
4758
}
59+
60+
# Download Node.js runtime using node-installer
61+
$NODE_INSTALLER = Join-Path $ScriptDir "node/installer/$node_installer_platform/tabnine-node-installer.exe"
62+
if (Test-Path $NODE_INSTALLER -PathType Leaf) {
63+
Write-Output "Downloading Node.js runtime using node-installer..."
64+
try {
65+
$NODE_RUNTIME_DIR = & $NODE_INSTALLER $TABNINE_UPDATE_SERVICE $NODE_VERSION 2>$null
66+
if ($NODE_RUNTIME_DIR) {
67+
Write-Output "Node.js runtime installed at: $NODE_RUNTIME_DIR"
68+
}
69+
}
70+
catch {
71+
Write-Warning "Failed to download Node.js runtime. Some features may not work."
72+
}
73+
}
74+
else {
75+
Write-Warning "node-installer not found at $NODE_INSTALLER"
76+
}

dl_binaries.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
set -e
33

44
TABNINE_UPDATE_SERVICE=${1:-"https://update.tabnine.com"}
5+
NODE_VERSION="v24.12.0"
56
DEPENDS='unzip curl' # list of dependencies (commands)
67
HAS_ALL_DEPS=1 # 1 = present, 0 = missing
78
for dep in ${DEPENDS}; do
@@ -14,22 +15,29 @@ if [ "${HAS_ALL_DEPS}" -eq 0 ]; then # missing something.
1415
exit 1
1516
fi
1617

18+
# Get script directory
19+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
20+
1721
# This script downloads the binaries for the most recent version of TabNine.
1822
# Infrastructure detection heavily inspired by https://github.com/tzachar/cmp-tabnine/blob/main/install.sh
1923
version=${version:-$(curl -fsSL "$TABNINE_UPDATE_SERVICE/bundles/version")}
2024
case $(uname -s) in
2125
"Darwin")
2226
if [ "$(uname -m)" = "arm64" ]; then
2327
targets="aarch64-apple-darwin"
28+
node_installer_platform="macos-arm64"
2429
elif [ "$(uname -m)" = "x86_64" ]; then
2530
targets="x86_64-apple-darwin"
31+
node_installer_platform="macos-x64"
2632
fi
2733
;;
2834
"Linux")
2935
if [ "$(uname -m)" = "x86_64" ]; then
3036
targets="x86_64-unknown-linux-musl"
37+
node_installer_platform="linux-x64"
3138
elif [ "$(uname -m)" = "aarch64" ]; then
3239
targets="aarch64-unknown-linux-musl"
40+
node_installer_platform="linux-arm64"
3341
fi
3442
;;
3543
esac
@@ -54,3 +62,20 @@ echo "$targets" | while read -r target; do
5462
rm "binaries/$path/TabNine.zip"
5563
chmod +x "binaries/$path/"*
5664
done
65+
66+
# Download Node.js runtime using node-installer
67+
if [ -n "$node_installer_platform" ]; then
68+
NODE_INSTALLER="$SCRIPT_DIR/node/installer/$node_installer_platform/tabnine-node-installer"
69+
if [ -f "$NODE_INSTALLER" ]; then
70+
echo "Downloading Node.js runtime using node-installer..."
71+
chmod +x "$NODE_INSTALLER"
72+
NODE_RUNTIME_DIR=$("$NODE_INSTALLER" "$TABNINE_UPDATE_SERVICE" "$NODE_VERSION" 2>/dev/null) || {
73+
echo "Warning: Failed to download Node.js runtime. Some features may not work."
74+
}
75+
if [ -n "$NODE_RUNTIME_DIR" ]; then
76+
echo "Node.js runtime installed at: $NODE_RUNTIME_DIR"
77+
fi
78+
else
79+
echo "Warning: node-installer not found at $NODE_INSTALLER"
80+
fi
81+
fi

examples/javascript.gif

-6 MB
Binary file not shown.

examples/javascript.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

examples/lua-chat.gif

-1.88 MB
Binary file not shown.

examples/python-chat.gif

-5 MB
Binary file not shown.

examples/python.py

Lines changed: 0 additions & 6 deletions
This file was deleted.

lua/tabnine.lua

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ local chat_setup = require("tabnine.chat.setup")
33
local config = require("tabnine.config")
44
local consts = require("tabnine.consts")
55
local keymaps = require("tabnine.keymaps")
6+
local node_server = require("tabnine.node_server")
7+
local ports = require("tabnine.ports")
68
local semver = require("tabnine.third_party.semver.semver")
79
local status = require("tabnine.status")
10+
local tabnine_binary = require("tabnine.binary")
811
local user_commands = require("tabnine.user_commands")
912
local workspace = require("tabnine.workspace")
1013

@@ -13,6 +16,20 @@ local M = {}
1316
function M.setup(o)
1417
config.set_config(o)
1518

19+
-- 1. Initialize ports (allocates node_server_port and rust_server_port)
20+
ports.init()
21+
22+
-- 2. Start TabNine binary (receives NODE_SERVER_PORT and RUST_SERVER_PORT env vars)
23+
tabnine_binary:start()
24+
25+
-- 3. Trigger Rust HTTP server to start by sending ChatCommunicatorAddress request
26+
tabnine_binary:request({
27+
ChatCommunicatorAddress = { kind = "Forward" },
28+
}, function()
29+
-- 4. Start node server after Rust HTTP server is ready
30+
node_server:ensure_running()
31+
end)
32+
1633
local v = vim.version()
1734
local cur_version = semver(v.major, v.minor, v.patch)
1835
local min_version = semver(consts.min_nvim_version)

0 commit comments

Comments
 (0)