@zabaca/lattice 1.0.23 → 1.1.1

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/dist/main.js CHANGED
@@ -406,95 +406,172 @@ function ensureLatticeHome() {
406
406
  var __filename2 = fileURLToPath(import.meta.url);
407
407
  var __dirname2 = path.dirname(__filename2);
408
408
  var COMMANDS = ["research.md", "graph-sync.md", "entity-extract.md"];
409
+ var SITE_TEMPLATE_FILES = [
410
+ "astro.config.ts",
411
+ "package.json",
412
+ "tsconfig.json",
413
+ "src/content.config.ts",
414
+ "src/collections/authors.ts",
415
+ "src/collections/documents.ts",
416
+ "src/collections/tags.ts"
417
+ ];
409
418
 
410
419
  class InitCommand extends CommandRunner2 {
411
420
  async run(_inputs, _options) {
412
421
  try {
413
422
  ensureLatticeHome();
423
+ const latticeHome = getLatticeHome();
414
424
  const envPath = getEnvPath();
415
425
  if (!existsSync3(envPath)) {
416
426
  writeFileSync(envPath, `# Lattice Configuration
417
427
  # Get your API key from: https://www.voyageai.com/
418
-
419
428
  VOYAGE_API_KEY=
429
+
430
+ # Site Configuration (for lattice site command)
431
+ SPACESHIP_AUTHOR="Lattice"
432
+ SPACESHIP_BASE="/"
433
+ SPACESHIP_SITE="https://example.com"
434
+ SPACESHIP_TITLE="Lattice"
435
+ SPACESHIP_DESCRIPTION="Research Knowledge Base"
436
+ OBSIDIAN_VAULT_DIR=docs
437
+ `);
438
+ } else {
439
+ const envContent = await fs.readFile(envPath, "utf-8");
440
+ if (!envContent.includes("SPACESHIP_")) {
441
+ await fs.appendFile(envPath, `
442
+ # Site Configuration (for lattice site command)
443
+ SPACESHIP_AUTHOR="Lattice"
444
+ SPACESHIP_BASE="/"
445
+ SPACESHIP_SITE="https://example.com"
446
+ SPACESHIP_TITLE="Lattice"
447
+ SPACESHIP_DESCRIPTION="Research Knowledge Base"
448
+ OBSIDIAN_VAULT_DIR=docs
420
449
  `);
450
+ console.log("\u2705 Added site configuration to .env");
451
+ }
421
452
  }
422
- console.log(`\u2705 Lattice home directory: ${getLatticeHome()}`);
453
+ console.log(`\u2705 Lattice home directory: ${latticeHome}`);
423
454
  console.log(` Documents: ${getDocsPath()}`);
424
455
  console.log(` Config: ${envPath}`);
425
456
  console.log();
426
- const targetDir = path.join(homedir2(), ".claude", "commands");
427
- let commandsSourceDir = path.resolve(__dirname2, "..", "commands");
428
- try {
429
- await fs.access(commandsSourceDir);
430
- } catch {
431
- commandsSourceDir = path.resolve(__dirname2, "..", "..", "commands");
432
- }
433
- try {
434
- await fs.access(commandsSourceDir);
435
- } catch {
436
- console.error("Error: Commands source directory not found at", commandsSourceDir);
437
- console.error("This may indicate a corrupted installation. Try reinstalling @zabaca/lattice.");
438
- process.exit(1);
439
- }
440
- await fs.mkdir(targetDir, { recursive: true });
441
- let copied = 0;
442
- let skipped = 0;
443
- const installed = [];
444
- for (const file of COMMANDS) {
445
- const sourcePath = path.join(commandsSourceDir, file);
446
- const targetPath = path.join(targetDir, file);
447
- try {
448
- await fs.access(sourcePath);
449
- try {
450
- await fs.access(targetPath);
451
- const sourceContent = await fs.readFile(sourcePath, "utf-8");
452
- const targetContent = await fs.readFile(targetPath, "utf-8");
453
- if (sourceContent === targetContent) {
454
- skipped++;
455
- continue;
456
- }
457
- } catch {}
458
- await fs.copyFile(sourcePath, targetPath);
459
- installed.push(file);
460
- copied++;
461
- } catch (err) {
462
- console.error(`Warning: Could not copy ${file}:`, err instanceof Error ? err.message : String(err));
463
- }
464
- }
465
- console.log();
466
- console.log(`\u2705 Lattice commands installed to ${targetDir}`);
457
+ await this.setupSiteTemplate(latticeHome);
458
+ await this.installClaudeCommands();
467
459
  console.log();
468
- if (copied > 0) {
469
- console.log(`Installed ${copied} command(s):`);
470
- installed.forEach((f) => {
471
- const name = f.replace(".md", "");
472
- console.log(` - /${name}`);
473
- });
474
- }
475
- if (skipped > 0) {
476
- console.log(`Skipped ${skipped} unchanged command(s)`);
477
- }
460
+ console.log("Available commands:");
461
+ console.log(" lattice site - Build and run the documentation site");
462
+ console.log(" lattice sync - Sync documents to knowledge graph");
463
+ console.log(" lattice status - Show documents needing sync");
464
+ console.log(" lattice search - Semantic search across documents");
478
465
  console.log();
479
- console.log("Available commands in Claude Code:");
466
+ console.log("Claude Code slash commands:");
480
467
  console.log(" /research <topic> - AI-assisted research workflow");
481
468
  console.log(" /graph-sync - Extract entities and sync to graph");
482
- console.log(" /entity-extract - Extract entities from a single document");
483
- console.log();
484
- console.log(`\u26A0\uFE0F Add your Voyage API key to: ${getEnvPath()}`);
469
+ console.log(" /entity-extract - Extract entities from a document");
485
470
  console.log();
471
+ if (!(await fs.readFile(envPath, "utf-8")).includes("pa-")) {
472
+ console.log(`\u26A0\uFE0F Add your Voyage API key to: ${envPath}`);
473
+ console.log();
474
+ }
486
475
  process.exit(0);
487
476
  } catch (error) {
488
477
  console.error("Error:", error instanceof Error ? error.message : String(error));
489
478
  process.exit(1);
490
479
  }
491
480
  }
481
+ async setupSiteTemplate(latticeHome) {
482
+ let templateDir = path.resolve(__dirname2, "..", "site-template");
483
+ try {
484
+ await fs.access(templateDir);
485
+ } catch {
486
+ templateDir = path.resolve(__dirname2, "..", "..", "site-template");
487
+ }
488
+ try {
489
+ await fs.access(templateDir);
490
+ } catch {
491
+ console.log("\u26A0\uFE0F Site template not found - skipping site setup");
492
+ return;
493
+ }
494
+ await fs.mkdir(path.join(latticeHome, "src", "collections"), {
495
+ recursive: true
496
+ });
497
+ let copied = 0;
498
+ let skipped = 0;
499
+ for (const file of SITE_TEMPLATE_FILES) {
500
+ const sourcePath = path.join(templateDir, file);
501
+ const targetPath = path.join(latticeHome, file);
502
+ try {
503
+ await fs.access(sourcePath);
504
+ try {
505
+ await fs.access(targetPath);
506
+ const sourceContent = await fs.readFile(sourcePath, "utf-8");
507
+ const targetContent = await fs.readFile(targetPath, "utf-8");
508
+ if (sourceContent === targetContent) {
509
+ skipped++;
510
+ continue;
511
+ }
512
+ } catch {}
513
+ await fs.mkdir(path.dirname(targetPath), { recursive: true });
514
+ await fs.copyFile(sourcePath, targetPath);
515
+ copied++;
516
+ } catch (err) {}
517
+ }
518
+ if (copied > 0) {
519
+ console.log(`\u2705 Site template: ${copied} file(s) installed`);
520
+ }
521
+ if (skipped > 0) {
522
+ console.log(` Site template: ${skipped} file(s) unchanged`);
523
+ }
524
+ }
525
+ async installClaudeCommands() {
526
+ const targetDir = path.join(homedir2(), ".claude", "commands");
527
+ let commandsSourceDir = path.resolve(__dirname2, "..", "commands");
528
+ try {
529
+ await fs.access(commandsSourceDir);
530
+ } catch {
531
+ commandsSourceDir = path.resolve(__dirname2, "..", "..", "commands");
532
+ }
533
+ try {
534
+ await fs.access(commandsSourceDir);
535
+ } catch {
536
+ console.log("\u26A0\uFE0F Claude commands not found - skipping");
537
+ return;
538
+ }
539
+ await fs.mkdir(targetDir, { recursive: true });
540
+ let copied = 0;
541
+ let skipped = 0;
542
+ const installed = [];
543
+ for (const file of COMMANDS) {
544
+ const sourcePath = path.join(commandsSourceDir, file);
545
+ const targetPath = path.join(targetDir, file);
546
+ try {
547
+ await fs.access(sourcePath);
548
+ try {
549
+ await fs.access(targetPath);
550
+ const sourceContent = await fs.readFile(sourcePath, "utf-8");
551
+ const targetContent = await fs.readFile(targetPath, "utf-8");
552
+ if (sourceContent === targetContent) {
553
+ skipped++;
554
+ continue;
555
+ }
556
+ } catch {}
557
+ await fs.copyFile(sourcePath, targetPath);
558
+ installed.push(file);
559
+ copied++;
560
+ } catch (err) {}
561
+ }
562
+ if (copied > 0) {
563
+ console.log(`\u2705 Claude commands: ${copied} installed to ${targetDir}`);
564
+ }
565
+ if (skipped > 0) {
566
+ console.log(` Claude commands: ${skipped} unchanged`);
567
+ }
568
+ }
492
569
  }
493
570
  InitCommand = __legacyDecorateClassTS([
494
571
  Injectable3(),
495
572
  Command2({
496
573
  name: "init",
497
- description: "Install Claude Code slash commands for Lattice"
574
+ description: "Initialize Lattice with Claude Code commands and site generator"
498
575
  })
499
576
  ], InitCommand);
500
577
  // src/commands/migrate.command.ts
@@ -3120,10 +3197,214 @@ SqlCommand = __legacyDecorateClassTS([
3120
3197
  typeof GraphService === "undefined" ? Object : GraphService
3121
3198
  ])
3122
3199
  ], SqlCommand);
3123
- // src/commands/status.command.ts
3200
+ // src/commands/site.command.ts
3201
+ import { spawn } from "child_process";
3202
+ import { existsSync as existsSync6, readFileSync as readFileSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
3203
+ import * as path2 from "path";
3124
3204
  import { Injectable as Injectable16 } from "@nestjs/common";
3125
3205
  import { Command as Command6, CommandRunner as CommandRunner6, Option as Option4 } from "nest-commander";
3126
- class StatusCommand extends CommandRunner6 {
3206
+ class SiteCommand extends CommandRunner6 {
3207
+ getPidFile() {
3208
+ return path2.join(getLatticeHome(), "site.pid");
3209
+ }
3210
+ async run(_inputs, options) {
3211
+ if (options.kill) {
3212
+ this.killSiteProcess();
3213
+ process.exit(0);
3214
+ }
3215
+ const latticeHome = getLatticeHome();
3216
+ const packageJsonPath = path2.join(latticeHome, "package.json");
3217
+ const nodeModulesPath = path2.join(latticeHome, "node_modules");
3218
+ if (!existsSync6(packageJsonPath)) {
3219
+ console.error("Error: Site not initialized. Run 'lattice init' first.");
3220
+ process.exit(1);
3221
+ }
3222
+ if (this.isRunning()) {
3223
+ console.error("Error: A Lattice site is already running.");
3224
+ console.error("Use 'lattice site --kill' to stop it first.");
3225
+ process.exit(1);
3226
+ }
3227
+ if (!existsSync6(nodeModulesPath)) {
3228
+ console.log("\uD83D\uDCE6 Installing dependencies...");
3229
+ await this.runCommand("bun", ["install"], latticeHome);
3230
+ console.log();
3231
+ }
3232
+ if (options.build) {
3233
+ console.log("\uD83D\uDD28 Building site...");
3234
+ await this.runCommand("bun", ["run", "build"], latticeHome);
3235
+ console.log(`
3236
+ \u2705 Build complete! Output in: ~/.lattice/dist/`);
3237
+ process.exit(0);
3238
+ }
3239
+ if (options.dev) {
3240
+ console.log("\uD83D\uDE80 Starting dev server...");
3241
+ const port2 = options.port || "4321";
3242
+ await this.runServerCommand("bun", ["run", "dev", "--", "--port", port2], latticeHome);
3243
+ process.exit(0);
3244
+ }
3245
+ console.log("\uD83D\uDD28 Building site with search index...");
3246
+ await this.runCommand("bun", ["run", "build"], latticeHome);
3247
+ console.log(`
3248
+ \uD83D\uDE80 Starting preview server...`);
3249
+ const port = options.port || "4321";
3250
+ await this.runServerCommand("bun", ["run", "preview", "--", "--port", port], latticeHome);
3251
+ }
3252
+ runCommand(cmd, args, cwd) {
3253
+ return new Promise((resolve4, reject) => {
3254
+ const child = spawn(cmd, args, {
3255
+ cwd,
3256
+ stdio: "pipe",
3257
+ env: { ...process.env, FORCE_COLOR: "1" }
3258
+ });
3259
+ child.stdout?.on("data", (data) => {
3260
+ process.stdout.write(data);
3261
+ });
3262
+ child.stderr?.on("data", (data) => {
3263
+ process.stderr.write(data);
3264
+ });
3265
+ child.on("close", (code) => {
3266
+ if (code === 0) {
3267
+ resolve4();
3268
+ } else {
3269
+ reject(new Error(`Command failed with code ${code}`));
3270
+ }
3271
+ });
3272
+ child.on("error", (err) => {
3273
+ reject(err);
3274
+ });
3275
+ });
3276
+ }
3277
+ runServerCommand(cmd, args, cwd) {
3278
+ return new Promise((resolve4, reject) => {
3279
+ const child = spawn(cmd, args, {
3280
+ cwd,
3281
+ stdio: "inherit",
3282
+ env: { ...process.env, FORCE_COLOR: "1" }
3283
+ });
3284
+ if (child.pid) {
3285
+ writeFileSync2(this.getPidFile(), String(child.pid));
3286
+ }
3287
+ const cleanup = () => {
3288
+ try {
3289
+ unlinkSync(this.getPidFile());
3290
+ } catch {}
3291
+ };
3292
+ child.on("close", (code) => {
3293
+ cleanup();
3294
+ if (code === 0) {
3295
+ resolve4();
3296
+ } else {
3297
+ reject(new Error(`Command failed with code ${code}`));
3298
+ }
3299
+ });
3300
+ child.on("error", (err) => {
3301
+ cleanup();
3302
+ reject(err);
3303
+ });
3304
+ process.on("SIGINT", cleanup);
3305
+ process.on("SIGTERM", cleanup);
3306
+ });
3307
+ }
3308
+ isRunning() {
3309
+ const pidFile = this.getPidFile();
3310
+ if (!existsSync6(pidFile)) {
3311
+ return false;
3312
+ }
3313
+ try {
3314
+ const pid = parseInt(readFileSync2(pidFile, "utf-8").trim(), 10);
3315
+ process.kill(pid, 0);
3316
+ return true;
3317
+ } catch {
3318
+ try {
3319
+ unlinkSync(pidFile);
3320
+ } catch {}
3321
+ return false;
3322
+ }
3323
+ }
3324
+ killSiteProcess() {
3325
+ const pidFile = this.getPidFile();
3326
+ if (!existsSync6(pidFile)) {
3327
+ console.log("No Lattice site process running");
3328
+ return;
3329
+ }
3330
+ try {
3331
+ const pid = parseInt(readFileSync2(pidFile, "utf-8").trim(), 10);
3332
+ try {
3333
+ process.kill(-pid, "SIGTERM");
3334
+ } catch {
3335
+ process.kill(pid, "SIGTERM");
3336
+ }
3337
+ unlinkSync(pidFile);
3338
+ console.log(`\u2705 Killed Lattice site process (PID: ${pid})`);
3339
+ } catch (err) {
3340
+ try {
3341
+ unlinkSync(pidFile);
3342
+ } catch {}
3343
+ console.log("No Lattice site process running");
3344
+ }
3345
+ }
3346
+ parseBuild() {
3347
+ return true;
3348
+ }
3349
+ parseDev() {
3350
+ return true;
3351
+ }
3352
+ parsePort(val) {
3353
+ return val;
3354
+ }
3355
+ parseKill() {
3356
+ return true;
3357
+ }
3358
+ }
3359
+ __legacyDecorateClassTS([
3360
+ Option4({
3361
+ flags: "-b, --build",
3362
+ description: "Build the site without starting the server"
3363
+ }),
3364
+ __legacyMetadataTS("design:type", Function),
3365
+ __legacyMetadataTS("design:paramtypes", []),
3366
+ __legacyMetadataTS("design:returntype", Boolean)
3367
+ ], SiteCommand.prototype, "parseBuild", null);
3368
+ __legacyDecorateClassTS([
3369
+ Option4({
3370
+ flags: "-d, --dev",
3371
+ description: "Run in development mode (hot reload, no search)"
3372
+ }),
3373
+ __legacyMetadataTS("design:type", Function),
3374
+ __legacyMetadataTS("design:paramtypes", []),
3375
+ __legacyMetadataTS("design:returntype", Boolean)
3376
+ ], SiteCommand.prototype, "parseDev", null);
3377
+ __legacyDecorateClassTS([
3378
+ Option4({
3379
+ flags: "-p, --port <port>",
3380
+ description: "Port to run the server on (default: 4321)"
3381
+ }),
3382
+ __legacyMetadataTS("design:type", Function),
3383
+ __legacyMetadataTS("design:paramtypes", [
3384
+ String
3385
+ ]),
3386
+ __legacyMetadataTS("design:returntype", String)
3387
+ ], SiteCommand.prototype, "parsePort", null);
3388
+ __legacyDecorateClassTS([
3389
+ Option4({
3390
+ flags: "-k, --kill",
3391
+ description: "Kill the running Lattice site process"
3392
+ }),
3393
+ __legacyMetadataTS("design:type", Function),
3394
+ __legacyMetadataTS("design:paramtypes", []),
3395
+ __legacyMetadataTS("design:returntype", Boolean)
3396
+ ], SiteCommand.prototype, "parseKill", null);
3397
+ SiteCommand = __legacyDecorateClassTS([
3398
+ Injectable16(),
3399
+ Command6({
3400
+ name: "site",
3401
+ description: "Build and run the Lattice documentation site"
3402
+ })
3403
+ ], SiteCommand);
3404
+ // src/commands/status.command.ts
3405
+ import { Injectable as Injectable17 } from "@nestjs/common";
3406
+ import { Command as Command7, CommandRunner as CommandRunner7, Option as Option5 } from "nest-commander";
3407
+ class StatusCommand extends CommandRunner7 {
3127
3408
  syncService;
3128
3409
  dbChangeDetector;
3129
3410
  constructor(syncService, dbChangeDetector) {
@@ -3189,7 +3470,7 @@ class StatusCommand extends CommandRunner6 {
3189
3470
  }
3190
3471
  }
3191
3472
  __legacyDecorateClassTS([
3192
- Option4({
3473
+ Option5({
3193
3474
  flags: "-v, --verbose",
3194
3475
  description: "Show all documents including unchanged"
3195
3476
  }),
@@ -3198,8 +3479,8 @@ __legacyDecorateClassTS([
3198
3479
  __legacyMetadataTS("design:returntype", Boolean)
3199
3480
  ], StatusCommand.prototype, "parseVerbose", null);
3200
3481
  StatusCommand = __legacyDecorateClassTS([
3201
- Injectable16(),
3202
- Command6({
3482
+ Injectable17(),
3483
+ Command7({
3203
3484
  name: "status",
3204
3485
  description: "Show documents that need syncing (new or updated)"
3205
3486
  }),
@@ -3210,12 +3491,12 @@ StatusCommand = __legacyDecorateClassTS([
3210
3491
  ], StatusCommand);
3211
3492
  // src/commands/sync.command.ts
3212
3493
  import { watch } from "fs";
3213
- import { join as join3 } from "path";
3214
- import { Injectable as Injectable18 } from "@nestjs/common";
3215
- import { Command as Command7, CommandRunner as CommandRunner7, Option as Option5 } from "nest-commander";
3494
+ import { join as join4 } from "path";
3495
+ import { Injectable as Injectable19 } from "@nestjs/common";
3496
+ import { Command as Command8, CommandRunner as CommandRunner8, Option as Option6 } from "nest-commander";
3216
3497
 
3217
3498
  // src/sync/graph-validator.service.ts
3218
- import { Injectable as Injectable17, Logger as Logger9 } from "@nestjs/common";
3499
+ import { Injectable as Injectable18, Logger as Logger9 } from "@nestjs/common";
3219
3500
  class GraphValidatorService {
3220
3501
  graph;
3221
3502
  logger = new Logger9(GraphValidatorService.name);
@@ -3334,15 +3615,15 @@ class GraphValidatorService {
3334
3615
  });
3335
3616
  }
3336
3617
  }
3337
- async validateDocument(path2) {
3618
+ async validateDocument(path3) {
3338
3619
  const issues = [];
3339
3620
  try {
3340
- const result = await this.graph.query(`SELECT label, name, properties FROM nodes WHERE label = 'Document' AND name = '${this.escape(path2)}'`);
3621
+ const result = await this.graph.query(`SELECT label, name, properties FROM nodes WHERE label = 'Document' AND name = '${this.escape(path3)}'`);
3341
3622
  if (result.resultSet.length === 0) {
3342
3623
  issues.push({
3343
3624
  type: "error",
3344
3625
  nodeLabel: "Document",
3345
- nodeName: path2,
3626
+ nodeName: path3,
3346
3627
  field: "node",
3347
3628
  message: "Document not found in graph",
3348
3629
  suggestion: "Run 'lattice sync' to add this document"
@@ -3352,9 +3633,9 @@ class GraphValidatorService {
3352
3633
  const row = result.resultSet[0];
3353
3634
  const propertiesJson = row[2];
3354
3635
  const properties = typeof propertiesJson === "string" ? JSON.parse(propertiesJson) : propertiesJson;
3355
- this.validateDocumentNode(path2, properties, issues);
3636
+ this.validateDocumentNode(path3, properties, issues);
3356
3637
  } catch (error) {
3357
- this.logger.error(`Failed to validate document ${path2}: ${error instanceof Error ? error.message : String(error)}`);
3638
+ this.logger.error(`Failed to validate document ${path3}: ${error instanceof Error ? error.message : String(error)}`);
3358
3639
  throw error;
3359
3640
  }
3360
3641
  return issues;
@@ -3364,14 +3645,14 @@ class GraphValidatorService {
3364
3645
  }
3365
3646
  }
3366
3647
  GraphValidatorService = __legacyDecorateClassTS([
3367
- Injectable17(),
3648
+ Injectable18(),
3368
3649
  __legacyMetadataTS("design:paramtypes", [
3369
3650
  typeof GraphService === "undefined" ? Object : GraphService
3370
3651
  ])
3371
3652
  ], GraphValidatorService);
3372
3653
 
3373
3654
  // src/commands/sync.command.ts
3374
- class SyncCommand extends CommandRunner7 {
3655
+ class SyncCommand extends CommandRunner8 {
3375
3656
  syncService;
3376
3657
  graphService;
3377
3658
  _graphValidator;
@@ -3514,7 +3795,7 @@ class SyncCommand extends CommandRunner7 {
3514
3795
  `);
3515
3796
  this.watcher = watch(docsPath, { recursive: true }, (event, filename) => {
3516
3797
  if (filename?.endsWith(".md")) {
3517
- const fullPath = join3(docsPath, filename);
3798
+ const fullPath = join4(docsPath, filename);
3518
3799
  trackedFiles.add(fullPath);
3519
3800
  debouncedSync();
3520
3801
  }
@@ -3644,7 +3925,7 @@ class SyncCommand extends CommandRunner7 {
3644
3925
  }
3645
3926
  }
3646
3927
  __legacyDecorateClassTS([
3647
- Option5({
3928
+ Option6({
3648
3929
  flags: "-f, --force",
3649
3930
  description: "Force re-sync specified documents (requires paths to be specified)"
3650
3931
  }),
@@ -3653,7 +3934,7 @@ __legacyDecorateClassTS([
3653
3934
  __legacyMetadataTS("design:returntype", Boolean)
3654
3935
  ], SyncCommand.prototype, "parseForce", null);
3655
3936
  __legacyDecorateClassTS([
3656
- Option5({
3937
+ Option6({
3657
3938
  flags: "-d, --dry-run",
3658
3939
  description: "Show what would change without applying"
3659
3940
  }),
@@ -3662,7 +3943,7 @@ __legacyDecorateClassTS([
3662
3943
  __legacyMetadataTS("design:returntype", Boolean)
3663
3944
  ], SyncCommand.prototype, "parseDryRun", null);
3664
3945
  __legacyDecorateClassTS([
3665
- Option5({
3946
+ Option6({
3666
3947
  flags: "-v, --verbose",
3667
3948
  description: "Show detailed output"
3668
3949
  }),
@@ -3671,7 +3952,7 @@ __legacyDecorateClassTS([
3671
3952
  __legacyMetadataTS("design:returntype", Boolean)
3672
3953
  ], SyncCommand.prototype, "parseVerbose", null);
3673
3954
  __legacyDecorateClassTS([
3674
- Option5({
3955
+ Option6({
3675
3956
  flags: "-w, --watch",
3676
3957
  description: "Watch for file changes and sync automatically"
3677
3958
  }),
@@ -3680,7 +3961,7 @@ __legacyDecorateClassTS([
3680
3961
  __legacyMetadataTS("design:returntype", Boolean)
3681
3962
  ], SyncCommand.prototype, "parseWatch", null);
3682
3963
  __legacyDecorateClassTS([
3683
- Option5({
3964
+ Option6({
3684
3965
  flags: "--diff",
3685
3966
  description: "Show only changed documents (alias for --dry-run)"
3686
3967
  }),
@@ -3689,7 +3970,7 @@ __legacyDecorateClassTS([
3689
3970
  __legacyMetadataTS("design:returntype", Boolean)
3690
3971
  ], SyncCommand.prototype, "parseDiff", null);
3691
3972
  __legacyDecorateClassTS([
3692
- Option5({
3973
+ Option6({
3693
3974
  flags: "--skip-cascade",
3694
3975
  description: "Skip cascade analysis (faster for large repos)"
3695
3976
  }),
@@ -3698,7 +3979,7 @@ __legacyDecorateClassTS([
3698
3979
  __legacyMetadataTS("design:returntype", Boolean)
3699
3980
  ], SyncCommand.prototype, "parseSkipCascade", null);
3700
3981
  __legacyDecorateClassTS([
3701
- Option5({
3982
+ Option6({
3702
3983
  flags: "--no-embeddings",
3703
3984
  description: "Disable embedding generation during sync"
3704
3985
  }),
@@ -3707,7 +3988,7 @@ __legacyDecorateClassTS([
3707
3988
  __legacyMetadataTS("design:returntype", Boolean)
3708
3989
  ], SyncCommand.prototype, "parseNoEmbeddings", null);
3709
3990
  __legacyDecorateClassTS([
3710
- Option5({
3991
+ Option6({
3711
3992
  flags: "--skip-extraction",
3712
3993
  description: "Skip AI entity extraction (sync without re-extracting entities)"
3713
3994
  }),
@@ -3716,8 +3997,8 @@ __legacyDecorateClassTS([
3716
3997
  __legacyMetadataTS("design:returntype", Boolean)
3717
3998
  ], SyncCommand.prototype, "parseSkipExtraction", null);
3718
3999
  SyncCommand = __legacyDecorateClassTS([
3719
- Injectable18(),
3720
- Command7({
4000
+ Injectable19(),
4001
+ Command8({
3721
4002
  name: "sync",
3722
4003
  arguments: "[paths...]",
3723
4004
  description: "Synchronize documents to the knowledge graph"
@@ -3756,7 +4037,7 @@ GraphModule = __legacyDecorateClassTS([
3756
4037
  import { Module as Module3 } from "@nestjs/common";
3757
4038
 
3758
4039
  // src/query/query.service.ts
3759
- import { Injectable as Injectable19, Logger as Logger10 } from "@nestjs/common";
4040
+ import { Injectable as Injectable20, Logger as Logger10 } from "@nestjs/common";
3760
4041
  class QueryService {
3761
4042
  graphService;
3762
4043
  logger = new Logger10(QueryService.name);
@@ -3769,7 +4050,7 @@ class QueryService {
3769
4050
  }
3770
4051
  }
3771
4052
  QueryService = __legacyDecorateClassTS([
3772
- Injectable19(),
4053
+ Injectable20(),
3773
4054
  __legacyMetadataTS("design:paramtypes", [
3774
4055
  typeof GraphService === "undefined" ? Object : GraphService
3775
4056
  ])
@@ -3842,7 +4123,8 @@ AppModule = __legacyDecorateClassTS([
3842
4123
  SqlCommand,
3843
4124
  OntologyCommand,
3844
4125
  InitCommand,
3845
- MigrateCommand
4126
+ MigrateCommand,
4127
+ SiteCommand
3846
4128
  ]
3847
4129
  })
3848
4130
  ], AppModule);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zabaca/lattice",
3
- "version": "1.0.23",
3
+ "version": "1.1.1",
4
4
  "description": "Human-initiated, AI-powered knowledge graph for markdown documentation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,6 +9,7 @@
9
9
  "files": [
10
10
  "dist",
11
11
  "commands",
12
+ "site-template",
12
13
  "README.md"
13
14
  ],
14
15
  "scripts": {
@@ -44,7 +45,7 @@
44
45
  },
45
46
  "dependencies": {
46
47
  "@anthropic-ai/claude-agent-sdk": "^0.1.67",
47
- "@duckdb/node-api": "1.4.3-r.1",
48
+ "@duckdb/node-api": "1.3.1-alpha.23",
48
49
  "@nestjs/common": "^10.0.0",
49
50
  "@nestjs/config": "^3.0.0",
50
51
  "@nestjs/core": "^10.0.0",
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'astro/config';
2
+ import { astroSpaceship } from 'astro-spaceship';
3
+
4
+ import websiteConfig from 'astro-spaceship/config';
5
+
6
+ export default defineConfig({
7
+ integrations: [
8
+ astroSpaceship(websiteConfig)
9
+ ]
10
+ });
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "lattice-site",
3
+ "type": "module",
4
+ "version": "1.0.0",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "astro dev",
8
+ "build": "astro build --sync",
9
+ "preview": "astro preview"
10
+ },
11
+ "dependencies": {
12
+ "astro": "^5.12.8",
13
+ "astro-loader-obsidian": "^0.9.1",
14
+ "astro-spaceship": "^0.9.8",
15
+ "sharp": "^0.32.5",
16
+ "spaceship-monolith": "^0.9.8",
17
+ "varlock": "^0.0.11"
18
+ }
19
+ }
@@ -0,0 +1,15 @@
1
+ import { defineCollection } from 'astro:content';
2
+ import { glob } from "astro/loaders";
3
+
4
+ import { AUTHORS_COLLECTION_NAME } from 'astro-spaceship/constants';
5
+ import { AuthorSchema } from 'astro-spaceship/schemas';
6
+
7
+
8
+ export default {
9
+ [AUTHORS_COLLECTION_NAME]: defineCollection({
10
+ loader: glob({ pattern: "**/*.yml", base: "./src/content/authors" }),
11
+ schema: ({ image }) => AuthorSchema.extend({
12
+ avatar: image().optional(),
13
+ })
14
+ }),
15
+ };
@@ -0,0 +1,27 @@
1
+ import { defineCollection } from 'astro:content';
2
+
3
+ import { ObsidianMdLoader, ObsidianWikiLinkSchema } from "astro-loader-obsidian";
4
+
5
+ import { DOCUMENTS_COLLECTION_NAME, DEFAULT_VAULT_DIR } from 'astro-spaceship/constants';
6
+ import { DocumentSchema } from 'astro-spaceship/schemas';
7
+ import config from 'astro-spaceship/config';
8
+
9
+ import { ENV } from 'varlock/env';
10
+
11
+ export default {
12
+ [DOCUMENTS_COLLECTION_NAME]: defineCollection({
13
+ loader: ObsidianMdLoader({
14
+ author: config.author,
15
+ base: ENV.OBSIDIAN_VAULT_DIR ?? DEFAULT_VAULT_DIR,
16
+ url: '',
17
+ wikilinkFields: ['relateds']
18
+ }),
19
+ schema: ({ image }) => DocumentSchema.extend({
20
+ images: ObsidianWikiLinkSchema.extend({
21
+ href: image().optional(),
22
+ }).array().optional(),
23
+ cover: image().optional(),
24
+ image: image().optional(),
25
+ }),
26
+ })
27
+ }
@@ -0,0 +1,13 @@
1
+ import { defineCollection, z } from 'astro:content';
2
+ import { glob } from "astro/loaders";
3
+
4
+ import { TAGS_COLLECTION_NAME } from 'astro-spaceship/constants';
5
+ import { TagSchema } from 'astro-spaceship/schemas';
6
+
7
+
8
+ export default {
9
+ [TAGS_COLLECTION_NAME]: defineCollection({
10
+ loader: glob({ pattern: "**/*.yml", base: "./src/content/tags" }),
11
+ schema: () => TagSchema,
12
+ })
13
+ };
@@ -0,0 +1,9 @@
1
+ import authorsCollection from './collections/authors';
2
+ import documentsCollection from './collections/documents';
3
+ import tagsCollection from './collections/tags';
4
+
5
+ export const collections = {
6
+ ...authorsCollection,
7
+ ...documentsCollection,
8
+ ...tagsCollection,
9
+ };
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "astro/tsconfigs/strict",
3
+ "include": [".astro/types.d.ts", "**/*"],
4
+ "exclude": ["dist", "docs"],
5
+ "compilerOptions": {
6
+ "strictNullChecks": true,
7
+ "allowJs": true,
8
+ "baseUrl": ".",
9
+ "paths": {
10
+ "@/*": ["./src/*"]
11
+ }
12
+ }
13
+ }