moflo 4.8.10 โ 4.8.12
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/browser/browser-agent.yaml +182 -0
- 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/moflo-bootstrap.md +129 -0
- 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-hook.mjs +50 -0
- package/.claude/helpers/gate.cjs +138 -236
- package/.claude/helpers/hook-handler.cjs +64 -326
- package/.claude/helpers/post-commit +16 -0
- package/.claude/helpers/pre-commit +26 -0
- package/.claude/helpers/prompt-hook.mjs +72 -0
- package/.claude/scripts/build-embeddings.mjs +549 -0
- package/.claude/scripts/generate-code-map.mjs +697 -0
- package/.claude/scripts/hooks.mjs +656 -0
- package/.claude/scripts/index-guidance.mjs +893 -0
- package/.claude/scripts/index-tests.mjs +710 -0
- package/.claude/scripts/semantic-search.mjs +473 -0
- package/.claude/scripts/session-start-launcher.mjs +226 -0
- package/.claude/settings.json +351 -290
- package/.claude/settings.local.json +4 -3
- package/.claude/skills/browser/SKILL.md +204 -0
- 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/workflow-state.json +9 -0
- 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 +29 -35
- 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 +472 -440
- package/bin/session-start-launcher.mjs +81 -31
- package/bin/setup-project.mjs +65 -65
- 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.d.ts +29 -24
- package/src/@claude-flow/cli/dist/src/init/claudemd-generator.js +73 -494
- 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 +30 -23
- package/src/@claude-flow/cli/dist/src/init/moflo-init.js +727 -670
- 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 +106 -106
|
@@ -1,345 +1,83 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const origError = console.error;
|
|
17
|
-
console.log = () => {};
|
|
18
|
-
console.error = () => {};
|
|
19
|
-
try {
|
|
20
|
-
const mod = require(modulePath);
|
|
21
|
-
return mod;
|
|
22
|
-
} finally {
|
|
23
|
-
console.log = origLog;
|
|
24
|
-
console.error = origError;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
} catch (e) {
|
|
28
|
-
// silently fail
|
|
29
|
-
}
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const router = safeRequire(path.join(helpersDir, 'router.cjs'));
|
|
34
|
-
const session = safeRequire(path.join(helpersDir, 'session.cjs'));
|
|
35
|
-
const memory = safeRequire(path.join(helpersDir, 'memory.cjs'));
|
|
36
|
-
const intelligence = safeRequire(path.join(helpersDir, 'intelligence.cjs'));
|
|
37
|
-
|
|
38
|
-
const [,, command, ...args] = process.argv;
|
|
39
|
-
|
|
40
|
-
// Read stdin โ Claude Code sends hook data as JSON via stdin
|
|
41
|
-
// Uses a timeout to prevent hanging when stdin is in an ambiguous state
|
|
42
|
-
// (not TTY, not a proper pipe) which happens with Claude Code hook invocations.
|
|
43
|
-
async function readStdin() {
|
|
44
|
-
if (process.stdin.isTTY) return '';
|
|
45
|
-
return new Promise((resolve) => {
|
|
46
|
-
let data = '';
|
|
47
|
-
const timer = setTimeout(() => {
|
|
2
|
+
'use strict';
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
|
|
6
|
+
var PROJECT_DIR = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
7
|
+
var METRICS_FILE = path.join(PROJECT_DIR, '.claude-flow', 'metrics', 'learning.json');
|
|
8
|
+
var command = process.argv[2];
|
|
9
|
+
|
|
10
|
+
// Read stdin (Claude Code sends hook data as JSON)
|
|
11
|
+
function readStdin() {
|
|
12
|
+
if (process.stdin.isTTY) return Promise.resolve('');
|
|
13
|
+
return new Promise(function(resolve) {
|
|
14
|
+
var data = '';
|
|
15
|
+
var timer = setTimeout(function() {
|
|
48
16
|
process.stdin.removeAllListeners();
|
|
49
17
|
process.stdin.pause();
|
|
50
18
|
resolve(data);
|
|
51
19
|
}, 500);
|
|
52
20
|
process.stdin.setEncoding('utf8');
|
|
53
|
-
process.stdin.on('data', (chunk)
|
|
54
|
-
process.stdin.on('end', ()
|
|
55
|
-
process.stdin.on('error', ()
|
|
21
|
+
process.stdin.on('data', function(chunk) { data += chunk; });
|
|
22
|
+
process.stdin.on('end', function() { clearTimeout(timer); resolve(data); });
|
|
23
|
+
process.stdin.on('error', function() { clearTimeout(timer); resolve(data); });
|
|
56
24
|
process.stdin.resume();
|
|
57
25
|
});
|
|
58
26
|
}
|
|
59
27
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
28
|
+
function bumpMetric(key) {
|
|
29
|
+
try {
|
|
30
|
+
var metrics = {};
|
|
31
|
+
if (fs.existsSync(METRICS_FILE)) metrics = JSON.parse(fs.readFileSync(METRICS_FILE, 'utf-8'));
|
|
32
|
+
metrics[key] = (metrics[key] || 0) + 1;
|
|
33
|
+
metrics.lastUpdated = new Date().toISOString();
|
|
34
|
+
var dir = path.dirname(METRICS_FILE);
|
|
35
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
36
|
+
fs.writeFileSync(METRICS_FILE, JSON.stringify(metrics, null, 2));
|
|
37
|
+
} catch (e) { /* non-fatal */ }
|
|
38
|
+
}
|
|
63
39
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
40
|
+
readStdin().then(function(stdinData) {
|
|
41
|
+
var hookInput = {};
|
|
42
|
+
if (stdinData && stdinData.trim()) {
|
|
43
|
+
try { hookInput = JSON.parse(stdinData); } catch (e) { /* ignore */ }
|
|
67
44
|
}
|
|
68
45
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const handlers = {
|
|
76
|
-
'route': () => {
|
|
77
|
-
if (intelligence && intelligence.getContext) {
|
|
78
|
-
try {
|
|
79
|
-
const ctx = intelligence.getContext(prompt);
|
|
80
|
-
if (ctx) console.log(ctx);
|
|
81
|
-
} catch (e) { /* non-fatal */ }
|
|
82
|
-
}
|
|
83
|
-
if (router && router.routeTask) {
|
|
84
|
-
const result = router.routeTask(prompt);
|
|
85
|
-
var output = [];
|
|
86
|
-
output.push('[INFO] Routing task: ' + (prompt.substring(0, 80) || '(no prompt)'));
|
|
87
|
-
output.push('');
|
|
88
|
-
output.push('+------------------- Primary Recommendation -------------------+');
|
|
89
|
-
output.push('| Agent: ' + result.agent.padEnd(53) + '|');
|
|
90
|
-
output.push('| Confidence: ' + (result.confidence * 100).toFixed(1) + '%' + ' '.repeat(44) + '|');
|
|
91
|
-
output.push('| Reason: ' + result.reason.substring(0, 53).padEnd(53) + '|');
|
|
92
|
-
output.push('+--------------------------------------------------------------+');
|
|
93
|
-
console.log(output.join('\n'));
|
|
94
|
-
} else {
|
|
95
|
-
console.log('[INFO] Router not available, using default routing');
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
'pre-bash': () => {
|
|
100
|
-
var cmd = (hookInput.command || prompt).toLowerCase();
|
|
101
|
-
var dangerous = ['rm -rf /', 'format c:', 'del /s /q c:\\', ':(){:|:&};:'];
|
|
102
|
-
for (var i = 0; i < dangerous.length; i++) {
|
|
103
|
-
if (cmd.includes(dangerous[i])) {
|
|
104
|
-
console.error('[BLOCKED] Dangerous command detected: ' + dangerous[i]);
|
|
105
|
-
process.exit(1);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
console.log('[OK] Command validated');
|
|
109
|
-
},
|
|
110
|
-
|
|
111
|
-
'post-edit': () => {
|
|
112
|
-
if (session && session.metric) {
|
|
113
|
-
try { session.metric('edits'); } catch (e) { /* no active session */ }
|
|
114
|
-
}
|
|
115
|
-
if (intelligence && intelligence.recordEdit) {
|
|
116
|
-
try {
|
|
117
|
-
var file = hookInput.file_path || (hookInput.toolInput && hookInput.toolInput.file_path)
|
|
118
|
-
|| process.env.TOOL_INPUT_file_path || args[0] || '';
|
|
119
|
-
intelligence.recordEdit(file);
|
|
120
|
-
} catch (e) { /* non-fatal */ }
|
|
121
|
-
}
|
|
122
|
-
console.log('[OK] Edit recorded');
|
|
123
|
-
},
|
|
124
|
-
|
|
125
|
-
'session-restore': () => {
|
|
126
|
-
if (session) {
|
|
127
|
-
var existing = session.restore && session.restore();
|
|
128
|
-
if (!existing) {
|
|
129
|
-
session.start && session.start();
|
|
130
|
-
}
|
|
131
|
-
} else {
|
|
132
|
-
console.log('No session to restore');
|
|
133
|
-
console.log('Session started: session-' + Date.now());
|
|
134
|
-
}
|
|
135
|
-
if (intelligence && intelligence.init) {
|
|
136
|
-
try {
|
|
137
|
-
var result = intelligence.init();
|
|
138
|
-
if (result && result.nodes > 0) {
|
|
139
|
-
console.log('[INTELLIGENCE] Loaded ' + result.nodes + ' patterns, ' + result.edges + ' edges');
|
|
140
|
-
}
|
|
141
|
-
} catch (e) { /* non-fatal */ }
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Auto-index guidance, code map, and patterns on session start
|
|
145
|
-
try {
|
|
146
|
-
var projectDir = path.resolve(path.dirname(helpersDir), '..');
|
|
147
|
-
var cp = require('child_process');
|
|
148
|
-
var pidFile = path.join(projectDir, '.claude-flow', 'background-pids.json');
|
|
149
|
-
|
|
150
|
-
// Kill stale background processes from previous sessions
|
|
151
|
-
try {
|
|
152
|
-
if (fs.existsSync(pidFile)) {
|
|
153
|
-
var stalePids = JSON.parse(fs.readFileSync(pidFile, 'utf-8'));
|
|
154
|
-
for (var i = 0; i < stalePids.length; i++) {
|
|
155
|
-
try { process.kill(stalePids[i].pid, 0); /* test if alive */ } catch (e) { continue; }
|
|
156
|
-
try { process.kill(stalePids[i].pid, 'SIGTERM'); } catch (e) { /* already gone */ }
|
|
157
|
-
}
|
|
158
|
-
fs.unlinkSync(pidFile);
|
|
159
|
-
}
|
|
160
|
-
} catch (e) { /* non-fatal: best-effort cleanup */ }
|
|
161
|
-
|
|
162
|
-
// Read moflo.yaml auto_index flags (default: both true)
|
|
163
|
-
var autoGuidance = true;
|
|
164
|
-
var autoCodeMap = true;
|
|
165
|
-
var mofloConfigPath = path.join(projectDir, 'moflo.yaml');
|
|
166
|
-
var mofloJsonPath = path.join(projectDir, 'moflo.config.json');
|
|
167
|
-
|
|
168
|
-
if (fs.existsSync(mofloConfigPath)) {
|
|
169
|
-
try {
|
|
170
|
-
var content = fs.readFileSync(mofloConfigPath, 'utf-8');
|
|
171
|
-
if (/auto_index:\s*\n\s+guidance:\s*false/i.test(content)) autoGuidance = false;
|
|
172
|
-
if (/auto_index:\s*\n(?:\s+guidance:\s*\w+\n)?\s+code_map:\s*false/i.test(content)) autoCodeMap = false;
|
|
173
|
-
} catch (e) { /* ignore */ }
|
|
174
|
-
} else if (fs.existsSync(mofloJsonPath)) {
|
|
175
|
-
try {
|
|
176
|
-
var config = JSON.parse(fs.readFileSync(mofloJsonPath, 'utf-8'));
|
|
177
|
-
var ai = config.auto_index || config.autoIndex || {};
|
|
178
|
-
if (ai.guidance === false) autoGuidance = false;
|
|
179
|
-
if (ai.code_map === false || ai.codeMap === false) autoCodeMap = false;
|
|
180
|
-
} catch (e) { /* ignore */ }
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Helper: find a moflo bin script by filename
|
|
184
|
-
function findMofloScript(scriptName) {
|
|
185
|
-
var candidates = [
|
|
186
|
-
path.join(projectDir, 'bin', scriptName),
|
|
187
|
-
path.join(projectDir, 'node_modules', 'moflo', 'bin', scriptName),
|
|
188
|
-
];
|
|
189
|
-
for (var i = 0; i < candidates.length; i++) {
|
|
190
|
-
if (fs.existsSync(candidates[i])) return candidates[i];
|
|
191
|
-
}
|
|
192
|
-
try {
|
|
193
|
-
var resolved = require.resolve('moflo/bin/' + scriptName, { paths: [projectDir] });
|
|
194
|
-
if (fs.existsSync(resolved)) return resolved;
|
|
195
|
-
} catch (e) { /* not installed */ }
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Track PIDs of background processes so next session can clean them up
|
|
200
|
-
var trackedPids = [];
|
|
201
|
-
|
|
202
|
-
function spawnBackground(script, label, extraArgs) {
|
|
203
|
-
var args = [script].concat(extraArgs || []);
|
|
204
|
-
var child = cp.spawn('node', args, {
|
|
205
|
-
stdio: 'ignore',
|
|
206
|
-
cwd: projectDir,
|
|
207
|
-
detached: true,
|
|
208
|
-
windowsHide: true
|
|
209
|
-
});
|
|
210
|
-
if (child.pid) {
|
|
211
|
-
trackedPids.push({ pid: child.pid, script: label, startedAt: new Date().toISOString() });
|
|
212
|
-
}
|
|
213
|
-
child.unref();
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// 1. Index guidance docs (with embeddings for semantic search)
|
|
217
|
-
if (autoGuidance) {
|
|
218
|
-
var guidanceScript = findMofloScript('index-guidance.mjs');
|
|
219
|
-
if (guidanceScript) spawnBackground(guidanceScript, 'index-guidance');
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// 2. Generate code map (structural index of source files)
|
|
223
|
-
if (autoCodeMap) {
|
|
224
|
-
var codeMapScript = findMofloScript('generate-code-map.mjs');
|
|
225
|
-
if (codeMapScript) spawnBackground(codeMapScript, 'generate-code-map');
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// 3. Start learning service (pattern research on codebase)
|
|
229
|
-
var learnScript = findMofloScript('../.claude/helpers/learning-service.mjs');
|
|
230
|
-
if (!learnScript) learnScript = findMofloScript('learning-service.mjs');
|
|
231
|
-
// Also check the .claude/helpers location directly
|
|
232
|
-
if (!learnScript) {
|
|
233
|
-
var localLearn = path.join(projectDir, '.claude', 'helpers', 'learning-service.mjs');
|
|
234
|
-
if (fs.existsSync(localLearn)) learnScript = localLearn;
|
|
235
|
-
}
|
|
236
|
-
// Check inside node_modules/moflo/.claude/helpers
|
|
237
|
-
if (!learnScript) {
|
|
238
|
-
var nmLearn = path.join(projectDir, 'node_modules', 'moflo', '.claude', 'helpers', 'learning-service.mjs');
|
|
239
|
-
if (fs.existsSync(nmLearn)) learnScript = nmLearn;
|
|
240
|
-
}
|
|
241
|
-
if (learnScript) spawnBackground(learnScript, 'learning-service');
|
|
242
|
-
|
|
243
|
-
// Persist tracked PIDs for cleanup on next session start
|
|
244
|
-
if (trackedPids.length > 0) {
|
|
245
|
-
try {
|
|
246
|
-
var pidDir = path.dirname(pidFile);
|
|
247
|
-
if (!fs.existsSync(pidDir)) fs.mkdirSync(pidDir, { recursive: true });
|
|
248
|
-
fs.writeFileSync(pidFile, JSON.stringify(trackedPids));
|
|
249
|
-
} catch (e) { /* non-fatal */ }
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
} catch (e) { /* non-fatal: session-start indexing is best-effort */ }
|
|
253
|
-
},
|
|
254
|
-
|
|
255
|
-
'session-end': () => {
|
|
256
|
-
if (intelligence && intelligence.consolidate) {
|
|
257
|
-
try {
|
|
258
|
-
var result = intelligence.consolidate();
|
|
259
|
-
if (result && result.entries > 0) {
|
|
260
|
-
var msg = '[INTELLIGENCE] Consolidated: ' + result.entries + ' entries, ' + result.edges + ' edges';
|
|
261
|
-
if (result.newEntries > 0) msg += ', ' + result.newEntries + ' new';
|
|
262
|
-
msg += ', PageRank recomputed';
|
|
263
|
-
console.log(msg);
|
|
264
|
-
}
|
|
265
|
-
} catch (e) { /* non-fatal */ }
|
|
266
|
-
}
|
|
267
|
-
if (session && session.end) {
|
|
268
|
-
session.end();
|
|
269
|
-
} else {
|
|
270
|
-
console.log('[OK] Session ended');
|
|
46
|
+
switch (command) {
|
|
47
|
+
case 'route': {
|
|
48
|
+
var prompt = hookInput.prompt || hookInput.command || process.env.PROMPT || '';
|
|
49
|
+
if (prompt) console.log('[INFO] Routing: ' + prompt.substring(0, 80));
|
|
50
|
+
else console.log('[INFO] Ready');
|
|
51
|
+
break;
|
|
271
52
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
var result = router.routeTask(prompt);
|
|
280
|
-
console.log('[INFO] Task routed to: ' + result.agent + ' (confidence: ' + result.confidence + ')');
|
|
281
|
-
} else {
|
|
53
|
+
case 'pre-edit':
|
|
54
|
+
case 'post-edit':
|
|
55
|
+
bumpMetric('edits');
|
|
56
|
+
console.log('[OK] Edit recorded');
|
|
57
|
+
break;
|
|
58
|
+
case 'pre-task':
|
|
59
|
+
bumpMetric('tasks');
|
|
282
60
|
console.log('[OK] Task started');
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
61
|
+
break;
|
|
62
|
+
case 'post-task':
|
|
63
|
+
bumpMetric('tasksCompleted');
|
|
64
|
+
console.log('[OK] Task completed');
|
|
65
|
+
break;
|
|
66
|
+
case 'session-end': {
|
|
67
|
+
// Kill tracked background processes via shared sync helper
|
|
288
68
|
try {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
'compact-manual': () => {
|
|
296
|
-
console.log('PreCompact Guidance:');
|
|
297
|
-
console.log('IMPORTANT: Review CLAUDE.md in project root for:');
|
|
298
|
-
console.log(' - Available agents and concurrent usage patterns');
|
|
299
|
-
console.log(' - Swarm coordination strategies (hierarchical, mesh, adaptive)');
|
|
300
|
-
console.log(' - Critical concurrent execution rules (1 MESSAGE = ALL OPERATIONS)');
|
|
301
|
-
console.log('Ready for compact operation');
|
|
302
|
-
},
|
|
303
|
-
|
|
304
|
-
'compact-auto': () => {
|
|
305
|
-
console.log('Auto-Compact Guidance (Context Window Full):');
|
|
306
|
-
console.log('CRITICAL: Before compacting, ensure you understand:');
|
|
307
|
-
console.log(' - All agents available in .claude/agents/ directory');
|
|
308
|
-
console.log(' - Concurrent execution patterns from CLAUDE.md');
|
|
309
|
-
console.log(' - Swarm coordination strategies for complex tasks');
|
|
310
|
-
console.log('Apply GOLDEN RULE: Always batch operations in single messages');
|
|
311
|
-
console.log('Auto-compact proceeding with full agent context');
|
|
312
|
-
},
|
|
313
|
-
|
|
314
|
-
'status': () => {
|
|
315
|
-
console.log('[OK] Status check');
|
|
316
|
-
},
|
|
317
|
-
|
|
318
|
-
'stats': () => {
|
|
319
|
-
if (intelligence && intelligence.stats) {
|
|
320
|
-
intelligence.stats(args.includes('--json'));
|
|
321
|
-
} else {
|
|
322
|
-
console.log('[WARN] Intelligence module not available. Run session-restore first.');
|
|
323
|
-
}
|
|
324
|
-
},
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
if (command && handlers[command]) {
|
|
328
|
-
try {
|
|
329
|
-
handlers[command]();
|
|
330
|
-
} catch (e) {
|
|
331
|
-
console.log('[WARN] Hook ' + command + ' encountered an error: ' + e.message);
|
|
69
|
+
var cleanup = require('./lib/registry-cleanup.cjs');
|
|
70
|
+
var killed = cleanup.killTrackedSync(PROJECT_DIR);
|
|
71
|
+
if (killed > 0) console.log('[CLEANUP] Killed ' + killed + ' background process(es)');
|
|
72
|
+
} catch (e) { /* non-fatal: cleanup module not available */ }
|
|
73
|
+
console.log('[OK] Session ended');
|
|
74
|
+
break;
|
|
332
75
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
76
|
+
case 'notification':
|
|
77
|
+
// Silent โ just acknowledge
|
|
78
|
+
break;
|
|
79
|
+
default:
|
|
80
|
+
if (command) console.log('[OK] Hook: ' + command);
|
|
81
|
+
break;
|
|
337
82
|
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
main().catch(function(e) {
|
|
341
|
-
console.log('[WARN] Hook handler error: ' + e.message);
|
|
342
|
-
}).finally(function() {
|
|
343
|
-
// Ensure clean exit for Claude Code hooks
|
|
344
|
-
process.exit(0);
|
|
345
83
|
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Claude Flow Post-Commit Hook
|
|
3
|
+
# Records commit metrics and trains patterns
|
|
4
|
+
|
|
5
|
+
COMMIT_HASH=$(git rev-parse HEAD)
|
|
6
|
+
COMMIT_MSG=$(git log -1 --pretty=%B)
|
|
7
|
+
|
|
8
|
+
echo "๐ Recording commit metrics..."
|
|
9
|
+
|
|
10
|
+
# Notify claude-flow of commit
|
|
11
|
+
npx moflo hooks notify \
|
|
12
|
+
--message "Commit: $COMMIT_MSG" \
|
|
13
|
+
--level info \
|
|
14
|
+
--metadata '{"hash": "'$COMMIT_HASH'"}' 2>/dev/null || true
|
|
15
|
+
|
|
16
|
+
echo "โ
Commit recorded"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Claude Flow Pre-Commit Hook
|
|
3
|
+
# Validates code quality before commit
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
echo "๐ Running Claude Flow pre-commit checks..."
|
|
8
|
+
|
|
9
|
+
# Get staged files
|
|
10
|
+
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
|
|
11
|
+
|
|
12
|
+
# Run validation for each staged file
|
|
13
|
+
for FILE in $STAGED_FILES; do
|
|
14
|
+
if [[ "$FILE" =~ \.(ts|js|tsx|jsx)$ ]]; then
|
|
15
|
+
echo " Validating: $FILE"
|
|
16
|
+
npx moflo hooks pre-edit --file "$FILE" --validate-syntax 2>/dev/null || true
|
|
17
|
+
fi
|
|
18
|
+
done
|
|
19
|
+
|
|
20
|
+
# Run tests if available
|
|
21
|
+
if [ -f "package.json" ] && grep -q '"test"' package.json; then
|
|
22
|
+
echo "๐งช Running tests..."
|
|
23
|
+
npm test --if-present 2>/dev/null || echo " Tests skipped or failed"
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
echo "โ
Pre-commit checks complete"
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import { resolve } from 'path';
|
|
4
|
+
|
|
5
|
+
// Read stdin JSON from Claude Code
|
|
6
|
+
var stdinData = '';
|
|
7
|
+
try {
|
|
8
|
+
stdinData = await new Promise(function(res) {
|
|
9
|
+
var data = '';
|
|
10
|
+
var timeout = setTimeout(function() { res(data); }, 500);
|
|
11
|
+
process.stdin.setEncoding('utf-8');
|
|
12
|
+
process.stdin.on('data', function(chunk) { data += chunk; });
|
|
13
|
+
process.stdin.on('end', function() { clearTimeout(timeout); res(data); });
|
|
14
|
+
process.stdin.on('error', function() { clearTimeout(timeout); res(''); });
|
|
15
|
+
if (process.stdin.isTTY) { clearTimeout(timeout); res(''); }
|
|
16
|
+
});
|
|
17
|
+
} catch (e) { /* no stdin */ }
|
|
18
|
+
|
|
19
|
+
var hookContext = {};
|
|
20
|
+
try { if (stdinData.trim()) hookContext = JSON.parse(stdinData); } catch (e) {}
|
|
21
|
+
|
|
22
|
+
var userPrompt = hookContext.user_prompt || hookContext.prompt || '';
|
|
23
|
+
var env = Object.assign({}, process.env, { CLAUDE_USER_PROMPT: userPrompt });
|
|
24
|
+
|
|
25
|
+
// Run prompt-reminder via gate.cjs
|
|
26
|
+
var projectDir = (env.CLAUDE_PROJECT_DIR || process.cwd()).replace(/^\/([a-z])\//i, '$1:/');
|
|
27
|
+
var gateScript = resolve(projectDir, '.claude/helpers/gate.cjs');
|
|
28
|
+
var output = '';
|
|
29
|
+
try {
|
|
30
|
+
output = execSync('node "' + gateScript + '" prompt-reminder', {
|
|
31
|
+
env: env, encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe']
|
|
32
|
+
});
|
|
33
|
+
} catch (err) { output = (err && err.stdout) || ''; }
|
|
34
|
+
|
|
35
|
+
// Classify prompt for namespace hint
|
|
36
|
+
var lower = userPrompt.toLowerCase();
|
|
37
|
+
|
|
38
|
+
var KNOWLEDGE_ONLY = /\b(knowledge|remember|recall)\b|we (decid|agree|chose|said)/;
|
|
39
|
+
var EXPLICIT_NS = [
|
|
40
|
+
{ pattern: /\b(pattern|convention|best practice|style|coding rule)\b/, ns: 'patterns', label: 'code patterns and conventions' },
|
|
41
|
+
{ pattern: /\b(code.?map|file structure|project structure|directory)\b/, ns: 'code-map', label: 'codebase navigation' },
|
|
42
|
+
];
|
|
43
|
+
var PATTERN_HINTS = [/\b(template|example|similar to|how do we|how should)\b/];
|
|
44
|
+
var DOMAIN_HINTS = [
|
|
45
|
+
/\b(guidance|guide|docs|documentation|rules|how-to)\b/,
|
|
46
|
+
/\b(architecture|design|domain|tenant|migrat|schema|deploy)/,
|
|
47
|
+
/\b(rule|requirement|constraint|compliance)\b/,
|
|
48
|
+
];
|
|
49
|
+
var NAV_PATTERNS = [
|
|
50
|
+
/\b(find|where|which file|look up|locate|endpoint|route|url|path)\b/,
|
|
51
|
+
/\b(class|function|method|component|service|entity|module)\b/,
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
var nsHint = '';
|
|
55
|
+
if (KNOWLEDGE_ONLY.test(lower)) {
|
|
56
|
+
nsHint = 'Memory namespace hint: use "knowledge" for user-directed project decisions.';
|
|
57
|
+
} else {
|
|
58
|
+
var found = EXPLICIT_NS.find(function(e) { return e.pattern.test(lower); });
|
|
59
|
+
if (found) {
|
|
60
|
+
nsHint = 'Memory namespace hint: use "' + found.ns + '" for ' + found.label + '.';
|
|
61
|
+
} else if (DOMAIN_HINTS.some(function(p) { return p.test(lower); })) {
|
|
62
|
+
nsHint = 'Memory namespace hint: search "guidance" and "knowledge" for domain rules and project decisions.';
|
|
63
|
+
} else if (PATTERN_HINTS.some(function(p) { return p.test(lower); })) {
|
|
64
|
+
nsHint = 'Memory namespace hint: use "patterns" for code patterns and conventions.';
|
|
65
|
+
} else if (NAV_PATTERNS.some(function(p) { return p.test(lower); })) {
|
|
66
|
+
nsHint = 'Memory namespace hint: use "code-map" for codebase navigation.';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var parts = [output.trim(), nsHint].filter(Boolean);
|
|
71
|
+
if (parts.length) process.stdout.write(parts.join('\n') + '\n');
|
|
72
|
+
process.exit(0);
|