monomind 1.6.9 → 1.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/.claude/commands/monomind-createtask.md +75 -113
- package/.claude/commands/monomind-do.md +227 -115
- package/.claude/commands/monomind-idea.md +30 -104
- package/.claude/commands/monomind-improve.md +31 -103
- package/.claude/helpers/graphify-freshen.cjs +12 -97
- package/.claude/helpers/hook-handler.cjs +16 -0
- package/.claude/helpers/learning-service.mjs +0 -0
- package/.claude/helpers/metrics-db.mjs +0 -0
- package/.claude/helpers/statusline.cjs +89 -65
- package/.claude/helpers/swarm-hooks.sh +0 -0
- package/.claude/settings.local.json +2 -1
- package/.claude/skills/monomind-task-engine/SKILL.md +358 -0
- package/.claude/statusline-command.sh +0 -0
- package/.claude/statusline.sh +0 -0
- package/.claude-plugin/scripts/install.sh +0 -0
- package/.claude-plugin/scripts/uninstall.sh +0 -0
- package/.claude-plugin/scripts/verify.sh +0 -0
- package/package.json +17 -17
- package/packages/@monomind/cli/bin/cli.js +0 -0
- package/packages/@monomind/cli/bin/mcp-server.js +0 -0
- package/packages/@monomind/cli/dist/src/commands/doctor.js +36 -9
- package/packages/@monomind/cli/dist/src/init/executor.js +99 -28
- package/packages/@monomind/cli/dist/src/init/helpers-generator.js +14 -14
- package/packages/@monomind/cli/dist/src/init/shared-instructions-generator.d.ts +38 -0
- package/packages/@monomind/cli/dist/src/init/shared-instructions-generator.js +571 -0
- package/packages/@monomind/cli/dist/src/init/types.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/mcp-client.js +5 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/graphify-tools.d.ts +4 -67
- package/packages/@monomind/cli/dist/src/mcp-tools/graphify-tools.js +40 -1226
- package/packages/@monomind/cli/dist/src/mcp-tools/index.d.ts +1 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/index.js +1 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +495 -0
- package/packages/@monomind/cli/package.json +2 -1
- package/packages/@monomind/cli/README.md +0 -441
- package/packages/@monomind/guidance/README.md +0 -1195
- package/packages/@monomind/shared/README.md +0 -323
- package/packages/README.md +0 -514
|
@@ -11,6 +11,7 @@ import { dirname } from 'path';
|
|
|
11
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
12
12
|
const __dirname = dirname(__filename);
|
|
13
13
|
import { detectPlatform, DEFAULT_INIT_OPTIONS } from './types.js';
|
|
14
|
+
import { writeSharedInstructions } from './shared-instructions-generator.js';
|
|
14
15
|
import { generateSettingsJson, generateSettings } from './settings-generator.js';
|
|
15
16
|
import { generateMCPJson } from './mcp-generator.js';
|
|
16
17
|
import { generateStatuslineScript } from './statusline-generator.js';
|
|
@@ -66,7 +67,7 @@ const SKILLS_MAP = {
|
|
|
66
67
|
const COMMANDS_MAP = {
|
|
67
68
|
core: [
|
|
68
69
|
'monomind-help.md', 'monomind-swarm.md', 'monomind-memory.md',
|
|
69
|
-
'monomind-do.md', 'monomind-idea.md', 'monomind-createtask.md', 'monomind-repeat.md',
|
|
70
|
+
'monomind-do.md', 'monomind-idea.md', 'monomind-improve.md', 'monomind-createtask.md', 'monomind-repeat.md',
|
|
70
71
|
'mastermind.md', 'list-agents.md', 'use-agent.md',
|
|
71
72
|
'metrics.md', 'tokens.md', 'browse.md', 'sparc.md', 'ts.md',
|
|
72
73
|
],
|
|
@@ -281,12 +282,18 @@ export async function executeInit(options) {
|
|
|
281
282
|
if (options.components.claudeMd) {
|
|
282
283
|
await writeClaudeMd(targetDir, options, result);
|
|
283
284
|
}
|
|
285
|
+
// Generate .agents/shared_instructions.md + seed project memory
|
|
286
|
+
writeSharedInstructions(targetDir, options.force, result);
|
|
284
287
|
// Count enabled hooks
|
|
285
288
|
result.summary.hooksEnabled = countEnabledHooks(options);
|
|
286
289
|
// Build knowledge graph in background (non-blocking)
|
|
287
290
|
if (options.components.graphify) {
|
|
288
291
|
await initKnowledgeGraph(targetDir, result);
|
|
289
292
|
}
|
|
293
|
+
// Start daemon with background workers (non-blocking)
|
|
294
|
+
await startDaemonBackground(targetDir, result);
|
|
295
|
+
// Run doctor auto-fix (non-blocking, best-effort)
|
|
296
|
+
await runDoctorFix(targetDir, result);
|
|
290
297
|
}
|
|
291
298
|
catch (error) {
|
|
292
299
|
result.success = false;
|
|
@@ -295,39 +302,72 @@ export async function executeInit(options) {
|
|
|
295
302
|
return result;
|
|
296
303
|
}
|
|
297
304
|
/**
|
|
298
|
-
*
|
|
299
|
-
* Fire-and-forget
|
|
300
|
-
* Non-fatal: if @monomind/graph is unavailable the step is simply skipped.
|
|
305
|
+
* Initialize the Monograph knowledge graph (native TypeScript, no Python required).
|
|
306
|
+
* Fire-and-forget build — init does not wait for it to complete.
|
|
301
307
|
*/
|
|
302
308
|
async function initKnowledgeGraph(targetDir, result) {
|
|
309
|
+
const { mkdirSync } = await import('fs');
|
|
310
|
+
const outputDir = path.join(targetDir, '.monomind', 'graph');
|
|
311
|
+
mkdirSync(outputDir, { recursive: true });
|
|
303
312
|
try {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
313
|
+
const { buildAsync } = await import('@monoes/monograph');
|
|
314
|
+
buildAsync(targetDir, { codeOnly: false })
|
|
315
|
+
.then(() => { })
|
|
316
|
+
.catch((err) => {
|
|
317
|
+
console.warn('[monograph] Background build failed:', err);
|
|
318
|
+
});
|
|
319
|
+
result.created.files.push('.monomind/monograph.db (knowledge graph building in background)');
|
|
320
|
+
}
|
|
321
|
+
catch (err) {
|
|
322
|
+
result.skipped.push('knowledge graph: monograph package unavailable');
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Start the monomind daemon with background workers.
|
|
327
|
+
* Non-fatal: if daemon fails to start, init continues.
|
|
328
|
+
*/
|
|
329
|
+
async function startDaemonBackground(targetDir, result) {
|
|
330
|
+
try {
|
|
331
|
+
const { execSync } = await import('child_process');
|
|
332
|
+
// Check if daemon is already running
|
|
333
|
+
const pidFile = path.join(targetDir, '.monomind', 'daemon.pid');
|
|
334
|
+
const { existsSync, readFileSync } = await import('fs');
|
|
335
|
+
if (existsSync(pidFile)) {
|
|
336
|
+
const pid = parseInt(readFileSync(pidFile, 'utf8').trim(), 10);
|
|
337
|
+
try {
|
|
338
|
+
process.kill(pid, 0);
|
|
339
|
+
result.skipped.push('daemon: already running (PID ' + pid + ')');
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
catch { /* stale PID, continue */ }
|
|
343
|
+
}
|
|
344
|
+
execSync('npx monomind@latest daemon start --background', {
|
|
345
|
+
cwd: targetDir,
|
|
346
|
+
stdio: 'ignore',
|
|
347
|
+
timeout: 15000,
|
|
348
|
+
});
|
|
349
|
+
result.created.files.push('monomind daemon (background workers started)');
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
result.skipped.push('daemon: could not auto-start (run: monomind daemon start)');
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Run doctor --install to auto-fix any remaining issues.
|
|
357
|
+
* Non-fatal: best-effort health check and auto-install.
|
|
358
|
+
*/
|
|
359
|
+
async function runDoctorFix(targetDir, result) {
|
|
360
|
+
try {
|
|
361
|
+
const { execSync } = await import('child_process');
|
|
362
|
+
execSync('npx monomind@latest doctor --install', {
|
|
320
363
|
cwd: targetDir,
|
|
364
|
+
stdio: 'ignore',
|
|
365
|
+
timeout: 120000,
|
|
321
366
|
});
|
|
322
|
-
|
|
323
|
-
child.stdin?.write(script);
|
|
324
|
-
child.stdin?.end();
|
|
325
|
-
child.unref();
|
|
326
|
-
result.created.files.push('.monomind/graph/ (knowledge graph building in background)');
|
|
367
|
+
result.created.files.push('doctor --install (health check + auto-fix)');
|
|
327
368
|
}
|
|
328
|
-
catch
|
|
329
|
-
|
|
330
|
-
result.skipped.push('knowledge graph: @monomind/graph not available');
|
|
369
|
+
catch {
|
|
370
|
+
result.skipped.push('doctor: auto-fix skipped (run: monomind doctor --install)');
|
|
331
371
|
}
|
|
332
372
|
}
|
|
333
373
|
/**
|
|
@@ -1811,6 +1851,37 @@ async function writeClaudeMd(targetDir, options, result) {
|
|
|
1811
1851
|
catch {
|
|
1812
1852
|
// Non-critical — global CLAUDE.md is best-effort
|
|
1813
1853
|
}
|
|
1854
|
+
// Also inject the token-display hook into ~/.claude/settings.json
|
|
1855
|
+
const globalSettingsPath = path.join(globalClaudeDir, 'settings.json');
|
|
1856
|
+
try {
|
|
1857
|
+
if (!fs.existsSync(globalClaudeDir)) {
|
|
1858
|
+
fs.mkdirSync(globalClaudeDir, { recursive: true });
|
|
1859
|
+
}
|
|
1860
|
+
let globalSettings = {};
|
|
1861
|
+
if (fs.existsSync(globalSettingsPath)) {
|
|
1862
|
+
try {
|
|
1863
|
+
globalSettings = JSON.parse(fs.readFileSync(globalSettingsPath, 'utf-8'));
|
|
1864
|
+
}
|
|
1865
|
+
catch { /* malformed JSON — start fresh */ }
|
|
1866
|
+
}
|
|
1867
|
+
// Inject SessionStart token hook if not already present
|
|
1868
|
+
const hooks = globalSettings.hooks ?? {};
|
|
1869
|
+
const sessionStartHooks = hooks['SessionStart'] ?? [];
|
|
1870
|
+
const tokenHookCommand = 'npx --yes monomind@latest tokens today';
|
|
1871
|
+
const alreadyPresent = sessionStartHooks.some(entry => Array.isArray(entry.hooks) && entry.hooks.some(h => h.command === tokenHookCommand));
|
|
1872
|
+
if (!alreadyPresent) {
|
|
1873
|
+
sessionStartHooks.push({
|
|
1874
|
+
hooks: [{ type: 'command', command: tokenHookCommand, timeout: 10000 }],
|
|
1875
|
+
});
|
|
1876
|
+
hooks['SessionStart'] = sessionStartHooks;
|
|
1877
|
+
globalSettings.hooks = hooks;
|
|
1878
|
+
fs.writeFileSync(globalSettingsPath, JSON.stringify(globalSettings, null, 2), 'utf-8');
|
|
1879
|
+
result.created.files.push('~/.claude/settings.json (added token hook)');
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
catch {
|
|
1883
|
+
// Non-critical — global settings hook is best-effort
|
|
1884
|
+
}
|
|
1814
1885
|
}
|
|
1815
1886
|
}
|
|
1816
1887
|
/**
|
|
@@ -22,7 +22,7 @@ STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
|
|
|
22
22
|
for FILE in $STAGED_FILES; do
|
|
23
23
|
if [[ "$FILE" =~ \\.(ts|js|tsx|jsx)$ ]]; then
|
|
24
24
|
echo " Validating: $FILE"
|
|
25
|
-
npx @
|
|
25
|
+
npx @monomind/cli hooks pre-edit --file "$FILE" --validate-syntax 2>/dev/null || true
|
|
26
26
|
fi
|
|
27
27
|
done
|
|
28
28
|
|
|
@@ -451,21 +451,21 @@ export function generateHookHandler() {
|
|
|
451
451
|
" var archKeywords = ['understand', 'architecture', 'how does', 'what calls', 'dependency', 'depends on', 'flow', 'how is', 'explain codebase', 'project structure', 'what is the relationship', 'graph', 'knowledge'];",
|
|
452
452
|
' var promptLower = prompt.toLowerCase();',
|
|
453
453
|
' var isArchQuery = archKeywords.some(function(k) { return promptLower.includes(k); });',
|
|
454
|
-
" var graphJson = require('path').join(process.cwd(), '
|
|
454
|
+
" var graphJson = require('path').join(process.cwd(), '.monomind', 'monograph.db');",
|
|
455
455
|
" var hasGraph = require('fs').existsSync(graphJson);",
|
|
456
456
|
' if (isArchQuery) {',
|
|
457
457
|
" var gfOutput = [];",
|
|
458
458
|
" gfOutput.push('');",
|
|
459
|
-
" gfOutput.push('+-------
|
|
459
|
+
" gfOutput.push('+------- monograph | Knowledge Graph Available ---------------+');",
|
|
460
460
|
' if (hasGraph) {',
|
|
461
|
-
" gfOutput.push('| Graph:
|
|
462
|
-
" gfOutput.push('| Use:
|
|
463
|
-
" gfOutput.push('|
|
|
464
|
-
" gfOutput.push('|
|
|
465
|
-
" gfOutput.push('| Tip: Call
|
|
461
|
+
" gfOutput.push('| Graph: .monomind/monograph.db |');",
|
|
462
|
+
" gfOutput.push('| Use: mcp__monomind__monograph_god_nodes |');",
|
|
463
|
+
" gfOutput.push('| mcp__monomind__monograph_query |');",
|
|
464
|
+
" gfOutput.push('| mcp__monomind__monograph_shortest_path |');",
|
|
465
|
+
" gfOutput.push('| Tip: Call monograph_god_nodes first for architecture overview|');",
|
|
466
466
|
' } else {',
|
|
467
467
|
" gfOutput.push('| No graph found. Build with: |');",
|
|
468
|
-
" gfOutput.push('|
|
|
468
|
+
" gfOutput.push('| mcp__monomind__monograph_build |');",
|
|
469
469
|
' }',
|
|
470
470
|
" gfOutput.push('+--------------------------------------------------------------+');",
|
|
471
471
|
" console.log(gfOutput.join('\\n'));",
|
|
@@ -842,7 +842,7 @@ export function generateIntelligenceStub() {
|
|
|
842
842
|
/**
|
|
843
843
|
* Generate a minimal auto-memory-hook.mjs fallback for fresh installs.
|
|
844
844
|
* This ESM script handles import/sync/status commands gracefully when
|
|
845
|
-
* @
|
|
845
|
+
* @monomind/memory is not installed. Gets overwritten when source copy succeeds.
|
|
846
846
|
*/
|
|
847
847
|
export function generateAutoMemoryHook() {
|
|
848
848
|
return `#!/usr/bin/env node
|
|
@@ -879,17 +879,17 @@ async function loadMemoryPackage() {
|
|
|
879
879
|
try {
|
|
880
880
|
const { createRequire } = await import('module');
|
|
881
881
|
const require = createRequire(join(PROJECT_ROOT, 'package.json'));
|
|
882
|
-
return require('@
|
|
882
|
+
return require('@monomind/memory');
|
|
883
883
|
} catch { /* fall through */ }
|
|
884
884
|
|
|
885
|
-
// Strategy 2: ESM import (works when @
|
|
886
|
-
try { return await import('@
|
|
885
|
+
// Strategy 2: ESM import (works when @monomind/memory is a direct dependency)
|
|
886
|
+
try { return await import('@monomind/memory'); } catch { /* fall through */ }
|
|
887
887
|
|
|
888
888
|
// Strategy 3: Walk up from PROJECT_ROOT looking for the package in any node_modules
|
|
889
889
|
let searchDir = PROJECT_ROOT;
|
|
890
890
|
const { parse } = await import('path');
|
|
891
891
|
while (searchDir !== parse(searchDir).root) {
|
|
892
|
-
const candidate = join(searchDir, 'node_modules', '@
|
|
892
|
+
const candidate = join(searchDir, 'node_modules', '@monomind', 'memory', 'dist', 'index.js');
|
|
893
893
|
if (existsSync(candidate)) {
|
|
894
894
|
try { return await import(\`file://\${candidate}\`); } catch { /* fall through */ }
|
|
895
895
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Instructions Generator
|
|
3
|
+
*
|
|
4
|
+
* Auto-detects project profile and generates:
|
|
5
|
+
* 1. .agents/shared_instructions.md — prepended to every agent prompt
|
|
6
|
+
* 2. Memory seeds — pre-loaded into AgentDB so agents start with project best practices
|
|
7
|
+
*/
|
|
8
|
+
import type { InitResult } from './types.js';
|
|
9
|
+
export interface ProjectProfile {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
language: 'typescript' | 'javascript' | 'python' | 'go' | 'rust' | 'unknown';
|
|
13
|
+
framework: string[];
|
|
14
|
+
packageManager: 'pnpm' | 'npm' | 'yarn' | 'bun' | 'cargo' | 'poetry' | 'uv' | 'pip' | 'unknown';
|
|
15
|
+
testFramework: string[];
|
|
16
|
+
buildTool: string[];
|
|
17
|
+
isMonorepo: boolean;
|
|
18
|
+
monorepoTool: string;
|
|
19
|
+
database: string[];
|
|
20
|
+
hasDocker: boolean;
|
|
21
|
+
hasCi: boolean;
|
|
22
|
+
ciTool: string;
|
|
23
|
+
maxFileLines: number | null;
|
|
24
|
+
srcDir: string;
|
|
25
|
+
testDir: string;
|
|
26
|
+
version: string;
|
|
27
|
+
isPublicNpm: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function detectProjectProfile(cwd: string): ProjectProfile;
|
|
30
|
+
export declare function generateSharedInstructions(profile: ProjectProfile): string;
|
|
31
|
+
export interface MemorySeed {
|
|
32
|
+
key: string;
|
|
33
|
+
value: string;
|
|
34
|
+
namespace: string;
|
|
35
|
+
}
|
|
36
|
+
export declare function generateMemorySeeds(profile: ProjectProfile): MemorySeed[];
|
|
37
|
+
export declare function writeSharedInstructions(cwd: string, force: boolean, result: InitResult): void;
|
|
38
|
+
//# sourceMappingURL=shared-instructions-generator.d.ts.map
|