gnosys 5.1.0 → 5.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.
package/dist/cli.js CHANGED
@@ -455,11 +455,11 @@ program
455
455
  });
456
456
  // ─── gnosys init ─────────────────────────────────────────────────────────
457
457
  program
458
- .command("init")
459
- .description("Initialize Gnosys in the current directory. Creates project identity, registers in central DB, and sets up store.")
458
+ .command("init [ide]")
459
+ .description("Initialize Gnosys in the current directory. Optionally specify IDE: cursor, claude, or codex to force IDE setup.")
460
460
  .option("-d, --directory <dir>", "Target directory (default: cwd)")
461
461
  .option("-n, --name <name>", "Project name (default: directory basename)")
462
- .action(async (opts) => {
462
+ .action(async (ide, opts) => {
463
463
  const targetDir = opts.directory
464
464
  ? path.resolve(opts.directory)
465
465
  : process.cwd();
@@ -550,6 +550,68 @@ program
550
550
  console.log(` .config/ (internal config)`);
551
551
  console.log(` tags.json (tag registry)`);
552
552
  }
553
+ // Configure IDE hooks for automatic memory recall
554
+ const { configureIdeHooks } = await import("./lib/projectIdentity.js");
555
+ const hookResult = await configureIdeHooks(targetDir);
556
+ if (hookResult.configured) {
557
+ console.log(`\nIDE hooks (${hookResult.ide}):`);
558
+ console.log(` ${hookResult.details}`);
559
+ console.log(` File: ${hookResult.filePath}`);
560
+ }
561
+ else {
562
+ console.log(`\nIDE hooks: ${hookResult.details}`);
563
+ }
564
+ // If a specific IDE was requested, force-create its config
565
+ if (ide) {
566
+ const validIdes = ["cursor", "claude", "codex"];
567
+ const normalizedIde = ide.toLowerCase();
568
+ if (!validIdes.includes(normalizedIde)) {
569
+ console.log(`\nUnknown IDE: "${ide}". Valid options: ${validIdes.join(", ")}`);
570
+ }
571
+ else {
572
+ const { configureCursor, configureClaudeCode, configureCodex } = await import("./lib/projectIdentity.js");
573
+ let result;
574
+ switch (normalizedIde) {
575
+ case "cursor":
576
+ result = await configureCursor(targetDir);
577
+ break;
578
+ case "claude":
579
+ result = await configureClaudeCode(targetDir);
580
+ break;
581
+ case "codex":
582
+ result = await configureCodex(targetDir);
583
+ break;
584
+ }
585
+ if (result?.configured) {
586
+ console.log(`\nIDE setup (${result.ide}):`);
587
+ console.log(` ${result.details}`);
588
+ console.log(` File: ${result.filePath}`);
589
+ }
590
+ // Also set up MCP config for the IDE
591
+ const { setupIDE } = await import("./lib/setup.js");
592
+ const mcp = await setupIDE(normalizedIde, targetDir);
593
+ if (mcp.success) {
594
+ console.log(` MCP: ${mcp.message}`);
595
+ }
596
+ // Update agentRulesTarget in gnosys.json
597
+ const identityPath = path.join(storePath, "gnosys.json");
598
+ try {
599
+ const identityContent = await fs.readFile(identityPath, "utf-8");
600
+ const identity = JSON.parse(identityContent);
601
+ const targetMap = {
602
+ cursor: ".cursor/rules/gnosys.mdc",
603
+ claude: "CLAUDE.md",
604
+ codex: "CODEX.md",
605
+ };
606
+ identity.agentRulesTarget = targetMap[normalizedIde] || null;
607
+ await fs.writeFile(identityPath, JSON.stringify(identity, null, 2) + "\n", "utf-8");
608
+ console.log(` Config: agentRulesTarget → ${identity.agentRulesTarget}`);
609
+ }
610
+ catch {
611
+ // Non-critical
612
+ }
613
+ }
614
+ }
553
615
  console.log(`\nStart adding memories with: gnosys add "your knowledge here"`);
554
616
  });
555
617
  // ─── gnosys migrate ─────────────────────────────────────────────────────
@@ -2424,6 +2486,9 @@ program
2424
2486
  }
2425
2487
  centralDb.close();
2426
2488
  }
2489
+ // Configure IDE hooks for automatic memory recall
2490
+ const { configureIdeHooks } = await import("./lib/projectIdentity.js");
2491
+ await configureIdeHooks(projectDir);
2427
2492
  upgraded.push(projectDir);
2428
2493
  }
2429
2494
  catch (err) {
@@ -2662,6 +2727,104 @@ program
2662
2727
  }
2663
2728
  }
2664
2729
  });
2730
+ // ─── gnosys check ─────────────────────────────────────────────────────────
2731
+ program
2732
+ .command("check")
2733
+ .description("Test LLM connectivity for all 5 task configurations (structuring, synthesis, vision, transcription, dream)")
2734
+ .option("-d, --directory <dir>", "Project directory (default: cwd)")
2735
+ .action(async (opts) => {
2736
+ const projectDir = opts.directory ? path.resolve(opts.directory) : process.cwd();
2737
+ const storePath = path.join(projectDir, ".gnosys");
2738
+ const cfg = await loadConfig(storePath);
2739
+ const GREEN = "\x1b[32m";
2740
+ const RED = "\x1b[31m";
2741
+ const YELLOW = "\x1b[33m";
2742
+ const DIM = "\x1b[2m";
2743
+ const BOLD = "\x1b[1m";
2744
+ const RESET = "\x1b[0m";
2745
+ const CHECK = `${GREEN}✓${RESET}`;
2746
+ const CROSS = `${RED}✗${RESET}`;
2747
+ const WARN = `${YELLOW}⚠${RESET}`;
2748
+ console.log(`\n${BOLD}Gnosys LLM Check${RESET}\n`);
2749
+ const tasks = [
2750
+ {
2751
+ name: "structuring",
2752
+ description: "adding memories, tagging",
2753
+ resolve: () => resolveTaskModel(cfg, "structuring"),
2754
+ },
2755
+ {
2756
+ name: "synthesis",
2757
+ description: "Q&A answers (gnosys ask)",
2758
+ resolve: () => resolveTaskModel(cfg, "synthesis"),
2759
+ },
2760
+ {
2761
+ name: "vision",
2762
+ description: "images, PDFs",
2763
+ resolve: () => resolveTaskModel(cfg, "vision"),
2764
+ },
2765
+ {
2766
+ name: "transcription",
2767
+ description: "audio files",
2768
+ resolve: () => resolveTaskModel(cfg, "transcription"),
2769
+ },
2770
+ {
2771
+ name: "dream",
2772
+ description: "overnight consolidation",
2773
+ resolve: () => ({
2774
+ provider: cfg.dream?.provider || "ollama",
2775
+ model: cfg.dream?.model || "llama3.2",
2776
+ }),
2777
+ },
2778
+ ];
2779
+ let passed = 0;
2780
+ let failed = 0;
2781
+ let skipped = 0;
2782
+ for (const task of tasks) {
2783
+ const { provider, model } = task.resolve();
2784
+ const label = `${task.name.padEnd(16)} ${DIM}${provider} / ${model}${RESET}`;
2785
+ const desc = `${DIM}(${task.description})${RESET}`;
2786
+ // Special handling for dream — check if enabled
2787
+ if (task.name === "dream" && !cfg.dream?.enabled) {
2788
+ console.log(` ${WARN} ${label} disabled ${desc}`);
2789
+ skipped++;
2790
+ continue;
2791
+ }
2792
+ // Check provider availability (API key, etc.)
2793
+ const availability = isProviderAvailable(cfg, provider);
2794
+ if (!availability.available) {
2795
+ console.log(` ${CROSS} ${label} ${RED}${availability.error}${RESET} ${desc}`);
2796
+ failed++;
2797
+ continue;
2798
+ }
2799
+ // Test actual connection with timing
2800
+ const start = Date.now();
2801
+ try {
2802
+ const llmProvider = getLLMProvider({ ...cfg, llm: { ...cfg.llm, defaultProvider: provider } });
2803
+ await llmProvider.testConnection();
2804
+ const ms = Date.now() - start;
2805
+ console.log(` ${CHECK} ${label} ${GREEN}${ms}ms${RESET} ${desc}`);
2806
+ passed++;
2807
+ }
2808
+ catch (err) {
2809
+ const ms = Date.now() - start;
2810
+ const errMsg = err instanceof Error ? err.message : String(err);
2811
+ // Truncate long error messages
2812
+ const shortErr = errMsg.length > 60 ? errMsg.slice(0, 57) + "..." : errMsg;
2813
+ console.log(` ${CROSS} ${label} ${RED}${shortErr}${RESET} (${ms}ms) ${desc}`);
2814
+ failed++;
2815
+ }
2816
+ }
2817
+ console.log();
2818
+ const total = passed + failed + skipped;
2819
+ if (failed === 0) {
2820
+ console.log(`${CHECK} All ${passed}/${total} tasks connected.`);
2821
+ }
2822
+ else {
2823
+ console.log(`${passed}/${total} connected, ${failed} failed${skipped > 0 ? `, ${skipped} skipped` : ""}.`);
2824
+ console.log(`\n${DIM}Fix: Run 'gnosys setup' to configure providers and API keys.${RESET}`);
2825
+ }
2826
+ console.log();
2827
+ });
2665
2828
  // ─── gnosys dream ────────────────────────────────────────────────────────
2666
2829
  program
2667
2830
  .command("dream")