gnosys 5.4.0 → 5.4.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/README.md +114 -8
- package/dist/cli.js +157 -63
- package/dist/cli.js.map +1 -1
- package/dist/index.js +202 -99
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +0 -5
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +71 -9
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/dashboard.d.ts +14 -0
- package/dist/lib/dashboard.d.ts.map +1 -1
- package/dist/lib/dashboard.js +200 -94
- package/dist/lib/dashboard.js.map +1 -1
- package/dist/lib/db.d.ts +87 -3
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +236 -17
- package/dist/lib/db.js.map +1 -1
- package/dist/lib/desktopNotify.d.ts +31 -0
- package/dist/lib/desktopNotify.d.ts.map +1 -0
- package/dist/lib/desktopNotify.js +80 -0
- package/dist/lib/desktopNotify.js.map +1 -0
- package/dist/lib/dream.d.ts +12 -0
- package/dist/lib/dream.d.ts.map +1 -1
- package/dist/lib/dream.js +82 -2
- package/dist/lib/dream.js.map +1 -1
- package/dist/lib/ingest.d.ts.map +1 -1
- package/dist/lib/ingest.js +24 -4
- package/dist/lib/ingest.js.map +1 -1
- package/dist/lib/lock.d.ts +5 -0
- package/dist/lib/lock.d.ts.map +1 -1
- package/dist/lib/lock.js +9 -0
- package/dist/lib/lock.js.map +1 -1
- package/dist/lib/remote.d.ts +15 -0
- package/dist/lib/remote.d.ts.map +1 -1
- package/dist/lib/remote.js +85 -0
- package/dist/lib/remote.js.map +1 -1
- package/dist/lib/setup.d.ts +15 -0
- package/dist/lib/setup.d.ts.map +1 -1
- package/dist/lib/setup.js +228 -0
- package/dist/lib/setup.js.map +1 -1
- package/dist/lib/store.d.ts +2 -0
- package/dist/lib/store.d.ts.map +1 -1
- package/dist/lib/store.js +4 -11
- package/dist/lib/store.js.map +1 -1
- package/package.json +2 -1
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,
|
|
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,
|
|
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,81 @@ This improves your site's visibility in AI-powered search results and enables LL
|
|
|
235
235
|
|
|
236
236
|
## MCP Server Setup
|
|
237
237
|
|
|
238
|
-
|
|
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
|
-
|
|
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
|
+
## Setup Wizards
|
|
273
|
+
|
|
274
|
+
`gnosys setup` runs the full interactive wizard. To configure just one piece without walking the whole thing, use one of these subcommands:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
gnosys setup # full wizard (provider, models, IDE, remote sync, dream)
|
|
278
|
+
gnosys setup models # LLM provider + model only
|
|
279
|
+
gnosys setup remote # multi-machine sync (NAS/shared drive)
|
|
280
|
+
gnosys setup dream # Dream Mode designation, schedule, sub-tasks
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Dream Mode setup (v5.4.2+)
|
|
284
|
+
|
|
285
|
+
Dream Mode is the idle-time consolidation engine — confidence decay, summary generation, self-critique, relationship discovery. With multi-machine sync (v5.3.0+), running dream cycles from every machine wastes work and fights for SQLite write locks. v5.4.2 introduces a **single designated machine** model:
|
|
286
|
+
|
|
287
|
+
- Run `gnosys setup dream` on the machine you want to host dream cycles.
|
|
288
|
+
- The wizard validates your provider/model with a live API probe before saving.
|
|
289
|
+
- Other machines stay quiet — they see the designation in the central DB and skip the scheduler.
|
|
290
|
+
- `gnosys dream log` shows recent runs; `gnosys dashboard` has a `DREAM HEALTH` section with last-run timestamp, designated machine, and consecutive-failure counter.
|
|
291
|
+
- If the designated machine's LLM provider becomes unreachable, you'll see warnings at three layers: in audit log entries (`dream_provider_unreachable`), as stderr at MCP startup, and as a desktop notification after 3 consecutive failures.
|
|
292
|
+
|
|
293
|
+
### Removed in v5.4.2
|
|
294
|
+
|
|
295
|
+
The following commands were removed in favor of the canonical `gnosys setup <thing>` form:
|
|
296
|
+
|
|
297
|
+
| Removed | Use instead |
|
|
298
|
+
|---|---|
|
|
299
|
+
| `gnosys models` | `gnosys setup models` |
|
|
300
|
+
| `gnosys remote configure` | `gnosys setup remote` |
|
|
301
|
+
|
|
302
|
+
`gnosys remote push|pull|sync|status` remain unchanged — only `configure` moved.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
### Manual config (if you prefer)
|
|
307
|
+
|
|
308
|
+
If you'd rather edit configs by hand, here's where each client looks for MCP servers.
|
|
309
|
+
|
|
310
|
+
#### Claude Desktop (Chat, Cowork, and Code share the same config)
|
|
311
|
+
|
|
312
|
+
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
313
|
|
|
242
314
|
```json
|
|
243
315
|
{
|
|
@@ -250,9 +322,11 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
|
250
322
|
}
|
|
251
323
|
```
|
|
252
324
|
|
|
253
|
-
|
|
325
|
+
Restart Claude Desktop after editing.
|
|
326
|
+
|
|
327
|
+
#### Cursor
|
|
254
328
|
|
|
255
|
-
Add to `.cursor/mcp.json
|
|
329
|
+
Add to `.cursor/mcp.json` in your project:
|
|
256
330
|
|
|
257
331
|
```json
|
|
258
332
|
{
|
|
@@ -265,13 +339,13 @@ Add to `.cursor/mcp.json`:
|
|
|
265
339
|
}
|
|
266
340
|
```
|
|
267
341
|
|
|
268
|
-
|
|
342
|
+
#### Claude Code
|
|
269
343
|
|
|
270
344
|
```bash
|
|
271
345
|
claude mcp add gnosys gnosys serve
|
|
272
346
|
```
|
|
273
347
|
|
|
274
|
-
|
|
348
|
+
#### Codex
|
|
275
349
|
|
|
276
350
|
Add to `.codex/config.toml`:
|
|
277
351
|
|
|
@@ -281,6 +355,38 @@ type = "local"
|
|
|
281
355
|
command = ["gnosys", "serve"]
|
|
282
356
|
```
|
|
283
357
|
|
|
358
|
+
#### Gemini CLI
|
|
359
|
+
|
|
360
|
+
Add to `~/.gemini/settings.json` (preserves any existing settings):
|
|
361
|
+
|
|
362
|
+
```json
|
|
363
|
+
{
|
|
364
|
+
"mcpServers": {
|
|
365
|
+
"gnosys": {
|
|
366
|
+
"command": "gnosys",
|
|
367
|
+
"args": ["serve"]
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
#### Antigravity
|
|
374
|
+
|
|
375
|
+
Add to `~/.gemini/antigravity/mcp_config.json`:
|
|
376
|
+
|
|
377
|
+
```json
|
|
378
|
+
{
|
|
379
|
+
"mcpServers": {
|
|
380
|
+
"gnosys": {
|
|
381
|
+
"command": "gnosys",
|
|
382
|
+
"args": ["serve"]
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
Antigravity reloads MCP servers automatically when you save the file.
|
|
389
|
+
|
|
284
390
|
> **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
391
|
|
|
286
392
|
---
|
package/dist/cli.js
CHANGED
|
@@ -503,11 +503,12 @@ setupCmd
|
|
|
503
503
|
// `gnosys setup remote` — configure remote sync (alias for `gnosys remote configure`)
|
|
504
504
|
setupCmd
|
|
505
505
|
.command("remote")
|
|
506
|
-
.description("Configure multi-machine sync (
|
|
506
|
+
.description("Configure multi-machine sync (NAS/shared drive)")
|
|
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
|
-
|
|
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();
|
|
@@ -527,17 +528,18 @@ setupCmd
|
|
|
527
528
|
db.close();
|
|
528
529
|
}
|
|
529
530
|
});
|
|
530
|
-
//
|
|
531
|
-
|
|
532
|
-
.command("
|
|
533
|
-
.description("
|
|
534
|
-
.
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
.action(async (opts) => {
|
|
538
|
-
const { runModelsCommand } = await import("./lib/setup.js");
|
|
539
|
-
await runModelsCommand(opts);
|
|
531
|
+
// `gnosys setup dream` — configure dream mode (designation, provider, schedule)
|
|
532
|
+
setupCmd
|
|
533
|
+
.command("dream")
|
|
534
|
+
.description("Configure Dream Mode — designate this machine, pick provider/model, set schedule")
|
|
535
|
+
.action(async () => {
|
|
536
|
+
const { runDreamSetup } = await import("./lib/setup.js");
|
|
537
|
+
await runDreamSetup({ directory: process.cwd() });
|
|
540
538
|
});
|
|
539
|
+
// v5.4.2 removal: `gnosys models` (top-level shortcut) was removed in favor
|
|
540
|
+
// of the canonical `gnosys setup models` form. The implementation function
|
|
541
|
+
// runModelsCommand() in setup.ts is no longer wired but kept for now in case
|
|
542
|
+
// we need to revive a top-level shortcut later.
|
|
541
543
|
// ─── gnosys init ─────────────────────────────────────────────────────────
|
|
542
544
|
program
|
|
543
545
|
.command("init [ide]")
|
|
@@ -1713,14 +1715,60 @@ program
|
|
|
1713
1715
|
.command("graph")
|
|
1714
1716
|
.description("Show the full cross-reference graph across all memories")
|
|
1715
1717
|
.action(async () => {
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1718
|
+
// v5.4.1: Query the central DB directly. Previously this used the
|
|
1719
|
+
// filesystem resolver, which returns nothing in v5.x DB-only mode
|
|
1720
|
+
// because memories no longer live as markdown files.
|
|
1721
|
+
let centralDb = null;
|
|
1722
|
+
try {
|
|
1723
|
+
centralDb = GnosysDB.openCentral();
|
|
1724
|
+
if (!centralDb.isAvailable()) {
|
|
1725
|
+
console.error("Central DB not available.");
|
|
1726
|
+
process.exit(1);
|
|
1727
|
+
}
|
|
1728
|
+
const dbMemories = centralDb.getAllMemories();
|
|
1729
|
+
if (dbMemories.length === 0) {
|
|
1730
|
+
console.log("No memories found.");
|
|
1731
|
+
return;
|
|
1732
|
+
}
|
|
1733
|
+
// Adapt DbMemory → legacy Memory shape that buildLinkGraph expects.
|
|
1734
|
+
// The graph builder only reads id, title, content, and synthesises
|
|
1735
|
+
// a filesystem-style path for display.
|
|
1736
|
+
const adapted = dbMemories.map((m) => {
|
|
1737
|
+
let parsedTags = [];
|
|
1738
|
+
try {
|
|
1739
|
+
parsedTags = JSON.parse(m.tags);
|
|
1740
|
+
}
|
|
1741
|
+
catch {
|
|
1742
|
+
parsedTags = [];
|
|
1743
|
+
}
|
|
1744
|
+
const relativePath = `${m.category}/${m.id}.md`;
|
|
1745
|
+
return {
|
|
1746
|
+
frontmatter: {
|
|
1747
|
+
id: m.id,
|
|
1748
|
+
title: m.title,
|
|
1749
|
+
category: m.category,
|
|
1750
|
+
tags: parsedTags,
|
|
1751
|
+
relevance: m.relevance,
|
|
1752
|
+
author: m.author,
|
|
1753
|
+
authority: m.authority,
|
|
1754
|
+
confidence: m.confidence,
|
|
1755
|
+
created: m.created,
|
|
1756
|
+
modified: m.modified,
|
|
1757
|
+
last_reviewed: m.modified,
|
|
1758
|
+
status: m.status,
|
|
1759
|
+
supersedes: m.supersedes,
|
|
1760
|
+
},
|
|
1761
|
+
content: m.content,
|
|
1762
|
+
filePath: relativePath,
|
|
1763
|
+
relativePath,
|
|
1764
|
+
};
|
|
1765
|
+
});
|
|
1766
|
+
const graph = buildLinkGraph(adapted);
|
|
1767
|
+
console.log(formatGraphSummary(graph));
|
|
1768
|
+
}
|
|
1769
|
+
finally {
|
|
1770
|
+
centralDb?.close();
|
|
1721
1771
|
}
|
|
1722
|
-
const graph = buildLinkGraph(allMemories);
|
|
1723
|
-
console.log(formatGraphSummary(graph));
|
|
1724
1772
|
});
|
|
1725
1773
|
// ─── gnosys bootstrap <sourceDir> ────────────────────────────────────────
|
|
1726
1774
|
program
|
|
@@ -2541,7 +2589,8 @@ remoteCmd
|
|
|
2541
2589
|
.action(async (opts) => {
|
|
2542
2590
|
let centralDb = null;
|
|
2543
2591
|
try {
|
|
2544
|
-
|
|
2592
|
+
// Sync operations need explicit local DB access (not auto-routed remote).
|
|
2593
|
+
centralDb = GnosysDB.openLocal();
|
|
2545
2594
|
if (!centralDb.isAvailable()) {
|
|
2546
2595
|
console.error("Central DB not available.");
|
|
2547
2596
|
process.exit(1);
|
|
@@ -2592,7 +2641,7 @@ remoteCmd
|
|
|
2592
2641
|
.action(async (opts) => {
|
|
2593
2642
|
let centralDb = null;
|
|
2594
2643
|
try {
|
|
2595
|
-
centralDb = GnosysDB.
|
|
2644
|
+
centralDb = GnosysDB.openLocal();
|
|
2596
2645
|
if (!centralDb.isAvailable()) {
|
|
2597
2646
|
console.error("Central DB not available.");
|
|
2598
2647
|
process.exit(1);
|
|
@@ -2606,7 +2655,8 @@ remoteCmd
|
|
|
2606
2655
|
const sync = new RemoteSync(centralDb, remotePath);
|
|
2607
2656
|
const result = await sync.push({ strategy: opts.newerWins ? "newer-wins" : "skip-and-flag" });
|
|
2608
2657
|
sync.closeRemote();
|
|
2609
|
-
|
|
2658
|
+
const projParts = (result.projectsPushed || 0) > 0 ? ` | Projects pushed: ${result.projectsPushed}` : "";
|
|
2659
|
+
console.log(`Pushed: ${result.pushed} | Skipped: ${result.skipped} | Conflicts: ${result.conflicts.length}${projParts}`);
|
|
2610
2660
|
if (result.errors.length > 0) {
|
|
2611
2661
|
console.log("\nErrors:");
|
|
2612
2662
|
for (const e of result.errors)
|
|
@@ -2633,7 +2683,7 @@ remoteCmd
|
|
|
2633
2683
|
.action(async (opts) => {
|
|
2634
2684
|
let centralDb = null;
|
|
2635
2685
|
try {
|
|
2636
|
-
centralDb = GnosysDB.
|
|
2686
|
+
centralDb = GnosysDB.openLocal();
|
|
2637
2687
|
if (!centralDb.isAvailable()) {
|
|
2638
2688
|
console.error("Central DB not available.");
|
|
2639
2689
|
process.exit(1);
|
|
@@ -2647,7 +2697,8 @@ remoteCmd
|
|
|
2647
2697
|
const sync = new RemoteSync(centralDb, remotePath);
|
|
2648
2698
|
const result = await sync.pull({ strategy: opts.newerWins ? "newer-wins" : "skip-and-flag" });
|
|
2649
2699
|
sync.closeRemote();
|
|
2650
|
-
|
|
2700
|
+
const projParts = (result.projectsPulled || 0) > 0 ? ` | Projects pulled: ${result.projectsPulled}` : "";
|
|
2701
|
+
console.log(`Pulled: ${result.pulled} | Skipped: ${result.skipped} | Conflicts: ${result.conflicts.length}${projParts}`);
|
|
2651
2702
|
if (result.errors.length > 0) {
|
|
2652
2703
|
console.log("\nErrors:");
|
|
2653
2704
|
for (const e of result.errors)
|
|
@@ -2670,7 +2721,7 @@ remoteCmd
|
|
|
2670
2721
|
.action(async (opts) => {
|
|
2671
2722
|
let centralDb = null;
|
|
2672
2723
|
try {
|
|
2673
|
-
centralDb = GnosysDB.
|
|
2724
|
+
centralDb = GnosysDB.openLocal();
|
|
2674
2725
|
if (!centralDb.isAvailable()) {
|
|
2675
2726
|
if (!opts.auto)
|
|
2676
2727
|
console.error("Central DB not available.");
|
|
@@ -2690,7 +2741,10 @@ remoteCmd
|
|
|
2690
2741
|
});
|
|
2691
2742
|
sync.closeRemote();
|
|
2692
2743
|
if (!opts.auto || result.conflicts.length > 0 || result.errors.length > 0) {
|
|
2693
|
-
|
|
2744
|
+
const pp = result.projectsPushed || 0;
|
|
2745
|
+
const pl = result.projectsPulled || 0;
|
|
2746
|
+
const projParts = (pp + pl) > 0 ? ` | Projects: ↑${pp}/↓${pl}` : "";
|
|
2747
|
+
console.log(`Pushed: ${result.pushed} | Pulled: ${result.pulled} | Conflicts: ${result.conflicts.length}${projParts}`);
|
|
2694
2748
|
if (result.errors.length > 0) {
|
|
2695
2749
|
console.log("\nErrors:");
|
|
2696
2750
|
for (const e of result.errors)
|
|
@@ -2717,7 +2771,7 @@ remoteCmd
|
|
|
2717
2771
|
.action(async (memoryId, opts) => {
|
|
2718
2772
|
let centralDb = null;
|
|
2719
2773
|
try {
|
|
2720
|
-
centralDb = GnosysDB.
|
|
2774
|
+
centralDb = GnosysDB.openLocal();
|
|
2721
2775
|
if (!centralDb.isAvailable()) {
|
|
2722
2776
|
console.error("Central DB not available.");
|
|
2723
2777
|
process.exit(1);
|
|
@@ -2751,39 +2805,10 @@ remoteCmd
|
|
|
2751
2805
|
centralDb?.close();
|
|
2752
2806
|
}
|
|
2753
2807
|
});
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
.option("--migrate", "Copy current local DB to remote on first setup (with --path)")
|
|
2759
|
-
.action(async (opts) => {
|
|
2760
|
-
let centralDb = null;
|
|
2761
|
-
try {
|
|
2762
|
-
centralDb = GnosysDB.openCentral();
|
|
2763
|
-
if (!centralDb.isAvailable()) {
|
|
2764
|
-
console.error("Central DB not available.");
|
|
2765
|
-
process.exit(1);
|
|
2766
|
-
}
|
|
2767
|
-
const { runConfigureWizard, configureFromPath } = await import("./lib/remoteWizard.js");
|
|
2768
|
-
if (opts.path) {
|
|
2769
|
-
// Non-interactive mode
|
|
2770
|
-
const ok = await configureFromPath(centralDb, opts.path, { migrate: opts.migrate });
|
|
2771
|
-
process.exit(ok ? 0 : 1);
|
|
2772
|
-
}
|
|
2773
|
-
else {
|
|
2774
|
-
// Interactive wizard
|
|
2775
|
-
const ok = await runConfigureWizard(centralDb);
|
|
2776
|
-
process.exit(ok ? 0 : 1);
|
|
2777
|
-
}
|
|
2778
|
-
}
|
|
2779
|
-
catch (err) {
|
|
2780
|
-
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
2781
|
-
process.exit(1);
|
|
2782
|
-
}
|
|
2783
|
-
finally {
|
|
2784
|
-
centralDb?.close();
|
|
2785
|
-
}
|
|
2786
|
-
});
|
|
2808
|
+
// v5.4.2 removal: `gnosys remote configure` was removed in favor of the
|
|
2809
|
+
// canonical `gnosys setup remote` form (which calls the same wizard
|
|
2810
|
+
// helpers from lib/remoteWizard.ts). Sync operations like push/pull/sync
|
|
2811
|
+
// remain under the `remote` parent.
|
|
2787
2812
|
// ─── gnosys upgrade ─────────────────────────────────────────────────────
|
|
2788
2813
|
program
|
|
2789
2814
|
.command("upgrade")
|
|
@@ -3275,10 +3300,12 @@ program
|
|
|
3275
3300
|
}
|
|
3276
3301
|
console.log();
|
|
3277
3302
|
});
|
|
3278
|
-
// ─── gnosys dream
|
|
3279
|
-
program
|
|
3303
|
+
// ─── gnosys dream (parent command) ───────────────────────────────────────
|
|
3304
|
+
const dreamCmd = program
|
|
3280
3305
|
.command("dream")
|
|
3281
|
-
.description("
|
|
3306
|
+
.description("Dream Mode — idle-time consolidation (run a cycle, view log)");
|
|
3307
|
+
// Bare `gnosys dream` runs a cycle now (preserves v5.4.1 behavior).
|
|
3308
|
+
dreamCmd
|
|
3282
3309
|
.option("--max-runtime <minutes>", "Max runtime in minutes (default: 30)")
|
|
3283
3310
|
.option("--no-critique", "Skip self-critique phase")
|
|
3284
3311
|
.option("--no-summaries", "Skip summary generation")
|
|
@@ -3325,6 +3352,73 @@ program
|
|
|
3325
3352
|
}
|
|
3326
3353
|
db.close();
|
|
3327
3354
|
});
|
|
3355
|
+
// `gnosys dream log` — view recent dream runs from audit_log
|
|
3356
|
+
dreamCmd
|
|
3357
|
+
.command("log")
|
|
3358
|
+
.description("Show recent dream runs from the audit log (default: last 20)")
|
|
3359
|
+
.option("--last <N>", "Number of most recent runs to show", "20")
|
|
3360
|
+
.option("--since <YYYY-MM-DD>", "Only runs since this date")
|
|
3361
|
+
.option("--failures-only", "Only runs with errors or unreachable provider")
|
|
3362
|
+
.option("--json", "Output raw audit rows as JSON")
|
|
3363
|
+
.action(async function (opts) {
|
|
3364
|
+
let centralDb = null;
|
|
3365
|
+
try {
|
|
3366
|
+
centralDb = GnosysDB.openCentral();
|
|
3367
|
+
if (!centralDb.isAvailable()) {
|
|
3368
|
+
console.error("Central DB not available.");
|
|
3369
|
+
process.exit(1);
|
|
3370
|
+
}
|
|
3371
|
+
const limit = Math.max(1, parseInt(opts.last) || 20);
|
|
3372
|
+
const sinceIso = opts.since ? `${opts.since}T00:00:00Z` : undefined;
|
|
3373
|
+
const runs = centralDb.getRecentDreamRuns(limit, {
|
|
3374
|
+
failuresOnly: !!opts.failuresOnly,
|
|
3375
|
+
sinceIso,
|
|
3376
|
+
});
|
|
3377
|
+
// Commander v13 hoists `--json` to the parent when both parent and
|
|
3378
|
+
// subcommand define it. Check the parent (dreamCmd) too so users can
|
|
3379
|
+
// type `gnosys dream log --json` and get JSON output.
|
|
3380
|
+
const wantJson = !!opts.json || !!(this.parent?.opts().json);
|
|
3381
|
+
// JSON path always emits a structured response — including empty runs.
|
|
3382
|
+
if (wantJson) {
|
|
3383
|
+
console.log(JSON.stringify({ count: runs.length, runs }, null, 2));
|
|
3384
|
+
return;
|
|
3385
|
+
}
|
|
3386
|
+
if (runs.length === 0) {
|
|
3387
|
+
console.log("No dream runs recorded.");
|
|
3388
|
+
return;
|
|
3389
|
+
}
|
|
3390
|
+
const DIM = "\x1b[2m";
|
|
3391
|
+
const RESET = "\x1b[0m";
|
|
3392
|
+
const RED = "\x1b[31m";
|
|
3393
|
+
const GREEN = "\x1b[32m";
|
|
3394
|
+
console.log(`${runs.length} dream run(s):\n`);
|
|
3395
|
+
for (const r of runs) {
|
|
3396
|
+
const d = r.details;
|
|
3397
|
+
const dur = r.durationMs != null ? `${(r.durationMs / 1000).toFixed(1)}s` : "—";
|
|
3398
|
+
const summaries = Number(d.summariesGenerated || 0);
|
|
3399
|
+
const decays = Number(d.decayUpdated || 0);
|
|
3400
|
+
const reviews = Number(d.reviewSuggestions || 0);
|
|
3401
|
+
const rels = Number(d.relationshipsDiscovered || 0);
|
|
3402
|
+
const errors = Number(d.errors || 0);
|
|
3403
|
+
const unreachable = Boolean(d.providerUnreachable);
|
|
3404
|
+
const status = unreachable
|
|
3405
|
+
? `${RED}provider unreachable${RESET}`
|
|
3406
|
+
: errors > 0
|
|
3407
|
+
? `${RED}${errors} error(s)${RESET}`
|
|
3408
|
+
: summaries + decays + rels > 0
|
|
3409
|
+
? `${GREEN}did work${RESET}`
|
|
3410
|
+
: `${DIM}no LLM work${RESET}`;
|
|
3411
|
+
console.log(` ${r.completed} ${DIM}(${dur})${RESET} ${status}`);
|
|
3412
|
+
console.log(` decays=${decays} summaries=${summaries} reviews=${reviews} relations=${rels}`);
|
|
3413
|
+
if (d.provider) {
|
|
3414
|
+
console.log(` ${DIM}provider=${d.provider}${d.model ? "/" + d.model : ""}${RESET}`);
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
}
|
|
3418
|
+
finally {
|
|
3419
|
+
centralDb?.close();
|
|
3420
|
+
}
|
|
3421
|
+
});
|
|
3328
3422
|
// ─── gnosys export ───────────────────────────────────────────────────────
|
|
3329
3423
|
program
|
|
3330
3424
|
.command("export")
|