monomind 1.17.1 → 1.17.2
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 +1 -1
- package/packages/@monomind/cli/dist/src/agents/registry-builder.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/agents/registry-builder.js +22 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.d.ts +1 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +45 -1
- package/packages/@monomind/cli/dist/src/commands/doctor.js +4 -2
- package/packages/@monomind/cli/dist/src/index.js +8 -37
- package/packages/@monomind/cli/package.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monomind",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.2",
|
|
4
4
|
"description": "Monomind - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -7,6 +7,7 @@ type AgentRegistryEntry = {
|
|
|
7
7
|
name: string;
|
|
8
8
|
version: string;
|
|
9
9
|
category: string;
|
|
10
|
+
description: string;
|
|
10
11
|
capabilities: string[];
|
|
11
12
|
taskTypes: string[];
|
|
12
13
|
tools: string[];
|
|
@@ -32,6 +33,13 @@ type AgentRegistry = {
|
|
|
32
33
|
* @returns The built AgentRegistry object.
|
|
33
34
|
*/
|
|
34
35
|
export declare function buildRegistry(agentsRoot: string, outputPath?: string): AgentRegistry;
|
|
36
|
+
/**
|
|
37
|
+
* Compute the ordered list of agent-definition roots for `cwd`: extras
|
|
38
|
+
* (canonical, from MONOMIND_EXTRA_AGENT_PATHS or a sibling `agency-agents`
|
|
39
|
+
* dir) first, then the project's `.claude/agents`. Shared by CLI startup
|
|
40
|
+
* and `monomind doctor` so both build the registry the same way.
|
|
41
|
+
*/
|
|
42
|
+
export declare function computeAgentRoots(cwd: string): string[];
|
|
35
43
|
/**
|
|
36
44
|
* Build a unified agent registry from multiple root directories, deduplicating
|
|
37
45
|
* by slug. When the same slug appears in more than one root, the entry from the
|
|
@@ -132,6 +132,27 @@ function categoryFromPath(filePath, agentsRoot) {
|
|
|
132
132
|
export function buildRegistry(agentsRoot, outputPath) {
|
|
133
133
|
return buildUnifiedRegistry([agentsRoot], outputPath);
|
|
134
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Compute the ordered list of agent-definition roots for `cwd`: extras
|
|
137
|
+
* (canonical, from MONOMIND_EXTRA_AGENT_PATHS or a sibling `agency-agents`
|
|
138
|
+
* dir) first, then the project's `.claude/agents`. Shared by CLI startup
|
|
139
|
+
* and `monomind doctor` so both build the registry the same way.
|
|
140
|
+
*/
|
|
141
|
+
export function computeAgentRoots(cwd) {
|
|
142
|
+
const devAgentsRoot = join(cwd, '.claude', 'agents');
|
|
143
|
+
const extraPaths = process.env.MONOMIND_EXTRA_AGENT_PATHS
|
|
144
|
+
? process.env.MONOMIND_EXTRA_AGENT_PATHS.split(':').filter(Boolean)
|
|
145
|
+
: [];
|
|
146
|
+
const siblingExtraPath = join(cwd, '..', 'agency-agents');
|
|
147
|
+
if (extraPaths.length === 0) {
|
|
148
|
+
try {
|
|
149
|
+
if (statSync(siblingExtraPath).isDirectory())
|
|
150
|
+
extraPaths.push(siblingExtraPath);
|
|
151
|
+
}
|
|
152
|
+
catch { /* sibling path doesn't exist */ }
|
|
153
|
+
}
|
|
154
|
+
return [...extraPaths, devAgentsRoot];
|
|
155
|
+
}
|
|
135
156
|
/**
|
|
136
157
|
* Build a unified agent registry from multiple root directories, deduplicating
|
|
137
158
|
* by slug. When the same slug appears in more than one root, the entry from the
|
|
@@ -178,6 +199,7 @@ export function buildUnifiedRegistry(roots, outputPath) {
|
|
|
178
199
|
version: (typeof fm.version === 'string' ? fm.version : undefined) || '0.0.0',
|
|
179
200
|
category: (typeof fm.category === 'string' ? fm.category : undefined) ||
|
|
180
201
|
categoryFromPath(file, root),
|
|
202
|
+
description: typeof fm.description === 'string' ? fm.description : '',
|
|
181
203
|
capabilities: toStringArray(fm.capabilities),
|
|
182
204
|
taskTypes: toStringArray(fm.taskTypes ?? fm['task-types'] ?? fm.task_types),
|
|
183
205
|
tools: toStringArray(fm.tools),
|
|
@@ -15,5 +15,6 @@ export declare function checkMonoesMemory(): Promise<HealthCheck>;
|
|
|
15
15
|
export declare function checkHelpersFresh(): Promise<HealthCheck>;
|
|
16
16
|
export declare function checkMonoesIntegration(): Promise<HealthCheck>;
|
|
17
17
|
export declare function checkGitignoreCoverage(): Promise<HealthCheck>;
|
|
18
|
+
export declare function checkAgentRegistry(): Promise<HealthCheck>;
|
|
18
19
|
export declare function checkGuidanceGates(): Promise<HealthCheck>;
|
|
19
20
|
//# sourceMappingURL=doctor-project-checks.d.ts.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Doctor — project/monomind health checks
|
|
3
3
|
* Config, daemon, memory, API keys, MCP, monograph, helpers, routing, gates, gitignore
|
|
4
4
|
*/
|
|
5
|
-
import { existsSync, readFileSync, statSync } from 'fs';
|
|
5
|
+
import { existsSync, readFileSync, statSync, mkdirSync } from 'fs';
|
|
6
6
|
import { join, dirname } from 'path';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
import { execSync } from 'child_process';
|
|
@@ -356,6 +356,50 @@ export async function checkGitignoreCoverage() {
|
|
|
356
356
|
const missingList = missing.map(m => m.pattern).join(', ');
|
|
357
357
|
return { name: 'Gitignore Coverage', status: 'warn', message: `${missing.length} runtime path(s) not in .gitignore: ${missingList}`, fix: `printf "${missing.map(m => m.pattern).join('\\n')}\\n" >> .gitignore` };
|
|
358
358
|
}
|
|
359
|
+
export async function checkAgentRegistry() {
|
|
360
|
+
try {
|
|
361
|
+
const { buildUnifiedRegistry, computeAgentRoots } = await import('../agents/registry-builder.js');
|
|
362
|
+
const cwd = process.cwd();
|
|
363
|
+
const roots = computeAgentRoots(cwd);
|
|
364
|
+
const outDir = join(cwd, '.monomind');
|
|
365
|
+
mkdirSync(outDir, { recursive: true });
|
|
366
|
+
// Rebuilds fresh in-memory (and refreshes .monomind/registry.json on disk)
|
|
367
|
+
// rather than reading a file that a separate, unawaited startup task also
|
|
368
|
+
// writes — avoids reporting stale results from a race between the two.
|
|
369
|
+
const registry = buildUnifiedRegistry(roots, join(outDir, 'registry.json'));
|
|
370
|
+
const entries = registry.agents;
|
|
371
|
+
if (entries.length === 0) {
|
|
372
|
+
return { name: 'Agent Registry', status: 'warn', message: 'No agents found under .claude/agents', fix: 'monomind init (installs agent definitions)' };
|
|
373
|
+
}
|
|
374
|
+
let missingSlug = 0, missingName = 0, missingDescription = 0;
|
|
375
|
+
for (const agent of entries) {
|
|
376
|
+
if (!agent.slug)
|
|
377
|
+
missingSlug++;
|
|
378
|
+
if (!agent.name)
|
|
379
|
+
missingName++;
|
|
380
|
+
if (!agent.description)
|
|
381
|
+
missingDescription++;
|
|
382
|
+
}
|
|
383
|
+
const total = missingSlug + missingName + missingDescription;
|
|
384
|
+
if (total === 0) {
|
|
385
|
+
return { name: 'Agent Registry', status: 'pass', message: `${entries.length} agent(s), all metadata complete` };
|
|
386
|
+
}
|
|
387
|
+
const parts = [
|
|
388
|
+
missingSlug > 0 ? `${missingSlug} missing slug` : null,
|
|
389
|
+
missingName > 0 ? `${missingName} missing name` : null,
|
|
390
|
+
missingDescription > 0 ? `${missingDescription} missing description` : null,
|
|
391
|
+
].filter(Boolean).join(', ');
|
|
392
|
+
return {
|
|
393
|
+
name: 'Agent Registry',
|
|
394
|
+
status: 'warn',
|
|
395
|
+
message: `${total} metadata issue(s) across ${entries.length} agent(s): ${parts}`,
|
|
396
|
+
fix: 'Add the missing field(s) to frontmatter in .claude/agents/*.md',
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
catch {
|
|
400
|
+
return { name: 'Agent Registry', status: 'warn', message: 'Could not build/parse agent registry' };
|
|
401
|
+
}
|
|
402
|
+
}
|
|
359
403
|
export async function checkGuidanceGates() {
|
|
360
404
|
const settingsPath = join(process.cwd(), '.claude', 'settings.json');
|
|
361
405
|
const gatesHandlerPath = join(process.cwd(), '.claude', 'helpers', 'handlers', 'gates-handler.cjs');
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { output } from '../output.js';
|
|
8
8
|
import { checkNodeVersion, checkNpmVersion, checkGit, checkGitRepo, checkDiskSpace, checkBuildTools, checkVersionFreshness, checkClaudeCode, installClaudeCode, } from './doctor-env-checks.js';
|
|
9
|
-
import { checkConfigFile, checkDaemonStatus, checkMemoryDatabase, checkApiKeys, checkMcpServers, checkMonograph, checkMonographFreshness, checkMonoesMemory, checkHelpersFresh, checkMonoesIntegration, checkGuidanceGates, checkGitignoreCoverage, } from './doctor-project-checks.js';
|
|
9
|
+
import { checkConfigFile, checkDaemonStatus, checkMemoryDatabase, checkApiKeys, checkMcpServers, checkMonograph, checkMonographFreshness, checkMonoesMemory, checkHelpersFresh, checkMonoesIntegration, checkGuidanceGates, checkGitignoreCoverage, checkAgentRegistry, } from './doctor-project-checks.js';
|
|
10
10
|
function formatCheck(check) {
|
|
11
11
|
const icon = check.status === 'pass' ? output.success('✓') :
|
|
12
12
|
check.status === 'warn' ? output.warning('⚠') :
|
|
@@ -21,7 +21,7 @@ export const doctorCommand = {
|
|
|
21
21
|
{ name: 'install', short: 'i', description: 'Auto-install missing dependencies (Claude Code CLI)', type: 'boolean', default: false },
|
|
22
22
|
{
|
|
23
23
|
name: 'component', short: 'c',
|
|
24
|
-
description: 'Check specific component (version, node, npm, config, daemon, memory, api, git, mcp, claude, disk, typescript, monograph, graph-freshness, memory-pkg, helpers, monoes, gates, gitignore)',
|
|
24
|
+
description: 'Check specific component (version, node, npm, config, daemon, memory, api, git, mcp, claude, disk, typescript, monograph, graph-freshness, memory-pkg, helpers, monoes, gates, gitignore, registry)',
|
|
25
25
|
type: 'string',
|
|
26
26
|
},
|
|
27
27
|
{ name: 'verbose', short: 'v', description: 'Verbose output', type: 'boolean', default: false },
|
|
@@ -48,6 +48,7 @@ export const doctorCommand = {
|
|
|
48
48
|
checkApiKeys, checkMcpServers, checkDiskSpace, checkBuildTools,
|
|
49
49
|
checkMonograph, checkMonographFreshness, checkMonoesMemory,
|
|
50
50
|
checkHelpersFresh, checkMonoesIntegration, checkGuidanceGates, checkGitignoreCoverage,
|
|
51
|
+
checkAgentRegistry,
|
|
51
52
|
];
|
|
52
53
|
const componentMap = {
|
|
53
54
|
version: checkVersionFreshness, freshness: checkVersionFreshness,
|
|
@@ -58,6 +59,7 @@ export const doctorCommand = {
|
|
|
58
59
|
'graph-freshness': checkMonographFreshness, 'memory-pkg': checkMonoesMemory,
|
|
59
60
|
helpers: checkHelpersFresh, monoes: checkMonoesIntegration,
|
|
60
61
|
gates: checkGuidanceGates, gitignore: checkGitignoreCoverage,
|
|
62
|
+
registry: checkAgentRegistry,
|
|
61
63
|
};
|
|
62
64
|
const checksToRun = (component && componentMap[component]) ? [componentMap[component]] : allChecks;
|
|
63
65
|
const results = [];
|
|
@@ -439,50 +439,21 @@ export class CLI {
|
|
|
439
439
|
// Extra paths are read from MONOMIND_EXTRA_AGENT_PATHS env var (colon-separated)
|
|
440
440
|
// or fall back to the known local path when available.
|
|
441
441
|
try {
|
|
442
|
-
const { buildUnifiedRegistry } = await import('./agents/registry-builder.js');
|
|
442
|
+
const { buildUnifiedRegistry, computeAgentRoots } = await import('./agents/registry-builder.js');
|
|
443
443
|
const { mkdirSync } = await import('fs');
|
|
444
444
|
const { join } = await import('path');
|
|
445
|
-
const
|
|
446
|
-
const extraPaths = process.env.MONOMIND_EXTRA_AGENT_PATHS
|
|
447
|
-
? process.env.MONOMIND_EXTRA_AGENT_PATHS.split(':').filter(Boolean)
|
|
448
|
-
: [];
|
|
449
|
-
// Fallback: well-known sibling path relative to project root (no hardcoded dev paths)
|
|
450
|
-
const { existsSync } = await import('fs');
|
|
451
|
-
const siblingExtraPath = join(process.cwd(), '..', 'agency-agents');
|
|
452
|
-
if (extraPaths.length === 0 && existsSync(siblingExtraPath)) {
|
|
453
|
-
extraPaths.push(siblingExtraPath);
|
|
454
|
-
}
|
|
455
|
-
// extras-first so they win deduplication; dev agents fill in the rest
|
|
456
|
-
const roots = [...extraPaths, devAgentsRoot];
|
|
445
|
+
const roots = computeAgentRoots(process.cwd());
|
|
457
446
|
const outDir = join(process.cwd(), '.monomind');
|
|
458
447
|
mkdirSync(outDir, { recursive: true });
|
|
459
448
|
buildUnifiedRegistry(roots, join(outDir, 'registry.json'));
|
|
460
449
|
}
|
|
461
450
|
catch { /* optional — registry build failures must never block startup */ }
|
|
462
|
-
// Task 04: CapabilityMetadata
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
if (existsSync(registryPath) && statSyncReg(registryPath).size <= MAX_REGISTRY_BYTES) {
|
|
469
|
-
const registry = JSON.parse(readFileSync(registryPath, 'utf-8'));
|
|
470
|
-
const entries = registry.agents ?? [];
|
|
471
|
-
const issues = [];
|
|
472
|
-
for (const agent of entries) {
|
|
473
|
-
if (!agent.slug)
|
|
474
|
-
issues.push(`Agent missing 'slug'`);
|
|
475
|
-
if (!agent.name)
|
|
476
|
-
issues.push(`Agent ${String(agent.slug ?? '?')} missing 'name'`);
|
|
477
|
-
if (!agent.description)
|
|
478
|
-
issues.push(`Agent ${String(agent.slug ?? '?')} missing 'description'`);
|
|
479
|
-
}
|
|
480
|
-
if (issues.length > 0) {
|
|
481
|
-
console.warn(`[CapabilityMetadata] ${issues.length} agent metadata issue(s) in registry — run 'monomind doctor' to review`);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
catch { /* optional */ }
|
|
451
|
+
// Task 04: CapabilityMetadata validation moved to `monomind doctor -c registry`
|
|
452
|
+
// (see doctor-project-checks.ts:checkAgentRegistry). Printing this from a
|
|
453
|
+
// fire-and-forget startup task raced process exit — short-lived commands
|
|
454
|
+
// could skip the warning even when the underlying issue was present. Doctor
|
|
455
|
+
// runs it synchronously within its own check pass instead, so it's always
|
|
456
|
+
// visible and itemized when you actually look for it.
|
|
486
457
|
// NOTE: Semantic routing (@monomind/routing) is constructed on-demand by
|
|
487
458
|
// its consumers — `monomind route` and `monomind agent --task` (see
|
|
488
459
|
// commands/route.ts and commands/agent.ts). It is intentionally NOT
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monomindcli",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Monomind CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
|
|
6
6
|
"main": "dist/src/index.js",
|