moflo 4.8.9 → 4.8.11
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/agents/core/coder.md +265 -265
- package/.claude/agents/core/planner.md +167 -167
- package/.claude/agents/core/researcher.md +189 -189
- package/.claude/agents/core/reviewer.md +325 -325
- package/.claude/agents/core/tester.md +318 -318
- package/.claude/agents/dual-mode/codex-coordinator.md +224 -224
- package/.claude/agents/dual-mode/codex-worker.md +211 -211
- package/.claude/agents/dual-mode/dual-orchestrator.md +291 -291
- package/.claude/agents/github/code-review-swarm.md +537 -537
- package/.claude/agents/github/github-modes.md +172 -172
- package/.claude/agents/github/issue-tracker.md +318 -318
- package/.claude/agents/github/multi-repo-swarm.md +552 -552
- package/.claude/agents/github/pr-manager.md +190 -190
- package/.claude/agents/github/project-board-sync.md +508 -508
- package/.claude/agents/github/release-manager.md +366 -366
- package/.claude/agents/github/release-swarm.md +582 -582
- package/.claude/agents/github/repo-architect.md +397 -397
- package/.claude/agents/github/swarm-issue.md +572 -572
- package/.claude/agents/github/swarm-pr.md +427 -427
- package/.claude/agents/github/sync-coordinator.md +451 -451
- package/.claude/agents/github/workflow-automation.md +634 -634
- package/.claude/agents/goal/code-goal-planner.md +445 -445
- package/.claude/agents/hive-mind/collective-intelligence-coordinator.md +129 -129
- package/.claude/agents/hive-mind/queen-coordinator.md +202 -202
- package/.claude/agents/hive-mind/scout-explorer.md +241 -241
- package/.claude/agents/hive-mind/swarm-memory-manager.md +192 -192
- package/.claude/agents/hive-mind/worker-specialist.md +216 -216
- package/.claude/agents/neural/safla-neural.md +73 -73
- package/.claude/agents/reasoning/goal-planner.md +72 -72
- package/.claude/agents/swarm/adaptive-coordinator.md +395 -395
- package/.claude/agents/swarm/hierarchical-coordinator.md +326 -326
- package/.claude/agents/swarm/mesh-coordinator.md +391 -391
- package/.claude/agents/templates/migration-plan.md +745 -745
- package/.claude/commands/agents/agent-spawning.md +28 -28
- package/.claude/commands/analysis/COMMAND_COMPLIANCE_REPORT.md +53 -53
- package/.claude/commands/analysis/bottleneck-detect.md +162 -162
- package/.claude/commands/analysis/performance-bottlenecks.md +58 -58
- package/.claude/commands/analysis/token-efficiency.md +44 -44
- package/.claude/commands/automation/auto-agent.md +122 -122
- package/.claude/commands/automation/self-healing.md +105 -105
- package/.claude/commands/automation/session-memory.md +89 -89
- package/.claude/commands/automation/smart-agents.md +72 -72
- package/.claude/commands/coordination/init.md +44 -44
- package/.claude/commands/coordination/orchestrate.md +43 -43
- package/.claude/commands/coordination/spawn.md +45 -45
- package/.claude/commands/coordination/swarm-init.md +85 -85
- package/.claude/commands/github/github-modes.md +146 -146
- package/.claude/commands/github/github-swarm.md +121 -121
- package/.claude/commands/github/issue-tracker.md +291 -291
- package/.claude/commands/github/pr-manager.md +169 -169
- package/.claude/commands/github/release-manager.md +337 -337
- package/.claude/commands/github/repo-architect.md +366 -366
- package/.claude/commands/github/sync-coordinator.md +300 -300
- package/.claude/commands/memory/neural.md +47 -47
- package/.claude/commands/monitoring/agents.md +44 -44
- package/.claude/commands/monitoring/status.md +46 -46
- package/.claude/commands/optimization/auto-topology.md +61 -61
- package/.claude/commands/optimization/parallel-execution.md +49 -49
- package/.claude/commands/sparc/analyzer.md +51 -51
- package/.claude/commands/sparc/architect.md +53 -53
- package/.claude/commands/sparc/ask.md +97 -97
- package/.claude/commands/sparc/batch-executor.md +54 -54
- package/.claude/commands/sparc/code.md +89 -89
- package/.claude/commands/sparc/coder.md +54 -54
- package/.claude/commands/sparc/debug.md +83 -83
- package/.claude/commands/sparc/debugger.md +54 -54
- package/.claude/commands/sparc/designer.md +53 -53
- package/.claude/commands/sparc/devops.md +109 -109
- package/.claude/commands/sparc/docs-writer.md +80 -80
- package/.claude/commands/sparc/documenter.md +54 -54
- package/.claude/commands/sparc/innovator.md +54 -54
- package/.claude/commands/sparc/integration.md +83 -83
- package/.claude/commands/sparc/mcp.md +117 -117
- package/.claude/commands/sparc/memory-manager.md +54 -54
- package/.claude/commands/sparc/optimizer.md +54 -54
- package/.claude/commands/sparc/orchestrator.md +131 -131
- package/.claude/commands/sparc/post-deployment-monitoring-mode.md +83 -83
- package/.claude/commands/sparc/refinement-optimization-mode.md +83 -83
- package/.claude/commands/sparc/researcher.md +54 -54
- package/.claude/commands/sparc/reviewer.md +54 -54
- package/.claude/commands/sparc/security-review.md +80 -80
- package/.claude/commands/sparc/sparc-modes.md +174 -174
- package/.claude/commands/sparc/sparc.md +111 -111
- package/.claude/commands/sparc/spec-pseudocode.md +80 -80
- package/.claude/commands/sparc/supabase-admin.md +348 -348
- package/.claude/commands/sparc/swarm-coordinator.md +54 -54
- package/.claude/commands/sparc/tdd.md +54 -54
- package/.claude/commands/sparc/tester.md +54 -54
- package/.claude/commands/sparc/tutorial.md +79 -79
- package/.claude/commands/sparc/workflow-manager.md +54 -54
- package/.claude/commands/sparc.md +166 -166
- package/.claude/commands/swarm/analysis.md +95 -95
- package/.claude/commands/swarm/development.md +96 -96
- package/.claude/commands/swarm/examples.md +168 -168
- package/.claude/commands/swarm/maintenance.md +102 -102
- package/.claude/commands/swarm/optimization.md +117 -117
- package/.claude/commands/swarm/research.md +136 -136
- package/.claude/commands/swarm/testing.md +131 -131
- package/.claude/commands/training/neural-patterns.md +73 -73
- package/.claude/commands/training/specialization.md +62 -62
- package/.claude/commands/workflows/development.md +77 -77
- package/.claude/commands/workflows/research.md +62 -62
- package/.claude/guidance/{agent-bootstrap.md → shipped/agent-bootstrap.md} +126 -126
- package/.claude/guidance/{guidance-memory-strategy.md → shipped/guidance-memory-strategy.md} +262 -262
- package/.claude/guidance/{memory-strategy.md → shipped/memory-strategy.md} +204 -204
- package/.claude/guidance/{moflo.md → shipped/moflo.md} +45 -31
- package/.claude/guidance/{task-swarm-integration.md → shipped/task-swarm-integration.md} +441 -348
- package/.claude/helpers/gate.cjs +236 -236
- package/.claude/helpers/hook-handler.cjs +42 -46
- package/.claude/settings.json +2 -2
- package/.claude/settings.local.json +3 -3
- package/.claude/skills/fl/SKILL.md +29 -23
- package/.claude/skills/flo/SKILL.md +29 -23
- package/.claude/skills/github-code-review/SKILL.md +4 -4
- package/.claude/skills/github-multi-repo/SKILL.md +8 -8
- package/.claude/skills/github-project-management/SKILL.md +6 -6
- package/.claude/skills/github-release-management/SKILL.md +12 -12
- package/.claude/skills/github-workflow-automation/SKILL.md +6 -6
- package/.claude/skills/hooks-automation/SKILL.md +1201 -1201
- package/.claude/skills/performance-analysis/SKILL.md +563 -563
- package/.claude/skills/sparc-methodology/SKILL.md +64 -64
- package/.claude/skills/swarm-advanced/SKILL.md +77 -77
- package/.claude-plugin/README.md +3 -3
- package/.claude-plugin/docs/PLUGIN_SUMMARY.md +3 -3
- package/.claude-plugin/docs/QUICKSTART.md +4 -4
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +3 -3
- package/.claude-plugin/scripts/install.sh +9 -9
- package/.claude-plugin/scripts/verify.sh +7 -7
- package/README.md +311 -116
- package/bin/gate-hook.mjs +50 -0
- package/bin/gate.cjs +138 -0
- package/bin/hook-handler.cjs +83 -0
- package/bin/hooks.mjs +72 -12
- package/bin/index-guidance.mjs +28 -34
- package/bin/index-tests.mjs +710 -0
- package/bin/lib/process-manager.mjs +243 -0
- package/bin/lib/registry-cleanup.cjs +41 -0
- package/bin/prompt-hook.mjs +72 -0
- package/bin/semantic-search.mjs +473 -441
- package/bin/session-start-launcher.mjs +81 -31
- package/bin/setup-project.mjs +13 -10
- package/package.json +4 -2
- package/src/@claude-flow/cli/README.md +1 -1
- package/src/@claude-flow/cli/bin/cli.js +175 -175
- package/src/@claude-flow/cli/dist/src/commands/doctor.js +1091 -736
- package/src/@claude-flow/cli/dist/src/commands/github.d.ts +12 -0
- package/src/@claude-flow/cli/dist/src/commands/github.js +505 -0
- package/src/@claude-flow/cli/dist/src/commands/hive-mind.js +90 -90
- package/src/@claude-flow/cli/dist/src/commands/index.d.ts +1 -0
- package/src/@claude-flow/cli/dist/src/commands/index.js +7 -0
- package/src/@claude-flow/cli/dist/src/config-adapter.js +1 -1
- package/src/@claude-flow/cli/dist/src/init/claudemd-generator.js +1 -1
- package/src/@claude-flow/cli/dist/src/init/executor.js +109 -5
- package/src/@claude-flow/cli/dist/src/init/helpers-generator.d.ts +14 -0
- package/src/@claude-flow/cli/dist/src/init/helpers-generator.js +156 -24
- package/src/@claude-flow/cli/dist/src/init/mcp-generator.js +20 -20
- package/src/@claude-flow/cli/dist/src/init/moflo-init.d.ts +7 -0
- package/src/@claude-flow/cli/dist/src/init/moflo-init.js +72 -10
- package/src/@claude-flow/cli/dist/src/init/settings-generator.js +23 -14
- package/src/@claude-flow/cli/dist/src/mcp-server.js +3 -3
- package/src/@claude-flow/cli/dist/src/plugins/manager.js +9 -8
- package/src/@claude-flow/cli/dist/src/services/worker-daemon.d.ts +1 -0
- package/src/@claude-flow/cli/dist/src/services/worker-daemon.js +3 -1
- package/src/@claude-flow/cli/dist/src/services/workflow-gate.js +10 -10
- package/src/@claude-flow/cli/package.json +1 -1
|
@@ -178,6 +178,8 @@ export function generateHelpers(options) {
|
|
|
178
178
|
helpers['pre-commit'] = generatePreCommitHook();
|
|
179
179
|
helpers['post-commit'] = generatePostCommitHook();
|
|
180
180
|
helpers['gate.cjs'] = generateGateScript();
|
|
181
|
+
helpers['gate-hook.mjs'] = generateGateHookScript();
|
|
182
|
+
helpers['prompt-hook.mjs'] = generatePromptHookScript();
|
|
181
183
|
helpers['hook-handler.cjs'] = generateHookHandlerScript();
|
|
182
184
|
}
|
|
183
185
|
if (options.components.statusline) {
|
|
@@ -197,7 +199,7 @@ export function generateGateScript() {
|
|
|
197
199
|
var fs = require('fs');
|
|
198
200
|
var path = require('path');
|
|
199
201
|
|
|
200
|
-
var PROJECT_DIR = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
202
|
+
var PROJECT_DIR = (process.env.CLAUDE_PROJECT_DIR || process.cwd()).replace(/^\\/([a-z])\\//i, '$1:/');
|
|
201
203
|
var STATE_FILE = path.join(PROJECT_DIR, '.claude', 'workflow-state.json');
|
|
202
204
|
|
|
203
205
|
function readState() {
|
|
@@ -241,13 +243,15 @@ var TASK_RE = /\\b(fix|bug|error|implement|add|create|build|write|refactor|debug
|
|
|
241
243
|
switch (command) {
|
|
242
244
|
case 'check-before-agent': {
|
|
243
245
|
var s = readState();
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
process.
|
|
246
|
+
// Hard gate: memory must be searched
|
|
247
|
+
if (config.memory_first && s.memoryRequired && !s.memorySearched) {
|
|
248
|
+
process.stderr.write('BLOCKED: Search memory (mcp__moflo__memory_search) before spawning agents.\\n');
|
|
249
|
+
process.exit(2);
|
|
247
250
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
+
// Soft gate: TaskCreate recommended but not blocking
|
|
252
|
+
// (TaskCreate PostToolUse doesn't fire in Claude Code, so we can't track it reliably)
|
|
253
|
+
if (config.task_create_first && !s.tasksCreated) {
|
|
254
|
+
process.stdout.write('REMINDER: Use TaskCreate before spawning agents. Task tool is blocked until then.\\n');
|
|
251
255
|
}
|
|
252
256
|
break;
|
|
253
257
|
}
|
|
@@ -257,14 +261,8 @@ switch (command) {
|
|
|
257
261
|
if (s.memorySearched || !s.memoryRequired) break;
|
|
258
262
|
var target = (process.env.TOOL_INPUT_pattern || '') + ' ' + (process.env.TOOL_INPUT_path || '');
|
|
259
263
|
if (EXEMPT.some(function(p) { return target.indexOf(p) >= 0; })) break;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
if (now - last > 2000) {
|
|
263
|
-
s.lastBlockedAt = new Date(now).toISOString();
|
|
264
|
-
writeState(s);
|
|
265
|
-
console.log('BLOCKED: Search memory before exploring files.');
|
|
266
|
-
}
|
|
267
|
-
process.exit(1);
|
|
264
|
+
process.stderr.write('BLOCKED: Search memory before exploring files. Use mcp__moflo__memory_search.\\n');
|
|
265
|
+
process.exit(2);
|
|
268
266
|
}
|
|
269
267
|
case 'check-before-read': {
|
|
270
268
|
if (!config.memory_first) break;
|
|
@@ -272,14 +270,8 @@ switch (command) {
|
|
|
272
270
|
if (s.memorySearched || !s.memoryRequired) break;
|
|
273
271
|
var fp = process.env.TOOL_INPUT_file_path || '';
|
|
274
272
|
if (fp.indexOf('.claude/guidance/') < 0 && fp.indexOf('.claude\\\\guidance\\\\') < 0) break;
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (now - last > 2000) {
|
|
278
|
-
s.lastBlockedAt = new Date(now).toISOString();
|
|
279
|
-
writeState(s);
|
|
280
|
-
console.log('BLOCKED: Search memory before reading guidance files.');
|
|
281
|
-
}
|
|
282
|
-
process.exit(1);
|
|
273
|
+
process.stderr.write('BLOCKED: Search memory before reading guidance files. Use mcp__moflo__memory_search.\\n');
|
|
274
|
+
process.exit(2);
|
|
283
275
|
}
|
|
284
276
|
case 'record-task-created': {
|
|
285
277
|
var s = readState();
|
|
@@ -325,7 +317,7 @@ switch (command) {
|
|
|
325
317
|
var ic = s.interactionCount;
|
|
326
318
|
if (ic > 30) console.log('Context: CRITICAL. Commit, store learnings, suggest new session.');
|
|
327
319
|
else if (ic > 20) console.log('Context: DEPLETED. Checkpoint progress. Recommend /compact or fresh session.');
|
|
328
|
-
else if (ic > 10) console.log('Context: MODERATE. Re-state goal before architectural decisions.');
|
|
320
|
+
else if (ic > 10) console.log('Context: MODERATE. Re-state goal before architectural decisions. Use agents for >300 LOC.');
|
|
329
321
|
}
|
|
330
322
|
break;
|
|
331
323
|
}
|
|
@@ -342,6 +334,146 @@ switch (command) {
|
|
|
342
334
|
}
|
|
343
335
|
`;
|
|
344
336
|
}
|
|
337
|
+
/**
|
|
338
|
+
* Generate gate-hook.mjs — ESM wrapper that reads Claude Code stdin JSON
|
|
339
|
+
* and passes tool_name + tool_input to gate.cjs via environment variables.
|
|
340
|
+
*
|
|
341
|
+
* Claude Code hooks receive context as JSON on stdin but don't set env vars
|
|
342
|
+
* for tool input. This script bridges that gap. It also translates exit code 1
|
|
343
|
+
* from gate.cjs into exit code 2 (which Claude Code requires to block tools).
|
|
344
|
+
*/
|
|
345
|
+
export function generateGateHookScript() {
|
|
346
|
+
return `#!/usr/bin/env node
|
|
347
|
+
import { execSync } from 'child_process';
|
|
348
|
+
import { resolve } from 'path';
|
|
349
|
+
|
|
350
|
+
var command = process.argv[2];
|
|
351
|
+
if (!command) process.exit(0);
|
|
352
|
+
|
|
353
|
+
// Read stdin JSON from Claude Code
|
|
354
|
+
var stdinData = '';
|
|
355
|
+
try {
|
|
356
|
+
stdinData = await new Promise(function(res) {
|
|
357
|
+
var data = '';
|
|
358
|
+
var timeout = setTimeout(function() { res(data); }, 500);
|
|
359
|
+
process.stdin.setEncoding('utf-8');
|
|
360
|
+
process.stdin.on('data', function(chunk) { data += chunk; });
|
|
361
|
+
process.stdin.on('end', function() { clearTimeout(timeout); res(data); });
|
|
362
|
+
process.stdin.on('error', function() { clearTimeout(timeout); res(''); });
|
|
363
|
+
if (process.stdin.isTTY) { clearTimeout(timeout); res(''); }
|
|
364
|
+
});
|
|
365
|
+
} catch (e) { /* no stdin */ }
|
|
366
|
+
|
|
367
|
+
var hookContext = {};
|
|
368
|
+
try { if (stdinData.trim()) hookContext = JSON.parse(stdinData); } catch (e) {}
|
|
369
|
+
|
|
370
|
+
// Pass tool info as env vars for gate.cjs
|
|
371
|
+
var env = Object.assign({}, process.env);
|
|
372
|
+
if (hookContext.tool_name) env.TOOL_NAME = hookContext.tool_name;
|
|
373
|
+
if (hookContext.tool_input && typeof hookContext.tool_input === 'object') {
|
|
374
|
+
Object.keys(hookContext.tool_input).forEach(function(key) {
|
|
375
|
+
if (typeof hookContext.tool_input[key] === 'string') {
|
|
376
|
+
env['TOOL_INPUT_' + key] = hookContext.tool_input[key];
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Run gate.cjs with the enriched environment
|
|
382
|
+
var projectDir = (env.CLAUDE_PROJECT_DIR || process.cwd()).replace(/^\\/([a-z])\\//i, '$1:/');
|
|
383
|
+
var gateScript = resolve(projectDir, '.claude/helpers/gate.cjs');
|
|
384
|
+
try {
|
|
385
|
+
var output = execSync('node "' + gateScript + '" ' + command, {
|
|
386
|
+
env: env, encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe']
|
|
387
|
+
});
|
|
388
|
+
if (output.trim()) process.stdout.write(output);
|
|
389
|
+
process.exit(0);
|
|
390
|
+
} catch (err) {
|
|
391
|
+
// gate.cjs exit(2) = block, exit(1) = also block attempt — translate both to exit(2)
|
|
392
|
+
if (err.stderr) process.stderr.write(err.stderr);
|
|
393
|
+
if (err.stdout) process.stderr.write(err.stdout);
|
|
394
|
+
process.exit(err.status === 2 || err.status === 1 ? 2 : 0);
|
|
395
|
+
}
|
|
396
|
+
`;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Generate prompt-hook.mjs — reads user prompt from Claude Code stdin JSON,
|
|
400
|
+
* runs prompt classification via gate.cjs, and appends namespace hints.
|
|
401
|
+
*/
|
|
402
|
+
export function generatePromptHookScript() {
|
|
403
|
+
return `#!/usr/bin/env node
|
|
404
|
+
import { execSync } from 'child_process';
|
|
405
|
+
import { resolve } from 'path';
|
|
406
|
+
|
|
407
|
+
// Read stdin JSON from Claude Code
|
|
408
|
+
var stdinData = '';
|
|
409
|
+
try {
|
|
410
|
+
stdinData = await new Promise(function(res) {
|
|
411
|
+
var data = '';
|
|
412
|
+
var timeout = setTimeout(function() { res(data); }, 500);
|
|
413
|
+
process.stdin.setEncoding('utf-8');
|
|
414
|
+
process.stdin.on('data', function(chunk) { data += chunk; });
|
|
415
|
+
process.stdin.on('end', function() { clearTimeout(timeout); res(data); });
|
|
416
|
+
process.stdin.on('error', function() { clearTimeout(timeout); res(''); });
|
|
417
|
+
if (process.stdin.isTTY) { clearTimeout(timeout); res(''); }
|
|
418
|
+
});
|
|
419
|
+
} catch (e) { /* no stdin */ }
|
|
420
|
+
|
|
421
|
+
var hookContext = {};
|
|
422
|
+
try { if (stdinData.trim()) hookContext = JSON.parse(stdinData); } catch (e) {}
|
|
423
|
+
|
|
424
|
+
var userPrompt = hookContext.user_prompt || hookContext.prompt || '';
|
|
425
|
+
var env = Object.assign({}, process.env, { CLAUDE_USER_PROMPT: userPrompt });
|
|
426
|
+
|
|
427
|
+
// Run prompt-reminder via gate.cjs
|
|
428
|
+
var projectDir = (env.CLAUDE_PROJECT_DIR || process.cwd()).replace(/^\\/([a-z])\\//i, '$1:/');
|
|
429
|
+
var gateScript = resolve(projectDir, '.claude/helpers/gate.cjs');
|
|
430
|
+
var output = '';
|
|
431
|
+
try {
|
|
432
|
+
output = execSync('node "' + gateScript + '" prompt-reminder', {
|
|
433
|
+
env: env, encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe']
|
|
434
|
+
});
|
|
435
|
+
} catch (err) { output = (err && err.stdout) || ''; }
|
|
436
|
+
|
|
437
|
+
// Classify prompt for namespace hint
|
|
438
|
+
var lower = userPrompt.toLowerCase();
|
|
439
|
+
|
|
440
|
+
var KNOWLEDGE_ONLY = /\\b(knowledge|remember|recall)\\b|we (decid|agree|chose|said)/;
|
|
441
|
+
var EXPLICIT_NS = [
|
|
442
|
+
{ pattern: /\\b(pattern|convention|best practice|style|coding rule)\\b/, ns: 'patterns', label: 'code patterns and conventions' },
|
|
443
|
+
{ pattern: /\\b(code.?map|file structure|project structure|directory)\\b/, ns: 'code-map', label: 'codebase navigation' },
|
|
444
|
+
];
|
|
445
|
+
var PATTERN_HINTS = [/\\b(template|example|similar to|how do we|how should)\\b/];
|
|
446
|
+
var DOMAIN_HINTS = [
|
|
447
|
+
/\\b(guidance|guide|docs|documentation|rules|how-to)\\b/,
|
|
448
|
+
/\\b(architecture|design|domain|tenant|migrat|schema|deploy)/,
|
|
449
|
+
/\\b(rule|requirement|constraint|compliance)\\b/,
|
|
450
|
+
];
|
|
451
|
+
var NAV_PATTERNS = [
|
|
452
|
+
/\\b(find|where|which file|look up|locate|endpoint|route|url|path)\\b/,
|
|
453
|
+
/\\b(class|function|method|component|service|entity|module)\\b/,
|
|
454
|
+
];
|
|
455
|
+
|
|
456
|
+
var nsHint = '';
|
|
457
|
+
if (KNOWLEDGE_ONLY.test(lower)) {
|
|
458
|
+
nsHint = 'Memory namespace hint: use "knowledge" for user-directed project decisions.';
|
|
459
|
+
} else {
|
|
460
|
+
var found = EXPLICIT_NS.find(function(e) { return e.pattern.test(lower); });
|
|
461
|
+
if (found) {
|
|
462
|
+
nsHint = 'Memory namespace hint: use "' + found.ns + '" for ' + found.label + '.';
|
|
463
|
+
} else if (DOMAIN_HINTS.some(function(p) { return p.test(lower); })) {
|
|
464
|
+
nsHint = 'Memory namespace hint: search "guidance" and "knowledge" for domain rules and project decisions.';
|
|
465
|
+
} else if (PATTERN_HINTS.some(function(p) { return p.test(lower); })) {
|
|
466
|
+
nsHint = 'Memory namespace hint: use "patterns" for code patterns and conventions.';
|
|
467
|
+
} else if (NAV_PATTERNS.some(function(p) { return p.test(lower); })) {
|
|
468
|
+
nsHint = 'Memory namespace hint: use "code-map" for codebase navigation.';
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
var parts = [output.trim(), nsHint].filter(Boolean);
|
|
473
|
+
if (parts.length) process.stdout.write(parts.join('\\n') + '\\n');
|
|
474
|
+
process.exit(0);
|
|
475
|
+
`;
|
|
476
|
+
}
|
|
345
477
|
/**
|
|
346
478
|
* Generate lightweight hook-handler.cjs — hook dispatch without CLI bootstrap.
|
|
347
479
|
* Handles routing, edit/task tracking, session lifecycle, and notifications.
|
|
@@ -8,28 +8,25 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { existsSync } from 'fs';
|
|
10
10
|
import { join } from 'path';
|
|
11
|
+
const isWindows = process.platform === 'win32';
|
|
11
12
|
/**
|
|
12
|
-
* Generate MCP server entry using npx (for external packages)
|
|
13
|
+
* Generate MCP server entry using npx (for external packages).
|
|
14
|
+
* On Windows, wraps with `cmd /c` so Claude Code can spawn the process.
|
|
13
15
|
*/
|
|
14
16
|
function createNpxServerEntry(npxArgs, env, additionalProps = {}) {
|
|
15
|
-
return
|
|
16
|
-
command: 'npx',
|
|
17
|
-
args: ['-y', ...npxArgs],
|
|
18
|
-
env,
|
|
19
|
-
...additionalProps,
|
|
20
|
-
};
|
|
17
|
+
return isWindows
|
|
18
|
+
? { command: 'cmd', args: ['/c', 'npx', '-y', ...npxArgs], env, ...additionalProps }
|
|
19
|
+
: { command: 'npx', args: ['-y', ...npxArgs], env, ...additionalProps };
|
|
21
20
|
}
|
|
22
21
|
/**
|
|
23
22
|
* Generate MCP server entry using direct node invocation (for local moflo).
|
|
24
23
|
* Avoids npx overhead — faster startup, fewer intermediate processes.
|
|
24
|
+
* On Windows, wraps with `cmd /c` so Claude Code can spawn the process.
|
|
25
25
|
*/
|
|
26
26
|
function createDirectServerEntry(cliPath, cliArgs, env, additionalProps = {}) {
|
|
27
|
-
return
|
|
28
|
-
command: 'node',
|
|
29
|
-
args: [cliPath, ...cliArgs],
|
|
30
|
-
env,
|
|
31
|
-
...additionalProps,
|
|
32
|
-
};
|
|
27
|
+
return isWindows
|
|
28
|
+
? { command: 'cmd', args: ['/c', 'node', cliPath, ...cliArgs], env, ...additionalProps }
|
|
29
|
+
: { command: 'node', args: [cliPath, ...cliArgs], env, ...additionalProps };
|
|
33
30
|
}
|
|
34
31
|
/**
|
|
35
32
|
* Find the moflo CLI entry point relative to the project root.
|
|
@@ -73,10 +70,10 @@ export function generateMCPConfig(options) {
|
|
|
73
70
|
const projectRoot = options.targetDir ?? process.cwd();
|
|
74
71
|
const localCli = findMofloCli(projectRoot);
|
|
75
72
|
if (localCli) {
|
|
76
|
-
mcpServers['
|
|
73
|
+
mcpServers['moflo'] = createDirectServerEntry(localCli, ['mcp', 'start'], mcpEnv, { autoStart: config.autoStart, ...deferProps });
|
|
77
74
|
}
|
|
78
75
|
else {
|
|
79
|
-
mcpServers['
|
|
76
|
+
mcpServers['moflo'] = createNpxServerEntry(['moflo', 'mcp', 'start'], mcpEnv, { autoStart: config.autoStart, ...deferProps });
|
|
80
77
|
}
|
|
81
78
|
}
|
|
82
79
|
// Ruv-Swarm MCP server (enhanced coordination) — always npx (external package)
|
|
@@ -102,21 +99,22 @@ export function generateMCPJson(options) {
|
|
|
102
99
|
export function generateMCPCommands(options) {
|
|
103
100
|
const commands = [];
|
|
104
101
|
const config = options.mcp;
|
|
102
|
+
const cmdPrefix = isWindows ? 'cmd /c ' : '';
|
|
105
103
|
if (config.claudeFlow) {
|
|
106
104
|
const projectRoot = options.targetDir ?? process.cwd();
|
|
107
105
|
const localCli = findMofloCli(projectRoot);
|
|
108
106
|
if (localCli) {
|
|
109
|
-
commands.push(`claude mcp add
|
|
107
|
+
commands.push(`claude mcp add moflo -- ${cmdPrefix}node ${localCli} mcp start`);
|
|
110
108
|
}
|
|
111
109
|
else {
|
|
112
|
-
commands.push(
|
|
110
|
+
commands.push(`claude mcp add moflo -- ${cmdPrefix}npx -y moflo mcp start`);
|
|
113
111
|
}
|
|
114
112
|
}
|
|
115
113
|
if (config.ruvSwarm) {
|
|
116
|
-
commands.push(
|
|
114
|
+
commands.push(`claude mcp add ruv-swarm -- ${cmdPrefix}npx -y ruv-swarm mcp start`);
|
|
117
115
|
}
|
|
118
116
|
if (config.flowNexus) {
|
|
119
|
-
commands.push(
|
|
117
|
+
commands.push(`claude mcp add flow-nexus -- ${cmdPrefix}npx -y flow-nexus@latest mcp start`);
|
|
120
118
|
}
|
|
121
119
|
return commands;
|
|
122
120
|
}
|
|
@@ -129,7 +127,9 @@ export function getPlatformInstructions() {
|
|
|
129
127
|
: process.platform === 'darwin' ? 'macOS' : 'Linux';
|
|
130
128
|
return {
|
|
131
129
|
platform,
|
|
132
|
-
note:
|
|
130
|
+
note: isWindows
|
|
131
|
+
? 'MCP configuration uses cmd /c wrapper for Windows compatibility.'
|
|
132
|
+
: 'MCP configuration uses npx directly.',
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
135
|
//# sourceMappingURL=mcp-generator.js.map
|
|
@@ -10,6 +10,8 @@ export interface MofloInitAnswers {
|
|
|
10
10
|
guidanceDirs: string[];
|
|
11
11
|
codeMap: boolean;
|
|
12
12
|
srcDirs: string[];
|
|
13
|
+
tests: boolean;
|
|
14
|
+
testDirs: string[];
|
|
13
15
|
gates: boolean;
|
|
14
16
|
stopHook: boolean;
|
|
15
17
|
}
|
|
@@ -20,5 +22,10 @@ export interface MofloInitResult {
|
|
|
20
22
|
detail?: string;
|
|
21
23
|
}[];
|
|
22
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Discover test directories by checking common locations and walking for
|
|
27
|
+
* colocated __tests__ dirs. Returns relative paths.
|
|
28
|
+
*/
|
|
29
|
+
export declare function discoverTestDirs(root: string): string[];
|
|
23
30
|
export declare function initMoflo(options: MofloInitOptions): Promise<MofloInitResult>;
|
|
24
31
|
//# sourceMappingURL=moflo-init.d.ts.map
|
|
@@ -53,6 +53,37 @@ function discoverGuidanceDirs(root) {
|
|
|
53
53
|
walk('', 0);
|
|
54
54
|
return found;
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Discover test directories by checking common locations and walking for
|
|
58
|
+
* colocated __tests__ dirs. Returns relative paths.
|
|
59
|
+
*/
|
|
60
|
+
export function discoverTestDirs(root) {
|
|
61
|
+
const TOP_LEVEL = ['tests', 'test', '__tests__', 'spec', 'e2e'];
|
|
62
|
+
const found = TOP_LEVEL.filter(d => fs.existsSync(path.join(root, d)));
|
|
63
|
+
// Walk up to 3 levels deep looking for __tests__ dirs inside src
|
|
64
|
+
const SKIP = new Set(['node_modules', '.git', 'dist', 'build', 'coverage', '.next', '.reports', '.swarm', '.claude-flow']);
|
|
65
|
+
function walk(dir, depth) {
|
|
66
|
+
if (depth > 3)
|
|
67
|
+
return;
|
|
68
|
+
try {
|
|
69
|
+
const entries = fs.readdirSync(path.join(root, dir), { withFileTypes: true });
|
|
70
|
+
for (const entry of entries) {
|
|
71
|
+
if (!entry.isDirectory() || SKIP.has(entry.name))
|
|
72
|
+
continue;
|
|
73
|
+
const rel = dir ? `${dir}/${entry.name}` : entry.name;
|
|
74
|
+
if (entry.name === '__tests__') {
|
|
75
|
+
found.push(rel);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
walk(rel, depth + 1);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch { /* skip unreadable directories */ }
|
|
83
|
+
}
|
|
84
|
+
walk('', 0);
|
|
85
|
+
return found;
|
|
86
|
+
}
|
|
56
87
|
/**
|
|
57
88
|
* Discover source directories by walking the project tree.
|
|
58
89
|
* Finds directories named 'src' (or top-level 'packages', 'lib', etc.)
|
|
@@ -140,6 +171,22 @@ async function runWizard(root) {
|
|
|
140
171
|
});
|
|
141
172
|
srcDirs = answer.split(',').map((d) => d.trim()).filter(Boolean);
|
|
142
173
|
}
|
|
174
|
+
// Detect test directories
|
|
175
|
+
const detectedTests = discoverTestDirs(root);
|
|
176
|
+
const tests = await confirm({
|
|
177
|
+
message: detectedTests.length > 0
|
|
178
|
+
? `Found tests in ${detectedTests.join(', ')}. Enable test file indexing?`
|
|
179
|
+
: 'Enable test file indexing?',
|
|
180
|
+
default: true,
|
|
181
|
+
});
|
|
182
|
+
let testDirs = detectedTests.length > 0 ? detectedTests : ['tests'];
|
|
183
|
+
if (tests) {
|
|
184
|
+
const answer = await input({
|
|
185
|
+
message: 'Test directories (comma-separated):',
|
|
186
|
+
default: testDirs.join(', '),
|
|
187
|
+
});
|
|
188
|
+
testDirs = answer.split(',').map((d) => d.trim()).filter(Boolean);
|
|
189
|
+
}
|
|
143
190
|
const gates = await confirm({
|
|
144
191
|
message: 'Enable workflow gates (memory-first, task-create-before-agents)?',
|
|
145
192
|
default: true,
|
|
@@ -148,7 +195,7 @@ async function runWizard(root) {
|
|
|
148
195
|
message: 'Enable session-end hook (saves session state)?',
|
|
149
196
|
default: true,
|
|
150
197
|
});
|
|
151
|
-
return { guidance, guidanceDirs, codeMap, srcDirs, gates, stopHook };
|
|
198
|
+
return { guidance, guidanceDirs, codeMap, srcDirs, tests, testDirs, gates, stopHook };
|
|
152
199
|
}
|
|
153
200
|
/**
|
|
154
201
|
* Get default answers (--yes mode).
|
|
@@ -160,13 +207,16 @@ function defaultAnswers(root) {
|
|
|
160
207
|
const srcDirs = discoverSrcDirs(root);
|
|
161
208
|
if (srcDirs.length === 0)
|
|
162
209
|
srcDirs.push('src');
|
|
163
|
-
|
|
210
|
+
const testDirs = discoverTestDirs(root);
|
|
211
|
+
if (testDirs.length === 0)
|
|
212
|
+
testDirs.push('tests');
|
|
213
|
+
return { guidance: true, guidanceDirs, codeMap: true, srcDirs, tests: true, testDirs, gates: true, stopHook: true };
|
|
164
214
|
}
|
|
165
215
|
/**
|
|
166
216
|
* Get minimal answers (--minimal mode).
|
|
167
217
|
*/
|
|
168
218
|
function minimalAnswers() {
|
|
169
|
-
return { guidance: false, guidanceDirs: [], codeMap: false, srcDirs: [], gates: false, stopHook: false };
|
|
219
|
+
return { guidance: false, guidanceDirs: [], codeMap: false, srcDirs: [], tests: false, testDirs: [], gates: false, stopHook: false };
|
|
170
220
|
}
|
|
171
221
|
export async function initMoflo(options) {
|
|
172
222
|
const { projectRoot, force, interactive, minimal } = options;
|
|
@@ -204,6 +254,7 @@ function generateConfig(root, force, answers) {
|
|
|
204
254
|
const projectName = path.basename(root);
|
|
205
255
|
const guidanceDirs = answers?.guidanceDirs ?? ['.claude/guidance'];
|
|
206
256
|
const srcDirs = answers?.srcDirs ?? ['src'];
|
|
257
|
+
const testDirs = answers?.testDirs ?? ['tests'];
|
|
207
258
|
const gatesEnabled = answers?.gates ?? true;
|
|
208
259
|
// Detect languages
|
|
209
260
|
const extensions = new Set();
|
|
@@ -240,6 +291,15 @@ ${srcDirs.map(d => ` - ${d}`).join('\n')}
|
|
|
240
291
|
exclude: [node_modules, dist, .next, coverage, build, __pycache__, target, .git]
|
|
241
292
|
namespace: code-map
|
|
242
293
|
|
|
294
|
+
# Test file discovery and indexing
|
|
295
|
+
tests:
|
|
296
|
+
directories:
|
|
297
|
+
${testDirs.map(d => ` - ${d}`).join('\n')}
|
|
298
|
+
patterns: ["*.test.*", "*.spec.*", "*.test-*"]
|
|
299
|
+
extensions: [".ts", ".tsx", ".js", ".jsx"]
|
|
300
|
+
exclude: [node_modules, coverage, dist]
|
|
301
|
+
namespace: tests
|
|
302
|
+
|
|
243
303
|
# Workflow gates (enforced via Claude Code hooks)
|
|
244
304
|
gates:
|
|
245
305
|
memory_first: ${gatesEnabled}
|
|
@@ -250,6 +310,7 @@ gates:
|
|
|
250
310
|
auto_index:
|
|
251
311
|
guidance: ${answers?.guidance ?? true}
|
|
252
312
|
code_map: ${answers?.codeMap ?? true}
|
|
313
|
+
tests: ${answers?.tests ?? true}
|
|
253
314
|
|
|
254
315
|
# Memory backend
|
|
255
316
|
memory:
|
|
@@ -432,7 +493,7 @@ function generateHooks(root, force, answers) {
|
|
|
432
493
|
}]
|
|
433
494
|
},
|
|
434
495
|
{
|
|
435
|
-
"matcher": "^
|
|
496
|
+
"matcher": "^mcp__moflo__memory_(search|retrieve)$",
|
|
436
497
|
"hooks": [{
|
|
437
498
|
"type": "command",
|
|
438
499
|
"command": "npx flo gate record-memory-searched",
|
|
@@ -590,7 +651,7 @@ This project uses [MoFlo](https://github.com/eric-cielo/moflo) for AI-assisted d
|
|
|
590
651
|
Your first tool call for every new user prompt MUST be a memory search. Do this BEFORE Glob, Grep, Read, or any file exploration.
|
|
591
652
|
|
|
592
653
|
\`\`\`
|
|
593
|
-
|
|
654
|
+
mcp__moflo__memory_search — query: "<task description>", namespace: "guidance" or "patterns" or "knowledge" or "code-map"
|
|
594
655
|
\`\`\`
|
|
595
656
|
|
|
596
657
|
For codebase navigation, search the \`code-map\` namespace first. For patterns and domain knowledge, search \`patterns\`, \`knowledge\`, and \`guidance\`.
|
|
@@ -612,11 +673,11 @@ Research → Enhance → Implement → Test → Simplify → PR
|
|
|
612
673
|
|
|
613
674
|
| Tool | Purpose |
|
|
614
675
|
|------|---------|
|
|
615
|
-
| \`
|
|
616
|
-
| \`
|
|
617
|
-
| \`
|
|
618
|
-
| \`
|
|
619
|
-
| \`
|
|
676
|
+
| \`mcp__moflo__memory_search\` | Semantic search across indexed knowledge |
|
|
677
|
+
| \`mcp__moflo__memory_store\` | Store patterns and decisions |
|
|
678
|
+
| \`mcp__moflo__hooks_route\` | Route task to optimal agent type |
|
|
679
|
+
| \`mcp__moflo__hooks_pre-task\` | Record task start |
|
|
680
|
+
| \`mcp__moflo__hooks_post-task\` | Record task completion for learning |
|
|
620
681
|
|
|
621
682
|
### Agent Icon Mapping
|
|
622
683
|
|
|
@@ -659,6 +720,7 @@ const SCRIPT_MAP = {
|
|
|
659
720
|
'build-embeddings.mjs': 'build-embeddings.mjs',
|
|
660
721
|
'generate-code-map.mjs': 'generate-code-map.mjs',
|
|
661
722
|
'semantic-search.mjs': 'semantic-search.mjs',
|
|
723
|
+
'index-tests.mjs': 'index-tests.mjs',
|
|
662
724
|
};
|
|
663
725
|
function syncScripts(root, force) {
|
|
664
726
|
const scriptsDir = path.join(root, '.claude', 'scripts');
|
|
@@ -22,7 +22,7 @@ export function generateSettings(options) {
|
|
|
22
22
|
'Bash(npx moflo*)',
|
|
23
23
|
'Bash(npx flo*)',
|
|
24
24
|
'Bash(node .claude/*)',
|
|
25
|
-
'
|
|
25
|
+
'mcp__moflo__:*',
|
|
26
26
|
],
|
|
27
27
|
deny: [
|
|
28
28
|
'Read(./.env)',
|
|
@@ -176,6 +176,14 @@ function autoMemoryCmd(subcommand) {
|
|
|
176
176
|
function gateCmd(subcommand) {
|
|
177
177
|
return hookCmd('"$CLAUDE_PROJECT_DIR/.claude/helpers/gate.cjs"', subcommand);
|
|
178
178
|
}
|
|
179
|
+
/** Gate hook wrapper — reads stdin JSON for tool input, uses exit code 2 for blocking */
|
|
180
|
+
function gateHookCmd(subcommand) {
|
|
181
|
+
return hookCmdEsm('"$CLAUDE_PROJECT_DIR/.claude/helpers/gate-hook.mjs"', subcommand);
|
|
182
|
+
}
|
|
183
|
+
/** Prompt hook — reads stdin JSON for user prompt, classifies namespace */
|
|
184
|
+
function promptHookCmd() {
|
|
185
|
+
return `node "$CLAUDE_PROJECT_DIR/.claude/helpers/prompt-hook.mjs"`;
|
|
186
|
+
}
|
|
179
187
|
/**
|
|
180
188
|
* Generate statusLine configuration for Claude Code
|
|
181
189
|
* Uses local helper script for cross-platform compatibility (no npx cold-start)
|
|
@@ -194,7 +202,7 @@ function generateStatusLineConfig(_options) {
|
|
|
194
202
|
/**
|
|
195
203
|
* Generate hooks configuration
|
|
196
204
|
* All hooks use direct node invocation via lightweight helper scripts
|
|
197
|
-
* (gate.cjs, hook-handler.cjs) instead of `npx flo` to avoid spawning
|
|
205
|
+
* (gate.cjs, gate-hook.mjs, hook-handler.cjs) instead of `npx flo` to avoid spawning
|
|
198
206
|
* a full CLI process on every tool call.
|
|
199
207
|
*/
|
|
200
208
|
function generateHooksConfig(config) {
|
|
@@ -208,22 +216,21 @@ function generateHooksConfig(config) {
|
|
|
208
216
|
},
|
|
209
217
|
{
|
|
210
218
|
matcher: '^(Glob|Grep)$',
|
|
211
|
-
hooks: [{ type: 'command', command:
|
|
219
|
+
hooks: [{ type: 'command', command: gateHookCmd('check-before-scan'), timeout: 3000 }],
|
|
212
220
|
},
|
|
213
221
|
{
|
|
214
222
|
matcher: '^Read$',
|
|
215
|
-
hooks: [{ type: 'command', command:
|
|
223
|
+
hooks: [{ type: 'command', command: gateHookCmd('check-before-read'), timeout: 3000 }],
|
|
216
224
|
},
|
|
217
225
|
{
|
|
218
|
-
matcher: '^
|
|
226
|
+
matcher: '^Agent$',
|
|
219
227
|
hooks: [
|
|
220
|
-
{ type: 'command', command:
|
|
221
|
-
{ type: 'command', command: hookHandlerCmd('pre-task'), timeout: 5000 },
|
|
228
|
+
{ type: 'command', command: gateHookCmd('check-before-agent'), timeout: 3000 },
|
|
222
229
|
],
|
|
223
230
|
},
|
|
224
231
|
{
|
|
225
232
|
matcher: '^Bash$',
|
|
226
|
-
hooks: [{ type: 'command', command:
|
|
233
|
+
hooks: [{ type: 'command', command: gateHookCmd('check-dangerous-command'), timeout: 2000 }],
|
|
227
234
|
},
|
|
228
235
|
];
|
|
229
236
|
}
|
|
@@ -235,20 +242,23 @@ function generateHooksConfig(config) {
|
|
|
235
242
|
hooks: [{ type: 'command', command: hookHandlerCmd('post-edit'), timeout: 5000 }],
|
|
236
243
|
},
|
|
237
244
|
{
|
|
238
|
-
matcher: '^
|
|
245
|
+
matcher: '^Agent$',
|
|
239
246
|
hooks: [{ type: 'command', command: hookHandlerCmd('post-task'), timeout: 5000 }],
|
|
240
247
|
},
|
|
241
248
|
{
|
|
249
|
+
// TaskCreate PostToolUse only fires in some Claude Code versions.
|
|
250
|
+
// The prompt-reminder and soft gate in check-before-agent handle the common case.
|
|
242
251
|
matcher: '^TaskCreate$',
|
|
243
252
|
hooks: [{ type: 'command', command: gateCmd('record-task-created'), timeout: 2000 }],
|
|
244
253
|
},
|
|
245
254
|
{
|
|
246
255
|
matcher: '^Bash$',
|
|
247
|
-
hooks: [{ type: 'command', command:
|
|
256
|
+
hooks: [{ type: 'command', command: gateHookCmd('check-bash-memory'), timeout: 2000 }],
|
|
248
257
|
},
|
|
249
258
|
{
|
|
250
|
-
matcher
|
|
251
|
-
|
|
259
|
+
// Simplified matcher — anchored regex with parens doesn't match MCP tool names reliably
|
|
260
|
+
matcher: 'mcp__moflo__memory_',
|
|
261
|
+
hooks: [{ type: 'command', command: gateCmd('record-memory-searched'), timeout: 3000 }],
|
|
252
262
|
},
|
|
253
263
|
];
|
|
254
264
|
}
|
|
@@ -257,8 +267,7 @@ function generateHooksConfig(config) {
|
|
|
257
267
|
hooks.UserPromptSubmit = [
|
|
258
268
|
{
|
|
259
269
|
hooks: [
|
|
260
|
-
{ type: 'command', command:
|
|
261
|
-
{ type: 'command', command: hookHandlerCmd('route'), timeout: 5000 },
|
|
270
|
+
{ type: 'command', command: promptHookCmd(), timeout: 3000 },
|
|
262
271
|
],
|
|
263
272
|
},
|
|
264
273
|
];
|
|
@@ -274,7 +274,7 @@ export class MCPServerManager extends EventEmitter {
|
|
|
274
274
|
method: 'server.initialized',
|
|
275
275
|
params: {
|
|
276
276
|
serverInfo: {
|
|
277
|
-
name: '
|
|
277
|
+
name: 'moflo',
|
|
278
278
|
version: VERSION,
|
|
279
279
|
capabilities: {
|
|
280
280
|
tools: { listChanged: true },
|
|
@@ -388,7 +388,7 @@ export class MCPServerManager extends EventEmitter {
|
|
|
388
388
|
id: message.id,
|
|
389
389
|
result: {
|
|
390
390
|
protocolVersion: '2024-11-05',
|
|
391
|
-
serverInfo: { name: '
|
|
391
|
+
serverInfo: { name: 'moflo', version: '3.0.0' },
|
|
392
392
|
capabilities: {
|
|
393
393
|
tools: { listChanged: true },
|
|
394
394
|
resources: { subscribe: true, listChanged: true },
|
|
@@ -480,7 +480,7 @@ export class MCPServerManager extends EventEmitter {
|
|
|
480
480
|
error: (msg, data) => this.emit('log', { level: 'error', msg, data }),
|
|
481
481
|
};
|
|
482
482
|
const mcpServer = createMCPServer({
|
|
483
|
-
name: '
|
|
483
|
+
name: 'MoFlo MCP Server V3',
|
|
484
484
|
version: '3.0.0',
|
|
485
485
|
transport: this.options.transport,
|
|
486
486
|
host: this.options.host,
|
|
@@ -114,10 +114,11 @@ export class PluginManager {
|
|
|
114
114
|
if (fs.existsSync(packageJsonPath)) {
|
|
115
115
|
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
116
116
|
installedVersion = pkg.version;
|
|
117
|
-
// Check for claude-flow plugin metadata
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
// Check for moflo/claude-flow plugin metadata (backward compat)
|
|
118
|
+
const pluginMeta = pkg['moflo'] || pkg['claude-flow'];
|
|
119
|
+
if (pluginMeta) {
|
|
120
|
+
commands = pluginMeta.commands || [];
|
|
121
|
+
hooks = pluginMeta.hooks || [];
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
// Create plugin entry
|
|
@@ -177,8 +178,8 @@ export class PluginManager {
|
|
|
177
178
|
enabled: true,
|
|
178
179
|
source: 'local',
|
|
179
180
|
path: absolutePath,
|
|
180
|
-
commands: pkg['claude-flow']?.commands || [],
|
|
181
|
-
hooks: pkg['claude-flow']?.hooks || [],
|
|
181
|
+
commands: (pkg['moflo'] || pkg['claude-flow'])?.commands || [],
|
|
182
|
+
hooks: (pkg['moflo'] || pkg['claude-flow'])?.hooks || [],
|
|
182
183
|
};
|
|
183
184
|
// Save to manifest
|
|
184
185
|
this.manifest.plugins[packageName] = plugin;
|
|
@@ -338,8 +339,8 @@ export class PluginManager {
|
|
|
338
339
|
if (fs.existsSync(packageJsonPath)) {
|
|
339
340
|
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
340
341
|
existing.version = pkg.version;
|
|
341
|
-
existing.commands = pkg['claude-flow']?.commands || existing.commands;
|
|
342
|
-
existing.hooks = pkg['claude-flow']?.hooks || existing.hooks;
|
|
342
|
+
existing.commands = (pkg['moflo'] || pkg['claude-flow'])?.commands || existing.commands;
|
|
343
|
+
existing.hooks = (pkg['moflo'] || pkg['claude-flow'])?.hooks || existing.hooks;
|
|
343
344
|
}
|
|
344
345
|
await this.saveManifest();
|
|
345
346
|
console.log(`[PluginManager] Upgraded ${packageName} to ${existing.version}`);
|