@zabaca/lattice 0.1.2 → 0.2.0

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 +4 -5
  2. package/dist/cli.js +36 -69
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -108,13 +108,12 @@ lattice status --verbose # Include detailed change information
108
108
 
109
109
  ### `lattice search`
110
110
 
111
- Search the knowledge graph.
111
+ Semantic search across the knowledge graph.
112
112
 
113
113
  ```bash
114
- lattice search --semantic "query" # Semantic search using embeddings
115
- lattice search --keyword "term" # Keyword-based search
116
- lattice search --type concept # Filter by entity type
117
- lattice search --limit 10 # Limit results
114
+ lattice search "query" # Search all entity types
115
+ lattice search --label Technology "query" # Filter by entity label
116
+ lattice search --limit 10 "query" # Limit results (default: 20)
118
117
  ```
119
118
 
120
119
  ### `lattice stats`
package/dist/cli.js CHANGED
@@ -2385,98 +2385,65 @@ Relationship Types (${stats.relationshipTypes.length}):`);
2385
2385
  process.exit(1);
2386
2386
  }
2387
2387
  });
2388
- program.command("search").description("Search for nodes in the graph or perform semantic search").option("-l, --label <label>", "Filter by node label").option("-n, --name <name>", "Filter by name (substring match)").option("-s, --semantic <query>", "Perform semantic/vector search on documents").option("--limit <n>", "Limit results", "20").action(async (options) => {
2388
+ program.command("search <query>").description("Semantic search across the knowledge graph").option("-l, --label <label>", "Filter by entity label (e.g., Technology, Concept, Document)").option("--limit <n>", "Limit results", "20").action(async (query, options) => {
2389
2389
  let app;
2390
2390
  try {
2391
2391
  app = await NestFactory3.createApplicationContext(AppModule, {
2392
2392
  logger: ["error"]
2393
2393
  });
2394
2394
  const graph = app.get(GraphService);
2395
- if (options.semantic) {
2396
- const embedding = app.get(EmbeddingService);
2397
- const limit2 = Math.min(parseInt(options.limit, 10), 100);
2398
- try {
2399
- const queryEmbedding = await embedding.generateEmbedding(options.semantic);
2400
- const results2 = await graph.vectorSearchAll(queryEmbedding, limit2);
2401
- console.log(`
2402
- === Semantic Search Results for "${options.semantic}" ===
2403
- `);
2404
- if (results2.length === 0) {
2405
- console.log(`No results found with semantic search.
2406
- `);
2407
- await app.close();
2408
- process.exit(0);
2409
- }
2410
- results2.forEach((result2, idx) => {
2411
- console.log(`${idx + 1}. [${result2.label}] ${result2.name}`);
2412
- if (result2.title) {
2413
- console.log(` Title: ${result2.title}`);
2414
- }
2415
- if (result2.description && result2.label !== "Document") {
2416
- const desc = result2.description.length > 80 ? result2.description.slice(0, 80) + "..." : result2.description;
2417
- console.log(` ${desc}`);
2418
- }
2419
- console.log(` Similarity: ${(result2.score * 100).toFixed(2)}%`);
2420
- });
2421
- console.log();
2422
- await app.close();
2423
- process.exit(0);
2424
- } catch (semanticError) {
2425
- const errorMsg = semanticError instanceof Error ? semanticError.message : String(semanticError);
2426
- console.error("Semantic search error:", errorMsg);
2427
- if (errorMsg.includes("no embeddings") || errorMsg.includes("vector")) {
2428
- console.log(`
2429
- Note: Semantic search requires embeddings to be generated first.`);
2430
- console.log(`Run 'lattice sync' to generate embeddings for documents.
2431
- `);
2432
- }
2433
- await app.close();
2434
- process.exit(1);
2435
- }
2436
- }
2437
- let cypher;
2395
+ const embedding = app.get(EmbeddingService);
2438
2396
  const limit = Math.min(parseInt(options.limit, 10), 100);
2439
- if (options.label && options.name) {
2440
- const escapedLabel = options.label.replace(/`/g, "\\`");
2441
- const escapedName = options.name.replace(/'/g, "\\'");
2442
- cypher = `MATCH (n:\`${escapedLabel}\`) WHERE n.name CONTAINS '${escapedName}' RETURN n LIMIT ${limit}`;
2443
- } else if (options.label) {
2444
- const escapedLabel = options.label.replace(/`/g, "\\`");
2445
- cypher = `MATCH (n:\`${escapedLabel}\`) RETURN n LIMIT ${limit}`;
2446
- } else if (options.name) {
2447
- const escapedName = options.name.replace(/'/g, "\\'");
2448
- cypher = `MATCH (n) WHERE n.name CONTAINS '${escapedName}' RETURN n LIMIT ${limit}`;
2397
+ const queryEmbedding = await embedding.generateEmbedding(query);
2398
+ let results;
2399
+ if (options.label) {
2400
+ const labelResults = await graph.vectorSearch(options.label, queryEmbedding, limit);
2401
+ results = labelResults.map((r) => ({
2402
+ name: r.name,
2403
+ label: options.label,
2404
+ title: r.title,
2405
+ score: r.score
2406
+ }));
2449
2407
  } else {
2450
- cypher = `MATCH (n) RETURN n LIMIT ${limit}`;
2408
+ results = await graph.vectorSearchAll(queryEmbedding, limit);
2451
2409
  }
2452
- const result = await graph.query(cypher);
2453
- const results = result.resultSet || [];
2410
+ const labelSuffix = options.label ? ` (${options.label})` : "";
2454
2411
  console.log(`
2455
- === Search Results (${results.length} nodes) ===
2412
+ === Semantic Search Results for "${query}"${labelSuffix} ===
2456
2413
  `);
2457
2414
  if (results.length === 0) {
2458
- console.log(`No nodes found matching criteria.
2415
+ console.log(`No results found.
2416
+ `);
2417
+ if (options.label) {
2418
+ console.log(`Tip: Try without --label to search all entity types.
2459
2419
  `);
2420
+ }
2460
2421
  await app.close();
2461
2422
  process.exit(0);
2462
2423
  }
2463
- results.forEach((row) => {
2464
- const node = row[0];
2465
- const labels = (node.labels || []).join(", ");
2466
- const name = node.properties?.name || "unnamed";
2467
- console.log(`[${labels}] ${name}`);
2468
- if (node.properties?.description) {
2469
- console.log(` Description: ${node.properties.description}`);
2424
+ results.forEach((result, idx) => {
2425
+ console.log(`${idx + 1}. [${result.label}] ${result.name}`);
2426
+ if (result.title) {
2427
+ console.log(` Title: ${result.title}`);
2470
2428
  }
2471
- if (node.properties?.importance) {
2472
- console.log(` Importance: ${node.properties.importance}`);
2429
+ if (result.description && result.label !== "Document") {
2430
+ const desc = result.description.length > 80 ? result.description.slice(0, 80) + "..." : result.description;
2431
+ console.log(` ${desc}`);
2473
2432
  }
2433
+ console.log(` Similarity: ${(result.score * 100).toFixed(2)}%`);
2474
2434
  });
2475
2435
  console.log();
2476
2436
  await app.close();
2477
2437
  process.exit(0);
2478
2438
  } catch (error) {
2479
- console.error("Error:", error instanceof Error ? error.message : String(error));
2439
+ const errorMsg = error instanceof Error ? error.message : String(error);
2440
+ console.error("Error:", errorMsg);
2441
+ if (errorMsg.includes("no embeddings") || errorMsg.includes("vector")) {
2442
+ console.log(`
2443
+ Note: Semantic search requires embeddings to be generated first.`);
2444
+ console.log(`Run 'lattice sync' to generate embeddings for documents.
2445
+ `);
2446
+ }
2480
2447
  if (app)
2481
2448
  await app.close();
2482
2449
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zabaca/lattice",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Human-initiated, AI-powered knowledge graph for markdown documentation",
5
5
  "type": "module",
6
6
  "bin": {