gnosys 5.4.0 → 5.4.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/README.md CHANGED
@@ -24,7 +24,7 @@
24
24
 
25
25
  Gnosys is **sandbox-first**: a persistent background process holds the database connection while agents import a tiny helper library and call memory operations like normal code — no MCP schemas, no round-trips, near-zero context cost. The central brain at `~/.gnosys/gnosys.db` unifies all projects, user preferences, and global knowledge. Federated search ranks results across scopes with tier boosting and recency awareness. The **Web Knowledge Base** turns any website into a searchable knowledge base for serverless chatbots — pre-computed JSON index, zero runtime dependencies. **Multimodal ingestion** handles PDFs, images, audio, and video. **Portfolio Dashboard** gives a bird's-eye view of all projects. Process tracing builds call chains from source code. Dream Mode consolidates knowledge during idle time. One-command export regenerates a full Obsidian vault.
26
26
 
27
- It also runs as a CLI and a complete MCP server that drops straight into Cursor, Claude Desktop, Claude Code, Cowork, Codex, or any MCP client.
27
+ It also runs as a CLI and a complete MCP server that drops straight into Cursor, Claude Desktop (Chat / Cowork / Code), Claude Code, Codex, Gemini CLI, Antigravity, or any MCP client.
28
28
 
29
29
  No vector DBs. No black boxes. No external services. Just SQLite and optional Obsidian export — the way knowledge should be.
30
30
 
@@ -53,7 +53,7 @@ Gnosys takes a different approach: the central brain is a single SQLite database
53
53
  - **Bulk import** — CSV, JSON, JSONL. Import entire datasets in seconds.
54
54
  - **Obsidian-native** — `gnosys export` generates a full vault with YAML frontmatter, `[[wikilinks]]`, summaries, and graph data.
55
55
  - **Multi-machine sync (v5.3.0)** — share your `gnosys.db` across machines via NAS or shared drive. Local cache for speed, remote source of truth for consistency. Built-in conflict detection with skip-and-flag resolution. Run `gnosys remote configure` to set up.
56
- - **MCP-compatible** — also runs as a full MCP server that drops into Cursor, Claude Desktop, Claude Code, Cowork, Codex, or any MCP client.
56
+ - **MCP-compatible** — also runs as a full MCP server that drops into Cursor, Claude Desktop (Chat / Cowork / Code), Claude Code, Codex, Gemini CLI, Antigravity, or any MCP client.
57
57
  - **Zero infrastructure** — no external databases, no Docker (unless you want it), no cloud services. Just `npm install`.
58
58
 
59
59
  > For the complete CLI reference and detailed guides, see the **[User Guide](https://gnosys.ai/guide.html)**.
@@ -235,9 +235,47 @@ This improves your site's visibility in AI-powered search results and enables LL
235
235
 
236
236
  ## MCP Server Setup
237
237
 
238
- ### Claude Desktop
238
+ The fastest way to wire gnosys into any supported client is to run `gnosys init <ide>` from the project directory you want memory-enabled. Examples:
239
239
 
240
- Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
240
+ ```bash
241
+ gnosys init claude-desktop # Claude Desktop (covers Chat, Cowork, and Code)
242
+ gnosys init claude # Claude Code CLI
243
+ gnosys init cursor # Cursor
244
+ gnosys init codex # Codex
245
+ gnosys init gemini-cli # Gemini CLI
246
+ gnosys init antigravity # Google Antigravity
247
+ ```
248
+
249
+ This does two things at once:
250
+ 1. Wires gnosys into the IDE's MCP config (idempotent — safe to re-run).
251
+ 2. Initializes the current directory as a gnosys project (creates `.gnosys/gnosys.json`, registers it in the central DB) so your memories can be scoped to it.
252
+
253
+ ### One-time vs. per-project
254
+
255
+ The IDE wiring writes to a **user-level** config file, so it only needs to happen **once**. Re-running it in another project just re-merges the same `mcpServers.gnosys` entry — harmless.
256
+
257
+ The project registration is **per-directory**: every codebase you want to be memory-aware of needs its own `gnosys init`. From then on, agents pass `projectRoot: "/path/to/project"` to gnosys MCP tools to scope memory to that codebase.
258
+
259
+ ```bash
260
+ # Once, anywhere — wires Claude Desktop's MCP config:
261
+ gnosys init claude-desktop
262
+
263
+ # Once per project — registers the codebase in the central DB:
264
+ cd /path/to/project-a && gnosys init
265
+ cd /path/to/project-b && gnosys init
266
+ ```
267
+
268
+ > **Cowork users:** Cowork sessions don't have a working directory like a CLI does. The agent in Cowork uses whichever `projectRoot` it's told to use (typically auto-detected from open files or set via the system prompt). The "every working directory" question doesn't apply to Cowork itself — only to the projects you want memory-enabled. Run `gnosys init claude-desktop` once globally; run `gnosys init` per project.
269
+
270
+ ---
271
+
272
+ ### Manual config (if you prefer)
273
+
274
+ If you'd rather edit configs by hand, here's where each client looks for MCP servers.
275
+
276
+ #### Claude Desktop (Chat, Cowork, and Code share the same config)
277
+
278
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS), `%APPDATA%\Claude\claude_desktop_config.json` (Windows), or `~/.config/Claude/claude_desktop_config.json` (Linux):
241
279
 
242
280
  ```json
243
281
  {
@@ -250,9 +288,11 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
250
288
  }
251
289
  ```
252
290
 
253
- ### Cursor
291
+ Restart Claude Desktop after editing.
292
+
293
+ #### Cursor
254
294
 
255
- Add to `.cursor/mcp.json`:
295
+ Add to `.cursor/mcp.json` in your project:
256
296
 
257
297
  ```json
258
298
  {
@@ -265,13 +305,13 @@ Add to `.cursor/mcp.json`:
265
305
  }
266
306
  ```
267
307
 
268
- ### Claude Code
308
+ #### Claude Code
269
309
 
270
310
  ```bash
271
311
  claude mcp add gnosys gnosys serve
272
312
  ```
273
313
 
274
- ### Codex
314
+ #### Codex
275
315
 
276
316
  Add to `.codex/config.toml`:
277
317
 
@@ -281,6 +321,38 @@ type = "local"
281
321
  command = ["gnosys", "serve"]
282
322
  ```
283
323
 
324
+ #### Gemini CLI
325
+
326
+ Add to `~/.gemini/settings.json` (preserves any existing settings):
327
+
328
+ ```json
329
+ {
330
+ "mcpServers": {
331
+ "gnosys": {
332
+ "command": "gnosys",
333
+ "args": ["serve"]
334
+ }
335
+ }
336
+ }
337
+ ```
338
+
339
+ #### Antigravity
340
+
341
+ Add to `~/.gemini/antigravity/mcp_config.json`:
342
+
343
+ ```json
344
+ {
345
+ "mcpServers": {
346
+ "gnosys": {
347
+ "command": "gnosys",
348
+ "args": ["serve"]
349
+ }
350
+ }
351
+ }
352
+ ```
353
+
354
+ Antigravity reloads MCP servers automatically when you save the file.
355
+
284
356
  > **Note:** API keys are configured via `gnosys setup` (macOS Keychain, environment variable, or `~/.config/gnosys/.env`). See [LLM Provider Setup](https://gnosys.ai/guide.html#guide-llm-provider-setup) in the User Guide.
285
357
 
286
358
  ---
package/dist/cli.js CHANGED
@@ -507,7 +507,8 @@ setupCmd
507
507
  .option("--path <path>", "Set remote path directly (non-interactive)")
508
508
  .action(async (opts) => {
509
509
  const { GnosysDB } = await import("./lib/db.js");
510
- const db = GnosysDB.openCentral();
510
+ // Sync configuration needs explicit local DB access (not auto-routed remote).
511
+ const db = GnosysDB.openLocal();
511
512
  if (!db.isAvailable()) {
512
513
  console.error("Central DB not available.");
513
514
  db.close();
@@ -1713,14 +1714,60 @@ program
1713
1714
  .command("graph")
1714
1715
  .description("Show the full cross-reference graph across all memories")
1715
1716
  .action(async () => {
1716
- const resolver = await getResolver();
1717
- const allMemories = await resolver.getAllMemories();
1718
- if (allMemories.length === 0) {
1719
- console.log("No memories found.");
1720
- return;
1717
+ // v5.4.1: Query the central DB directly. Previously this used the
1718
+ // filesystem resolver, which returns nothing in v5.x DB-only mode
1719
+ // because memories no longer live as markdown files.
1720
+ let centralDb = null;
1721
+ try {
1722
+ centralDb = GnosysDB.openCentral();
1723
+ if (!centralDb.isAvailable()) {
1724
+ console.error("Central DB not available.");
1725
+ process.exit(1);
1726
+ }
1727
+ const dbMemories = centralDb.getAllMemories();
1728
+ if (dbMemories.length === 0) {
1729
+ console.log("No memories found.");
1730
+ return;
1731
+ }
1732
+ // Adapt DbMemory → legacy Memory shape that buildLinkGraph expects.
1733
+ // The graph builder only reads id, title, content, and synthesises
1734
+ // a filesystem-style path for display.
1735
+ const adapted = dbMemories.map((m) => {
1736
+ let parsedTags = [];
1737
+ try {
1738
+ parsedTags = JSON.parse(m.tags);
1739
+ }
1740
+ catch {
1741
+ parsedTags = [];
1742
+ }
1743
+ const relativePath = `${m.category}/${m.id}.md`;
1744
+ return {
1745
+ frontmatter: {
1746
+ id: m.id,
1747
+ title: m.title,
1748
+ category: m.category,
1749
+ tags: parsedTags,
1750
+ relevance: m.relevance,
1751
+ author: m.author,
1752
+ authority: m.authority,
1753
+ confidence: m.confidence,
1754
+ created: m.created,
1755
+ modified: m.modified,
1756
+ last_reviewed: m.modified,
1757
+ status: m.status,
1758
+ supersedes: m.supersedes,
1759
+ },
1760
+ content: m.content,
1761
+ filePath: relativePath,
1762
+ relativePath,
1763
+ };
1764
+ });
1765
+ const graph = buildLinkGraph(adapted);
1766
+ console.log(formatGraphSummary(graph));
1767
+ }
1768
+ finally {
1769
+ centralDb?.close();
1721
1770
  }
1722
- const graph = buildLinkGraph(allMemories);
1723
- console.log(formatGraphSummary(graph));
1724
1771
  });
1725
1772
  // ─── gnosys bootstrap <sourceDir> ────────────────────────────────────────
1726
1773
  program
@@ -2541,7 +2588,8 @@ remoteCmd
2541
2588
  .action(async (opts) => {
2542
2589
  let centralDb = null;
2543
2590
  try {
2544
- centralDb = GnosysDB.openCentral();
2591
+ // Sync operations need explicit local DB access (not auto-routed remote).
2592
+ centralDb = GnosysDB.openLocal();
2545
2593
  if (!centralDb.isAvailable()) {
2546
2594
  console.error("Central DB not available.");
2547
2595
  process.exit(1);
@@ -2592,7 +2640,7 @@ remoteCmd
2592
2640
  .action(async (opts) => {
2593
2641
  let centralDb = null;
2594
2642
  try {
2595
- centralDb = GnosysDB.openCentral();
2643
+ centralDb = GnosysDB.openLocal();
2596
2644
  if (!centralDb.isAvailable()) {
2597
2645
  console.error("Central DB not available.");
2598
2646
  process.exit(1);
@@ -2606,7 +2654,8 @@ remoteCmd
2606
2654
  const sync = new RemoteSync(centralDb, remotePath);
2607
2655
  const result = await sync.push({ strategy: opts.newerWins ? "newer-wins" : "skip-and-flag" });
2608
2656
  sync.closeRemote();
2609
- console.log(`Pushed: ${result.pushed} | Skipped: ${result.skipped} | Conflicts: ${result.conflicts.length}`);
2657
+ const projParts = (result.projectsPushed || 0) > 0 ? ` | Projects pushed: ${result.projectsPushed}` : "";
2658
+ console.log(`Pushed: ${result.pushed} | Skipped: ${result.skipped} | Conflicts: ${result.conflicts.length}${projParts}`);
2610
2659
  if (result.errors.length > 0) {
2611
2660
  console.log("\nErrors:");
2612
2661
  for (const e of result.errors)
@@ -2633,7 +2682,7 @@ remoteCmd
2633
2682
  .action(async (opts) => {
2634
2683
  let centralDb = null;
2635
2684
  try {
2636
- centralDb = GnosysDB.openCentral();
2685
+ centralDb = GnosysDB.openLocal();
2637
2686
  if (!centralDb.isAvailable()) {
2638
2687
  console.error("Central DB not available.");
2639
2688
  process.exit(1);
@@ -2647,7 +2696,8 @@ remoteCmd
2647
2696
  const sync = new RemoteSync(centralDb, remotePath);
2648
2697
  const result = await sync.pull({ strategy: opts.newerWins ? "newer-wins" : "skip-and-flag" });
2649
2698
  sync.closeRemote();
2650
- console.log(`Pulled: ${result.pulled} | Skipped: ${result.skipped} | Conflicts: ${result.conflicts.length}`);
2699
+ const projParts = (result.projectsPulled || 0) > 0 ? ` | Projects pulled: ${result.projectsPulled}` : "";
2700
+ console.log(`Pulled: ${result.pulled} | Skipped: ${result.skipped} | Conflicts: ${result.conflicts.length}${projParts}`);
2651
2701
  if (result.errors.length > 0) {
2652
2702
  console.log("\nErrors:");
2653
2703
  for (const e of result.errors)
@@ -2670,7 +2720,7 @@ remoteCmd
2670
2720
  .action(async (opts) => {
2671
2721
  let centralDb = null;
2672
2722
  try {
2673
- centralDb = GnosysDB.openCentral();
2723
+ centralDb = GnosysDB.openLocal();
2674
2724
  if (!centralDb.isAvailable()) {
2675
2725
  if (!opts.auto)
2676
2726
  console.error("Central DB not available.");
@@ -2690,7 +2740,10 @@ remoteCmd
2690
2740
  });
2691
2741
  sync.closeRemote();
2692
2742
  if (!opts.auto || result.conflicts.length > 0 || result.errors.length > 0) {
2693
- console.log(`Pushed: ${result.pushed} | Pulled: ${result.pulled} | Conflicts: ${result.conflicts.length}`);
2743
+ const pp = result.projectsPushed || 0;
2744
+ const pl = result.projectsPulled || 0;
2745
+ const projParts = (pp + pl) > 0 ? ` | Projects: ↑${pp}/↓${pl}` : "";
2746
+ console.log(`Pushed: ${result.pushed} | Pulled: ${result.pulled} | Conflicts: ${result.conflicts.length}${projParts}`);
2694
2747
  if (result.errors.length > 0) {
2695
2748
  console.log("\nErrors:");
2696
2749
  for (const e of result.errors)
@@ -2717,7 +2770,7 @@ remoteCmd
2717
2770
  .action(async (memoryId, opts) => {
2718
2771
  let centralDb = null;
2719
2772
  try {
2720
- centralDb = GnosysDB.openCentral();
2773
+ centralDb = GnosysDB.openLocal();
2721
2774
  if (!centralDb.isAvailable()) {
2722
2775
  console.error("Central DB not available.");
2723
2776
  process.exit(1);
@@ -2759,7 +2812,7 @@ remoteCmd
2759
2812
  .action(async (opts) => {
2760
2813
  let centralDb = null;
2761
2814
  try {
2762
- centralDb = GnosysDB.openCentral();
2815
+ centralDb = GnosysDB.openLocal();
2763
2816
  if (!centralDb.isAvailable()) {
2764
2817
  console.error("Central DB not available.");
2765
2818
  process.exit(1);