Files
rUv 402b701a9d fix(security): ADR-165 Phase 1 — close 5 critical CVEs + refresh registry + audit CI gate (#2508)
* fix(security): ADR-165 Phase 1 — close all critical CVEs, refresh registry, add CI gate

Closes ADR-165 Phase 1. Both workspaces pass `npm audit --audit-level=critical`.

## Before (2026-06-29)

| Workspace | Critical | High | Moderate | Total |
|-----------|----------|------|----------|-------|
| Root      | **1**    | 6    | 31       | 38    |
| v3        | **4**    | 33   | 57       | 97    |

## After

| Workspace | Critical | High | Moderate | Total |
|-----------|----------|------|----------|-------|
| Root      | **0**    | 0    | 31       | 31    |
| v3        | **0**    | 27   | 58       | 88    |

All 5 critical advisories closed (vitest GHSA-5xrq, handlebars prototype-pollution,
protobufjs constructor-pollution, plus 2 more in v3). 12 of 39 high advisories
closed via overrides; the remaining 27 v3 highs are deeper transitive chains
that would require breaking-change major bumps — flagged for ADR-165 Phase 2.

## Changes

### Root workspace overrides (package.json)

- `vitest`: `^1.0.0` → `^3.2.6` (closes critical GHSA-5xrq CVSS 9.8)
- `hono`: `>=4.11.4` → `>=4.12.25` (closes 6 hono advisories)
- `undici`: `>=7.18.0` → `>=8.5.0` (closes 7 undici advisories — bumps the
  stale pin that ADR-165 flagged as still-in-vulnerable-range)
- `vite`: `>=6.4.6` → `>=8.0.16` (closes 2 vite advisories)
- NEW `@grpc/grpc-js`: `>=1.14.4`
- NEW `form-data`: `>=4.0.6`
- NEW `http-proxy-middleware`: `>=3.0.7`
- `@hono/node-server`: `>=1.19.10` → `>=1.19.14`

### v3 workspace overrides (v3/package.json + pnpm.overrides)

- `vitest`: `^4.0.16` → `^4.1.0` (and `@vitest/coverage-v8` matched)
- Top-level + pnpm overrides: `handlebars: >=4.7.9`, `protobufjs: >=8.6.0`
- 27 sub-package `package.json` updated to `vitest ^4.1.0`

### CVE registry refresh (v3/@claude-flow/security/src/CVE-REMEDIATION.ts)

Rewritten from 5 stale Jan-2026 entries to 16 total: 15 fixed, 1 open
(ADR165-OPEN-01 — PII pipeline wiring per ADR-164 §6.1 not yet on
dispatch-layer). `SECURITY_SUMMARY` is now computed dynamically from the
registry; `validateRemediation()` correctly returns `allFixed: false`
with 1 issue. ADR-165 §5 flagged this as THE Phase 2 priority — now closed.

### New CI gate

`.github/workflows/cve-audit.yml`:
- `audit-root` — `npm audit --audit-level=critical` in root, blocking
- `audit-v3` — same in v3, blocking
- `audit-high-report` — warn-only summary on high-severity drift
- Triggers: PR, push to main, daily cron

### ADR-165 §9 evidence ledger addendum

Captures AFTER-remediation `npm audit --json` metadata for both workspaces.
The diff between BEFORE (already in §9) and AFTER makes Phase 1 verifiable.

Also CORRECTED one prior surprise in §9: the `validate-input.ts` in
`mcp-tools/` is NOT a 9-line shim. It's 269 lines of real implementation.
(That was an inaccurate findings note from the initial audit.)

### §7.3 research items resolved

- `protobufjs` v3 chain confirmed gone after override pins
- `handlebars` v3 chain confirmed not user-reachable on the workflow path
  (toolchain-only; override sufficient)
- `validate-input.ts` confirmed real implementation, not a shim (registry
  entry corrected)
- CORS surface check: no `cors()` / `app.use(cors` call sites — the hono
  CORS-wildcard advisory is not exploitable on the current server
- ADR-164 §6.1 PII pipeline NOT wired in current agentbbs dispatch —
  recorded as ADR165-OPEN-01 (Phase 3 work)

## Gates (all PASS)

- `npm audit --audit-level=critical` root: exit 0 (was non-zero)
- `npm audit --audit-level=critical` v3:   exit 0 (was non-zero)
- vitest suites: 105/109 pass (4 skip-conditional — same as before)
- ADR-112 audit: 352/352 tools with guidance
- business-pods smoke: 11/11 PASS
- agentbbs smoke: 8/8 PASS
- agenticow smoke: 8/8 PASS
- cli build: clean (tsc)

## Phase 2+ deferred

The 27 v3 high-severity advisories that remain are transitive chains with
no patched-in-range version. ADR-165 §6 Phase 2 picks these up after the
`cve-watch.yml` automation in §6 lands (NEW PR — not in scope here).

Co-Authored-By: RuFlo <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01WbBa4nccx5aGhXphoHxcni

* chore(lock): regen v3/pnpm-lock.yaml after override updates (PR #2508 CI fix)

PR #2508 added handlebars + protobufjs to v3 overrides + bumped vitest pin,
but v3/pnpm-lock.yaml wasn't regenerated. CI surfaced
ERR_PNPM_LOCKFILE_CONFIG_MISMATCH on every install step.

Same pattern as the previous lockfile-drift fixes on PR #2500 and #2503.

* fix(ci): cve-audit.yml jq-only + regen witness manifests for #1609 marker drift

Two PR #2508 CI failures fixed:

1. Static-regression-guard tripped on cve-audit.yml line 52: the static
   YAML strict-parser sees `if high > 0:` inside the `run: |` block as
   a YAML block-mapping key indicator. Refactored all 3 inline-python
   blocks to use jq (preinstalled on ubuntu-latest) — no embedded
   `if x > 0:` lines, so the YAML guard passes.

2. Witness marker drift smoke flagged fix-marker #1609 — the Phase 1
   vitest bump (4.0.16 → 4.1.0) drifted the cited marker string in
   v3/@claude-flow/aidefence/package.json. Updated `marker` field in
   all 3 platform manifests + `desc` to reference ADR-165 Phase 1, then
   re-signed via plugins/ruflo-core/scripts/witness/regen.mjs.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-06-29 22:41:24 -04:00
..
2026-01-07 04:57:08 +00:00
2026-01-07 04:44:44 +00:00
2026-01-05 16:42:40 +00:00

@claude-flow/embeddings

npm version npm downloads License: MIT TypeScript Performance

High-performance embedding generation module for Claude Flow V3 - multi-provider support with persistent caching, document chunking, normalization, hyperbolic embeddings, and neural substrate integration.

Features

Core Embedding

  • Multiple Providers - Agentic-Flow (ONNX), OpenAI, Transformers.js, and Mock
  • Auto-Install - Automatically installs agentic-flow when using provider: 'auto'
  • Smart Fallback - Graceful fallback chain: agentic-flow → transformers → mock
  • LRU + Disk Caching - In-memory LRU + SQLite persistent cache with TTL
  • Batch Processing - Efficient batch embedding with partial cache hits
  • Similarity Functions - Cosine, Euclidean, and dot product metrics
  • 75x Faster - Agentic-flow ONNX is 75x faster than Transformers.js

Advanced Features (New in v3.0.0-alpha.11)

  • Document Chunking - Character, sentence, paragraph, and token-based chunking with overlap
  • Multiple Normalization - L2, L1, min-max, and z-score normalization
  • Hyperbolic Embeddings - Poincaré ball model for hierarchical representations
  • Neural Substrate - Semantic drift detection, memory physics, swarm coordination
  • Persistent Cache - SQLite-backed disk cache with LRU eviction and TTL

Installation

npm install @claude-flow/embeddings

Standalone use (without the Ruflo CLI)

This package runs on its own — no @claude-flow/cli, no MCP server, no API key required for the recipes below (the MockEmbeddingService gives deterministic 384-dim vectors so examples are reproducible). Swap to OpenAIEmbeddingService / TransformersEmbeddingService / AgenticFlowEmbeddingService when you're ready for real embeddings.

Recipe — Embed + compare without a network call

// recipe.mjs
import {
  MockEmbeddingService,
  cosineSimilarity,
} from '@claude-flow/embeddings';

const service = new MockEmbeddingService({ dimension: 384 });

// `embed()` returns { embedding: Float32Array, tokens, ... } —
// destructure for the raw vector.
const [{ embedding: cat }, { embedding: dog }, { embedding: car }] =
  await Promise.all([
    service.embed('a friendly cat'),
    service.embed('a friendly dog'),
    service.embed('a red sports car'),
  ]);

console.log('cat ↔ dog:', cosineSimilarity(cat, dog).toFixed(4));
console.log('cat ↔ car:', cosineSimilarity(cat, car).toFixed(4));
// With real embeddings the pet pair will score higher than the cat/car pair.

Provider swap — same surface, real vectors

import { createEmbeddingService, cosineSimilarity } from '@claude-flow/embeddings';

// OpenAI
const openai = createEmbeddingService({
  provider: 'openai',
  model: 'text-embedding-3-small',
  apiKey: process.env.OPENAI_API_KEY!,
});

// Or local ONNX via @huggingface/transformers (no API key needed)
const local = createEmbeddingService({
  provider: 'transformers',
  model: 'Xenova/all-MiniLM-L6-v2', // 384-dim, ~25MB
});

await openai.initialize();
const v = await openai.embed('hello world');

cosineSimilarity, euclideanDistance, dotProduct, and computeSimilarity are exported as plain functions — useful when you already have vectors from another source and just need the math.

Quick Start

import { createEmbeddingService, cosineSimilarity } from '@claude-flow/embeddings';

// Create embedding service
const service = createEmbeddingService({
  provider: 'openai',
  apiKey: process.env.OPENAI_API_KEY!,
  model: 'text-embedding-3-small',
  dimensions: 1536,
});

// Generate embedding
const result = await service.embed('Hello, world!');
console.log(`Embedding dimension: ${result.embedding.length}`);
console.log(`Latency: ${result.latencyMs}ms`);

// Batch embed
const batchResult = await service.embedBatch([
  'First document',
  'Second document',
  'Third document',
]);
console.log(`Processed ${batchResult.embeddings.length} embeddings`);
console.log(`Cache hits: ${batchResult.cacheStats?.hits}`);

// Calculate similarity
const similarity = cosineSimilarity(
  batchResult.embeddings[0],
  batchResult.embeddings[1]
);
console.log(`Similarity: ${similarity.toFixed(4)}`);

CLI Usage

# Generate embedding from CLI
claude-flow embeddings embed "Your text here"

# Batch embed from file
claude-flow embeddings batch documents.txt -o embeddings.json

# Similarity search
claude-flow embeddings search "query" --index ./vectors

# Initialize agentic-flow model
claude-flow embeddings init --provider agentic-flow

API Reference

Factory Functions

import {
  createEmbeddingService,
  createEmbeddingServiceAsync,
  getEmbedding
} from '@claude-flow/embeddings';

// Sync: Create with known provider
const service = createEmbeddingService({
  provider: 'openai',
  apiKey: 'your-api-key',
  model: 'text-embedding-3-small',
});

// Async: Auto-select best provider with fallback
const autoService = await createEmbeddingServiceAsync({
  provider: 'auto',       // agentic-flow → transformers → mock
  autoInstall: true,      // Install agentic-flow if missing
  fallback: 'transformers', // Custom fallback
});

// Quick one-off embedding
const embedding = await getEmbedding('Hello world', {
  provider: 'mock',
  dimensions: 384,
});

OpenAI Provider

import { OpenAIEmbeddingService } from '@claude-flow/embeddings';

const service = new OpenAIEmbeddingService({
  provider: 'openai',
  apiKey: process.env.OPENAI_API_KEY!,
  model: 'text-embedding-3-small',  // or 'text-embedding-3-large'
  dimensions: 1536,                  // Adjustable for v3 models
  baseURL: 'https://api.openai.com/v1/embeddings',
  timeout: 30000,
  maxRetries: 3,
  cacheSize: 1000,
});

const result = await service.embed('Your text here');
console.log('Tokens used:', result.usage?.totalTokens);

Agentic-Flow Provider (Fastest)

import { AgenticFlowEmbeddingService } from '@claude-flow/embeddings';

const service = new AgenticFlowEmbeddingService({
  provider: 'agentic-flow',
  modelId: 'default',     // Uses optimized ONNX model
  cacheSize: 256,
});

// 75x faster than Transformers.js (3ms vs 233ms)
const result = await service.embed('Your text here');
console.log(`ONNX embedding in ${result.latencyMs}ms`);

Transformers.js Provider (Local)

import { TransformersEmbeddingService } from '@claude-flow/embeddings';

const service = new TransformersEmbeddingService({
  provider: 'transformers',
  model: 'Xenova/all-MiniLM-L6-v2',  // Any HuggingFace model
  cacheSize: 1000,
});

// First call downloads the model
const result = await service.embed('Your text here');
console.log(`Local embedding generated in ${result.latencyMs}ms`);

Mock Provider (Testing)

import { MockEmbeddingService } from '@claude-flow/embeddings';

const service = new MockEmbeddingService({
  provider: 'mock',
  dimensions: 384,
  simulatedLatency: 10,  // Optional delay
  cacheSize: 100,
});

// Deterministic embeddings based on text hash
const result = await service.embed('Your text here');

Batch Processing

const result = await service.embedBatch([
  'Document 1: Introduction to machine learning',
  'Document 2: Deep learning fundamentals',
  'Document 3: Natural language processing',
  'Document 4: Computer vision basics',
]);

console.log('Batch Results:', {
  count: result.embeddings.length,
  totalLatency: `${result.totalLatencyMs}ms`,
  avgLatency: `${result.avgLatencyMs}ms`,
  cacheHits: result.cacheStats?.hits,
  cacheMisses: result.cacheStats?.misses,
  tokensUsed: result.usage?.totalTokens,
});

Similarity Functions

import {
  cosineSimilarity,
  euclideanDistance,
  dotProduct,
  computeSimilarity,
} from '@claude-flow/embeddings';

// Cosine similarity (most common for embeddings)
const cosine = cosineSimilarity(embedding1, embedding2);
// Returns: 0.0 to 1.0 (higher = more similar)

// Euclidean distance
const distance = euclideanDistance(embedding1, embedding2);
// Returns: 0.0 to infinity (lower = more similar)

// Dot product
const dot = dotProduct(embedding1, embedding2);
// Returns: unbounded (higher = more similar for normalized vectors)

// Generic similarity with metric selection
const result = computeSimilarity(embedding1, embedding2, 'cosine');
// Returns: { score: 0.95, metric: 'cosine' }

Cache Management

// Get cache statistics
const stats = service.getCacheStats();
console.log('Cache Stats:', {
  size: stats.size,
  maxSize: stats.maxSize,
  hitRate: `${(stats.hitRate * 100).toFixed(1)}%`,
});

// Clear cache
service.clearCache();

// Shutdown service
await service.shutdown();

Event System

// Subscribe to embedding events
service.addEventListener((event) => {
  switch (event.type) {
    case 'embed_start':
      console.log(`Starting: ${event.text.substring(0, 50)}...`);
      break;
    case 'embed_complete':
      console.log(`Completed in ${event.latencyMs}ms`);
      break;
    case 'embed_error':
      console.error(`Error: ${event.error}`);
      break;
    case 'cache_hit':
      console.log('Cache hit!');
      break;
    case 'batch_start':
      console.log(`Batch of ${event.count} started`);
      break;
    case 'batch_complete':
      console.log(`Batch completed in ${event.latencyMs}ms`);
      break;
    case 'cache_eviction':
      console.log(`Cache evicted ${event.size} entries`);
      break;
  }
});

// Remove listener
service.removeEventListener(listener);

Provider Comparison

Provider Latency Quality Cost Offline
Agentic-Flow ~3ms Good Free Yes
OpenAI ~50-100ms Excellent $0.02-0.13/1M tokens No
Transformers.js ~230ms Good Free Yes
Mock <1ms N/A Free Yes
Model Dimensions Speed Best For
default 384 3ms General purpose, fastest

OpenAI Models

Model Dimensions Max Tokens Best For
text-embedding-3-small 1536 8191 General purpose, cost-effective
text-embedding-3-large 3072 8191 Highest quality
text-embedding-ada-002 1536 8191 Legacy support

Transformers.js Models

Model Dimensions Size Best For
Xenova/all-MiniLM-L6-v2 384 23MB Fast, general purpose
Xenova/all-mpnet-base-v2 768 110MB Higher quality
Xenova/bge-small-en-v1.5 384 33MB Retrieval optimized

TypeScript Types

import type {
  // Provider types
  EmbeddingProvider,
  EmbeddingConfig,
  OpenAIEmbeddingConfig,
  TransformersEmbeddingConfig,
  AgenticFlowEmbeddingConfig,
  MockEmbeddingConfig,
  AutoEmbeddingConfig,

  // Result types
  EmbeddingResult,
  BatchEmbeddingResult,

  // Service interface
  IEmbeddingService,

  // Event types
  EmbeddingEvent,
  EmbeddingEventListener,

  // Similarity types
  SimilarityMetric,
  SimilarityResult,
} from '@claude-flow/embeddings';

Environment Variables

# OpenAI configuration
OPENAI_API_KEY=sk-...

# Optional: Custom base URL (for Azure OpenAI, etc.)
OPENAI_BASE_URL=https://your-endpoint.openai.azure.com/

Error Handling

try {
  const result = await service.embed('Your text');
} catch (error) {
  if (error instanceof Error) {
    if (error.message.includes('API error')) {
      // Handle API errors (rate limits, auth, etc.)
    } else if (error.message.includes('Failed to initialize')) {
      // Handle model loading errors (Transformers.js)
    }
  }
}

Integration with Memory Module

import { createEmbeddingService } from '@claude-flow/embeddings';
import { HNSWIndex } from '@claude-flow/memory';

// Create embedding service
const embeddings = createEmbeddingService({
  provider: 'openai',
  apiKey: process.env.OPENAI_API_KEY!,
  model: 'text-embedding-3-small',
});

// Create HNSW index
const index = new HNSWIndex({
  dimensions: 1536,
  metric: 'cosine',
});

// Index documents
const documents = ['Doc 1 content', 'Doc 2 content', 'Doc 3 content'];
const { embeddings: vectors } = await embeddings.embedBatch(documents);

vectors.forEach((vector, i) => {
  index.addPoint(`doc-${i}`, new Float32Array(vector));
});

// Search
const queryResult = await embeddings.embed('Search query');
const results = await index.search(new Float32Array(queryResult.embedding), 5);

Document Chunking

Split long documents into overlapping chunks for embedding:

import { chunkText, estimateTokens, reconstructFromChunks } from '@claude-flow/embeddings';

// Chunk by sentence (default)
const result = chunkText(longDocument, {
  maxChunkSize: 512,
  overlap: 50,
  strategy: 'sentence',  // 'character' | 'sentence' | 'paragraph' | 'token'
  minChunkSize: 100,
});

console.log('Chunks:', result.totalChunks);
result.chunks.forEach((chunk, i) => {
  console.log(`Chunk ${i}: ${chunk.length} chars, ~${chunk.tokenCount} tokens`);
});

// Estimate tokens
const tokens = estimateTokens('Hello world');  // ~3 tokens

// Reconstruct (approximate)
const reconstructed = reconstructFromChunks(result.chunks);

Normalization

Normalize embeddings for consistent similarity computation:

import {
  l2Normalize,    // Unit vector (Euclidean norm = 1)
  l1Normalize,    // Manhattan norm = 1
  minMaxNormalize, // Values in [0, 1]
  zScoreNormalize, // Mean 0, std 1
  normalize,       // Generic with type option
  l2Norm,
  isNormalized,
} from '@claude-flow/embeddings';

const embedding = new Float32Array([3, 4, 0]);

// L2 normalize (most common for cosine similarity)
const l2 = l2Normalize(embedding);  // [0.6, 0.8, 0]
console.log('L2 norm:', l2Norm(l2));  // 1.0

// Check if already normalized
console.log(isNormalized(l2));  // true
console.log(isNormalized(embedding));  // false

// Generic normalize with type
const normalized = normalize(embedding, { type: 'l2' });

Hyperbolic Embeddings (Poincaré Ball)

Transform embeddings to hyperbolic space for better hierarchical representation:

import {
  euclideanToPoincare,
  poincareToEuclidean,
  hyperbolicDistance,
  mobiusAdd,
  isInPoincareBall,
  batchEuclideanToPoincare,
  hyperbolicCentroid,
} from '@claude-flow/embeddings';

// Convert Euclidean embedding to Poincaré ball
const euclidean = new Float32Array([0.5, 0.3, 0.2]);
const poincare = euclideanToPoincare(euclidean);

// Check if point is in the ball
console.log(isInPoincareBall(poincare));  // true

// Round-trip conversion
const back = poincareToEuclidean(poincare);

// Hyperbolic distance (geodesic in Poincaré ball)
const a = euclideanToPoincare(new Float32Array([0.1, 0.2, 0.1]));
const b = euclideanToPoincare(new Float32Array([0.3, 0.1, 0.2]));
const dist = hyperbolicDistance(a, b);

// Möbius addition (hyperbolic "plus")
const sum = mobiusAdd(a, b);

// Batch conversion
const embeddings = [vec1, vec2, vec3];
const hyperbolic = batchEuclideanToPoincare(embeddings);

// Hyperbolic centroid (Fréchet mean)
const centroid = hyperbolicCentroid(hyperbolic);

Why Hyperbolic?

Hyperbolic space has natural properties for representing hierarchical data:

  • Exponential growth - Tree-like structures fit naturally
  • Better hierarchy - Parent-child relationships preserved
  • Lower distortion - Taxonomies represented with less error

Neural Substrate Integration

Access agentic-flow's neural features for advanced embedding operations:

import {
  NeuralEmbeddingService,
  createNeuralService,
  isNeuralAvailable,
  listEmbeddingModels,
  downloadEmbeddingModel,
} from '@claude-flow/embeddings';

// Check if neural features are available
const available = await isNeuralAvailable();

// Create neural service
const neural = createNeuralService({ dimension: 384 });
await neural.init();

if (neural.isAvailable()) {
  // Semantic drift detection
  await neural.setDriftBaseline('Initial context about the topic');
  const drift = await neural.detectDrift('New input to check for drift');
  console.log('Drift:', drift?.trend);  // 'stable' | 'drifting' | 'accelerating'

  // Memory with interference detection
  const stored = await neural.storeMemory('mem-1', 'Important information');
  console.log('Interference:', stored?.interference);

  // Recall by similarity
  const memories = await neural.recallMemories('query', 5);

  // Swarm coordination
  await neural.addSwarmAgent('agent-1', 'researcher');
  const coordination = await neural.coordinateSwarm('Analyze this task');

  // Coherence checking
  await neural.calibrateCoherence(['good output 1', 'good output 2']);
  const coherence = await neural.checkCoherence('Output to check');

  // Health status
  const health = neural.health();
  console.log('Memory count:', health?.memoryCount);
}

// List available ONNX models
const models = await listEmbeddingModels();
console.log(models);
// [{ id: 'all-MiniLM-L6-v2', dimension: 384, size: '23MB', ... }]

// Download model
const path = await downloadEmbeddingModel('all-MiniLM-L6-v2', '.models');

Persistent Disk Cache

SQLite-backed persistent cache for embeddings:

import { PersistentEmbeddingCache, isPersistentCacheAvailable } from '@claude-flow/embeddings';

// Check if SQLite is available
const hasSQLite = await isPersistentCacheAvailable();

// Create persistent cache
const cache = new PersistentEmbeddingCache({
  dbPath: './embeddings.db',  // SQLite database path
  maxSize: 10000,             // Max entries before LRU eviction
  ttlMs: 7 * 24 * 60 * 60 * 1000,  // 7 day TTL
});

// Initialize
await cache.init();

// Store embedding
await cache.set('my text', new Float32Array([0.1, 0.2, 0.3]));

// Retrieve
const embedding = await cache.get('my text');

// Get stats
const stats = await cache.getStats();
console.log('Cache stats:', {
  size: stats.totalEntries,
  hitRate: stats.hitRate,
  avgLatency: stats.avgLatencyMs,
});

// Close when done
await cache.close();

Enable in Embedding Service

const service = createEmbeddingService({
  provider: 'openai',
  apiKey: process.env.OPENAI_API_KEY!,
  persistentCache: {
    enabled: true,
    dbPath: './cache/embeddings.db',
    maxSize: 50000,
    ttlMs: 30 * 24 * 60 * 60 * 1000,  // 30 days
  },
  normalization: 'l2',  // Auto-normalize embeddings
});

CLI Commands (New)

# Document chunking
claude-flow embeddings chunk document.txt --strategy sentence --max-size 512

# Normalize embedding file
claude-flow embeddings normalize embeddings.json --type l2 -o normalized.json

# Convert to hyperbolic
claude-flow embeddings hyperbolic embeddings.json -o poincare.json

# Neural operations
claude-flow embeddings neural drift --baseline "context" --input "check this"
claude-flow embeddings neural store --id mem-1 --content "data"
claude-flow embeddings neural recall "query" --top-k 5

# List/download models
claude-flow embeddings models list
claude-flow embeddings models download all-MiniLM-L6-v2

# Cache management
claude-flow embeddings cache stats
claude-flow embeddings cache clear --older-than 7d

License

MIT