gnosys 5.11.1 → 5.11.3
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 +2 -1
- package/dist/cli.js +7 -61
- package/dist/index.js +17 -3
- package/dist/lib/setup/sections/ides.js +1 -1
- package/dist/lib/setup.d.ts +4 -7
- package/dist/lib/setup.js +34 -21
- package/dist/postinstall.js +3 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -36,6 +36,7 @@ gnosys setup # configures provider, API key, and your IDE/agent
|
|
|
36
36
|
## Quick start
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
+
gnosys setup ides # wire MCP into your IDEs (once)
|
|
39
40
|
cd your-project
|
|
40
41
|
gnosys init # register the project
|
|
41
42
|
gnosys add "We chose PostgreSQL over MySQL for JSON support"
|
|
@@ -61,7 +62,7 @@ All tools are exposed over stdio and HTTP transports. Many tools accept an optio
|
|
|
61
62
|
|
|
62
63
|
This package installs two binaries:
|
|
63
64
|
|
|
64
|
-
- **`gnosys`** — the CLI. `gnosys serve` starts the MCP server (stdio by default, `--transport http` for the central-server topology). `gnosys
|
|
65
|
+
- **`gnosys`** — the CLI. `gnosys serve` starts the MCP server (stdio by default, `--transport http` for the central-server topology). `gnosys setup ides` wires `gnosys-mcp` into your IDE/agent configs.
|
|
65
66
|
- **`gnosys-mcp`** — a direct alias for the MCP stdio server entry, for MCP clients that prefer to spawn the server binary directly (e.g. `npx -y gnosys-mcp`). Equivalent to `gnosys serve`.
|
|
66
67
|
|
|
67
68
|
| Tool | Description |
|
package/dist/cli.js
CHANGED
|
@@ -973,7 +973,7 @@ setupCmd
|
|
|
973
973
|
// `gnosys setup ides` — configure IDE / MCP integrations standalone
|
|
974
974
|
setupCmd
|
|
975
975
|
.command("ides")
|
|
976
|
-
.description("Configure IDE integrations (Claude Code/Desktop, Cursor, Codex, Gemini CLI, Antigravity)")
|
|
976
|
+
.description("Configure IDE MCP integrations (Claude Code/Desktop, Cursor, Codex, Grok Build, Gemini CLI, Antigravity)")
|
|
977
977
|
.action(async () => {
|
|
978
978
|
const readline = await import("readline/promises");
|
|
979
979
|
const { runIdesSetup } = await import("./lib/setup/sections/ides.js");
|
|
@@ -1021,11 +1021,11 @@ setupCmd
|
|
|
1021
1021
|
// we need to revive a top-level shortcut later.
|
|
1022
1022
|
// ─── gnosys init ─────────────────────────────────────────────────────────
|
|
1023
1023
|
program
|
|
1024
|
-
.command("init
|
|
1025
|
-
.description("Initialize Gnosys in the current directory
|
|
1024
|
+
.command("init")
|
|
1025
|
+
.description("Initialize Gnosys in the current directory (project store, identity, central DB). Wire IDE MCP servers with: gnosys setup ides")
|
|
1026
1026
|
.option("-d, --directory <dir>", "Target directory (default: cwd)")
|
|
1027
1027
|
.option("-n, --name <name>", "Project name (default: directory basename)")
|
|
1028
|
-
.action(async (
|
|
1028
|
+
.action(async (opts) => {
|
|
1029
1029
|
const targetDir = opts.directory
|
|
1030
1030
|
? path.resolve(opts.directory)
|
|
1031
1031
|
: process.cwd();
|
|
@@ -1127,62 +1127,8 @@ program
|
|
|
1127
1127
|
else {
|
|
1128
1128
|
console.log(`\nIDE hooks: ${hookResult.details}`);
|
|
1129
1129
|
}
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
const validIdes = ["cursor", "claude", "claude-desktop", "codex", "gemini-cli", "antigravity"];
|
|
1133
|
-
const normalizedIde = ide.toLowerCase();
|
|
1134
|
-
if (!validIdes.includes(normalizedIde)) {
|
|
1135
|
-
console.log(`\nUnknown IDE: "${ide}". Valid options: ${validIdes.join(", ")}`);
|
|
1136
|
-
}
|
|
1137
|
-
else {
|
|
1138
|
-
const { configureCursor, configureClaudeCode, configureCodex } = await import("./lib/projectIdentity.js");
|
|
1139
|
-
// Cursor/Claude/Codex have IDE-specific session hooks. Gemini CLI and
|
|
1140
|
-
// Antigravity don't yet, so we skip the hook step for them.
|
|
1141
|
-
let result;
|
|
1142
|
-
switch (normalizedIde) {
|
|
1143
|
-
case "cursor":
|
|
1144
|
-
result = await configureCursor(targetDir);
|
|
1145
|
-
break;
|
|
1146
|
-
case "claude":
|
|
1147
|
-
result = await configureClaudeCode(targetDir);
|
|
1148
|
-
break;
|
|
1149
|
-
case "codex":
|
|
1150
|
-
result = await configureCodex(targetDir);
|
|
1151
|
-
break;
|
|
1152
|
-
}
|
|
1153
|
-
if (result?.configured) {
|
|
1154
|
-
console.log(`\nIDE setup (${result.ide}):`);
|
|
1155
|
-
console.log(` ${result.details}`);
|
|
1156
|
-
console.log(` File: ${result.filePath}`);
|
|
1157
|
-
}
|
|
1158
|
-
// Set up MCP config for the IDE
|
|
1159
|
-
const { setupIDE } = await import("./lib/setup.js");
|
|
1160
|
-
const mcp = await setupIDE(normalizedIde, targetDir);
|
|
1161
|
-
if (mcp.success) {
|
|
1162
|
-
console.log(` MCP: ${mcp.message}`);
|
|
1163
|
-
}
|
|
1164
|
-
// Update agentRulesTarget in gnosys.json (only for IDEs with rules files)
|
|
1165
|
-
const targetMap = {
|
|
1166
|
-
cursor: ".cursor/rules/gnosys.mdc",
|
|
1167
|
-
claude: "CLAUDE.md",
|
|
1168
|
-
codex: "CODEX.md",
|
|
1169
|
-
};
|
|
1170
|
-
if (targetMap[normalizedIde]) {
|
|
1171
|
-
const identityPath = path.join(storePath, "gnosys.json");
|
|
1172
|
-
try {
|
|
1173
|
-
const identityContent = await fs.readFile(identityPath, "utf-8");
|
|
1174
|
-
const identity = JSON.parse(identityContent);
|
|
1175
|
-
identity.agentRulesTarget = targetMap[normalizedIde];
|
|
1176
|
-
await fs.writeFile(identityPath, JSON.stringify(identity, null, 2) + "\n", "utf-8");
|
|
1177
|
-
console.log(` Config: agentRulesTarget → ${identity.agentRulesTarget}`);
|
|
1178
|
-
}
|
|
1179
|
-
catch {
|
|
1180
|
-
// Non-critical
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
console.log(`\nStart adding memories with: gnosys add "your knowledge here"`);
|
|
1130
|
+
console.log(`\nWire IDE MCP servers: gnosys setup ides`);
|
|
1131
|
+
console.log(`Start adding memories with: gnosys add "your knowledge here"`);
|
|
1186
1132
|
});
|
|
1187
1133
|
// ─── gnosys migrate ─────────────────────────────────────────────────────
|
|
1188
1134
|
program
|
|
@@ -4422,7 +4368,7 @@ exportCmd
|
|
|
4422
4368
|
// ─── gnosys serve ────────────────────────────────────────────────────────
|
|
4423
4369
|
program
|
|
4424
4370
|
.command("serve")
|
|
4425
|
-
.description("Start the MCP server (stdio mode). Used by IDE integrations — Claude Code/Desktop, Cursor, Codex, etc. spawn this command in the background to talk to gnosys via the Model Context Protocol. You don't normally invoke this yourself; `gnosys
|
|
4371
|
+
.description("Start the MCP server (stdio mode). Used by IDE integrations — Claude Code/Desktop, Cursor, Codex, etc. spawn this command in the background to talk to gnosys via the Model Context Protocol. You don't normally invoke this yourself; `gnosys setup ides` wires gnosys-mcp into your IDE configs.")
|
|
4426
4372
|
.option("--with-maintenance", "Run maintenance every 6 hours in background")
|
|
4427
4373
|
.option("--transport <mode>", "Transport: 'stdio' (default) or 'http' (central-server topology)", "stdio")
|
|
4428
4374
|
.option("--host <addr>", "HTTP bind address — http transport (default 127.0.0.1; use a tailnet addr to share)", "127.0.0.1")
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// MCP stdio JSON protocol. parse() is a pure function with no side effects.
|
|
11
11
|
import dotenv from "dotenv";
|
|
12
12
|
import path from "path";
|
|
13
|
-
import { readFileSync } from "fs";
|
|
13
|
+
import { readFileSync, realpathSync } from "fs";
|
|
14
14
|
import { fileURLToPath } from "url";
|
|
15
15
|
const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
|
|
16
16
|
try {
|
|
@@ -3092,8 +3092,22 @@ export async function startMcpServer() {
|
|
|
3092
3092
|
// Notification handler setup failed — non-critical
|
|
3093
3093
|
}
|
|
3094
3094
|
}
|
|
3095
|
-
|
|
3096
|
-
|
|
3095
|
+
/** True when this file is the process entry (direct path or npm `gnosys-mcp` bin symlink). */
|
|
3096
|
+
function isMcpEntryPoint() {
|
|
3097
|
+
if (!process.argv[1])
|
|
3098
|
+
return false;
|
|
3099
|
+
const entry = path.resolve(process.argv[1]);
|
|
3100
|
+
const self = fileURLToPath(import.meta.url);
|
|
3101
|
+
if (entry === self)
|
|
3102
|
+
return true;
|
|
3103
|
+
try {
|
|
3104
|
+
return realpathSync(entry) === realpathSync(self);
|
|
3105
|
+
}
|
|
3106
|
+
catch {
|
|
3107
|
+
return false;
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
if (isMcpEntryPoint()) {
|
|
3097
3111
|
startMcpServer().catch((err) => {
|
|
3098
3112
|
console.error("Fatal error:", err);
|
|
3099
3113
|
process.exit(1);
|
|
@@ -38,7 +38,7 @@ const IDE_TARGET_DISPLAY = {
|
|
|
38
38
|
codex: ".codex/mcp.json",
|
|
39
39
|
"gemini-cli": "~/.gemini/settings.json",
|
|
40
40
|
antigravity: "~/.gemini/antigravity/mcp_config.json",
|
|
41
|
-
"grok-build": "~/.grok/config.toml",
|
|
41
|
+
"grok-build": "~/.grok/config.toml ([mcp_servers.gnosys])",
|
|
42
42
|
};
|
|
43
43
|
function ideTarget(ide) {
|
|
44
44
|
return IDE_TARGET_DISPLAY[ide] ?? `.${ide}/mcp.json`;
|
package/dist/lib/setup.d.ts
CHANGED
|
@@ -56,14 +56,11 @@ export declare function writeApiKey(provider: string, key: string): Promise<void
|
|
|
56
56
|
*/
|
|
57
57
|
export declare function detectIDEs(projectDir: string): Promise<string[]>;
|
|
58
58
|
/**
|
|
59
|
-
* Replace (or append) a `[
|
|
60
|
-
*
|
|
61
|
-
* deci-046 read-then-merge rule. We can't pull in a TOML dependency
|
|
62
|
-
* without adding to package.json, so we ship a minimal hand-rolled
|
|
63
|
-
* updater scoped exactly to the `[mcp.gnosys]` use case.
|
|
59
|
+
* Replace (or append) a `[mcp_servers.<name>]` block inside Grok Build's
|
|
60
|
+
* `~/.grok/config.toml`. Preserves every line outside that block (deci-046).
|
|
64
61
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
62
|
+
* Grok Build reads `mcp_servers.*` only — legacy `[mcp.*]` blocks are ignored
|
|
63
|
+
* by `grok mcp list` / the agent runtime (see ~/.grok/README.md).
|
|
67
64
|
*
|
|
68
65
|
* Exported for tests.
|
|
69
66
|
*/
|
package/dist/lib/setup.js
CHANGED
|
@@ -567,33 +567,48 @@ export async function detectIDEs(projectDir) {
|
|
|
567
567
|
}
|
|
568
568
|
return detected;
|
|
569
569
|
}
|
|
570
|
+
/** Remove a single `[section]` block from Grok TOML (hand-rolled; see upsertGrokMcpBlock). */
|
|
571
|
+
function removeGrokTomlSection(existing, sectionHeader) {
|
|
572
|
+
const lines = existing.split("\n");
|
|
573
|
+
const headerIdx = lines.findIndex((line) => line.trim() === sectionHeader);
|
|
574
|
+
if (headerIdx === -1)
|
|
575
|
+
return existing;
|
|
576
|
+
let endIdx = lines.length;
|
|
577
|
+
for (let i = headerIdx + 1; i < lines.length; i++) {
|
|
578
|
+
if (/^\s*\[/.test(lines[i])) {
|
|
579
|
+
endIdx = i;
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
const before = lines.slice(0, headerIdx).join("\n");
|
|
584
|
+
const after = lines.slice(endIdx).join("\n");
|
|
585
|
+
const merged = [before, after].filter((s) => s.length > 0).join("\n");
|
|
586
|
+
return merged.length > 0 ? `${merged}\n` : "";
|
|
587
|
+
}
|
|
570
588
|
/**
|
|
571
|
-
* Replace (or append) a `[
|
|
572
|
-
*
|
|
573
|
-
* deci-046 read-then-merge rule. We can't pull in a TOML dependency
|
|
574
|
-
* without adding to package.json, so we ship a minimal hand-rolled
|
|
575
|
-
* updater scoped exactly to the `[mcp.gnosys]` use case.
|
|
589
|
+
* Replace (or append) a `[mcp_servers.<name>]` block inside Grok Build's
|
|
590
|
+
* `~/.grok/config.toml`. Preserves every line outside that block (deci-046).
|
|
576
591
|
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
592
|
+
* Grok Build reads `mcp_servers.*` only — legacy `[mcp.*]` blocks are ignored
|
|
593
|
+
* by `grok mcp list` / the agent runtime (see ~/.grok/README.md).
|
|
579
594
|
*
|
|
580
595
|
* Exported for tests.
|
|
581
596
|
*/
|
|
582
597
|
export function upsertGrokMcpBlock(existing, name, entry) {
|
|
583
|
-
|
|
584
|
-
|
|
598
|
+
// Drop mistaken v5.9.4 `[mcp.<name>]` sections so we don't leave dead config.
|
|
599
|
+
let content = removeGrokTomlSection(existing, `[mcp.${name}]`);
|
|
600
|
+
const sectionHeader = `[mcp_servers.${name}]`;
|
|
601
|
+
const lines = content.split("\n");
|
|
585
602
|
const headerIdx = lines.findIndex((line) => line.trim() === sectionHeader);
|
|
586
603
|
const blockBody = renderGrokMcpBlock(entry);
|
|
587
604
|
if (headerIdx === -1) {
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
605
|
+
const prefix = content.length === 0 || content.endsWith("\n\n")
|
|
606
|
+
? content
|
|
607
|
+
: content.endsWith("\n")
|
|
608
|
+
? `${content}\n`
|
|
609
|
+
: `${content}\n\n`;
|
|
592
610
|
return `${prefix}${sectionHeader}\n${blockBody}`;
|
|
593
611
|
}
|
|
594
|
-
// Replace the existing block — everything from sectionHeader up to the
|
|
595
|
-
// next `[` header (or EOF). Count blank lines immediately after the block
|
|
596
|
-
// so we can preserve the original spacing before the next section.
|
|
597
612
|
let endIdx = lines.length;
|
|
598
613
|
for (let i = headerIdx + 1; i < lines.length; i++) {
|
|
599
614
|
if (/^\s*\[/.test(lines[i])) {
|
|
@@ -611,7 +626,6 @@ export function upsertGrokMcpBlock(existing, name, entry) {
|
|
|
611
626
|
const beforeBlock = lines.slice(0, headerIdx).join("\n");
|
|
612
627
|
const head = beforeBlock.length > 0 ? `${beforeBlock}\n` : "";
|
|
613
628
|
if (!hasFollowingSection) {
|
|
614
|
-
// No following section — drop trailing blank lines and end with a single \n.
|
|
615
629
|
return `${head}${sectionHeader}\n${blockBody}`;
|
|
616
630
|
}
|
|
617
631
|
const gap = "\n".repeat(Math.max(1, trailingBlankBeforeNext));
|
|
@@ -814,10 +828,9 @@ export async function setupIDE(ide, projectDir) {
|
|
|
814
828
|
return { success: true, message: "Antigravity MCP config updated (~/.gemini/antigravity/mcp_config.json)" };
|
|
815
829
|
}
|
|
816
830
|
case "grok-build": {
|
|
817
|
-
// v5.9.4 Bug 12 — Grok Build reads
|
|
818
|
-
// `[mcp.<name>]`
|
|
819
|
-
// unrelated TOML content (per deci-046 read-then-merge rule)
|
|
820
|
-
// helper preserves every line outside the `[mcp.gnosys]` block.
|
|
831
|
+
// v5.9.4 Bug 12 — Grok Build reads MCP from `[mcp_servers.<name>]`
|
|
832
|
+
// in ~/.grok/config.toml (not `[mcp.<name>]`). We never clobber
|
|
833
|
+
// unrelated TOML content (per deci-046 read-then-merge rule).
|
|
821
834
|
const grokDir = path.join(os.homedir(), ".grok");
|
|
822
835
|
const configPath = path.join(grokDir, "config.toml");
|
|
823
836
|
await fs.mkdir(grokDir, { recursive: true });
|
package/dist/postinstall.js
CHANGED
|
@@ -77,8 +77,9 @@ async function main() {
|
|
|
77
77
|
out();
|
|
78
78
|
out(" Get started:");
|
|
79
79
|
out(" 1. gnosys setup configure LLM providers and preferences");
|
|
80
|
-
out(" 2. gnosys
|
|
81
|
-
out(" 3. gnosys
|
|
80
|
+
out(" 2. gnosys setup ides wire MCP into your IDEs (once per machine)");
|
|
81
|
+
out(" 3. gnosys init initialize gnosys in a project directory");
|
|
82
|
+
out(" 4. gnosys status check project status");
|
|
82
83
|
out();
|
|
83
84
|
// If interactive, offer to run setup automatically
|
|
84
85
|
if (isInteractive) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gnosys",
|
|
3
|
-
"version": "5.11.
|
|
3
|
+
"version": "5.11.3",
|
|
4
4
|
"description": "Gnosys — Persistent Memory for AI Agents. Sandbox-first runtime, central SQLite brain, federated search, Dream Mode, Web Knowledge Base, Obsidian export.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"docs:mcp-tools": "node scripts/gen-mcp-tools.mjs --write",
|
|
35
35
|
"docs:cli": "node scripts/gen-cli-docs.mjs --write",
|
|
36
36
|
"postinstall": "node dist/postinstall.js || true",
|
|
37
|
-
"prepublishOnly": "npm run build:publish"
|
|
37
|
+
"prepublishOnly": "npm run build:publish && node -e \"const fs=require('fs');for (const f of ['dist/cli.js','dist/index.js']) fs.chmodSync(f,0o755)\""
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@anthropic-ai/sdk": "^0.78.0",
|