Opowieść o tym, jak desperacka potrzeba, kilka mrożących krew w żyłach godzin i chęć niepodawania się doprowadziły do przełomu w integracji AI z IDE
Czy kiedykolwiek miałeś moment, gdy potrzebujesz czegoś tak bardzo, że gotów jesteś to stworzyć od zera? Ja właśnie przeżyłem taki moment. Historia, którą wam opowiem, to nie tylko techniczne studium przypadku, ale przede wszystkim opowieść o tym, że czasem najbardziej frustrujące problemy prowadzą do najciekawszych rozwiązań.
Geneza problemu, czyli dlaczego w ogóle zacząłem
Wyobraźcie sobie sytuację: masz świetnie działający Claude VSCode Controller na Windows, który pozwala AI sterować twoim IDE przez naturalne komendy. Wszystko działa jak marzenie - “otwórz plik”, “stwórz komponent”, “uruchom testy” - i nagle przenosisz się na Linux Ubuntu 24. Oczekujesz, że wszystko będzie działać tak samo… i tu zaczyna się koszmar programisty.
❌ Extension Host (LocalProcess pid: 16296) is unresponsive
❌ Failed to load resource: the server responded with a status of 404 ()
❌ UNRESPONSIVE extension host: starting to profile NOW
Pierwsze uruchomienie na Linux skończyło się spektakularnym crashem Extension Host. Claude Desktop widział MCP server, ale most do VSCode nie chciał się uruchomić. Po trzech godzinach debugowania myślałem sobie: “No dobra, może to jakiś błąd w tej konkretnej wersji VSCode”. Spoiler: nie był.
Pierwsza linia obrony - standardowe podejście
Zacznijmy od początku. Claude VSCode Controller to projekt, który łączy Claude Desktop z VSCode przez:
- MCP Server (Model Context Protocol) - komunikujący się z Claude Desktop
- Rozszerzenie VSCode - most używający WebSocket na porcie 3333
- Komunikację WebSocket - połączenie w czasie rzeczywistym między MCP a VSCode
Na Windows wszystko działało bez zarzutu. Ale Linux… Linux miał swoje zdanie na ten temat.
Anatomia problemu
Pierwszym sygnałem ostrzegawczym były logi Extension Host:
// To działało na Windows:
import { WebSocketServer, WebSocket } from 'ws';
// Ale na Linux Extension Host krzyczał:
// Cannot find module 'ws'
// Extension activation failed
“No dobra”, pomyślałem, “klasyczny problem z zależnościami”. Sprawdziłem node_modules, reinstalowałem wszystko, czyściłem cache. Nic. Extension Host nadal się wywalał przy próbie załadowania modułu WebSocket.
Głębiej w króliczą norę - śledztwo
Po kilku godzinach frustracji zacząłem kopać głębiej. Okazało się, że Extension Host na Linux ma… powiedzmy sobie delikatnie… “specyficzne” podejście do ładowania zewnętrznych modułów. Szczególnie tych, które używają natywnych powiązań, jak WebSocket.
Eureka #1: ES6 vs CommonJS
Pierwszym przełomem było odkrycie, że Linux Extension Host ma problemy z importami ES6 przy zewnętrznych zależnościach:
// ❌ Crashuje Extension Host na Linux:
import { WebSocketServer } from 'ws';
let wss: WebSocketServer | null = null;
wss.on('connection', (ws) => { ... }); // BOOM!
// ✅ Działa stabilnie:
const { WebSocketServer } = require('ws');
Ale to była dopiero pierwsza część układanki. TypeScript nie był zadowolony z takiego podejścia…
Eureka #2: TypeScript strict null checks
// ❌ Błąd TypeScript:
let wss: WebSocketServer | null = null;
wss.on('connection', (ws) => { ... }); // Error: wss is possibly null
// ✅ Eleganckie rozwiązanie:
const wsServer = new WebSocketServer({ port: 3333 });
wss = wsServer; // Przechowujemy referencję do sprzątania
wsServer.on('connection', (ws: WS) => { ... });
Eureka #3: Podejście hybrydowe
Finalnym rozwiązaniem okazało się połączenie importów typów TypeScript z require na etapie działania:
// Import typów dla TypeScript (tylko na etapie kompilacji)
import type { WebSocketServer as WSServer, WebSocket as WS } from 'ws';
// Użycie require w runtime (zgodne z Linux)
const { WebSocketServer, WebSocket } = require('ws');
let wss: WSServer | null = null;
Budowanie rozwiązania - od chaosu do porządku
Gdy już zrozumiałem naturę problemu, czas było na systematyczne rozwiązanie. Stworzyłem fix-extension-linux.sh - skrypt, który automatyzuje cały proces naprawy:
Krok 1: Konfiguracja TypeScript
// tsconfig.json - przełączenie na CommonJS
{
"compilerOptions": {
"module": "commonjs", // Zmienione z "es2020"
"strict": false // Poluzowane dla zewnętrznych modułów
// ...
}
}
Krok 2: Bundlowanie zależności
Zamiast polegać na rozwiązywaniu zależności przez marketplace VSCode, bundlujemy zależności bezpośrednio w katalogu rozszerzenia:
# Bundluj ws bezpośrednio w katalogu rozszerzenia
mkdir -p ~/.vscode/extensions/claude-mcp-controller/node_modules
cp -r node_modules/ws ~/.vscode/extensions/claude-mcp-controller/node_modules/
Krok 3: Automatyczne testowanie
#!/bin/bash
# test-extension-comprehensive.sh
echo "🧪 Testowanie rozszerzenia VSCode (tryb bezpieczny Linux)..."
# Test 1: Czy pliki rozszerzenia istnieją
if [ -f "$HOME/.vscode/extensions/claude-mcp-controller/out/extension.js" ]; then
echo "✅ Pliki rozszerzenia istnieją"
else
echo "❌ Brak plików rozszerzenia"
exit 1
fi
# Test 2: Czy moduł WebSocket jest obecny
if [ -d "$HOME/.vscode/extensions/claude-mcp-controller/node_modules/ws" ]; then
echo "✅ Moduł WebSocket znaleziony"
else
echo "❌ Brak modułu WebSocket"
fi
# Test 3: Czy używany jest require
if grep -q "require.*ws" "$HOME/.vscode/extensions/claude-mcp-controller/out/extension.js"; then
echo "✅ Używa require('ws') - zgodne z Linux"
else
echo "❌ Rozszerzenie może mieć problemy ze zgodnością"
fi
Moment prawdy - testowanie rozwiązania
Po wdrożeniu wszystkich poprawek, czas na moment prawdy. Restart VSCode, aktywacja rozszerzenia… i…
✅ 🤖 Claude MCP: Online
✅ Extension Host: claude-mcp-controller uruchomiony poprawnie
✅ WebSocket server nasłuchuje na porcie 3333
✅ Połączenie mostka nawiązane
DZIAŁA! 🎉
Pierwszy test - “Pokaż informacje o workspace” w Claude Desktop:
{
"hasWorkspace": true,
"folders": [
{
"name": "claude-vscode-controller",
"path": "/home/dk/claude-vscode-controller"
}
],
"activeEditor": {
"fileName": "/home/dk/claude-vscode-controller/package.json",
"language": "json",
"lineCount": 67
}
}
Claude Desktop miał pełną kontrolę nad VSCode na Linux!
Lekcje wyciągnięte z okopów
Techniczne wnioski
- Extension Host na Linux jest bardziej restrykcyjny niż na Windows/macOS w kwestii zewnętrznych modułów
- Hybrydowa strategia importu (typy TypeScript + require w runtime) to eleganckie rozwiązanie dla zgodności między systemami
- Bundlowanie zależności w katalogu rozszerzenia eliminuje problemy z rozwiązywaniem przez marketplace
- Kompilacja do CommonJS jest stabilniejsza niż ES6 modules dla rozszerzeń VSCode na Linux
Wnioski miękkie
- Wytrwałość popłaca - problem wydawał się nierozwiązywalny przez pierwsze kilka godzin
- Systematyczne debugowanie - krok po kroku, log po logu, aż do źródła problemu
- Nie poddawaj się - jak coś nie działa, można to naprawić lub stworzyć od nowa
- Dokumentacja ma znaczenie - każde rozwiązanie warto udokumentować dla innych
Techniczne szczegóły - dla dociekliwych
Schemat architektury
┌─────────────────┐ WebSocket ┌──────────────────┐
│ Claude │◄────────────────►│ VSCode │
│ Desktop │ Port 3333 │ Extension │
│ │ │ (Bridge) │
└─────────────────┘ └──────────────────┘
▲ ▲
│ MCP Protocol │ VSCode API
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ Enhanced │ │ VSCode │
│ MCP Server │ │ Editor │
└─────────────────┘ └──────────────────┘
Kluczowe komponenty techniczne
1. MCP Server (enhanced-mcp-server.js)
// Tłumaczy komendy Claude na wywołania mostka VSCode
case "vscode_create_file":
return await this.sendVSCodeCommand('createFile', {
filePath: args.filePath,
content: args.content
});
2. Mostek rozszerzenia VSCode
// Obsługuje komunikację WebSocket i wywołania API VSCode
async function handleCommand(command: any, ws: WS) {
switch (command.method) {
case 'createFile':
result = await createFile(command.params.filePath, command.params.content);
break;
case 'getWorkspaceInfo':
result = getWorkspaceInfo();
break;
// ... 30+ innych komend
}
ws.send(
JSON.stringify({
id: command.id,
result: result,
}),
);
}
3. Warstwa zgodności z Linux
// Hybrydowe ładowanie modułów dla zgodności z Linux
import type { WebSocketServer as WSServer, WebSocket as WS } from 'ws';
const { WebSocketServer, WebSocket } = require('ws');
function startMCPBridge() {
const wsServer = new WebSocketServer({ port: 3333 });
wss = wsServer; // Przechowujemy referencję do sprzątania
wsServer.on('connection', (ws: WS) => {
// Obsługa połączenia Claude Desktop
});
}
Co dalej - rozwój projektu
Teraz, gdy wsparcie dla Linux jest rzeczywistością, czas na dalszy rozwój:
Najbliższe plany
- Optymalizacje wydajności dla Extension Host na Linux
- Testy na innych dystrybucjach (Fedora, Arch, openSUSE)
- Zaawansowane narzędzia debugowania dla łatwiejszego rozwiązywania problemów
Dalsza wizja
- Obsługa wielu workspace’ów - wsparcie dla kilku instancji VSCode
- System pluginów - możliwość rozszerzania komend
- Praca zdalna - wsparcie dla VSCode w trybie zdalnym
Wnioski - więcej niż tylko techniczne rozwiązanie
Ta historia to więcej niż opis rozwiązania problemu technicznego. To przypomnienie o kilku fundamentalnych prawdach w świecie programowania:
1. “Nie ma” nie znaczy “nie można”
Gdy Claude VSCode Controller nie działał na Linux, mogłem się poddać i zostać przy Windows. Zamiast tego pomyślałem: “A co jeśli da się to naprawić?”. Często najbardziej wartościowe rzeczy powstają z frustracji i potrzeby.
2. Społeczność ma znaczenie
Problem z Extension Host na Linux dotyka wielu programistów. Stworzenie rozwiązania i podzielenie się nim z innymi to korzyść dla wszystkich. Pomagamy innym, a przy okazji budujemy swoją reputację.
3. Dokumentuj wszystko
Każde rozwiązanie, które powstało w trudnych godzinach debugowania, warto opisać. Przyszłe ja (i inni programiści) będą wdzięczni.
4. Oswój chaos
Niektóre z najlepszych rozwiązań rodzą się z pozornie beznadziejnych sytuacji. Problemy z Extension Host wydawały się końcem świata, a stały się początkiem fascynującej drogi w programowaniu wieloplatformowym.
Epilog - od zera do bohatera
Dziś, po tych chaotycznych godzinach debugowania, Claude VSCode Controller na Linux nie tylko działa, ale też służy społeczności programistów korzystających z tego systemu. Projekt ma profesjonalną dokumentację, automatyczne narzędzia instalacyjne i rozbudowany system testów.
Co więcej, wnioski techniczne z tego projektu pomagają innym w podobnych wyzwaniach.
Ale najważniejsza lekcja jest taka: gdy potrzebujesz czegoś, czego nie ma - stwórz to. Świat programowania jest pełen możliwości dla tych, którzy są gotowi szukać głębiej, debugować dłużej i nie poddawać się, gdy pojawiają się trudności.
Często najlepsze rozwiązania rodzą się z największego chaosu. Problemy z Extension Host były koszmarem, ale stały się fundamentem czegoś znacznie większego, niż początkowo planowałem.
PS: Jeśli kiedykolwiek będziesz miał problem z Extension Host w VSCode na Linux, pamiętaj - zawsze jest jakieś wyjście. Czasem wystarczy kreatywność z TypeScriptem, modułami i importami WebSocket. Powodzenia w debugowaniu! 🐧🚀
Linki i zasoby
- Repozytorium GitHub: claude-vscode-controller
- Gałąź Linux: Wersja zoptymalizowana pod Linux
- Instrukcja instalacji: Kompletny setup na Linux
- Opis sukcesu technicznego: Dokumentacja sukcesu