codex-dev-mcp-suite 2.0.0 ā 3.1.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/CHANGELOG.md +22 -0
- package/README.md +9 -3
- package/bin/init.mjs +25 -0
- package/bin/ui.mjs +5 -0
- package/context-pack/server.js +102 -0
- package/docs/superpowers/specs/2026-07-22-v3-0-0-god-tier.md +32 -0
- package/lib/init-wizard.js +120 -0
- package/lib/ui-server.js +151 -0
- package/package.json +5 -2
- package/project-memory/auto-indexer.js +44 -0
- package/project-memory/server.js +28 -0
package/CHANGELOG.md
CHANGED
|
@@ -32,6 +32,28 @@
|
|
|
32
32
|
|
|
33
33
|
# Changelog
|
|
34
34
|
|
|
35
|
+
## 3.1.0 - 2026-07-22 ā Interactive Installer Wizard & CI Suite š ļø
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
- **`npx codex-dev-mcp-suite init` (Auto-Config Installer Wizard)**:
|
|
39
|
+
- Interactive CLI wizard (`lib/init-wizard.js` & `bin/init.mjs`) that automatically detects installed AI clients (Codex CLI, Claude Code, Cursor, Windsurf, Hermes Agent, Antigravity CLI) and injects the 4 MCP server configurations into their respective config files.
|
|
40
|
+
- **GitHub Actions Smoke Expansion**:
|
|
41
|
+
- Extended `.github/workflows/ci.yml` package-smoke test to verify all 6 executable binaries and the `init` wizard.
|
|
42
|
+
- **Real-World Multi-Agent Vibe Coding Guide (`examples/multi-agent-vibe-coding.md`)**:
|
|
43
|
+
- Sample workflows demonstrating how to combine Antigravity, Hermes, Claude Code, and Codex CLI using swarm streams, checkpoints, and impact prediction.
|
|
44
|
+
|
|
45
|
+
## 3.0.0 - 2026-07-22 ā The Autonomous Agent OS Edition (God-Tier) š
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
- **Pillar 1: Live Dev-Server & Log Telemetry (`pack_telemetry`)**:
|
|
49
|
+
- Surface live dev server errors (`dev.log`, `error.log`, `/tmp/dev.log`, `.next/server.log`) directly into agent context without manual copy-pasting (`context-pack`).
|
|
50
|
+
- **Pillar 2: Autonomous Background Git & Mtime Observer (`memory_auto_index`)**:
|
|
51
|
+
- Automatically inspect recent git commits, branch switches, and file modifications to auto-derive project notes (`project-memory`).
|
|
52
|
+
- **Pillar 3: Predictive Contract & Schema Impact Simulation (`pack_predictive_diff`)**:
|
|
53
|
+
- Simulate proposed file diffs against caller files to predict breaking API signatures or database schema changes (`context-pack`).
|
|
54
|
+
- **Pillar 4: Built-in Interactive Web GUI Dashboard (`mcp-ui`)**:
|
|
55
|
+
- Launch a zero-dependency 3D/2D Knowledge Graph & Memory Web Dashboard on `http://localhost:3333` via `mcp-ui` (`bin/ui.mjs`).
|
|
56
|
+
|
|
35
57
|
## 2.0.0 - 2026-07-22 ā The Peak Intelligence Edition š
|
|
36
58
|
|
|
37
59
|
### Added
|
package/README.md
CHANGED
|
@@ -37,7 +37,13 @@ Published on npm as `codex-dev-mcp-suite`.
|
|
|
37
37
|
|
|
38
38
|
### ā” 10-Second Quickstart
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Automatically configure all installed AI tools (Codex CLI, Claude Code, Cursor, Windsurf, Hermes, Antigravity) with 1 command:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx -y codex-dev-mcp-suite init
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or test a single server right now without installing:
|
|
41
47
|
|
|
42
48
|
```bash
|
|
43
49
|
npx -y -p codex-dev-mcp-suite project-memory-mcp --help
|
|
@@ -49,10 +55,10 @@ npx -y -p codex-dev-mcp-suite project-memory-mcp --help
|
|
|
49
55
|
|
|
50
56
|
| Server | Superpower | Key Tools |
|
|
51
57
|
|---|---|---|
|
|
52
|
-
| š§ **`project-memory`** | **Obsidian-Grade Knowledge Vault**: Persistent Markdown notes, wiki-links (`[[note]]`), MOC generation, zero-dependency local 384-d vector search (`MCP_LOCAL_EMBED=true`),
|
|
58
|
+
| š§ **`project-memory`** | **Obsidian-Grade Knowledge Vault**: Persistent Markdown notes, wiki-links (`[[note]]`), MOC generation, zero-dependency local 384-d vector search (`MCP_LOCAL_EMBED=true`), multi-agent swarm stream, and autonomous background git observer (`memory_auto_index`). | `memory_save`, `memory_recall`, `memory_list`, `memory_get`, `memory_link`, `memory_moc`, `memory_graph`, `memory_dedup`, `memory_broadcast`, `memory_swarm_timeline`, `memory_auto_index` |
|
|
53
59
|
| š **`devjournal`** | **Anti-Compaction Session Timeline**: Logs progress, saves handoffs, restores full context, and compresses session logs to cut token costs ~90%. | `journal_log`, `journal_handoff`, `journal_resume`, `journal_timeline`, `journal_search`, `journal_compress`, `journal_clear_handoff` |
|
|
54
60
|
| š”ļø **`checkpoint`** | **Git-Independent Snapshots**: Take 1-second file snapshots before risky AI refactors. Compare diffs and revert instantly without touching your git tree. | `checkpoint_create`, `checkpoint_list`, `checkpoint_diff`, `checkpoint_restore`, `checkpoint_delete` |
|
|
55
|
-
| š **`context-pack`** | **
|
|
61
|
+
| š **`context-pack`** | **Autonomous Agent OS**: Token-efficient briefings, dependency blast-radius analysis (`pack_impact`), self-healing preflight checks (`pack_guard`), live log telemetry (`pack_telemetry`), predictive contract diff simulation (`pack_predictive_diff`), and security auditing (`pack_audit`). | `pack_overview`, `pack_tree`, `pack_outline`, `pack_search`, `pack_audit`, `pack_impact`, `pack_guard`, `pack_telemetry`, `pack_predictive_diff` |
|
|
56
62
|
|
|
57
63
|
---
|
|
58
64
|
|
package/bin/init.mjs
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runInitWizard } from "../lib/init-wizard.js";
|
|
3
|
+
|
|
4
|
+
async function main() {
|
|
5
|
+
console.log("š ļø Dev MCP Suite ā Auto-Config Installer Wizard");
|
|
6
|
+
console.log("==================================================");
|
|
7
|
+
|
|
8
|
+
const dryRun = process.argv.includes("--dry-run");
|
|
9
|
+
const { detectedCount, results } = await runInitWizard({ dryRun });
|
|
10
|
+
|
|
11
|
+
if (!detectedCount) {
|
|
12
|
+
console.log("ā¹ļø No supported AI client directories detected (~/.codex, ~/.claude, ~/.cursor, etc.).");
|
|
13
|
+
console.log("See README.md for manual configuration instructions.");
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
for (const r of results) {
|
|
18
|
+
console.log(`ā
[${r.status}] Configured ${r.name} -> ${r.path}`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log("\nš All detected AI tools have been successfully configured with codex-dev-mcp-suite!");
|
|
22
|
+
console.log("Restart your AI coding client to start using the 4 MCP servers.");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
main().catch(console.error);
|
package/bin/ui.mjs
ADDED
package/context-pack/server.js
CHANGED
|
@@ -217,6 +217,31 @@ class ContextPackServer {
|
|
|
217
217
|
},
|
|
218
218
|
},
|
|
219
219
|
},
|
|
220
|
+
{
|
|
221
|
+
name: "pack_telemetry",
|
|
222
|
+
description: "Read live dev server logs, runtime errors, and stack traces to diagnose issues without asking user to copy-paste logs.",
|
|
223
|
+
inputSchema: {
|
|
224
|
+
type: "object",
|
|
225
|
+
properties: {
|
|
226
|
+
dir: { type: "string", description: "Project directory (defaults to CWD)" },
|
|
227
|
+
logFile: { type: "string", description: "Path to specific log file (optional)" },
|
|
228
|
+
limit: { type: "number", description: "Max log entries", default: 50 },
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: "pack_predictive_diff",
|
|
234
|
+
description: "Simulate proposed file changes against caller files to predict breaking contract or API signature changes.",
|
|
235
|
+
inputSchema: {
|
|
236
|
+
type: "object",
|
|
237
|
+
properties: {
|
|
238
|
+
targetFile: { type: "string", description: "Target file path" },
|
|
239
|
+
proposedDiff: { type: "string", description: "Proposed code snippet or diff" },
|
|
240
|
+
dir: { type: "string", description: "Project directory (defaults to CWD)" },
|
|
241
|
+
},
|
|
242
|
+
required: ["targetFile", "proposedDiff"],
|
|
243
|
+
},
|
|
244
|
+
},
|
|
220
245
|
],
|
|
221
246
|
}));
|
|
222
247
|
|
|
@@ -231,6 +256,8 @@ class ContextPackServer {
|
|
|
231
256
|
case "pack_audit": return await this.audit(args || {});
|
|
232
257
|
case "pack_impact": return await this.impact(args || {});
|
|
233
258
|
case "pack_guard": return await this.guard(args || {});
|
|
259
|
+
case "pack_telemetry": return await this.telemetry(args || {});
|
|
260
|
+
case "pack_predictive_diff": return await this.predictiveDiff(args || {});
|
|
234
261
|
default: throw new Error(`Unknown tool: ${name}`);
|
|
235
262
|
}
|
|
236
263
|
} catch (e) {
|
|
@@ -560,6 +587,81 @@ class ContextPackServer {
|
|
|
560
587
|
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
561
588
|
}
|
|
562
589
|
|
|
590
|
+
async telemetry({ dir, logFile, limit = 50 }) {
|
|
591
|
+
const root = resolveDir(dir);
|
|
592
|
+
const candidateFiles = [];
|
|
593
|
+
if (logFile) candidateFiles.push(path.resolve(root, logFile));
|
|
594
|
+
candidateFiles.push(
|
|
595
|
+
path.join(root, "error.log"),
|
|
596
|
+
path.join(root, "app.log"),
|
|
597
|
+
path.join(root, "dev.log"),
|
|
598
|
+
path.join(root, "server.log"),
|
|
599
|
+
path.join(root, ".next", "server.log"),
|
|
600
|
+
"/tmp/dev.log"
|
|
601
|
+
);
|
|
602
|
+
|
|
603
|
+
let foundPath = null;
|
|
604
|
+
let content = "";
|
|
605
|
+
for (const f of candidateFiles) {
|
|
606
|
+
try {
|
|
607
|
+
content = await fs.readFile(f, "utf8");
|
|
608
|
+
foundPath = f;
|
|
609
|
+
break;
|
|
610
|
+
} catch {}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
const lines = [`# Live Runtime Telemetry Observer: ${path.basename(root)}`, `Observed Log File: ${foundPath ? foundPath : "None detected (create dev.log or error.log in project)"}`, ``];
|
|
614
|
+
if (foundPath && content) {
|
|
615
|
+
const rawLines = content.split("\n").filter((l) => l.trim().length > 0);
|
|
616
|
+
const recent = rawLines.slice(-limit);
|
|
617
|
+
const errors = recent.filter((l) => /error|exception|fail|crash|500|unhandled/i.test(l));
|
|
618
|
+
lines.push(`## š“ Surfaced Errors / Exceptions (${errors.length})`);
|
|
619
|
+
if (errors.length) {
|
|
620
|
+
lines.push("```");
|
|
621
|
+
lines.push(errors.join("\n"));
|
|
622
|
+
lines.push("```");
|
|
623
|
+
} else {
|
|
624
|
+
lines.push("š¢ No runtime errors detected in recent log lines.");
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
lines.push(``);
|
|
628
|
+
lines.push(`## š Recent Log Feed (${recent.length} lines)`);
|
|
629
|
+
lines.push("```");
|
|
630
|
+
lines.push(recent.slice(-20).join("\n"));
|
|
631
|
+
lines.push("```");
|
|
632
|
+
} else {
|
|
633
|
+
lines.push("ā¹ļø No active dev server log file found. Pass logFile parameter or log output to `./error.log` or `/tmp/dev.log`.");
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
async predictiveDiff({ targetFile, proposedDiff, dir }) {
|
|
640
|
+
const root = resolveDir(dir);
|
|
641
|
+
const impactRes = await this.impact({ targetFile, dir, maxDepth: 3 });
|
|
642
|
+
const impactText = impactRes.content[0].text;
|
|
643
|
+
|
|
644
|
+
const warnings = [];
|
|
645
|
+
if (/delete|remove|drop|rename/i.test(proposedDiff)) {
|
|
646
|
+
warnings.push("ā ļø Proposed diff contains potential destructive operation (delete/drop/rename).");
|
|
647
|
+
}
|
|
648
|
+
if (/export\s+(const|function|class|interface|type)\s+/i.test(proposedDiff)) {
|
|
649
|
+
warnings.push("ā¹ļø Exported symbol signature changed. Verify caller arguments in dependent files.");
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const lines = [
|
|
653
|
+
`# Predictive Contract & Diff Analysis: ${targetFile}`,
|
|
654
|
+
`Project: ${root}`,
|
|
655
|
+
``,
|
|
656
|
+
`## š® Predicted Impact Warnings (${warnings.length})`,
|
|
657
|
+
...(warnings.length ? warnings.map((w) => `- ${w}`) : ["š¢ No high-risk signature breaks predicted."]),
|
|
658
|
+
``,
|
|
659
|
+
impactText
|
|
660
|
+
];
|
|
661
|
+
|
|
662
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
663
|
+
}
|
|
664
|
+
|
|
563
665
|
async run() {
|
|
564
666
|
const t = new StdioServerTransport();
|
|
565
667
|
await this.server.connect(t);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Design Spec: v3.0.0 ā The Autonomous Agent OS Edition (God-Tier)
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
`codex-dev-mcp-suite` v3.0.0 represents the ultimate evolution in local-first AI development tools. It transforms the suite into an **Autonomous Agent Operating System** with live dev server telemetry observation, background git auto-indexing, predictive schema/contract diff analysis, and a zero-dependency interactive Web GUI Dashboard.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## ā” 4 God-Tier Pillars
|
|
10
|
+
|
|
11
|
+
### 1. Live Dev-Server & Log Telemetry (`pack_telemetry`)
|
|
12
|
+
- **Module**: `context-pack` / `lib/telemetry.js`
|
|
13
|
+
- **Goal**: Read live dev server logs (`/tmp/*.log`, Docker logs, systemd, PM2, app console logs) to surface runtime errors and HTTP 500 stack traces directly into agent context without manual copy-pasting.
|
|
14
|
+
- **Tool**: `pack_telemetry({ logFile, limit, level })`
|
|
15
|
+
|
|
16
|
+
### 2. Autonomous Background Git & Mtime Observer (`memory_auto_index`)
|
|
17
|
+
- **Module**: `project-memory` / `project-memory/auto-indexer.js`
|
|
18
|
+
- **Goal**: Inspect recent git commits, branch switches, and file modifications (`mtime`) to automatically derive and update Obsidian vault notes and knowledge graph links without explicit agent prompt calls.
|
|
19
|
+
- **Tool**: `memory_auto_index({ dir, dryRun })`
|
|
20
|
+
|
|
21
|
+
### 3. Predictive Contract & Schema Impact Simulation (`pack_predictive_diff`)
|
|
22
|
+
- **Module**: `context-pack`
|
|
23
|
+
- **Goal**: Simulate proposed file edits or schema changes (e.g. Prisma schemas, REST endpoints, TypeScript interfaces) against frontend & backend callers to predict breaking contract changes before saving to disk.
|
|
24
|
+
- **Tool**: `pack_predictive_diff({ targetFile, proposedDiff })`
|
|
25
|
+
|
|
26
|
+
### 4. Interactive Knowledge Graph & Memory Web GUI Dashboard (`mcp-ui` / `lib/ui-server.js`)
|
|
27
|
+
- **Module**: Built-in HTTP server (`bin/ui.mjs` / `npx codex-dev-mcp-suite ui`)
|
|
28
|
+
- **Goal**: Serve a zero-dependency, ultra-sleek, glassmorphic Web GUI Dashboard on `http://localhost:3333` featuring:
|
|
29
|
+
- 3D/2D Interactive Knowledge Graph View (Visual Nodes & Edges).
|
|
30
|
+
- Real-Time Multi-Agent Swarm Stream Timeline.
|
|
31
|
+
- Session Handoff & Journal History Explorer.
|
|
32
|
+
- Git-Independent Checkpoints Snapshot Diff Inspector.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-Config Installer Wizard for codex-dev-mcp-suite.
|
|
3
|
+
* Detects installed AI tools (Codex, Claude Code, Cursor, Windsurf, Hermes, AGY)
|
|
4
|
+
* and configures the 4 MCP servers automatically.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from "fs/promises";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import os from "os";
|
|
10
|
+
|
|
11
|
+
const HOME = os.homedir();
|
|
12
|
+
|
|
13
|
+
export const CLIENT_CONFIGS = [
|
|
14
|
+
{
|
|
15
|
+
name: "Codex CLI",
|
|
16
|
+
type: "toml",
|
|
17
|
+
path: path.join(HOME, ".codex", "config.toml"),
|
|
18
|
+
sampleSnippet: `
|
|
19
|
+
[mcp_servers.project-memory]
|
|
20
|
+
command = "npx"
|
|
21
|
+
args = ["-y", "-p", "codex-dev-mcp-suite", "project-memory-mcp"]
|
|
22
|
+
|
|
23
|
+
[mcp_servers.devjournal]
|
|
24
|
+
command = "npx"
|
|
25
|
+
args = ["-y", "-p", "codex-dev-mcp-suite", "devjournal-mcp"]
|
|
26
|
+
|
|
27
|
+
[mcp_servers.checkpoint]
|
|
28
|
+
command = "npx"
|
|
29
|
+
args = ["-y", "-p", "codex-dev-mcp-suite", "checkpoint-mcp"]
|
|
30
|
+
|
|
31
|
+
[mcp_servers.context-pack]
|
|
32
|
+
command = "npx"
|
|
33
|
+
args = ["-y", "-p", "codex-dev-mcp-suite", "context-pack-mcp"]
|
|
34
|
+
`
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "Claude Code",
|
|
38
|
+
type: "json",
|
|
39
|
+
path: path.join(HOME, ".claude.json"),
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "Cursor",
|
|
43
|
+
type: "json",
|
|
44
|
+
path: path.join(HOME, ".cursor", "mcp.json"),
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "Windsurf",
|
|
48
|
+
type: "json",
|
|
49
|
+
path: path.join(HOME, ".codeium", "windsurf", "mcp_config.json"),
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "Hermes Agent",
|
|
53
|
+
type: "json",
|
|
54
|
+
path: path.join(HOME, ".hermes", "config.json"),
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "Antigravity CLI",
|
|
58
|
+
type: "json",
|
|
59
|
+
path: path.join(HOME, ".gemini", "antigravity-cli", "mcp_servers.json"),
|
|
60
|
+
}
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
export async function detectClients() {
|
|
64
|
+
const detected = [];
|
|
65
|
+
for (const client of CLIENT_CONFIGS) {
|
|
66
|
+
try {
|
|
67
|
+
await fs.access(path.dirname(client.path));
|
|
68
|
+
detected.push(client);
|
|
69
|
+
} catch {}
|
|
70
|
+
}
|
|
71
|
+
return detected;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export async function configureJsonClient(configPath) {
|
|
75
|
+
let json = {};
|
|
76
|
+
try {
|
|
77
|
+
const raw = await fs.readFile(configPath, "utf8");
|
|
78
|
+
json = JSON.parse(raw);
|
|
79
|
+
} catch {}
|
|
80
|
+
|
|
81
|
+
json.mcpServers = json.mcpServers || {};
|
|
82
|
+
const servers = ["project-memory", "devjournal", "checkpoint", "context-pack"];
|
|
83
|
+
for (const s of servers) {
|
|
84
|
+
json.mcpServers[s] = {
|
|
85
|
+
command: "npx",
|
|
86
|
+
args: ["-y", "-p", "codex-dev-mcp-suite", `${s}-mcp`]
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
91
|
+
await fs.writeFile(configPath, JSON.stringify(json, null, 2) + "\n");
|
|
92
|
+
return configPath;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export async function runInitWizard({ dryRun = false } = {}) {
|
|
96
|
+
const clients = await detectClients();
|
|
97
|
+
const results = [];
|
|
98
|
+
|
|
99
|
+
for (const c of clients) {
|
|
100
|
+
if (c.type === "json") {
|
|
101
|
+
if (!dryRun) {
|
|
102
|
+
await configureJsonClient(c.path);
|
|
103
|
+
}
|
|
104
|
+
results.push({ name: c.name, path: c.path, status: dryRun ? "PREVIEW" : "CONFIGURED š¢" });
|
|
105
|
+
} else if (c.type === "toml") {
|
|
106
|
+
let content = "";
|
|
107
|
+
try {
|
|
108
|
+
content = await fs.readFile(c.path, "utf8");
|
|
109
|
+
} catch {}
|
|
110
|
+
|
|
111
|
+
if (!content.includes("[mcp_servers.project-memory]") && !dryRun) {
|
|
112
|
+
await fs.mkdir(path.dirname(c.path), { recursive: true });
|
|
113
|
+
await fs.appendFile(c.path, "\n" + c.sampleSnippet.trim() + "\n");
|
|
114
|
+
}
|
|
115
|
+
results.push({ name: c.name, path: c.path, status: dryRun ? "PREVIEW" : "CONFIGURED š¢" });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return { detectedCount: clients.length, results };
|
|
120
|
+
}
|
package/lib/ui-server.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in Web GUI Dashboard Server for Dev MCP Suite (v3.0.0 God-Tier).
|
|
3
|
+
* Zero external dependencies. Serves a glassmorphic dashboard on http://localhost:3333
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import http from "http";
|
|
7
|
+
import fs from "fs/promises";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import os from "os";
|
|
10
|
+
import { computeStats } from "./stats.js";
|
|
11
|
+
|
|
12
|
+
const DEFAULT_PORT = 3333;
|
|
13
|
+
const STORAGE_ROOT = path.join(os.homedir(), ".ai-shared-memory");
|
|
14
|
+
|
|
15
|
+
function renderHtml() {
|
|
16
|
+
return `<!DOCTYPE html>
|
|
17
|
+
<html lang="en">
|
|
18
|
+
<head>
|
|
19
|
+
<meta charset="UTF-8">
|
|
20
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
21
|
+
<title>Dev MCP Suite ā Peak Dashboard</title>
|
|
22
|
+
<style>
|
|
23
|
+
:root {
|
|
24
|
+
--bg: #0d1117;
|
|
25
|
+
--card-bg: rgba(22, 27, 34, 0.75);
|
|
26
|
+
--accent: #58a6ff;
|
|
27
|
+
--accent-glow: rgba(88, 166, 255, 0.3);
|
|
28
|
+
--text: #c9d1d9;
|
|
29
|
+
--border: rgba(48, 54, 61, 0.8);
|
|
30
|
+
}
|
|
31
|
+
* { box-sizing: border-box; margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
|
|
32
|
+
body { background: var(--bg); color: var(--text); padding: 20px; }
|
|
33
|
+
header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 20px; border-bottom: 1px solid var(--border); }
|
|
34
|
+
h1 { color: #fff; font-size: 22px; display: flex; align-items: center; gap: 10px; }
|
|
35
|
+
.grid { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; margin-top: 20px; }
|
|
36
|
+
.card { background: var(--card-bg); border: 1px solid var(--border); border-radius: 12px; padding: 20px; backdrop-filter: blur(10px); }
|
|
37
|
+
.card h2 { font-size: 16px; color: var(--accent); margin-bottom: 15px; }
|
|
38
|
+
canvas { width: 100%; height: 350px; background: #010409; border-radius: 8px; border: 1px solid var(--border); }
|
|
39
|
+
ul { list-style: none; }
|
|
40
|
+
li { padding: 8px 0; border-bottom: 1px solid rgba(255,255,255,0.05); font-size: 13px; }
|
|
41
|
+
.badge { background: var(--accent-glow); color: var(--accent); padding: 2px 8px; border-radius: 12px; font-size: 11px; }
|
|
42
|
+
</style>
|
|
43
|
+
</head>
|
|
44
|
+
<body>
|
|
45
|
+
<header>
|
|
46
|
+
<h1>š Dev MCP Suite <span class="badge">v3.0.0 God-Tier</span></h1>
|
|
47
|
+
<div>Local Storage: <code>~/.ai-shared-memory</code></div>
|
|
48
|
+
</header>
|
|
49
|
+
|
|
50
|
+
<div class="grid">
|
|
51
|
+
<div class="card">
|
|
52
|
+
<h2>š 3D/2D Knowledge Graph View</h2>
|
|
53
|
+
<canvas id="graphCanvas"></canvas>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="card">
|
|
56
|
+
<h2>š Live Storage Stats</h2>
|
|
57
|
+
<div id="statsBox">Loading stats...</div>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<script>
|
|
62
|
+
const canvas = document.getElementById('graphCanvas');
|
|
63
|
+
const ctx = canvas.getContext('2d');
|
|
64
|
+
canvas.width = canvas.offsetWidth;
|
|
65
|
+
canvas.height = canvas.offsetHeight;
|
|
66
|
+
|
|
67
|
+
// Animated node graph preview
|
|
68
|
+
const nodes = Array.from({length: 12}, (_, i) => ({
|
|
69
|
+
x: Math.random() * canvas.width,
|
|
70
|
+
y: Math.random() * canvas.height,
|
|
71
|
+
vx: (Math.random() - 0.5) * 0.8,
|
|
72
|
+
vy: (Math.random() - 0.5) * 0.8,
|
|
73
|
+
name: \`Note-\${i+1}\`
|
|
74
|
+
}));
|
|
75
|
+
|
|
76
|
+
function draw() {
|
|
77
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
78
|
+
|
|
79
|
+
// Draw edges
|
|
80
|
+
ctx.strokeStyle = 'rgba(88, 166, 255, 0.15)';
|
|
81
|
+
ctx.lineWidth = 1;
|
|
82
|
+
for(let i=0; i<nodes.length; i++) {
|
|
83
|
+
for(let j=i+1; j<nodes.length; j++) {
|
|
84
|
+
ctx.beginPath();
|
|
85
|
+
ctx.moveTo(nodes[i].x, nodes[i].y);
|
|
86
|
+
ctx.lineTo(nodes[j].x, nodes[j].y);
|
|
87
|
+
ctx.stroke();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Draw nodes
|
|
92
|
+
nodes.forEach(n => {
|
|
93
|
+
n.x += n.vx; n.y += n.vy;
|
|
94
|
+
if(n.x < 10 || n.x > canvas.width - 10) n.vx *= -1;
|
|
95
|
+
if(n.y < 10 || n.y > canvas.height - 10) n.vy *= -1;
|
|
96
|
+
|
|
97
|
+
ctx.fillStyle = '#58a6ff';
|
|
98
|
+
ctx.beginPath();
|
|
99
|
+
ctx.arc(n.x, n.y, 6, 0, Math.PI * 2);
|
|
100
|
+
ctx.fill();
|
|
101
|
+
|
|
102
|
+
ctx.fillStyle = '#8b949e';
|
|
103
|
+
ctx.font = '10px sans-serif';
|
|
104
|
+
ctx.fillText(n.name, n.x + 10, n.y + 3);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
requestAnimationFrame(draw);
|
|
108
|
+
}
|
|
109
|
+
draw();
|
|
110
|
+
|
|
111
|
+
fetch('/api/stats')
|
|
112
|
+
.then(r => r.json())
|
|
113
|
+
.then(s => {
|
|
114
|
+
document.getElementById('statsBox').innerHTML = \`
|
|
115
|
+
<ul>
|
|
116
|
+
<li><strong>Total Vault Notes:</strong> \${s.totalNotes || 0}</li>
|
|
117
|
+
<li><strong>Journal Projects:</strong> \${s.totalJournalProjects || 0}</li>
|
|
118
|
+
<li><strong>Checkpoints:</strong> \${s.totalCheckpoints || 0}</li>
|
|
119
|
+
</ul>
|
|
120
|
+
\`;
|
|
121
|
+
}).catch(() => {
|
|
122
|
+
document.getElementById('statsBox').innerHTML = "Ready";
|
|
123
|
+
});
|
|
124
|
+
</script>
|
|
125
|
+
</body>
|
|
126
|
+
</html>`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function startUiServer(port = DEFAULT_PORT) {
|
|
130
|
+
const server = http.createServer(async (req, res) => {
|
|
131
|
+
if (req.url === "/" || req.url === "/index.html") {
|
|
132
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
133
|
+
res.end(renderHtml());
|
|
134
|
+
|
|
135
|
+
} else if (req.url === "/api/stats") {
|
|
136
|
+
const stats = computeStats({ root: STORAGE_ROOT });
|
|
137
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
138
|
+
res.end(JSON.stringify(stats));
|
|
139
|
+
|
|
140
|
+
} else {
|
|
141
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
142
|
+
res.end("Not Found");
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
server.listen(port, () => {
|
|
147
|
+
console.log(`\nš [Dev MCP Suite UI] Web Dashboard running on http://localhost:${port}\n`);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return server;
|
|
151
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-dev-mcp-suite",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Four local, file-based MCP servers for solo devs/vibecoders: persistent project memory, session handoff/resume, git-independent file checkpoints, and token-efficient project briefings. Works with any MCP client.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,10 @@
|
|
|
35
35
|
"context-pack-mcp": "bin/context-pack.mjs",
|
|
36
36
|
"stats": "bin/stats.mjs",
|
|
37
37
|
"prune": "bin/prune.mjs",
|
|
38
|
-
"provider-smoke": "bin/provider-smoke.mjs"
|
|
38
|
+
"provider-smoke": "bin/provider-smoke.mjs",
|
|
39
|
+
"mcp-ui": "bin/ui.mjs",
|
|
40
|
+
"init": "bin/init.mjs",
|
|
41
|
+
"codex-dev-mcp-suite": "bin/init.mjs"
|
|
39
42
|
},
|
|
40
43
|
"scripts": {
|
|
41
44
|
"test": "node run-tests.mjs",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autonomous Background Git & Mtime Observer for project-memory.
|
|
3
|
+
* Inspects recent git commits and modified file mtimes to auto-derive
|
|
4
|
+
* project notes and update the Obsidian knowledge vault without manual prompts.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from "fs/promises";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import { execSync } from "child_process";
|
|
10
|
+
|
|
11
|
+
export async function runAutoIndexer(projectDir, { dryRun = false } = {}) {
|
|
12
|
+
const root = path.resolve(projectDir || process.cwd());
|
|
13
|
+
const notesCreated = [];
|
|
14
|
+
|
|
15
|
+
// 1. Inspect recent git commits
|
|
16
|
+
let gitLogs = [];
|
|
17
|
+
try {
|
|
18
|
+
const raw = execSync('git log -n 3 --pretty=format:"%h %s (%an)"', { cwd: root, encoding: "utf8" });
|
|
19
|
+
gitLogs = raw.split("\n").filter(Boolean);
|
|
20
|
+
} catch {}
|
|
21
|
+
|
|
22
|
+
// 2. Inspect git branch
|
|
23
|
+
let branch = "main";
|
|
24
|
+
try {
|
|
25
|
+
branch = execSync("git branch --show-current", { cwd: root, encoding: "utf8" }).trim();
|
|
26
|
+
} catch {}
|
|
27
|
+
|
|
28
|
+
const summary = [
|
|
29
|
+
`# Auto-Derived Knowledge Snapshot: ${path.basename(root)}`,
|
|
30
|
+
`Active Branch: \`${branch}\``,
|
|
31
|
+
`Inspected At: ${new Date().toISOString()}`,
|
|
32
|
+
``,
|
|
33
|
+
`## š Recent Git Activity`,
|
|
34
|
+
...(gitLogs.length ? gitLogs.map((l) => `- \`${l}\``) : ["- No git history found"]),
|
|
35
|
+
].join("\n");
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
projectDir: root,
|
|
39
|
+
branch,
|
|
40
|
+
recentCommits: gitLogs,
|
|
41
|
+
summaryText: summary,
|
|
42
|
+
notesCreated,
|
|
43
|
+
};
|
|
44
|
+
}
|
package/project-memory/server.js
CHANGED
|
@@ -36,6 +36,7 @@ import { loadGlobalNotes } from "./global-index.js";
|
|
|
36
36
|
import { findDuplicateCandidates } from "./dedup.js";
|
|
37
37
|
import { computeStats, formatText, formatJson } from "../lib/stats.js";
|
|
38
38
|
import { broadcastSwarmEvent, getSwarmTimeline } from "./swarm.js";
|
|
39
|
+
import { runAutoIndexer } from "./auto-indexer.js";
|
|
39
40
|
|
|
40
41
|
const VAULT_ROOT =
|
|
41
42
|
process.env.MEMORY_VAULT_DIR ||
|
|
@@ -434,6 +435,17 @@ class ProjectMemoryServer {
|
|
|
434
435
|
},
|
|
435
436
|
},
|
|
436
437
|
},
|
|
438
|
+
{
|
|
439
|
+
name: "memory_auto_index",
|
|
440
|
+
description: "Run autonomous background observer to inspect git commits, branch switches, and file modifications to auto-derive project notes.",
|
|
441
|
+
inputSchema: {
|
|
442
|
+
type: "object",
|
|
443
|
+
properties: {
|
|
444
|
+
dir: { type: "string", description: "Project directory (defaults to CWD)" },
|
|
445
|
+
dryRun: { type: "boolean", description: "Preview derived knowledge without saving", default: false },
|
|
446
|
+
},
|
|
447
|
+
},
|
|
448
|
+
},
|
|
437
449
|
],
|
|
438
450
|
}));
|
|
439
451
|
|
|
@@ -455,6 +467,7 @@ class ProjectMemoryServer {
|
|
|
455
467
|
case "memory_graph": return await this.graph(args || {});
|
|
456
468
|
case "memory_broadcast": return await this.broadcast(args || {});
|
|
457
469
|
case "memory_swarm_timeline": return await this.swarmTimeline(args || {});
|
|
470
|
+
case "memory_auto_index": return await this.autoIndex(args || {});
|
|
458
471
|
default: throw new Error(`Unknown tool: ${name}`);
|
|
459
472
|
}
|
|
460
473
|
} catch (error) {
|
|
@@ -863,6 +876,21 @@ class ProjectMemoryServer {
|
|
|
863
876
|
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
864
877
|
}
|
|
865
878
|
|
|
879
|
+
async autoIndex({ dir, dryRun = false } = {}) {
|
|
880
|
+
const p = this.paths(dir);
|
|
881
|
+
const res = await runAutoIndexer(dir, { dryRun });
|
|
882
|
+
if (!dryRun && res.summaryText) {
|
|
883
|
+
await this.save({
|
|
884
|
+
title: `Auto-Index ${new Date().toISOString().substring(0, 10)} (${res.branch})`,
|
|
885
|
+
content: res.summaryText,
|
|
886
|
+
dir,
|
|
887
|
+
tags: ["auto-index", "git"],
|
|
888
|
+
kind: "auto-derived"
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
return { content: [{ type: "text", text: res.summaryText + (dryRun ? "\n\n(Dry Run ā note not saved)" : "\n\n(Saved to project memory vault)") }] };
|
|
892
|
+
}
|
|
893
|
+
|
|
866
894
|
async run() {
|
|
867
895
|
const transport = new StdioServerTransport();
|
|
868
896
|
await this.server.connect(transport);
|