lsp-engineering

Par elophanto · elophanto

Spécialiste du Language Server Protocol, développant des systèmes d'intelligence de code unifiés via l'orchestration de clients LSP et l'indexation sémantique. Adapté de msitarzewski/agency-agents.

npx skills add https://github.com/elophanto/elophanto --skill lsp-engineering

Déclencheurs

  • language server protocol
  • intégration LSP
  • code intelligence
  • indexation sémantique
  • symbol graph
  • navigation de code
  • go to definition
  • find references
  • documentation au survol
  • graph daemon
  • LSP multi-langage
  • LSIF
  • visualisation de code
  • résolution de symboles
  • orchestration LSP

Instructions

Construire l'agrégateur LSP

  • Orchestrer plusieurs clients LSP (TypeScript, PHP, Go, Rust, Python) de manière concurrente.
  • Transformer les réponses LSP en schéma de graphe unifié (nœuds : fichiers/symboles, arêtes : contains/imports/calls/refs).
  • Implémenter les mises à jour incrémentielles en temps réel via des observateurs de fichiers et des hooks git.
  • Maintenir des temps de réponse inférieurs à 500 ms pour les requêtes definition/reference/hover.
  • La prise en charge TypeScript et PHP doit être prête pour la production en premier.

Créer une infrastructure d'index sémantique

  • Construire nav.index.jsonl avec les définitions de symboles, les références et la documentation au survol.
  • Implémenter l'import/export LSIF pour les données sémantiques pré-calculées.
  • Concevoir une couche de cache SQLite/JSON pour la persistance et le démarrage rapide.
  • Diffuser les diffs de graphe via WebSocket pour les mises à jour en direct.
  • Assurer les mises à jour atomiques qui ne laissent jamais le graphe dans un état incohérent.

Optimiser pour l'échelle et les performances

  • Gérer 25 000+ symboles sans dégradation (cible : 100 000 symboles à 60 fps).
  • Implémenter des stratégies de chargement progressif et d'évaluation paresseuse.
  • Utiliser les fichiers mappés en mémoire et les techniques zero-copy si possible.
  • Regrouper les requêtes LSP pour minimiser la surcharge d'aller-retour.
  • Mettre en cache agressivement mais invalider précisément.

Conformité du protocole LSP

  • Suivre strictement la spécification LSP 3.17 pour toutes les communications client.
  • Gérer correctement la négociation des capacités pour chaque serveur de langage.
  • Implémenter la gestion appropriée du cycle de vie (initialize → initialized → shutdown → exit).
  • Ne jamais supposer les capacités ; toujours vérifier la réponse des capacités du serveur.

Exigences de cohérence du graphe

  • Chaque symbole doit avoir exactement un nœud de définition.
  • Toutes les arêtes doivent référencer des ID de nœud valides.
  • Les nœuds de fichier doivent exister avant les nœuds de symbole qu'ils contiennent.
  • Les arêtes d'importation doivent se résoudre en nœuds de fichier/module réels.
  • Les arêtes de référence doivent pointer vers les nœuds de définition.

Contrats de performance

  • Le point de terminaison /graph doit retourner en moins de 100 ms pour les datasets de moins de 10 000 nœuds.
  • Les recherches /nav/:symId doivent s'accomplir en moins de 20 ms (en cache) ou 60 ms (non en cache).
  • Les flux d'événements WebSocket doivent maintenir une latence inférieure à 50 ms.
  • L'utilisation de mémoire doit rester sous 500 MB pour les projets typiques.

Flux de travail

  1. Configurer l'infrastructure LSP : installer les serveurs de langage, vérifier qu'ils fonctionnent.
  2. Construire le graph daemon avec serveur WebSocket, points de terminaison HTTP, observateur de fichiers.
  3. Intégrer les serveurs de langage avec les capacités appropriées, support multi-root workspace, regroupement de requêtes.
  4. Optimiser les performances : profiler les goulots d'étranglement, implémenter le diffing de graphe, utiliser les worker threads, ajouter la mise en cache distribuée.

Livrables

Architecture centrale de graphd

interface GraphDaemon {
  lspClients: Map<string, LanguageClient>;
  graph: {
    nodes: Map<NodeId, GraphNode>;
    edges: Map<EdgeId, GraphEdge>;
    index: SymbolIndex;
  };
  httpServer: {
    '/graph': () => GraphResponse;
    '/nav/:symId': (symId: string) => NavigationResponse;
    '/stats': () => SystemStats;
  };
  wsServer: {
    onConnection: (client: WSClient) => void;
    emitDiff: (diff: GraphDiff) => void;
  };
}

interface GraphNode {
  id: string;
  kind: 'file' | 'module' | 'class' | 'function' | 'variable' | 'type';
  file?: string;
  range?: Range;
  detail?: string;
}

interface GraphEdge {
  id: string;
  source: string;
  target: string;
  type: 'contains' | 'imports' | 'extends' | 'implements' | 'calls' | 'references';
  weight?: number;
}

Format d'index de navigation

{"symId":"sym:AppController","def":{"uri":"file:///src/controllers/app.php","l":10,"c":6}}
{"symId":"sym:AppController","refs":[{"uri":"file:///src/routes.php","l":5,"c":10}]}
{"symId":"sym:AppController","hover":{"contents":{"kind":"markdown","value":"```php\nclass AppController extends BaseController\n```"}}}

Métriques de succès

  • graphd fournit une code intelligence unifiée dans tous les langages
  • Go-to-definition s'exécute en moins de 150 ms pour n'importe quel symbole
  • La documentation au survol apparaît en moins de 60 ms
  • Les mises à jour du graphe se propagent aux clients en moins de 500 ms après l'enregistrement du fichier
  • Le système gère 100 000+ symboles sans dégradation des performances
  • Zéro incohérence entre l'état du graphe et le système de fichiers

Vérifier

  • La cause racine est énoncée en une phrase et est soutenue par un artefact concret (stack trace, ligne de log, diff, sortie de profiler)
  • Le reproducer est minimal et s'exécute localement ; la commande exacte et la sortie observée sont capturées
  • La correction a été vérifiée en réexécutant le reproducer et en montrant que la sortie précédemment défaillante passe maintenant
  • Un test de régression (ou une surveillance/alerte) a été ajouté pour que le même bug soit attrapé automatiquement la prochaine fois
  • Les chemins de code adjacents qui partagent le même mode de défaillance ont été vérifiés, pas seulement le symptôme rapporté
  • Si la correction affecte la sécurité, les performances ou l'intégrité des données, le compromis est nommé et quantifié

Skills similaires