gnosys 5.7.1 → 5.8.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/README.md +14 -0
- package/dist/cli.js +61 -9
- package/dist/cli.js.map +1 -1
- package/dist/index.js +71 -21
- package/dist/index.js.map +1 -1
- package/dist/lib/ask.d.ts.map +1 -1
- package/dist/lib/ask.js +20 -4
- package/dist/lib/ask.js.map +1 -1
- package/dist/lib/chat/SlashPalette.d.ts +34 -0
- package/dist/lib/chat/SlashPalette.d.ts.map +1 -0
- package/dist/lib/chat/SlashPalette.js +49 -0
- package/dist/lib/chat/SlashPalette.js.map +1 -0
- package/dist/lib/chat/index.d.ts.map +1 -1
- package/dist/lib/chat/index.js +6 -4
- package/dist/lib/chat/index.js.map +1 -1
- package/dist/lib/chat/llmTurn.d.ts.map +1 -1
- package/dist/lib/chat/llmTurn.js +4 -1
- package/dist/lib/chat/llmTurn.js.map +1 -1
- package/dist/lib/chat/render.d.ts.map +1 -1
- package/dist/lib/chat/render.js +91 -10
- package/dist/lib/chat/render.js.map +1 -1
- package/dist/lib/config.d.ts +25 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +30 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/db.d.ts +1 -0
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +8 -5
- package/dist/lib/db.js.map +1 -1
- package/dist/lib/import.d.ts.map +1 -1
- package/dist/lib/import.js +2 -1
- package/dist/lib/import.js.map +1 -1
- package/dist/lib/ingest.d.ts +7 -1
- package/dist/lib/ingest.d.ts.map +1 -1
- package/dist/lib/ingest.js +23 -4
- package/dist/lib/ingest.js.map +1 -1
- package/dist/lib/llm.d.ts +1 -1
- package/dist/lib/llm.d.ts.map +1 -1
- package/dist/lib/llm.js.map +1 -1
- package/dist/lib/setup/sections/routing.d.ts.map +1 -1
- package/dist/lib/setup/sections/routing.js +4 -2
- package/dist/lib/setup/sections/routing.js.map +1 -1
- package/dist/lib/setup.d.ts +5 -0
- package/dist/lib/setup.d.ts.map +1 -1
- package/dist/lib/setup.js +127 -0
- package/dist/lib/setup.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -109,6 +109,8 @@ gnosys chat --search <query> # full-text search across session logs
|
|
|
109
109
|
|
|
110
110
|
**Free-text or slash commands.** "remember that flag default is OFF" works the same as `/remember flag default is OFF`. The TUI also recognizes "what did we decide about ULIDs?" → `/recall`, "thanks, that's all" → `/quit`. Destructive intents always confirm; non-destructive ones auto-accept after 5 confirmations of the same pattern.
|
|
111
111
|
|
|
112
|
+
**Slash-command palette (v5.8.0).** Type `/` at column 0 → filterable popup of every chat command appears. Arrow keys navigate, Tab autocompletes the highlighted command into the input, Esc dismisses. Paste detection: when input has newlines or exceeds 200 chars, a compact "[paste: N lines, M chars]" preview surfaces above the input so the buffer stays readable.
|
|
113
|
+
|
|
112
114
|
**24 slash commands** across reading, recall, writing, focus, and polish — type `/help` inside the TUI for the full list. Highlights:
|
|
113
115
|
|
|
114
116
|
- `/pin <id>`, `/scope`, `/threshold`, `/recall <q>` — tune what shows up in context
|
|
@@ -322,6 +324,8 @@ gnosys setup # full wizard (provider, models, IDE, remote sync, dream)
|
|
|
322
324
|
gnosys setup models # LLM provider + model only
|
|
323
325
|
gnosys setup remote # multi-machine sync (NAS/shared drive)
|
|
324
326
|
gnosys setup dream # Dream Mode designation, schedule, sub-tasks
|
|
327
|
+
gnosys setup chat # chat TUI: provider/model, recall, tools, system prompt (v5.8.0)
|
|
328
|
+
gnosys setup routing # per-task LLM routing (structuring/synthesis/chat/vision/transcription)
|
|
325
329
|
```
|
|
326
330
|
|
|
327
331
|
### Dream Mode setup (v5.4.2+)
|
|
@@ -358,6 +362,16 @@ The following commands were removed in favor of the canonical `gnosys setup <thi
|
|
|
358
362
|
tells running MCP servers to exit-and-respawn against the new global
|
|
359
363
|
binary. Run it on each machine.
|
|
360
364
|
|
|
365
|
+
### Behaviour changes in v5.8.0
|
|
366
|
+
|
|
367
|
+
| What | Then | Now |
|
|
368
|
+
|---|---|---|
|
|
369
|
+
| `gnosys_sync` MCP tool | Always wrote a `GNOSYS:START/END` block into `CLAUDE.md` (a tracked file) | Inert by default — returns the block as text only. Pass `commit_to_disk: true` to actually write. |
|
|
370
|
+
| `gnosys_preference_set/delete` MCP success messages | Suggested "Run `gnosys_sync` to update agent rules" | No suggestion — SessionStart hook (`gnosys recall`) injects updated context next session. |
|
|
371
|
+
| `gnosys_add` / `gnosys_commit_context` when project's `gnosys.json` has no `llm` block | Failed with "set ANTHROPIC_API_KEY", ignoring the global xAI/OpenAI/etc. config | Resolves the LLM against the merged project+global config — falls back to the user's global provider. |
|
|
372
|
+
| Chat TUI input | Cleared before user turn appeared (visible glitch) | Both happen in the same render frame. |
|
|
373
|
+
| `gnosys --help`, `gnosys list`, etc. | Loaded `@huggingface/transformers` (80MB) every invocation | Heavy modules lazy-load on actual use (reindex, recall, chat, bootstrap, import). |
|
|
374
|
+
|
|
361
375
|
---
|
|
362
376
|
|
|
363
377
|
### Manual config (if you prefer)
|
package/dist/cli.js
CHANGED
|
@@ -10,27 +10,33 @@ import os from "os";
|
|
|
10
10
|
import { fileURLToPath } from "url";
|
|
11
11
|
import dotenv from "dotenv";
|
|
12
12
|
import { readFileSync, existsSync, copyFileSync } from "fs";
|
|
13
|
+
// v5.8.0 (#4): only the lightweight modules are imported at top-level.
|
|
14
|
+
// Anything that pulls @huggingface/transformers, mammoth/pdf-parse/turndown,
|
|
15
|
+
// large file-walking machinery, or otherwise costs >100ms to load gets
|
|
16
|
+
// `await import(...)` inside its own action handler. This keeps
|
|
17
|
+
// `gnosys --help` and other lightweight commands fast.
|
|
13
18
|
import { GnosysResolver } from "./lib/resolver.js";
|
|
14
19
|
import { getGnosysHome } from "./lib/paths.js";
|
|
15
20
|
import { GnosysSearch } from "./lib/search.js";
|
|
16
21
|
import { GnosysTagRegistry } from "./lib/tags.js";
|
|
17
|
-
import { GnosysIngestion } from "./lib/ingest.js";
|
|
18
22
|
import { applyLens } from "./lib/lensing.js";
|
|
19
23
|
import { getFileHistory, rollbackToCommit, hasGitHistory, getFileDiff } from "./lib/history.js";
|
|
20
24
|
import { computeStats } from "./lib/timeline.js";
|
|
21
25
|
import { buildLinkGraph, getBacklinks, getOutgoingLinks, formatGraphSummary } from "./lib/wikilinks.js";
|
|
22
|
-
import { bootstrap, discoverFiles } from "./lib/bootstrap.js";
|
|
23
|
-
import { performImport, formatImportSummary } from "./lib/import.js";
|
|
24
26
|
import { loadConfig, generateConfigTemplate, DEFAULT_CONFIG, writeConfig, resolveTaskModel, ALL_PROVIDERS, getProviderModel } from "./lib/config.js";
|
|
25
|
-
import { GnosysEmbeddings } from "./lib/embeddings.js";
|
|
26
|
-
import { GnosysHybridSearch } from "./lib/hybridSearch.js";
|
|
27
|
-
import { GnosysAsk } from "./lib/ask.js";
|
|
28
27
|
import { getLLMProvider, isProviderAvailable } from "./lib/llm.js";
|
|
29
28
|
import { GnosysDB } from "./lib/db.js";
|
|
30
|
-
import { migrate, formatMigrationReport } from "./lib/migrate.js";
|
|
31
29
|
import { createProjectIdentity, readProjectIdentity, findProjectIdentity, migrateProject } from "./lib/projectIdentity.js";
|
|
32
30
|
import { setPreference, getPreference, getAllPreferences, deletePreference } from "./lib/preferences.js";
|
|
33
31
|
import { syncToTarget } from "./lib/rulesGen.js";
|
|
32
|
+
// Lazy-loaded inside action handlers (each ~200ms-2.5s on cold cache):
|
|
33
|
+
// - ./lib/embeddings.js (@huggingface/transformers — 80MB)
|
|
34
|
+
// - ./lib/hybridSearch.js (depends on embeddings)
|
|
35
|
+
// - ./lib/ask.js (depends on hybridSearch)
|
|
36
|
+
// - ./lib/import.js (mammoth, pdf-parse, turndown)
|
|
37
|
+
// - ./lib/bootstrap.js (file walking — 2.5s)
|
|
38
|
+
// - ./lib/ingest.js (LLM machinery)
|
|
39
|
+
// - ./lib/migrate.js (only migrate-db needs it)
|
|
34
40
|
// Load API keys from ~/.config/gnosys/.env (same as MCP server)
|
|
35
41
|
// IMPORTANT: We use dotenv.parse() instead of dotenv.config() because
|
|
36
42
|
// dotenv v17+ writes injection notices to stdout, which corrupts
|
|
@@ -313,6 +319,7 @@ program
|
|
|
313
319
|
.option("--federated", "Use federated search with tier boosting (project > user > global)")
|
|
314
320
|
.option("--scope <scope>", "Filter by scope: project, user, global (comma-separated for multiple)")
|
|
315
321
|
.option("-d, --directory <dir>", "Project directory for context")
|
|
322
|
+
.option("--id-format <format>", "ID display format: short | long | raw (default: short)", "short")
|
|
316
323
|
.action(async (query, opts) => {
|
|
317
324
|
// Federated search path — uses central DB with tier boosting
|
|
318
325
|
if (opts.federated || opts.scope) {
|
|
@@ -371,11 +378,16 @@ program
|
|
|
371
378
|
});
|
|
372
379
|
return;
|
|
373
380
|
}
|
|
381
|
+
const { formatMemoryId, buildProjectNameLookup, parseIdFormat } = await import("./lib/idFormat.js");
|
|
382
|
+
const idFormat = parseIdFormat(opts.idFormat);
|
|
383
|
+
const projectNames = buildProjectNameLookup(centralDb);
|
|
374
384
|
outputResult(!!opts.json, { query, count: results.length, results }, () => {
|
|
375
385
|
console.log(`Found ${results.length} results for "${query}":\n`);
|
|
376
386
|
for (const r of results) {
|
|
387
|
+
const projectName = r.project_id ? projectNames.get(r.project_id) || null : null;
|
|
388
|
+
const displayId = formatMemoryId(r.id, projectName, idFormat);
|
|
377
389
|
console.log(` ${r.title}`);
|
|
378
|
-
console.log(` id: ${
|
|
390
|
+
console.log(` id: ${displayId}`);
|
|
379
391
|
console.log(` ${r.snippet.replace(/>>>/g, "").replace(/<<</g, "")}`);
|
|
380
392
|
console.log();
|
|
381
393
|
}
|
|
@@ -510,6 +522,7 @@ program
|
|
|
510
522
|
}
|
|
511
523
|
const tagRegistry = new GnosysTagRegistry(writeTarget.store.getStorePath());
|
|
512
524
|
await tagRegistry.load();
|
|
525
|
+
const { GnosysIngestion } = await import("./lib/ingest.js");
|
|
513
526
|
const ingestion = new GnosysIngestion(writeTarget.store, tagRegistry);
|
|
514
527
|
if (!ingestion.isLLMAvailable) {
|
|
515
528
|
console.error("Error: No LLM provider available. Add an API key to ~/.config/gnosys/.env or use a local model: gnosys config set provider ollama");
|
|
@@ -910,6 +923,14 @@ setupCmd
|
|
|
910
923
|
const { runDreamSetup } = await import("./lib/setup.js");
|
|
911
924
|
await runDreamSetup({ directory: process.cwd() });
|
|
912
925
|
});
|
|
926
|
+
// `gnosys setup chat` — configure chat TUI (provider, recall, tools, prefix)
|
|
927
|
+
setupCmd
|
|
928
|
+
.command("chat")
|
|
929
|
+
.description("Configure the chat TUI — provider/model, recall behavior, tools, system-prompt prefix")
|
|
930
|
+
.action(async () => {
|
|
931
|
+
const { runChatSetup } = await import("./lib/setup.js");
|
|
932
|
+
await runChatSetup({ directory: process.cwd() });
|
|
933
|
+
});
|
|
913
934
|
// `gnosys setup ides` — configure IDE / MCP integrations standalone
|
|
914
935
|
setupCmd
|
|
915
936
|
.command("ides")
|
|
@@ -1775,6 +1796,7 @@ program
|
|
|
1775
1796
|
}
|
|
1776
1797
|
const tagRegistry = new GnosysTagRegistry(writeTarget.store.getStorePath());
|
|
1777
1798
|
await tagRegistry.load();
|
|
1799
|
+
const { GnosysIngestion } = await import("./lib/ingest.js");
|
|
1778
1800
|
const ingestion = new GnosysIngestion(writeTarget.store, tagRegistry);
|
|
1779
1801
|
if (!ingestion.isLLMAvailable) {
|
|
1780
1802
|
console.error("Error: No LLM provider available. Add an API key to ~/.config/gnosys/.env or use a local model: gnosys config set provider ollama");
|
|
@@ -2324,6 +2346,7 @@ program
|
|
|
2324
2346
|
process.exit(1);
|
|
2325
2347
|
}
|
|
2326
2348
|
// Show what we'll scan
|
|
2349
|
+
const { bootstrap, discoverFiles } = await import("./lib/bootstrap.js");
|
|
2327
2350
|
const files = await discoverFiles(sourceDir, opts.pattern);
|
|
2328
2351
|
console.log(`Found ${files.length} files in ${sourceDir}\n`);
|
|
2329
2352
|
if (files.length === 0) {
|
|
@@ -2411,6 +2434,8 @@ const importCmd = program
|
|
|
2411
2434
|
}
|
|
2412
2435
|
const tagRegistry = new GnosysTagRegistry(writeTarget.store.getStorePath());
|
|
2413
2436
|
await tagRegistry.load();
|
|
2437
|
+
const { GnosysIngestion } = await import("./lib/ingest.js");
|
|
2438
|
+
const { performImport, formatImportSummary } = await import("./lib/import.js");
|
|
2414
2439
|
const ingestion = new GnosysIngestion(writeTarget.store, tagRegistry);
|
|
2415
2440
|
const format = opts.format;
|
|
2416
2441
|
const mode = opts.mode;
|
|
@@ -2530,6 +2555,8 @@ program
|
|
|
2530
2555
|
for (const s of stores) {
|
|
2531
2556
|
await search.addStoreMemories(s.store, s.label);
|
|
2532
2557
|
}
|
|
2558
|
+
const { GnosysEmbeddings } = await import("./lib/embeddings.js");
|
|
2559
|
+
const { GnosysHybridSearch } = await import("./lib/hybridSearch.js");
|
|
2533
2560
|
const embeddings = new GnosysEmbeddings(storePath);
|
|
2534
2561
|
const hybridSearch = new GnosysHybridSearch(search, embeddings, resolver, storePath);
|
|
2535
2562
|
console.log("Building semantic embeddings (downloading model on first run)...");
|
|
@@ -2606,6 +2633,8 @@ program
|
|
|
2606
2633
|
for (const s of stores) {
|
|
2607
2634
|
await search.addStoreMemories(s.store, s.label);
|
|
2608
2635
|
}
|
|
2636
|
+
const { GnosysEmbeddings } = await import("./lib/embeddings.js");
|
|
2637
|
+
const { GnosysHybridSearch } = await import("./lib/hybridSearch.js");
|
|
2609
2638
|
const embeddings = new GnosysEmbeddings(storePath);
|
|
2610
2639
|
const hybridSearch = new GnosysHybridSearch(search, embeddings, resolver, storePath);
|
|
2611
2640
|
const mode = opts.mode;
|
|
@@ -2653,6 +2682,8 @@ program
|
|
|
2653
2682
|
for (const s of stores) {
|
|
2654
2683
|
await search.addStoreMemories(s.store, s.label);
|
|
2655
2684
|
}
|
|
2685
|
+
const { GnosysEmbeddings } = await import("./lib/embeddings.js");
|
|
2686
|
+
const { GnosysHybridSearch } = await import("./lib/hybridSearch.js");
|
|
2656
2687
|
const embeddings = new GnosysEmbeddings(storePath);
|
|
2657
2688
|
const hybridSearch = new GnosysHybridSearch(search, embeddings, resolver, storePath);
|
|
2658
2689
|
const results = await hybridSearch.hybridSearch(query, parseInt(opts.limit), "semantic");
|
|
@@ -2701,11 +2732,30 @@ program
|
|
|
2701
2732
|
for (const s of stores) {
|
|
2702
2733
|
await search.addStoreMemories(s.store, s.label);
|
|
2703
2734
|
}
|
|
2735
|
+
const { GnosysEmbeddings } = await import("./lib/embeddings.js");
|
|
2736
|
+
const { GnosysHybridSearch } = await import("./lib/hybridSearch.js");
|
|
2737
|
+
const { GnosysAsk } = await import("./lib/ask.js");
|
|
2704
2738
|
const embeddings = new GnosysEmbeddings(storePath);
|
|
2705
2739
|
const hybridSearch = new GnosysHybridSearch(search, embeddings, resolver, storePath);
|
|
2706
2740
|
const ask = new GnosysAsk(hybridSearch, cliConfig, resolver, storePath);
|
|
2707
2741
|
if (!ask.isLLMAvailable) {
|
|
2708
|
-
|
|
2742
|
+
// v5.8.0 (#8): provider-aware error instead of hardcoded ANTHROPIC_API_KEY.
|
|
2743
|
+
const providerName = cliConfig.llm.defaultProvider;
|
|
2744
|
+
const envVarMap = {
|
|
2745
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
2746
|
+
openai: "OPENAI_API_KEY",
|
|
2747
|
+
groq: "GROQ_API_KEY",
|
|
2748
|
+
xai: "XAI_API_KEY",
|
|
2749
|
+
mistral: "MISTRAL_API_KEY",
|
|
2750
|
+
};
|
|
2751
|
+
const envVar = envVarMap[providerName];
|
|
2752
|
+
if (envVar) {
|
|
2753
|
+
console.error(`No LLM provider available. Configured default is "${providerName}" but its key wasn't found. ` +
|
|
2754
|
+
`Set ${envVar}, run 'gnosys setup' to store one in the macOS Keychain, or add llm.${providerName}.apiKey to gnosys.json.`);
|
|
2755
|
+
}
|
|
2756
|
+
else {
|
|
2757
|
+
console.error(`No LLM provider available. Provider "${providerName}" is not reachable. Run 'gnosys setup' to configure one.`);
|
|
2758
|
+
}
|
|
2709
2759
|
process.exit(1);
|
|
2710
2760
|
}
|
|
2711
2761
|
// If --federated, pre-retrieve from central DB and inject as context
|
|
@@ -3584,6 +3634,7 @@ program
|
|
|
3584
3634
|
// Check embeddings
|
|
3585
3635
|
if (stores.length > 0) {
|
|
3586
3636
|
console.log("Embeddings:");
|
|
3637
|
+
const { GnosysEmbeddings } = await import("./lib/embeddings.js");
|
|
3587
3638
|
const embeddings = new GnosysEmbeddings(stores[0].path);
|
|
3588
3639
|
try {
|
|
3589
3640
|
const stats = embeddings.getStats();
|
|
@@ -4389,6 +4440,7 @@ program
|
|
|
4389
4440
|
console.error("No writable store found. Run 'gnosys init' first.");
|
|
4390
4441
|
process.exit(1);
|
|
4391
4442
|
}
|
|
4443
|
+
const { migrate, formatMigrationReport } = await import("./lib/migrate.js");
|
|
4392
4444
|
const stats = await migrate(writeTarget.store.getStorePath(), { verbose: opts.verbose });
|
|
4393
4445
|
console.log(formatMigrationReport(stats));
|
|
4394
4446
|
return;
|