@zabaca/lattice 1.0.19 → 1.0.20

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 (3) hide show
  1. package/README.md +5 -25
  2. package/dist/main.js +64 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -173,15 +173,6 @@ Show relationships for a node.
173
173
  lattice rels "TypeScript" # Show all relationships for an entity
174
174
  ```
175
175
 
176
- ### `lattice validate`
177
-
178
- Validate entity references and relationships.
179
-
180
- ```bash
181
- lattice validate # Check for broken references
182
- lattice validate --fix # Attempt to fix validation issues
183
- ```
184
-
185
176
  ### `lattice ontology`
186
177
 
187
178
  Display the derived ontology from your documents.
@@ -218,23 +209,12 @@ You can back up, copy, or version control this file like any other.
218
209
 
219
210
  ### Entity Extraction
220
211
 
221
- When you run `/graph-sync`, Claude Code extracts entities from your documents and writes them to YAML frontmatter. The Lattice CLI then syncs this to DuckDB.
222
-
223
- ```yaml
224
- ---
225
- entities:
226
- - name: React
227
- type: technology
228
- description: JavaScript library for building user interfaces
229
-
230
- relationships:
231
- - source: React
232
- target: Component Architecture
233
- relation: REFERENCES
234
- ---
235
- ```
212
+ When you run `/graph-sync`, Claude Code extracts entities from your documents and writes them directly to the DuckDB database. No frontmatter required your markdown files stay clean.
236
213
 
237
- You don't need to write this manually — Claude Code handles it automatically.
214
+ The extraction identifies:
215
+ - **Entities**: People, technologies, concepts, tools, etc.
216
+ - **Relationships**: How entities connect to each other
217
+ - **Document metadata**: Title, summary, topic classification
238
218
 
239
219
  ### Database Schema
240
220
 
package/dist/main.js CHANGED
@@ -989,6 +989,29 @@ class GraphService {
989
989
  return [];
990
990
  }
991
991
  }
992
+ async findNodesWithMissingEmbeddings(labels) {
993
+ try {
994
+ const conn = await this.ensureConnected();
995
+ const labelFilter = labels.map((l) => `'${this.escape(l)}'`).join(", ");
996
+ const reader = await conn.runAndReadAll(`
997
+ SELECT label, name, properties->>'description' as description
998
+ FROM nodes
999
+ WHERE label IN (${labelFilter})
1000
+ AND embedding IS NULL
1001
+ `);
1002
+ return reader.getRows().map((row) => {
1003
+ const [label, name, description] = row;
1004
+ return {
1005
+ label,
1006
+ name,
1007
+ description: description || undefined
1008
+ };
1009
+ });
1010
+ } catch (error) {
1011
+ this.logger.error(`Failed to find nodes with missing embeddings: ${error instanceof Error ? error.message : String(error)}`);
1012
+ return [];
1013
+ }
1014
+ }
992
1015
  }
993
1016
  GraphService = __legacyDecorateClassTS([
994
1017
  Injectable4(),
@@ -2305,6 +2328,10 @@ class SyncService {
2305
2328
  }
2306
2329
  if (!options.dryRun) {
2307
2330
  result.entityEmbeddingsGenerated = await this.syncEntities(uniqueEntities, options);
2331
+ if (options.embeddings && !options.skipEmbeddings && this.embeddingService) {
2332
+ const repairedCount = await this.repairMissingEntityEmbeddings(options);
2333
+ result.entityEmbeddingsGenerated += repairedCount;
2334
+ }
2308
2335
  await this.graph.checkpoint();
2309
2336
  if (options.verbose) {
2310
2337
  this.logger.log(`Synced ${uniqueEntities.size} entities, generated ${result.entityEmbeddingsGenerated} embeddings`);
@@ -2613,6 +2640,43 @@ class SyncService {
2613
2640
  }
2614
2641
  }
2615
2642
  }
2643
+ async repairMissingEntityEmbeddings(options) {
2644
+ if (!this.embeddingService) {
2645
+ return 0;
2646
+ }
2647
+ const labelsToCheck = [...ENTITY_TYPES, "Document"];
2648
+ const nodesWithMissingEmbeddings = await this.graph.findNodesWithMissingEmbeddings(labelsToCheck);
2649
+ if (nodesWithMissingEmbeddings.length === 0) {
2650
+ return 0;
2651
+ }
2652
+ if (options.verbose) {
2653
+ this.logger.log(`Found ${nodesWithMissingEmbeddings.length} nodes with missing embeddings, repairing...`);
2654
+ }
2655
+ let repairedCount = 0;
2656
+ for (const node of nodesWithMissingEmbeddings) {
2657
+ try {
2658
+ const text = node.label === "Document" ? node.name : composeEntityEmbeddingText({
2659
+ type: node.label,
2660
+ name: node.name,
2661
+ description: node.description,
2662
+ documentPaths: []
2663
+ });
2664
+ if (text.trim()) {
2665
+ const embedding = await this.embeddingService.generateEmbedding(text);
2666
+ await this.graph.updateNodeEmbedding(node.label, node.name, embedding);
2667
+ repairedCount++;
2668
+ this.logger.debug(`Repaired embedding for ${node.label}:${node.name}`);
2669
+ }
2670
+ } catch (error) {
2671
+ const errorMessage = error instanceof Error ? error.message : String(error);
2672
+ this.logger.warn(`Failed to repair embedding for ${node.label}:${node.name}: ${errorMessage}`);
2673
+ }
2674
+ }
2675
+ if (options.verbose && repairedCount > 0) {
2676
+ this.logger.log(`Repaired ${repairedCount} missing embeddings`);
2677
+ }
2678
+ return repairedCount;
2679
+ }
2616
2680
  }
2617
2681
  SyncService = __legacyDecorateClassTS([
2618
2682
  Injectable11(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zabaca/lattice",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "Human-initiated, AI-powered knowledge graph for markdown documentation",
5
5
  "type": "module",
6
6
  "bin": {