monomind 2.5.5 → 2.5.7
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monomind",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.7",
|
|
4
4
|
"description": "Open-source CLI extension for Claude Code. Adds an MCP server with a codebase knowledge graph, persistent memory, multi-agent coordination, and reusable slash commands. MIT licensed, runs locally, no data leaves your machine.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@anthropic-ai/claude-agent-sdk": "^0.3.207",
|
|
65
65
|
"@monoes/monobrowse": "^1.0.3",
|
|
66
|
-
"@monoes/monograph": "^1.4.
|
|
66
|
+
"@monoes/monograph": "^1.4.1",
|
|
67
67
|
"@noble/ed25519": "^2.1.0",
|
|
68
68
|
"mammoth": "^1.12.0",
|
|
69
69
|
"pdf-parse": "^2.4.5",
|
|
@@ -84,17 +84,27 @@ if (isMCPMode) {
|
|
|
84
84
|
|
|
85
85
|
for (const line of lines) {
|
|
86
86
|
if (line.trim()) {
|
|
87
|
+
let parsed;
|
|
87
88
|
try {
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
parsed = JSON.parse(line);
|
|
90
|
+
} catch {
|
|
91
|
+
console.log(JSON.stringify({
|
|
92
|
+
jsonrpc: '2.0',
|
|
93
|
+
id: null,
|
|
94
|
+
error: { code: -32700, message: 'Parse error' },
|
|
95
|
+
}));
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
const response = await handleMessage(parsed);
|
|
90
100
|
if (response) {
|
|
91
101
|
console.log(JSON.stringify(response));
|
|
92
102
|
}
|
|
93
103
|
} catch (error) {
|
|
94
104
|
console.log(JSON.stringify({
|
|
95
105
|
jsonrpc: '2.0',
|
|
96
|
-
id: null,
|
|
97
|
-
error: { code: -
|
|
106
|
+
id: parsed.id ?? null,
|
|
107
|
+
error: { code: -32603, message: error instanceof Error ? error.message : 'Internal error' },
|
|
98
108
|
}));
|
|
99
109
|
}
|
|
100
110
|
}
|
|
@@ -132,7 +142,7 @@ if (isMCPMode) {
|
|
|
132
142
|
};
|
|
133
143
|
|
|
134
144
|
case 'tools/list': {
|
|
135
|
-
const tools = listMCPTools();
|
|
145
|
+
const tools = await listMCPTools();
|
|
136
146
|
return {
|
|
137
147
|
jsonrpc: '2.0',
|
|
138
148
|
id: message.id,
|
|
@@ -150,7 +160,7 @@ if (isMCPMode) {
|
|
|
150
160
|
const toolName = params.name;
|
|
151
161
|
const toolParams = params.arguments || {};
|
|
152
162
|
|
|
153
|
-
if (!hasTool(toolName)) {
|
|
163
|
+
if (!await hasTool(toolName)) {
|
|
154
164
|
return {
|
|
155
165
|
jsonrpc: '2.0',
|
|
156
166
|
id: message.id,
|
|
@@ -41,22 +41,31 @@ process.stdin.on('data', async (chunk) => {
|
|
|
41
41
|
|
|
42
42
|
for (const line of lines) {
|
|
43
43
|
if (line.trim()) {
|
|
44
|
+
let parsed;
|
|
44
45
|
try {
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
parsed = JSON.parse(line);
|
|
47
|
+
} catch {
|
|
48
|
+
console.log(JSON.stringify({
|
|
49
|
+
jsonrpc: '2.0',
|
|
50
|
+
id: null,
|
|
51
|
+
error: { code: -32700, message: 'Parse error' },
|
|
52
|
+
}));
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const response = await handleMessage(parsed);
|
|
47
57
|
if (response) {
|
|
48
58
|
console.log(JSON.stringify(response));
|
|
49
59
|
}
|
|
50
60
|
} catch (error) {
|
|
51
61
|
console.error(
|
|
52
|
-
`[${new Date().toISOString()}] ERROR [monomind-mcp]
|
|
62
|
+
`[${new Date().toISOString()}] ERROR [monomind-mcp] handler error:`,
|
|
53
63
|
error instanceof Error ? error.message : String(error)
|
|
54
64
|
);
|
|
55
|
-
// Send parse error response
|
|
56
65
|
console.log(JSON.stringify({
|
|
57
66
|
jsonrpc: '2.0',
|
|
58
|
-
id: null,
|
|
59
|
-
error: { code: -
|
|
67
|
+
id: parsed.id ?? null,
|
|
68
|
+
error: { code: -32603, message: error instanceof Error ? error.message : 'Internal error' },
|
|
60
69
|
}));
|
|
61
70
|
}
|
|
62
71
|
}
|
|
@@ -122,7 +131,7 @@ async function handleMessage(message) {
|
|
|
122
131
|
}
|
|
123
132
|
|
|
124
133
|
case 'tools/list': {
|
|
125
|
-
const tools = listMCPTools();
|
|
134
|
+
const tools = await listMCPTools();
|
|
126
135
|
return {
|
|
127
136
|
jsonrpc: '2.0',
|
|
128
137
|
id: message.id,
|
|
@@ -140,7 +149,7 @@ async function handleMessage(message) {
|
|
|
140
149
|
const toolName = params.name;
|
|
141
150
|
const toolParams = params.arguments || {};
|
|
142
151
|
|
|
143
|
-
if (!hasTool(toolName)) {
|
|
152
|
+
if (!await hasTool(toolName)) {
|
|
144
153
|
return {
|
|
145
154
|
jsonrpc: '2.0',
|
|
146
155
|
id: message.id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monomindcli",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI engine for Monomind \u2014 an open-source MCP server that extends Claude Code with a codebase knowledge graph (tree-sitter + SQLite), persistent memory, multi-agent task coordination, and session hooks. MIT licensed, fully local.",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"@anthropic-ai/claude-agent-sdk": "^0.3.207",
|
|
98
98
|
"@monoes/monobrowse": "^1.0.3",
|
|
99
99
|
"@monoes/monodesign": "^1.2.0",
|
|
100
|
-
"@monoes/monograph": "^1.4.
|
|
100
|
+
"@monoes/monograph": "^1.4.1",
|
|
101
101
|
"@noble/ed25519": "^2.1.0",
|
|
102
102
|
"mammoth": "^1.12.0",
|
|
103
103
|
"pdf-parse": "^2.4.5",
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Renders the public content calendar (HTML + MD) from each growth org's
|
|
3
|
+
// workspace/posts.md — the single canonical, ready-to-publish post ledger.
|
|
4
|
+
// Regenerate after any growth org run:
|
|
5
|
+
// node scripts/growth-content-calendar.mjs
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
|
|
9
|
+
const ROOT = process.cwd();
|
|
10
|
+
const ORGS = [
|
|
11
|
+
{ name: 'monomind-growth', dir: path.join(ROOT, '.monomind/orgs/monomind-growth/workspace') },
|
|
12
|
+
{ name: 'growth-execution', dir: path.join(ROOT, '.monomind/orgs/growth-execution/workspace') },
|
|
13
|
+
];
|
|
14
|
+
const OUT_DIR = path.join(ROOT, '.monomind/orgs/monomind-growth/workspace/reports/content-calendar');
|
|
15
|
+
|
|
16
|
+
// Record format in posts.md (one per finalized, ready-to-publish post):
|
|
17
|
+
//
|
|
18
|
+
// ### <Channel> — <YYYY-MM-DD>
|
|
19
|
+
// Image: <filename in ../assets/>
|
|
20
|
+
// <final publish-ready text, one or more lines, until the next "### " or EOF>
|
|
21
|
+
function parsePosts(text, org, sourceFile) {
|
|
22
|
+
const posts = [];
|
|
23
|
+
const blocks = text.split(/^### /m).slice(1);
|
|
24
|
+
for (const block of blocks) {
|
|
25
|
+
const lines = block.split('\n');
|
|
26
|
+
const headerLine = lines[0];
|
|
27
|
+
const m = headerLine.match(/^(.+?)\s*—\s*(\d{4}-\d{2}-\d{2})\s*$/);
|
|
28
|
+
if (!m) continue;
|
|
29
|
+
const [, channel, date] = m;
|
|
30
|
+
let image = null;
|
|
31
|
+
const bodyLines = [];
|
|
32
|
+
for (const line of lines.slice(1)) {
|
|
33
|
+
const imgMatch = line.match(/^Image:\s*(.+?)\s*$/i);
|
|
34
|
+
if (imgMatch) { image = imgMatch[1]; continue; }
|
|
35
|
+
bodyLines.push(line);
|
|
36
|
+
}
|
|
37
|
+
const text = bodyLines.join('\n').trim();
|
|
38
|
+
if (!text) continue;
|
|
39
|
+
posts.push({ org, sourceFile, channel: channel.trim(), date, text, image });
|
|
40
|
+
}
|
|
41
|
+
return posts;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function escapeHtml(s) {
|
|
45
|
+
return String(s).replace(/[&<>"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function render() {
|
|
49
|
+
fs.mkdirSync(OUT_DIR, { recursive: true });
|
|
50
|
+
|
|
51
|
+
let posts = [];
|
|
52
|
+
for (const org of ORGS) {
|
|
53
|
+
const postsFile = path.join(org.dir, 'posts.md');
|
|
54
|
+
if (!fs.existsSync(postsFile)) continue;
|
|
55
|
+
const text = fs.readFileSync(postsFile, 'utf8');
|
|
56
|
+
posts.push(...parsePosts(text, org.name, path.relative(ROOT, postsFile)));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// dedupe identical posts mirrored across both orgs
|
|
60
|
+
const merged = new Map();
|
|
61
|
+
for (const p of posts) {
|
|
62
|
+
const key = `${p.channel}|${p.date}|${p.text}`;
|
|
63
|
+
const existing = merged.get(key);
|
|
64
|
+
if (existing) { if (!existing.orgs.includes(p.org)) existing.orgs.push(p.org); }
|
|
65
|
+
else merged.set(key, { ...p, orgs: [p.org] });
|
|
66
|
+
}
|
|
67
|
+
posts = [...merged.values()].sort((a, b) => b.date.localeCompare(a.date));
|
|
68
|
+
|
|
69
|
+
// copy referenced images alongside html/md
|
|
70
|
+
const copied = new Set();
|
|
71
|
+
for (const p of posts) {
|
|
72
|
+
if (!p.image) continue;
|
|
73
|
+
for (const org of ORGS) {
|
|
74
|
+
const src = path.join(org.dir, 'assets', p.image);
|
|
75
|
+
if (fs.existsSync(src)) { fs.copyFileSync(src, path.join(OUT_DIR, p.image)); copied.add(p.image); break; }
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// --- MD ---
|
|
80
|
+
const md = [];
|
|
81
|
+
md.push('# Monomind Growth — Content Calendar (auto-generated)');
|
|
82
|
+
md.push('');
|
|
83
|
+
md.push('Regenerated by `scripts/growth-content-calendar.mjs` from each org\'s `workspace/posts.md`. Newest publish date first.');
|
|
84
|
+
md.push('');
|
|
85
|
+
let lastDate = null;
|
|
86
|
+
for (const p of posts) {
|
|
87
|
+
if (p.date !== lastDate) { md.push(`\n## ${p.date}`); lastDate = p.date; }
|
|
88
|
+
md.push(`\n### ${p.channel}\n`);
|
|
89
|
+
md.push(p.text);
|
|
90
|
+
if (p.image) md.push(`\n`);
|
|
91
|
+
}
|
|
92
|
+
if (!posts.length) md.push('\n_No finalized posts yet — workspace/posts.md is empty for both orgs._');
|
|
93
|
+
fs.writeFileSync(path.join(OUT_DIR, 'content-calendar.md'), md.join('\n') + '\n');
|
|
94
|
+
|
|
95
|
+
// --- HTML ---
|
|
96
|
+
const groups = [];
|
|
97
|
+
{ let cur = null; for (const p of posts) { if (p.date !== cur?.date) { cur = { date: p.date, items: [] }; groups.push(cur); } cur.items.push(p); } }
|
|
98
|
+
|
|
99
|
+
function card(p) {
|
|
100
|
+
const img = p.image && copied.has(p.image) ? `<img class="thumb" src="./${escapeHtml(p.image)}" alt="">` : '';
|
|
101
|
+
return `<div class="card">
|
|
102
|
+
<div class="channel">${escapeHtml(p.channel)}</div>
|
|
103
|
+
${img}
|
|
104
|
+
<div class="text">${escapeHtml(p.text).replace(/\n/g, '<br>')}</div>
|
|
105
|
+
</div>`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const html = `<!doctype html>
|
|
109
|
+
<html><head><meta charset="utf-8"><title>Monomind Growth — Content Calendar</title>
|
|
110
|
+
<style>
|
|
111
|
+
:root { color-scheme: light dark; --bg:#0b0d12; --card:#151922; --line:#232837; --text:#e7ebf3; --muted:#8a93a6; --accent:#7cc4ff; }
|
|
112
|
+
@media (prefers-color-scheme: light) { :root { --bg:#f6f7fb; --card:#ffffff; --line:#e4e7ef; --text:#171923; --muted:#5a6270; --accent:#2563eb; } }
|
|
113
|
+
* { box-sizing: border-box; }
|
|
114
|
+
body { margin:0; background:var(--bg); color:var(--text); font:15px/1.55 -apple-system,BlinkMacSystemFont,Segoe UI,sans-serif; }
|
|
115
|
+
header { padding:2.5rem 1.5rem 1rem; max-width:820px; margin:0 auto; }
|
|
116
|
+
h1 { margin:0 0 .3rem; font-size:1.6rem; }
|
|
117
|
+
.sub { color:var(--muted); font-size:.9rem; }
|
|
118
|
+
main { max-width:820px; margin:0 auto; padding:0 1.5rem 4rem; }
|
|
119
|
+
.date-heading { font-size:1.05rem; font-weight:700; color:var(--accent); border-bottom:1px solid var(--line); padding:1.6rem 0 .5rem; margin-bottom:1rem; }
|
|
120
|
+
.card { background:var(--card); border:1px solid var(--line); border-radius:12px; padding:1.1rem 1.3rem; margin-bottom:1rem; }
|
|
121
|
+
.channel { font-size:.72rem; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color:var(--accent); margin-bottom:.6rem; }
|
|
122
|
+
.thumb { max-width:100%; border-radius:8px; margin-bottom:.7rem; display:block; }
|
|
123
|
+
.text { font-size:.92rem; white-space:normal; }
|
|
124
|
+
.empty { color:var(--muted); padding:2rem 0; }
|
|
125
|
+
</style></head>
|
|
126
|
+
<body>
|
|
127
|
+
<header>
|
|
128
|
+
<h1>Monomind Growth — Content Calendar</h1>
|
|
129
|
+
<div class="sub">Auto-generated by <code>scripts/growth-content-calendar.mjs</code> from workspace/posts.md. Newest publish date first.</div>
|
|
130
|
+
</header>
|
|
131
|
+
<main>
|
|
132
|
+
${groups.length ? groups.map((g) => `<div class="date-heading">${g.date}</div>${g.items.map(card).join('\n')}`).join('\n') : '<div class="empty">No finalized posts yet — workspace/posts.md is empty for both orgs.</div>'}
|
|
133
|
+
</main>
|
|
134
|
+
</body></html>`;
|
|
135
|
+
fs.writeFileSync(path.join(OUT_DIR, 'content-calendar.html'), html);
|
|
136
|
+
|
|
137
|
+
console.log(`Wrote ${posts.length} post(s), ${copied.size} image(s) -> ${path.relative(ROOT, OUT_DIR)}`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
render();
|