@zabaca/lattice 1.0.1 → 1.0.2
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.
- package/commands/graph-sync.md +1 -1
- package/dist/main.js +112 -94
- package/package.json +1 -1
package/commands/graph-sync.md
CHANGED
|
@@ -3,7 +3,7 @@ description: Extract entities from modified docs and sync to graph
|
|
|
3
3
|
model: sonnet
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Identify modified documents
|
|
6
|
+
Identify modified documents in `~/.lattice/docs/`, extract entities from them, and sync to the knowledge graph.
|
|
7
7
|
|
|
8
8
|
## Process
|
|
9
9
|
|
package/dist/main.js
CHANGED
|
@@ -24,12 +24,52 @@ import { Module as Module5 } from "@nestjs/common";
|
|
|
24
24
|
import { ConfigModule as ConfigModule2 } from "@nestjs/config";
|
|
25
25
|
|
|
26
26
|
// src/commands/init.command.ts
|
|
27
|
+
import { existsSync as existsSync2, writeFileSync } from "fs";
|
|
27
28
|
import * as fs from "fs/promises";
|
|
28
|
-
import { homedir } from "os";
|
|
29
|
+
import { homedir as homedir2 } from "os";
|
|
29
30
|
import * as path from "path";
|
|
30
31
|
import { fileURLToPath } from "url";
|
|
31
32
|
import { Injectable } from "@nestjs/common";
|
|
32
33
|
import { Command, CommandRunner, Option } from "nest-commander";
|
|
34
|
+
|
|
35
|
+
// src/utils/paths.ts
|
|
36
|
+
import { existsSync, mkdirSync } from "fs";
|
|
37
|
+
import { homedir } from "os";
|
|
38
|
+
import { join } from "path";
|
|
39
|
+
var latticeHomeOverride = null;
|
|
40
|
+
function getLatticeHomeInternal() {
|
|
41
|
+
if (latticeHomeOverride) {
|
|
42
|
+
return latticeHomeOverride;
|
|
43
|
+
}
|
|
44
|
+
return join(homedir(), ".lattice");
|
|
45
|
+
}
|
|
46
|
+
function getLatticeHome() {
|
|
47
|
+
return getLatticeHomeInternal();
|
|
48
|
+
}
|
|
49
|
+
function getDocsPath() {
|
|
50
|
+
return join(getLatticeHomeInternal(), "docs");
|
|
51
|
+
}
|
|
52
|
+
function getDatabasePath() {
|
|
53
|
+
return join(getLatticeHomeInternal(), "lattice.duckdb");
|
|
54
|
+
}
|
|
55
|
+
function getManifestPath() {
|
|
56
|
+
return join(getLatticeHomeInternal(), ".sync-manifest.json");
|
|
57
|
+
}
|
|
58
|
+
function getEnvPath() {
|
|
59
|
+
return join(getLatticeHomeInternal(), ".env");
|
|
60
|
+
}
|
|
61
|
+
function ensureLatticeHome() {
|
|
62
|
+
const home = getLatticeHomeInternal();
|
|
63
|
+
if (!existsSync(home)) {
|
|
64
|
+
mkdirSync(home, { recursive: true });
|
|
65
|
+
}
|
|
66
|
+
const docsPath = getDocsPath();
|
|
67
|
+
if (!existsSync(docsPath)) {
|
|
68
|
+
mkdirSync(docsPath, { recursive: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/commands/init.command.ts
|
|
33
73
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
34
74
|
var __dirname2 = path.dirname(__filename2);
|
|
35
75
|
var COMMANDS = ["research.md", "graph-sync.md", "entity-extract.md"];
|
|
@@ -37,7 +77,20 @@ var COMMANDS = ["research.md", "graph-sync.md", "entity-extract.md"];
|
|
|
37
77
|
class InitCommand extends CommandRunner {
|
|
38
78
|
async run(_inputs, options) {
|
|
39
79
|
try {
|
|
40
|
-
|
|
80
|
+
ensureLatticeHome();
|
|
81
|
+
const envPath = getEnvPath();
|
|
82
|
+
if (!existsSync2(envPath)) {
|
|
83
|
+
writeFileSync(envPath, `# Lattice Configuration
|
|
84
|
+
# Get your API key from: https://www.voyageai.com/
|
|
85
|
+
|
|
86
|
+
VOYAGE_API_KEY=
|
|
87
|
+
`);
|
|
88
|
+
}
|
|
89
|
+
console.log(`\u2705 Lattice home directory: ${getLatticeHome()}`);
|
|
90
|
+
console.log(` Documents: ${getDocsPath()}`);
|
|
91
|
+
console.log(` Config: ${envPath}`);
|
|
92
|
+
console.log();
|
|
93
|
+
const targetDir = options.global ? path.join(homedir2(), ".claude", "commands") : path.join(process.cwd(), ".claude", "commands");
|
|
41
94
|
let commandsSourceDir = path.resolve(__dirname2, "..", "commands");
|
|
42
95
|
try {
|
|
43
96
|
await fs.access(commandsSourceDir);
|
|
@@ -97,7 +150,10 @@ class InitCommand extends CommandRunner {
|
|
|
97
150
|
console.log();
|
|
98
151
|
if (!options.global) {
|
|
99
152
|
console.log("\uD83D\uDCA1 Tip: Use 'lattice init --global' to install for all projects");
|
|
153
|
+
console.log();
|
|
100
154
|
}
|
|
155
|
+
console.log(`\u26A0\uFE0F Add your Voyage API key to: ${getEnvPath()}`);
|
|
156
|
+
console.log();
|
|
101
157
|
process.exit(0);
|
|
102
158
|
} catch (error) {
|
|
103
159
|
console.error("Error:", error instanceof Error ? error.message : String(error));
|
|
@@ -134,31 +190,13 @@ import { Injectable as Injectable3 } from "@nestjs/common";
|
|
|
134
190
|
// src/sync/document-parser.service.ts
|
|
135
191
|
import { createHash } from "crypto";
|
|
136
192
|
import { readFile as readFile2 } from "fs/promises";
|
|
137
|
-
import { resolve as resolve2 } from "path";
|
|
138
193
|
import { Injectable as Injectable2, Logger } from "@nestjs/common";
|
|
139
194
|
import { glob } from "glob";
|
|
140
195
|
|
|
141
|
-
// src/schemas/config.schemas.ts
|
|
142
|
-
import { z } from "zod";
|
|
143
|
-
var DuckDBConfigSchema = z.object({
|
|
144
|
-
dbPath: z.string().optional(),
|
|
145
|
-
embeddingDimensions: z.coerce.number().int().positive().default(512)
|
|
146
|
-
});
|
|
147
|
-
var EmbeddingConfigSchema = z.object({
|
|
148
|
-
provider: z.enum(["openai", "voyage", "nomic", "mock"]).default("voyage"),
|
|
149
|
-
apiKey: z.string().optional(),
|
|
150
|
-
model: z.string().min(1).default("voyage-3.5-lite"),
|
|
151
|
-
dimensions: z.coerce.number().int().positive().default(512)
|
|
152
|
-
});
|
|
153
|
-
var DocsConfigSchema = z.object({
|
|
154
|
-
projectRoot: z.string().default(process.cwd()),
|
|
155
|
-
docsPath: z.string().default("docs")
|
|
156
|
-
});
|
|
157
|
-
|
|
158
196
|
// src/utils/frontmatter.ts
|
|
159
197
|
import matter from "gray-matter";
|
|
160
|
-
import { z
|
|
161
|
-
var EntityTypeSchema =
|
|
198
|
+
import { z } from "zod";
|
|
199
|
+
var EntityTypeSchema = z.enum([
|
|
162
200
|
"Topic",
|
|
163
201
|
"Technology",
|
|
164
202
|
"Concept",
|
|
@@ -168,20 +206,20 @@ var EntityTypeSchema = z2.enum([
|
|
|
168
206
|
"Organization",
|
|
169
207
|
"Document"
|
|
170
208
|
]);
|
|
171
|
-
var RelationTypeSchema =
|
|
172
|
-
var EntitySchema =
|
|
173
|
-
name:
|
|
209
|
+
var RelationTypeSchema = z.enum(["REFERENCES"]);
|
|
210
|
+
var EntitySchema = z.object({
|
|
211
|
+
name: z.string().min(1),
|
|
174
212
|
type: EntityTypeSchema,
|
|
175
|
-
description:
|
|
213
|
+
description: z.string().optional()
|
|
176
214
|
});
|
|
177
|
-
var RelationshipSchema =
|
|
178
|
-
source:
|
|
215
|
+
var RelationshipSchema = z.object({
|
|
216
|
+
source: z.string().min(1),
|
|
179
217
|
relation: RelationTypeSchema,
|
|
180
|
-
target:
|
|
218
|
+
target: z.string().min(1)
|
|
181
219
|
});
|
|
182
|
-
var GraphMetadataSchema =
|
|
183
|
-
importance:
|
|
184
|
-
domain:
|
|
220
|
+
var GraphMetadataSchema = z.object({
|
|
221
|
+
importance: z.enum(["high", "medium", "low"]).optional(),
|
|
222
|
+
domain: z.string().optional()
|
|
185
223
|
});
|
|
186
224
|
var validateDateFormat = (dateStr) => {
|
|
187
225
|
const match = dateStr.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
@@ -201,15 +239,15 @@ var validateDateFormat = (dateStr) => {
|
|
|
201
239
|
}
|
|
202
240
|
return day <= daysInMonth[month - 1];
|
|
203
241
|
};
|
|
204
|
-
var FrontmatterSchema =
|
|
205
|
-
created:
|
|
206
|
-
updated:
|
|
207
|
-
status:
|
|
208
|
-
topic:
|
|
209
|
-
tags:
|
|
210
|
-
summary:
|
|
211
|
-
entities:
|
|
212
|
-
relationships:
|
|
242
|
+
var FrontmatterSchema = z.object({
|
|
243
|
+
created: z.string().refine(validateDateFormat, "Date must be in YYYY-MM-DD format"),
|
|
244
|
+
updated: z.string().refine(validateDateFormat, "Date must be in YYYY-MM-DD format"),
|
|
245
|
+
status: z.enum(["draft", "ongoing", "complete"]).optional(),
|
|
246
|
+
topic: z.string().optional(),
|
|
247
|
+
tags: z.array(z.string()).optional(),
|
|
248
|
+
summary: z.string().optional(),
|
|
249
|
+
entities: z.array(EntitySchema).optional(),
|
|
250
|
+
relationships: z.array(RelationshipSchema).optional(),
|
|
213
251
|
graph: GraphMetadataSchema.optional()
|
|
214
252
|
}).passthrough();
|
|
215
253
|
function parseFrontmatter(content) {
|
|
@@ -256,15 +294,8 @@ class DocumentParserService {
|
|
|
256
294
|
logger = new Logger(DocumentParserService.name);
|
|
257
295
|
docsPath;
|
|
258
296
|
constructor() {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
docsPath: process.env.DOCS_PATH
|
|
262
|
-
});
|
|
263
|
-
if (config.docsPath.startsWith("/")) {
|
|
264
|
-
this.docsPath = config.docsPath;
|
|
265
|
-
} else {
|
|
266
|
-
this.docsPath = resolve2(config.projectRoot, config.docsPath);
|
|
267
|
-
}
|
|
297
|
+
ensureLatticeHome();
|
|
298
|
+
this.docsPath = getDocsPath();
|
|
268
299
|
}
|
|
269
300
|
getDocsPath() {
|
|
270
301
|
return this.docsPath;
|
|
@@ -542,6 +573,18 @@ import { Command as Command3, CommandRunner as CommandRunner3, Option as Option2
|
|
|
542
573
|
import { Injectable as Injectable5, Logger as Logger2 } from "@nestjs/common";
|
|
543
574
|
import { ConfigService } from "@nestjs/config";
|
|
544
575
|
|
|
576
|
+
// src/schemas/config.schemas.ts
|
|
577
|
+
import { z as z2 } from "zod";
|
|
578
|
+
var DuckDBConfigSchema = z2.object({
|
|
579
|
+
embeddingDimensions: z2.coerce.number().int().positive().default(512)
|
|
580
|
+
});
|
|
581
|
+
var EmbeddingConfigSchema = z2.object({
|
|
582
|
+
provider: z2.enum(["openai", "voyage", "nomic", "mock"]).default("voyage"),
|
|
583
|
+
apiKey: z2.string().optional(),
|
|
584
|
+
model: z2.string().min(1).default("voyage-3.5-lite"),
|
|
585
|
+
dimensions: z2.coerce.number().int().positive().default(512)
|
|
586
|
+
});
|
|
587
|
+
|
|
545
588
|
// src/embedding/embedding.types.ts
|
|
546
589
|
var DEFAULT_EMBEDDING_CONFIG = {
|
|
547
590
|
provider: "voyage",
|
|
@@ -803,7 +846,8 @@ class GraphService {
|
|
|
803
846
|
embeddingDimensions;
|
|
804
847
|
constructor(configService) {
|
|
805
848
|
this.configService = configService;
|
|
806
|
-
|
|
849
|
+
ensureLatticeHome();
|
|
850
|
+
this.dbPath = getDatabasePath();
|
|
807
851
|
this.embeddingDimensions = this.configService.get("EMBEDDING_DIMENSIONS") || 512;
|
|
808
852
|
}
|
|
809
853
|
async onModuleDestroy() {
|
|
@@ -1329,9 +1373,8 @@ import { Command as Command4, CommandRunner as CommandRunner4, Option as Option3
|
|
|
1329
1373
|
|
|
1330
1374
|
// src/sync/manifest.service.ts
|
|
1331
1375
|
import { createHash as createHash2 } from "crypto";
|
|
1332
|
-
import { existsSync } from "fs";
|
|
1376
|
+
import { existsSync as existsSync3 } from "fs";
|
|
1333
1377
|
import { readFile as readFile3, writeFile } from "fs/promises";
|
|
1334
|
-
import { resolve as resolve3 } from "path";
|
|
1335
1378
|
import { Injectable as Injectable8 } from "@nestjs/common";
|
|
1336
1379
|
|
|
1337
1380
|
// src/schemas/manifest.schemas.ts
|
|
@@ -1350,23 +1393,15 @@ var SyncManifestSchema = z4.object({
|
|
|
1350
1393
|
});
|
|
1351
1394
|
|
|
1352
1395
|
// src/sync/manifest.service.ts
|
|
1353
|
-
function getProjectRoot() {
|
|
1354
|
-
if (process.env.PROJECT_ROOT) {
|
|
1355
|
-
return process.env.PROJECT_ROOT;
|
|
1356
|
-
}
|
|
1357
|
-
return process.cwd();
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
1396
|
class ManifestService {
|
|
1361
1397
|
manifestPath;
|
|
1362
1398
|
manifest = null;
|
|
1363
1399
|
constructor() {
|
|
1364
|
-
|
|
1365
|
-
this.manifestPath = resolve3(getProjectRoot(), docsPath, ".sync-manifest.json");
|
|
1400
|
+
this.manifestPath = getManifestPath();
|
|
1366
1401
|
}
|
|
1367
1402
|
async load() {
|
|
1368
1403
|
try {
|
|
1369
|
-
if (
|
|
1404
|
+
if (existsSync3(this.manifestPath)) {
|
|
1370
1405
|
const content = await readFile3(this.manifestPath, "utf-8");
|
|
1371
1406
|
this.manifest = SyncManifestSchema.parse(JSON.parse(content));
|
|
1372
1407
|
} else {
|
|
@@ -1852,16 +1887,16 @@ CascadeService = __legacyDecorateClassTS([
|
|
|
1852
1887
|
], CascadeService);
|
|
1853
1888
|
|
|
1854
1889
|
// src/sync/path-resolver.service.ts
|
|
1855
|
-
import { existsSync as
|
|
1856
|
-
import { isAbsolute, resolve as
|
|
1890
|
+
import { existsSync as existsSync4 } from "fs";
|
|
1891
|
+
import { isAbsolute, resolve as resolve2 } from "path";
|
|
1857
1892
|
import { Injectable as Injectable10 } from "@nestjs/common";
|
|
1858
1893
|
class PathResolverService {
|
|
1859
|
-
|
|
1860
|
-
constructor(
|
|
1861
|
-
this.
|
|
1894
|
+
docsPath;
|
|
1895
|
+
constructor() {
|
|
1896
|
+
this.docsPath = getDocsPath();
|
|
1862
1897
|
}
|
|
1863
1898
|
getDocsPath() {
|
|
1864
|
-
return this.
|
|
1899
|
+
return this.docsPath;
|
|
1865
1900
|
}
|
|
1866
1901
|
resolveDocPath(userPath, options = {}) {
|
|
1867
1902
|
const { requireExists = true, requireInDocs = true } = options;
|
|
@@ -1869,28 +1904,12 @@ class PathResolverService {
|
|
|
1869
1904
|
if (isAbsolute(userPath)) {
|
|
1870
1905
|
resolvedPath = userPath;
|
|
1871
1906
|
} else {
|
|
1872
|
-
|
|
1873
|
-
const fromDocs = resolve4(this.getDocsPath(), userPath);
|
|
1874
|
-
const docsPrefix = "docs/";
|
|
1875
|
-
const strippedFromDocs = userPath.startsWith(docsPrefix) ? resolve4(this.getDocsPath(), userPath.slice(docsPrefix.length)) : null;
|
|
1876
|
-
if (this.isUnderDocs(fromCwd) && existsSync2(fromCwd)) {
|
|
1877
|
-
resolvedPath = fromCwd;
|
|
1878
|
-
} else if (strippedFromDocs && existsSync2(strippedFromDocs)) {
|
|
1879
|
-
resolvedPath = strippedFromDocs;
|
|
1880
|
-
} else if (existsSync2(fromDocs)) {
|
|
1881
|
-
resolvedPath = fromDocs;
|
|
1882
|
-
} else if (this.isUnderDocs(fromCwd)) {
|
|
1883
|
-
resolvedPath = fromCwd;
|
|
1884
|
-
} else if (strippedFromDocs) {
|
|
1885
|
-
resolvedPath = strippedFromDocs;
|
|
1886
|
-
} else {
|
|
1887
|
-
resolvedPath = fromDocs;
|
|
1888
|
-
}
|
|
1907
|
+
resolvedPath = resolve2(this.docsPath, userPath);
|
|
1889
1908
|
}
|
|
1890
1909
|
if (requireInDocs && !this.isUnderDocs(resolvedPath)) {
|
|
1891
|
-
throw new Error(`Path "${userPath}" resolves to "${resolvedPath}" which is outside the docs directory (${this.
|
|
1910
|
+
throw new Error(`Path "${userPath}" resolves to "${resolvedPath}" which is outside the docs directory (${this.docsPath})`);
|
|
1892
1911
|
}
|
|
1893
|
-
if (requireExists && !
|
|
1912
|
+
if (requireExists && !existsSync4(resolvedPath)) {
|
|
1894
1913
|
throw new Error(`Path "${userPath}" does not exist (resolved to: ${resolvedPath})`);
|
|
1895
1914
|
}
|
|
1896
1915
|
return resolvedPath;
|
|
@@ -1914,9 +1933,7 @@ class PathResolverService {
|
|
|
1914
1933
|
}
|
|
1915
1934
|
PathResolverService = __legacyDecorateClassTS([
|
|
1916
1935
|
Injectable10(),
|
|
1917
|
-
__legacyMetadataTS("design:paramtypes", [
|
|
1918
|
-
typeof DocumentParserService === "undefined" ? Object : DocumentParserService
|
|
1919
|
-
])
|
|
1936
|
+
__legacyMetadataTS("design:paramtypes", [])
|
|
1920
1937
|
], PathResolverService);
|
|
1921
1938
|
|
|
1922
1939
|
// src/sync/sync.service.ts
|
|
@@ -2419,7 +2436,7 @@ StatusCommand = __legacyDecorateClassTS([
|
|
|
2419
2436
|
], StatusCommand);
|
|
2420
2437
|
// src/commands/sync.command.ts
|
|
2421
2438
|
import { watch } from "fs";
|
|
2422
|
-
import { join as
|
|
2439
|
+
import { join as join3 } from "path";
|
|
2423
2440
|
import { Injectable as Injectable13 } from "@nestjs/common";
|
|
2424
2441
|
import { Command as Command5, CommandRunner as CommandRunner5, Option as Option4 } from "nest-commander";
|
|
2425
2442
|
class SyncCommand extends CommandRunner5 {
|
|
@@ -2545,7 +2562,7 @@ class SyncCommand extends CommandRunner5 {
|
|
|
2545
2562
|
`);
|
|
2546
2563
|
this.watcher = watch(docsPath, { recursive: true }, (event, filename) => {
|
|
2547
2564
|
if (filename?.endsWith(".md")) {
|
|
2548
|
-
const fullPath =
|
|
2565
|
+
const fullPath = join3(docsPath, filename);
|
|
2549
2566
|
trackedFiles.add(fullPath);
|
|
2550
2567
|
debouncedSync();
|
|
2551
2568
|
}
|
|
@@ -2920,7 +2937,8 @@ AppModule = __legacyDecorateClassTS([
|
|
|
2920
2937
|
Module5({
|
|
2921
2938
|
imports: [
|
|
2922
2939
|
ConfigModule2.forRoot({
|
|
2923
|
-
isGlobal: true
|
|
2940
|
+
isGlobal: true,
|
|
2941
|
+
envFilePath: getEnvPath()
|
|
2924
2942
|
}),
|
|
2925
2943
|
GraphModule,
|
|
2926
2944
|
SyncModule,
|