monomind 1.18.15 → 1.19.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/agents/core/researcher.md +29 -24
- package/.claude/agents/github/code-review-swarm.md +1 -1
- package/.claude/agents/github/github-modes.md +1 -1
- package/.claude/agents/github/issue-tracker.md +1 -1
- package/.claude/agents/github/multi-repo-swarm.md +1 -1
- package/.claude/agents/github/pr-manager.md +1 -1
- package/.claude/agents/github/project-board-sync.md +1 -1
- package/.claude/agents/github/release-manager.md +1 -1
- package/.claude/agents/github/repo-architect.md +1 -1
- package/.claude/agents/github/swarm-issue.md +1 -1
- package/.claude/agents/github/swarm-pr.md +1 -1
- package/.claude/agents/github/sync-coordinator.md +1 -1
- package/.claude/agents/github/workflow-automation.md +1 -1
- package/.claude/agents/goal/goal-planner.md +1 -1
- package/.claude/agents/specialized/specialized-workflow-architect.md +11 -14
- package/.claude/agents/testing/production-validator.md +8 -7
- package/.claude/agents/testing/testing-evidence-collector.md +3 -1
- package/.claude/commands/mastermind/code-review.md +4 -4
- package/.claude/commands/mastermind/help.md +2 -2
- package/.claude/commands/mastermind/okf-export.md +14 -0
- package/.claude/commands/mastermind/okf-import.md +15 -0
- package/.claude/helpers/handlers/agent-start-handler.cjs +11 -36
- package/.claude/helpers/handlers/capture-handler.cjs +110 -0
- package/.claude/helpers/handlers/route-handler.cjs +174 -247
- package/.claude/helpers/handlers/session-handler.cjs +139 -142
- package/.claude/helpers/handlers/session-restore-handler.cjs +15 -10
- package/.claude/helpers/handlers/task-handler.cjs +8 -155
- package/.claude/helpers/hook-handler.cjs +89 -5
- package/.claude/helpers/intelligence.cjs +164 -15
- package/.claude/helpers/learning-service.mjs +1 -0
- package/.claude/helpers/mastermind-activate.cjs +33 -51
- package/.claude/helpers/monolean-activate.cjs +13 -3
- package/.claude/helpers/monolean-propagate.cjs +7 -3
- package/.claude/helpers/router.cjs +47 -9
- package/.claude/settings.json +0 -20
- package/.claude/skills/mastermind-skills/architect.md +5 -6
- package/.claude/skills/mastermind-skills/autodev.md +8 -5
- package/.claude/skills/mastermind-skills/review.md +8 -5
- package/.claude/skills/mastermind-skills/techport.md +37 -3
- package/.claude/skills/monodesign/document.md +9 -6
- package/.claude/skills/monodesign/extract.md +1 -1
- package/.claude/skills/monodesign/reference/document.md +1 -1
- package/.claude/skills/monodesign/reference/live.md +1 -1
- package/.claude/skills/monolean/SKILL.md +1 -1
- package/package.json +1 -1
- package/packages/@monomind/cli/.claude/agents/core/researcher.md +29 -24
- package/packages/@monomind/cli/.claude/agents/github/code-review-swarm.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/github-modes.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/issue-tracker.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/multi-repo-swarm.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/pr-manager.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/project-board-sync.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/release-manager.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/repo-architect.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/swarm-issue.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/swarm-pr.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/sync-coordinator.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/workflow-automation.md +1 -1
- package/packages/@monomind/cli/.claude/agents/goal/goal-planner.md +1 -1
- package/packages/@monomind/cli/.claude/agents/specialized/specialized-workflow-architect.md +11 -14
- package/packages/@monomind/cli/.claude/agents/testing/production-validator.md +8 -7
- package/packages/@monomind/cli/.claude/agents/testing/testing-evidence-collector.md +3 -1
- package/packages/@monomind/cli/.claude/commands/mastermind/code-review.md +4 -4
- package/packages/@monomind/cli/.claude/commands/mastermind/help.md +2 -2
- package/packages/@monomind/cli/.claude/commands/mastermind/okf-export.md +14 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/okf-import.md +15 -0
- package/packages/@monomind/cli/.claude/helpers/handlers/agent-start-handler.cjs +11 -36
- package/packages/@monomind/cli/.claude/helpers/handlers/capture-handler.cjs +110 -0
- package/packages/@monomind/cli/.claude/helpers/handlers/route-handler.cjs +174 -247
- package/packages/@monomind/cli/.claude/helpers/handlers/session-handler.cjs +139 -142
- package/packages/@monomind/cli/.claude/helpers/handlers/session-restore-handler.cjs +15 -10
- package/packages/@monomind/cli/.claude/helpers/handlers/task-handler.cjs +8 -155
- package/packages/@monomind/cli/.claude/helpers/hook-handler.cjs +89 -5
- package/packages/@monomind/cli/.claude/helpers/intelligence.cjs +164 -15
- package/packages/@monomind/cli/.claude/helpers/learning-service.mjs +1 -0
- package/packages/@monomind/cli/.claude/helpers/mastermind-activate.cjs +33 -51
- package/packages/@monomind/cli/.claude/helpers/monolean-activate.cjs +13 -3
- package/packages/@monomind/cli/.claude/helpers/monolean-propagate.cjs +7 -3
- package/packages/@monomind/cli/.claude/helpers/router.cjs +47 -9
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/architect.md +5 -6
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/autodev.md +8 -5
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/review.md +8 -5
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/techport.md +37 -3
- package/packages/@monomind/cli/.claude/skills/monodesign/document.md +9 -6
- package/packages/@monomind/cli/.claude/skills/monodesign/extract.md +1 -1
- package/packages/@monomind/cli/.claude/skills/monodesign/reference/document.md +1 -1
- package/packages/@monomind/cli/.claude/skills/monodesign/reference/live.md +1 -1
- package/packages/@monomind/cli/.claude/skills/monolean/SKILL.md +1 -1
- package/packages/@monomind/cli/bin/mcp-server.js +11 -1
- package/packages/@monomind/cli/dist/src/commands/agent-ops.d.ts +1 -2
- package/packages/@monomind/cli/dist/src/commands/agent-ops.js +1 -59
- package/packages/@monomind/cli/dist/src/commands/agent.js +2 -3
- package/packages/@monomind/cli/dist/src/commands/analyze-diff.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/browse-action.js +94 -2
- package/packages/@monomind/cli/dist/src/commands/completions.js +11 -56
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.js +2 -2
- package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.d.ts +1 -3
- package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.js +2 -116
- package/packages/@monomind/cli/dist/src/commands/hive-mind.js +2 -5
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +8 -7
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.js +2 -2
- package/packages/@monomind/cli/dist/src/commands/hooks-extended-commands.d.ts +0 -3
- package/packages/@monomind/cli/dist/src/commands/hooks-extended-commands.js +0 -307
- package/packages/@monomind/cli/dist/src/commands/hooks.js +1 -12
- package/packages/@monomind/cli/dist/src/commands/index.d.ts +3 -51
- package/packages/@monomind/cli/dist/src/commands/index.js +36 -184
- package/packages/@monomind/cli/dist/src/commands/init-wizard.js +2 -4
- package/packages/@monomind/cli/dist/src/commands/mcp.js +32 -4
- package/packages/@monomind/cli/dist/src/commands/memory-admin.d.ts +1 -2
- package/packages/@monomind/cli/dist/src/commands/memory-admin.js +1 -118
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.d.ts +1 -2
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.js +5 -171
- package/packages/@monomind/cli/dist/src/commands/memory.js +3 -6
- package/packages/@monomind/cli/dist/src/commands/neural-core.d.ts +3 -1
- package/packages/@monomind/cli/dist/src/commands/neural-core.js +145 -6
- package/packages/@monomind/cli/dist/src/commands/neural-optimize.js +4 -4
- package/packages/@monomind/cli/dist/src/commands/neural-registry.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/commands/neural-registry.js +4 -4
- package/packages/@monomind/cli/dist/src/commands/neural.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/commands/neural.js +6 -6
- package/packages/@monomind/cli/dist/src/commands/performance.js +68 -58
- package/packages/@monomind/cli/dist/src/commands/providers.js +2 -131
- package/packages/@monomind/cli/dist/src/commands/security-misc.d.ts +0 -1
- package/packages/@monomind/cli/dist/src/commands/security-misc.js +69 -45
- package/packages/@monomind/cli/dist/src/commands/security.js +2 -4
- package/packages/@monomind/cli/dist/src/commands/session.js +1 -285
- package/packages/@monomind/cli/dist/src/commands/start.js +2 -41
- package/packages/@monomind/cli/dist/src/commands/status.js +18 -29
- package/packages/@monomind/cli/dist/src/commands/swarm.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/task.js +2 -49
- package/packages/@monomind/cli/dist/src/commands/workflow.js +2 -104
- package/packages/@monomind/cli/dist/src/index.js +7 -0
- package/packages/@monomind/cli/dist/src/init/executor.js +3 -14
- package/packages/@monomind/cli/dist/src/init/helpers-generator.js +2 -22
- package/packages/@monomind/cli/dist/src/init/settings-generator.js +0 -1
- package/packages/@monomind/cli/dist/src/init/types.d.ts +1 -3
- package/packages/@monomind/cli/dist/src/init/types.js +0 -2
- package/packages/@monomind/cli/dist/src/mcp-client.js +0 -6
- package/packages/@monomind/cli/dist/src/mcp-server.js +16 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/agent-tools.js +0 -17
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/causal-infer.d.ts +5 -5
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/causal-infer.js +32 -46
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/consensus-verify.d.ts +2 -3
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/consensus-verify.js +22 -20
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/memory-gate.d.ts +3 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/memory-gate.js +32 -19
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/quantum-topology.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/quantum-topology.js +11 -17
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/spectral-analyze.d.ts +2 -3
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/spectral-analyze.js +51 -32
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/types.d.ts +5 -9
- package/packages/@monomind/cli/dist/src/mcp-tools/guidance-tools.js +2 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +25 -3
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.d.ts +0 -3
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.js +45 -159
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +1 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/index.d.ts +0 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/index.js +0 -3
- package/packages/@monomind/cli/dist/src/mcp-tools/memory-tools.js +24 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +428 -11
- package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.d.ts +4 -10
- package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +28 -54
- package/packages/@monomind/cli/dist/src/mcp-tools/performance-tools.js +5 -17
- package/packages/@monomind/cli/dist/src/mcp-tools/quality/coverage-analysis/prioritize-gaps.js +2 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/quality/security-compliance/detect-secrets.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/quality-tools.d.ts +7 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/quality-tools.js +7 -257
- package/packages/@monomind/cli/dist/src/memory/intelligence.d.ts +7 -8
- package/packages/@monomind/cli/dist/src/memory/intelligence.js +15 -16
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +1 -0
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +37 -0
- package/packages/@monomind/cli/dist/src/services/worker-daemon.d.ts +3 -21
- package/packages/@monomind/cli/dist/src/services/worker-daemon.js +13 -80
- package/packages/@monomind/cli/dist/src/suggest.js +0 -5
- package/packages/@monomind/cli/package.json +1 -1
- package/packages/@monomind/guidance/package.json +1 -74
- package/.claude/helpers/auto-memory-hook.mjs +0 -503
- package/packages/@monomind/cli/.claude/helpers/auto-memory-hook.mjs +0 -503
- package/packages/@monomind/cli/dist/src/commands/deployment.d.ts +0 -10
- package/packages/@monomind/cli/dist/src/commands/deployment.js +0 -706
|
@@ -22,29 +22,18 @@ module.exports = {
|
|
|
22
22
|
console.log('[SESSION] Skipping consolidation — daemon holds lock');
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (consResult.newEntries > 0) msg += ', ' + consResult.newEntries + ' new';
|
|
31
|
-
msg += ', PageRank recomputed';
|
|
32
|
-
console.log(msg);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
try {
|
|
36
|
-
if (session && session.end) {
|
|
37
|
-
session.end();
|
|
38
|
-
} else {
|
|
39
|
-
console.log('[OK] Session ended');
|
|
40
|
-
}
|
|
41
|
-
} catch (e) { console.log('[WARN] Session end failed: ' + e.message); }
|
|
25
|
+
// ── Session-end feedback BEFORE consolidation ──────────────────────────
|
|
26
|
+
// IMPORTANT: feedback() must run BEFORE consolidate() so that the session-end
|
|
27
|
+
// outcome record captures recentEdits from disk. consolidate() clears
|
|
28
|
+
// recent-edits.jsonl, so calling it first leaves the outcome empty.
|
|
29
|
+
// (Fixed: all outcomes previously had recentEdits: [].)
|
|
42
30
|
|
|
43
31
|
// ── Routing Feedback Loop (SE-001) ────────────────────────────────────
|
|
44
32
|
// Persist routing accuracy feedback so the router improves over sessions.
|
|
45
33
|
// sessionSuccess is derived from intelligence-outcomes.jsonl entries written
|
|
46
34
|
// during this session (last 30 minutes). A session is marked failed when the
|
|
47
35
|
// majority of feedback() calls carried success=false in that window.
|
|
36
|
+
var sessionSuccess = true; // optimistic default when no signal exists
|
|
48
37
|
try {
|
|
49
38
|
var feedbackPath = path.join(CWD, '.monomind', 'routing-feedback.jsonl');
|
|
50
39
|
var lastRoutePath = path.join(CWD, '.monomind', 'last-route.json');
|
|
@@ -52,26 +41,38 @@ module.exports = {
|
|
|
52
41
|
if (fs.existsSync(lastRoutePath) && (function() { try { return fs.statSync(lastRoutePath).size <= MAX_ROUTE; } catch(_) { return false; } }())) {
|
|
53
42
|
var lastRoute = JSON.parse(fs.readFileSync(lastRoutePath, 'utf-8'));
|
|
54
43
|
|
|
55
|
-
// Derive sessionSuccess from
|
|
56
|
-
var sessionSuccess = true; // optimistic default when no signal exists
|
|
44
|
+
// Derive sessionSuccess from git commits (strongest signal: user committed = success)
|
|
57
45
|
try {
|
|
58
|
-
var
|
|
59
|
-
var
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
var
|
|
69
|
-
|
|
70
|
-
|
|
46
|
+
var execSync = require('child_process').execSync;
|
|
47
|
+
var recentCommits = execSync('git log --oneline --since="30 minutes ago" 2>/dev/null || true', { cwd: CWD, timeout: 3000, encoding: 'utf-8' }).trim();
|
|
48
|
+
if (recentCommits.length > 0) {
|
|
49
|
+
sessionSuccess = true;
|
|
50
|
+
} else {
|
|
51
|
+
// No commits — check if files were modified (work in progress, not failure)
|
|
52
|
+
var gitStatus = execSync('git diff --name-only 2>/dev/null || true', { cwd: CWD, timeout: 3000, encoding: 'utf-8' }).trim();
|
|
53
|
+
// Modified files = probably still working; no changes at all = exploration or failure
|
|
54
|
+
if (gitStatus.length === 0) {
|
|
55
|
+
// Fall back to intelligence-outcomes as a weak signal
|
|
56
|
+
var outcomesPath = path.join(CWD, '.monomind', 'data', 'intelligence-outcomes.jsonl');
|
|
57
|
+
var MAX_OUTCOMES = 512 * 1024;
|
|
58
|
+
if (fs.existsSync(outcomesPath) && (function() { try { return fs.statSync(outcomesPath).size <= MAX_OUTCOMES; } catch(_) { return false; } }())) {
|
|
59
|
+
var windowMs = 30 * 60 * 1000;
|
|
60
|
+
var cutoff = Date.now() - windowMs;
|
|
61
|
+
var outcomeLines = fs.readFileSync(outcomesPath, 'utf-8').trim().split('\n').filter(Boolean);
|
|
62
|
+
var recent = outcomeLines.map(function(l) {
|
|
63
|
+
try { return JSON.parse(l); } catch { return null; }
|
|
64
|
+
}).filter(function(e) { return e && e.ts && e.ts >= cutoff; });
|
|
65
|
+
if (recent.length > 0) {
|
|
66
|
+
var failures = recent.filter(function(e) { return e.success === false; }).length;
|
|
67
|
+
sessionSuccess = failures / recent.length < 0.5;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
71
70
|
}
|
|
71
|
+
// else: modified files exist, keep optimistic default (true)
|
|
72
72
|
}
|
|
73
73
|
} catch (e) { /* non-critical — keep optimistic default */ }
|
|
74
74
|
|
|
75
|
+
// Record session-end feedback WITH recentEdits (before consolidate clears them)
|
|
75
76
|
if (intelligence && intelligence.feedback) {
|
|
76
77
|
try { intelligence.feedback(sessionSuccess); } catch (e) { /* non-fatal */ }
|
|
77
78
|
}
|
|
@@ -99,32 +100,24 @@ module.exports = {
|
|
|
99
100
|
}
|
|
100
101
|
} catch (e) { /* non-fatal */ }
|
|
101
102
|
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
var ls = await hCtx.getLearningService();
|
|
112
|
-
if (ls && ls.consolidate) {
|
|
113
|
-
var lResult = await hCtx.runWithTimeout(function() { return ls.consolidate(); }, 'learning.consolidate()');
|
|
114
|
-
if (lResult && lResult.promoted > 0) {
|
|
115
|
-
console.log('[LEARNING] Consolidated: ' + lResult.promoted + ' patterns promoted to long-term');
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
if (ls && ls.promoteEpisodic) {
|
|
119
|
-
try {
|
|
120
|
-
var promResult = await hCtx.runWithTimeout(function() { return ls.promoteEpisodic(); }, 'learning.promoteEpisodic()');
|
|
121
|
-
if (promResult && promResult.promoted > 0) {
|
|
122
|
-
console.log('[LEARNING] Promoted ' + promResult.promoted + ' episodic patterns to semantic memory');
|
|
123
|
-
}
|
|
124
|
-
} catch (e) { /* non-fatal */ }
|
|
125
|
-
}
|
|
126
|
-
} catch (e) { /* non-fatal — learning-service may need better-sqlite3 */ }
|
|
103
|
+
// Now consolidate AFTER feedback has been recorded (so the outcome has recentEdits)
|
|
104
|
+
if (!daemonHoldsLock && intelligence && intelligence.consolidate) {
|
|
105
|
+
var consResult = await hCtx.runWithTimeout(function() { return intelligence.consolidate(); }, 'intelligence.consolidate()');
|
|
106
|
+
if (consResult && consResult.entries > 0) {
|
|
107
|
+
var msg = '[INTELLIGENCE] Consolidated: ' + consResult.entries + ' entries';
|
|
108
|
+
if (consResult.newEntries > 0) msg += ', ' + consResult.newEntries + ' new patterns learned';
|
|
109
|
+
console.log(msg);
|
|
110
|
+
}
|
|
127
111
|
}
|
|
112
|
+
try {
|
|
113
|
+
if (session && session.end) {
|
|
114
|
+
session.end();
|
|
115
|
+
} else {
|
|
116
|
+
console.log('[OK] Session ended');
|
|
117
|
+
}
|
|
118
|
+
} catch (e) { console.log('[WARN] Session end failed: ' + e.message); }
|
|
119
|
+
|
|
120
|
+
// Memory Palace tombstone writes removed — redundant with raw session JSONL
|
|
128
121
|
|
|
129
122
|
// ── Context Persistence Auto-Archive ─────────────────────────────────
|
|
130
123
|
// Archive conversation context so it survives compaction and new sessions
|
|
@@ -139,99 +132,103 @@ module.exports = {
|
|
|
139
132
|
}
|
|
140
133
|
} catch (e) { /* non-fatal — context-persistence may not export archive() */ }
|
|
141
134
|
|
|
142
|
-
// ──
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
|
|
135
|
+
// ── Auto-populate: write session episode for every session ─────
|
|
136
|
+
// Even solo sessions (no subagents) produce an episode so the
|
|
137
|
+
// route handler can surface relevant past sessions.
|
|
138
|
+
try {
|
|
139
|
+
var episodicDir = path.join(CWD, '.monomind', 'episodic');
|
|
140
|
+
fs.mkdirSync(episodicDir, { recursive: true });
|
|
141
|
+
var epPath = path.join(episodicDir, 'episodes.jsonl');
|
|
142
|
+
|
|
143
|
+
// Collect session context
|
|
144
|
+
var sessId = String(hookInput.sessionId || hookInput.session_id || process.env.CLAUDE_SESSION_ID || '');
|
|
145
|
+
var lastRouteFile = path.join(CWD, '.monomind', 'last-route.json');
|
|
146
|
+
var routeAgent = 'unknown';
|
|
147
|
+
var routePrompt = '';
|
|
146
148
|
try {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (episodes.length >= 5) {
|
|
154
|
-
// Get learning service for scaffold optimizer metrics
|
|
155
|
-
var ls2 = await hCtx.getLearningService();
|
|
156
|
-
|
|
157
|
-
// Phase 2a: Scaffold optimization (gated revision)
|
|
158
|
-
if (ls2 && ls2.getLearningBridge) {
|
|
159
|
-
try {
|
|
160
|
-
var bridge = ls2.getLearningBridge();
|
|
161
|
-
if (bridge) {
|
|
162
|
-
// Load tunable thresholds from .monomind/automem-config.json
|
|
163
|
-
var scaffoldConfig = {};
|
|
164
|
-
try {
|
|
165
|
-
var amcPath = path.join(CWD, '.monomind', 'automem-config.json');
|
|
166
|
-
if (fs.existsSync(amcPath) && fs.statSync(amcPath).size < 64 * 1024) {
|
|
167
|
-
var amc = JSON.parse(fs.readFileSync(amcPath, 'utf-8'));
|
|
168
|
-
if (amc.scaffold) scaffoldConfig = amc.scaffold;
|
|
169
|
-
}
|
|
170
|
-
} catch (e5) { /* non-fatal */ }
|
|
171
|
-
var optimizer = new memMod.ScaffoldOptimizer(scaffoldConfig);
|
|
172
|
-
var optResult = await hCtx.runWithTimeout(function() { return optimizer.optimize(epStore, bridge); }, 'scaffold.optimize()');
|
|
173
|
-
if (optResult && optResult.accepted.length > 0) {
|
|
174
|
-
console.log('[AUTOMEM_SCAFFOLD] Accepted ' + optResult.accepted.length + ' revision(s): ' + optResult.accepted.map(function(r) { return r.description; }).join(', '));
|
|
175
|
-
// Persist revisions for diagnostics
|
|
176
|
-
try {
|
|
177
|
-
var revPath = path.join(CWD, '.monomind', 'data', 'scaffold-revisions.jsonl');
|
|
178
|
-
fs.mkdirSync(path.dirname(revPath), { recursive: true });
|
|
179
|
-
optResult.accepted.forEach(function(r) {
|
|
180
|
-
fs.appendFileSync(revPath, JSON.stringify(r) + '\n', 'utf-8');
|
|
181
|
-
});
|
|
182
|
-
} catch (e6) { /* non-fatal */ }
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
} catch (e3) { /* non-fatal */ }
|
|
186
|
-
}
|
|
149
|
+
if (fs.existsSync(lastRouteFile) && fs.statSync(lastRouteFile).size < 16384) {
|
|
150
|
+
var lr = JSON.parse(fs.readFileSync(lastRouteFile, 'utf-8'));
|
|
151
|
+
routeAgent = lr.agent || 'unknown';
|
|
152
|
+
routePrompt = lr.prompt || '';
|
|
153
|
+
}
|
|
154
|
+
} catch (e) {}
|
|
187
155
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
156
|
+
// Strip system noise (task notifications, XML tags) from prompt
|
|
157
|
+
if (routePrompt && (routePrompt.includes('<task-notification>') || routePrompt.includes('<system-reminder>'))) {
|
|
158
|
+
routePrompt = '';
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Determine session success from git commits (strongest signal)
|
|
162
|
+
var sessionOutcome = 'unknown';
|
|
163
|
+
var commitMessages = [];
|
|
164
|
+
var editedFiles = [];
|
|
165
|
+
try {
|
|
166
|
+
var execSync = require('child_process').execSync;
|
|
167
|
+
// Get recent commits as success signal
|
|
168
|
+
var commitLog = execSync('git log --oneline --since="30 minutes ago" 2>/dev/null || true', { cwd: CWD, timeout: 3000, encoding: 'utf-8' }).trim();
|
|
169
|
+
if (commitLog.length > 0) {
|
|
170
|
+
sessionOutcome = 'success';
|
|
171
|
+
commitMessages = commitLog.split('\n').filter(Boolean).map(function(l) {
|
|
172
|
+
return l.replace(/^[a-f0-9]+ /, '');
|
|
173
|
+
}).slice(0, 5);
|
|
174
|
+
}
|
|
175
|
+
// Get modified files from working tree
|
|
176
|
+
var diffOut = execSync('git diff --name-only HEAD 2>/dev/null || true', { cwd: CWD, timeout: 3000, encoding: 'utf-8' });
|
|
177
|
+
editedFiles = diffOut.trim().split('\n').filter(Boolean).map(function(f) { return path.basename(f); }).slice(0, 15);
|
|
178
|
+
if (sessionOutcome === 'unknown' && editedFiles.length > 0) {
|
|
179
|
+
sessionOutcome = 'in-progress';
|
|
180
|
+
}
|
|
181
|
+
} catch (e) {}
|
|
182
|
+
|
|
183
|
+
// Write episode with rich searchable content (commit messages are the user's own words)
|
|
184
|
+
var summaryParts = [];
|
|
185
|
+
if (routePrompt) summaryParts.push(routePrompt.slice(0, 300));
|
|
186
|
+
if (commitMessages.length > 0) summaryParts.push('Commits: ' + commitMessages.join('; '));
|
|
187
|
+
if (editedFiles.length > 0) summaryParts.push('Modified: ' + editedFiles.join(', '));
|
|
188
|
+
if (sessionOutcome !== 'unknown') summaryParts.push('Outcome: ' + sessionOutcome);
|
|
189
|
+
if (summaryParts.length === 0) summaryParts.push('Session with ' + routeAgent);
|
|
190
|
+
|
|
191
|
+
var soloEpisode = {
|
|
192
|
+
episodeId: require('crypto').randomUUID(),
|
|
193
|
+
sessionId: sessId,
|
|
194
|
+
runIds: [sessId],
|
|
195
|
+
summary: summaryParts.join('\n'),
|
|
196
|
+
startedAt: Date.now() - 300000,
|
|
197
|
+
endedAt: Date.now(),
|
|
198
|
+
agentSlugs: [routeAgent],
|
|
199
|
+
taskTypes: [routeAgent],
|
|
200
|
+
tokenEstimate: 0
|
|
201
|
+
};
|
|
202
|
+
fs.appendFileSync(epPath, JSON.stringify(soloEpisode) + '\n', 'utf-8');
|
|
203
|
+
|
|
204
|
+
// Rotate: keep last 500 episodes
|
|
205
|
+
try {
|
|
206
|
+
var epStat = fs.statSync(epPath);
|
|
207
|
+
if (epStat.size > 256 * 1024) {
|
|
208
|
+
var epLines = fs.readFileSync(epPath, 'utf-8').trim().split('\n').filter(Boolean);
|
|
209
|
+
if (epLines.length > 500) {
|
|
210
|
+
fs.writeFileSync(epPath, epLines.slice(-500).join('\n') + '\n', 'utf-8');
|
|
200
211
|
}
|
|
201
212
|
}
|
|
202
|
-
} catch (
|
|
203
|
-
}
|
|
213
|
+
} catch (e) {}
|
|
214
|
+
} catch (e) { /* non-fatal */ }
|
|
204
215
|
|
|
205
|
-
// ──
|
|
206
|
-
// Process and clean up any pending worker dispatch files
|
|
216
|
+
// ── Memory ops summary ──────────────────────────────────────
|
|
207
217
|
try {
|
|
208
|
-
var
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
218
|
+
var memOpsSessionId = String(hookInput.sessionId || hookInput.session_id || process.env.CLAUDE_SESSION_ID || '');
|
|
219
|
+
var memOpsPath = path.join(CWD, '.monomind', 'memory-ops-' + memOpsSessionId.slice(0, 16) + '.json');
|
|
220
|
+
if (fs.existsSync(memOpsPath)) {
|
|
221
|
+
var memOps = JSON.parse(fs.readFileSync(memOpsPath, 'utf-8'));
|
|
222
|
+
if (memOps.writes > 0 || memOps.searches > 0) {
|
|
223
|
+
var parts = [];
|
|
224
|
+
if (memOps.writes > 0) parts.push(memOps.writes + ' writes' + (memOps.redundantWrites > 0 ? ' (' + memOps.redundantWrites + ' redundant)' : ''));
|
|
225
|
+
if (memOps.searches > 0) parts.push(memOps.searches + ' searches' + (memOps.emptySearches > 0 ? ' (' + memOps.emptySearches + ' empty)' : ''));
|
|
226
|
+
console.log('[MEMORY_OPS] Session: ' + parts.join(', '));
|
|
213
227
|
}
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
fs.mkdirSync(processedDir, { recursive: true });
|
|
217
|
-
pending.forEach(function(f) {
|
|
218
|
-
try {
|
|
219
|
-
fs.renameSync(path.join(dispatchDir, f), path.join(processedDir, f));
|
|
220
|
-
} catch (e) { /* ignore */ }
|
|
221
|
-
});
|
|
222
|
-
// Trim processed/ to last 200 files to prevent unbounded growth
|
|
223
|
-
try {
|
|
224
|
-
var processedFiles = fs.readdirSync(processedDir)
|
|
225
|
-
.filter(function(f) { return f.startsWith('pending-'); })
|
|
226
|
-
.map(function(f) { var fp = path.join(processedDir, f); var mt = 0; try { mt = fs.statSync(fp).mtimeMs; } catch(e2){} return { f: f, mt: mt }; })
|
|
227
|
-
.sort(function(a, b) { return a.mt - b.mt; });
|
|
228
|
-
if (processedFiles.length > 200) {
|
|
229
|
-
processedFiles.slice(0, processedFiles.length - 200).forEach(function(item) {
|
|
230
|
-
try { fs.unlinkSync(path.join(processedDir, item.f)); } catch (e2) { /* ignore */ }
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
} catch (e2) { /* non-fatal */ }
|
|
228
|
+
// Clean up session stats file
|
|
229
|
+
try { fs.unlinkSync(memOpsPath); } catch (e) {}
|
|
234
230
|
}
|
|
235
231
|
} catch (e) { /* non-fatal */ }
|
|
232
|
+
|
|
236
233
|
}
|
|
237
234
|
};
|
|
@@ -30,6 +30,21 @@ module.exports = {
|
|
|
30
30
|
}
|
|
31
31
|
} catch (e) { console.log('[WARN] Session restore failed: ' + e.message); }
|
|
32
32
|
|
|
33
|
+
// ── Non-blocking security scan via @monomind/hooks worker ─────────────
|
|
34
|
+
// The hooks package ships a security worker (worker-security.ts) that scans
|
|
35
|
+
// for hardcoded secrets and vulnerability patterns. We run it at session
|
|
36
|
+
// start as a fire-and-forget check — failures are silently ignored since
|
|
37
|
+
// the package may not be installed or built.
|
|
38
|
+
try {
|
|
39
|
+
var hooksWorkersMod = require('@monomind/hooks/dist/workers/worker-security.js');
|
|
40
|
+
var _createSecurityWorker = hooksWorkersMod.createSecurityWorker;
|
|
41
|
+
if (typeof _createSecurityWorker === 'function') {
|
|
42
|
+
var _securityScan = _createSecurityWorker(CWD);
|
|
43
|
+
// Fire-and-forget: do not await — must not delay session restore
|
|
44
|
+
Promise.resolve(_securityScan()).catch(function() {});
|
|
45
|
+
}
|
|
46
|
+
} catch (e) { /* @monomind/hooks not available or not built — skip */ }
|
|
47
|
+
|
|
33
48
|
// Stale helper detection — warn when project helpers drift from the bundled npm copy.
|
|
34
49
|
// Skip when running inside the monomind dev repo itself: local helpers ARE the
|
|
35
50
|
// source of truth there, so any diff vs. the npm global install is expected.
|
|
@@ -356,15 +371,5 @@ module.exports = {
|
|
|
356
371
|
} catch (e) { /* non-fatal */ }
|
|
357
372
|
}
|
|
358
373
|
|
|
359
|
-
// Worker Queue Resume (SR-003).
|
|
360
|
-
try {
|
|
361
|
-
var dispatchDir = path.join(CWD, '.monomind', 'worker-dispatch');
|
|
362
|
-
if (fs.existsSync(dispatchDir)) {
|
|
363
|
-
var pendingFiles = fs.readdirSync(dispatchDir).filter(function(f) { return f.startsWith('pending-'); }).slice(0, 500);
|
|
364
|
-
if (pendingFiles.length > 0) {
|
|
365
|
-
console.log('[WORKER_RESUME] ' + pendingFiles.length + ' worker dispatch(es) pending from prior session');
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
} catch (e) { /* non-fatal */ }
|
|
369
374
|
},
|
|
370
375
|
};
|
|
@@ -18,114 +18,11 @@ module.exports = {
|
|
|
18
18
|
try { session.metric('tasks'); } catch (e) { /* no active session */ }
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (router && prompt) {
|
|
27
|
-
var routeFn = router.routeTaskSemantic || router.routeTask;
|
|
28
|
-
var result = await Promise.resolve(routeFn(prompt));
|
|
29
|
-
console.log('[INFO] Task routed to: ' + result.agent + ' (confidence: ' + result.confidence + ')');
|
|
30
|
-
} else {
|
|
31
|
-
console.log('[OK] Task started');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// AutoMem Phase 1: PLAN routine — consult memory before acting (arXiv:2607.01224)
|
|
35
|
-
if (prompt && typeof prompt === 'string' && prompt.length > 20) {
|
|
36
|
-
try {
|
|
37
|
-
var intelligence = hCtx.intelligence;
|
|
38
|
-
if (intelligence && intelligence.findSimilarPatterns) {
|
|
39
|
-
var memPatterns = await Promise.resolve(intelligence.findSimilarPatterns(prompt, { k: 3, type: 'memory-proficiency' }));
|
|
40
|
-
if (memPatterns && memPatterns.length > 0) {
|
|
41
|
-
console.log('[AUTOMEM_PLAN] Recalled ' + memPatterns.length + ' memory pattern(s): ' + memPatterns.map(function(p) { return p.content.substring(0, 80); }).join(' | '));
|
|
42
|
-
}
|
|
43
|
-
// Also check general patterns for task-relevant memory
|
|
44
|
-
var taskPatterns = await Promise.resolve(intelligence.findSimilarPatterns(prompt, { k: 2 }));
|
|
45
|
-
if (taskPatterns && taskPatterns.length > 0) {
|
|
46
|
-
console.log('[AUTOMEM_CONTEXT] ' + taskPatterns.length + ' relevant pattern(s) from prior sessions');
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
} catch (e) { /* non-fatal — PLAN is advisory */ }
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Task 24: PromptVersioning — resolve prompt variant before agent spawn
|
|
53
|
-
try {
|
|
54
|
-
var memMod = await import('@monomind/memory');
|
|
55
|
-
if (memMod && memMod.PromptVersionStore) {
|
|
56
|
-
var pvStore = new memMod.PromptVersionStore(path.join(CWD, '.monomind', 'prompt-versions'));
|
|
57
|
-
var pvMod = await import('file://' + path.join(CWD, 'packages/@monomind/cli/dist/src/agents/prompt-experiment.js'));
|
|
58
|
-
if (pvMod && pvMod.PromptExperimentRouter) {
|
|
59
|
-
var pvRouter = new pvMod.PromptExperimentRouter(pvStore);
|
|
60
|
-
var agentSlug24 = hookInput.agentSlug || hookInput.agentType || hookInput.agent_type || 'unknown';
|
|
61
|
-
if (agentSlug24 !== 'unknown') {
|
|
62
|
-
var resolved = pvRouter.resolvePromptForSpawn(agentSlug24);
|
|
63
|
-
if (resolved.version) {
|
|
64
|
-
console.log('[PROMPT_VERSION] ' + agentSlug24 + ' v' + resolved.version + (resolved.isCandidate ? ' (experiment candidate)' : ''));
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
} catch (e) { /* not available or no experiment */ }
|
|
70
|
-
|
|
71
|
-
// Monograph impact — detect changed files and surface their dependents
|
|
72
|
-
try {
|
|
73
|
-
var mgDbPath1 = path.join(CWD, '.monomind', 'monograph.db');
|
|
74
|
-
if (fs.existsSync(mgDbPath1)) {
|
|
75
|
-
var changedFiles1 = await new Promise(function(resolve) {
|
|
76
|
-
require('child_process').exec(
|
|
77
|
-
'git diff --name-only HEAD 2>/dev/null || git diff --name-only 2>/dev/null',
|
|
78
|
-
{ cwd: CWD, timeout: 3000 },
|
|
79
|
-
function(err, stdout) { resolve(err ? '' : (stdout || '').trim()); }
|
|
80
|
-
);
|
|
81
|
-
});
|
|
82
|
-
if (changedFiles1) {
|
|
83
|
-
var mgMod1 = null;
|
|
84
|
-
mgMod1 = hCtx._requireMonograph();
|
|
85
|
-
if (mgMod1 && mgMod1.openDb) {
|
|
86
|
-
var db1 = mgMod1.openDb(mgDbPath1);
|
|
87
|
-
try {
|
|
88
|
-
var fileList1 = changedFiles1.split('\n').filter(Boolean).slice(0, 8);
|
|
89
|
-
var impacted1 = [];
|
|
90
|
-
for (var fi = 0; fi < fileList1.length; fi++) {
|
|
91
|
-
var fBase = path.basename(fileList1[fi]);
|
|
92
|
-
var fNode = db1.prepare("SELECT id, name, label FROM nodes WHERE file_path LIKE ? LIMIT 1").get('%' + fBase);
|
|
93
|
-
if (fNode) {
|
|
94
|
-
var fImporters = db1.prepare(
|
|
95
|
-
'SELECT n2.name FROM edges e JOIN nodes n2 ON n2.id = e.source_id WHERE e.target_id = ? LIMIT 5'
|
|
96
|
-
).all(fNode.id);
|
|
97
|
-
var entry = fNode.name + ' (' + fNode.label + ')';
|
|
98
|
-
if (fImporters.length) entry += ' ← ' + fImporters.map(function(i){ return i.name; }).join(', ');
|
|
99
|
-
impacted1.push(entry);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
if (impacted1.length > 0) {
|
|
103
|
-
console.log('[MONOGRAPH_IMPACT] Changed files and their dependents: ' + impacted1.join(' | '));
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Effective blast radius — second pass using first impacted node
|
|
107
|
-
try {
|
|
108
|
-
if (fileList1.length > 0 && mgMod1.effectiveBlastRadius) {
|
|
109
|
-
var firstFile1 = path.basename(fileList1[0]);
|
|
110
|
-
var firstNode1 = db1.prepare("SELECT id, name, label FROM nodes WHERE file_path LIKE ? LIMIT 1").get('%' + firstFile1);
|
|
111
|
-
if (firstNode1) {
|
|
112
|
-
var blastResults1 = mgMod1.effectiveBlastRadius(db1, firstNode1.id, { maxDepth: 4 });
|
|
113
|
-
if (blastResults1 && blastResults1.length > 0) {
|
|
114
|
-
var bwdCount1 = blastResults1.filter(function(r){ return r.direction === 'backward' || r.direction === 'both'; }).length;
|
|
115
|
-
var fwdCount1 = blastResults1.filter(function(r){ return r.direction === 'forward' || r.direction === 'both'; }).length;
|
|
116
|
-
var topBlast1 = blastResults1.slice(0, 8).map(function(r){
|
|
117
|
-
return '[' + r.direction + ':' + r.hops + '] ' + r.nodeName + ' (' + r.nodeLabel + ')';
|
|
118
|
-
});
|
|
119
|
-
console.log('[MONOGRAPH_BLAST_RADIUS] Node: ' + firstNode1.name + ' | forward=' + fwdCount1 + ' backward=' + bwdCount1 + ' | ' + topBlast1.join(', '));
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
} catch(blastErr) { /* non-fatal */ }
|
|
124
|
-
} finally { if (mgMod1.closeDb) mgMod1.closeDb(db1); }
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
} catch(e) { /* non-fatal */ }
|
|
21
|
+
// monolean: removed per-subagent redundancies:
|
|
22
|
+
// - Re-routing (already done by route handler on parent prompt)
|
|
23
|
+
// - AUTOMEM pattern recall (marginal value, 2 similarity searches per spawn)
|
|
24
|
+
// - PromptVersioning experiments (unused feature)
|
|
25
|
+
// - Monograph blast radius (already shown by post-edit hook on actual changes)
|
|
129
26
|
|
|
130
27
|
// Bridge to @monomind/hooks registry — fires Tasks 26 (PromptAssembler) and any other PreTask hooks
|
|
131
28
|
var _hooksModule = hCtx._hooksModule;
|
|
@@ -148,7 +45,7 @@ module.exports = {
|
|
|
148
45
|
var taskSuccess = hookInput.success !== false && hookInput.status !== 'failed';
|
|
149
46
|
if (intelligence && intelligence.feedback) {
|
|
150
47
|
try {
|
|
151
|
-
intelligence.feedback(
|
|
48
|
+
intelligence.feedback(taskSuccess);
|
|
152
49
|
} catch (e) { /* non-fatal */ }
|
|
153
50
|
}
|
|
154
51
|
// Each TeammateIdle/TaskCompleted = one agent done → remove oldest registration (FIFO)
|
|
@@ -244,7 +141,8 @@ module.exports = {
|
|
|
244
141
|
}
|
|
245
142
|
} catch (e) { /* non-fatal */ }
|
|
246
143
|
|
|
247
|
-
//
|
|
144
|
+
// Record whether this task's outcome matched a recalled memory pattern,
|
|
145
|
+
// so future pattern recall can be scored for usefulness.
|
|
248
146
|
try {
|
|
249
147
|
var intelligence = hCtx.intelligence;
|
|
250
148
|
if (intelligence && intelligence.recordMemoryDecision) {
|
|
@@ -259,51 +157,6 @@ module.exports = {
|
|
|
259
157
|
}
|
|
260
158
|
} catch (e) { /* non-fatal — LOG is advisory */ }
|
|
261
159
|
|
|
262
|
-
// ── Worker Auto-Dispatch ──────────────────────────────────────────────
|
|
263
|
-
// Auto-dispatch background workers based on task outcome
|
|
264
|
-
try {
|
|
265
|
-
var taskDesc = (typeof prompt === 'string' ? prompt : hookInput.description || '').toLowerCase();
|
|
266
|
-
var workersToDispatch = [];
|
|
267
|
-
|
|
268
|
-
// Always consolidate memory after any task
|
|
269
|
-
workersToDispatch.push('consolidate');
|
|
270
|
-
|
|
271
|
-
// Security-related task → dispatch audit worker
|
|
272
|
-
if (/\b(security|auth|vuln|cve|threat|token|permission|crypto)\b/.test(taskDesc)) {
|
|
273
|
-
workersToDispatch.push('audit');
|
|
274
|
-
}
|
|
275
|
-
// Performance-related → dispatch benchmark worker
|
|
276
|
-
if (/\b(performance|optimiz|benchmark|latency|throughput)\b/.test(taskDesc)) {
|
|
277
|
-
workersToDispatch.push('benchmark');
|
|
278
|
-
}
|
|
279
|
-
// Code changes → dispatch testgaps worker
|
|
280
|
-
if (/\b(implement|feature|refactor|fix|build|add|create|modify)\b/.test(taskDesc)) {
|
|
281
|
-
workersToDispatch.push('testgaps');
|
|
282
|
-
}
|
|
283
|
-
// Any significant task → dispatch map worker for codebase indexing
|
|
284
|
-
if (taskDesc.length > 50) {
|
|
285
|
-
workersToDispatch.push('map');
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// Dispatch via @monomind/hooks if available, otherwise write dispatch file
|
|
289
|
-
if (workersToDispatch.length > 0) {
|
|
290
|
-
var dispatchDir = path.join(CWD, '.monomind', 'worker-dispatch');
|
|
291
|
-
fs.mkdirSync(dispatchDir, { recursive: true });
|
|
292
|
-
var dispatchPayload = {
|
|
293
|
-
workers: workersToDispatch,
|
|
294
|
-
trigger: 'post-task',
|
|
295
|
-
taskDesc: taskDesc.substring(0, 100),
|
|
296
|
-
success: taskSuccess,
|
|
297
|
-
timestamp: new Date().toISOString(),
|
|
298
|
-
};
|
|
299
|
-
fs.writeFileSync(
|
|
300
|
-
path.join(dispatchDir, 'pending-' + Date.now() + '-' + Math.random().toString(36).slice(2, 7) + '.json'),
|
|
301
|
-
JSON.stringify(dispatchPayload), 'utf-8'
|
|
302
|
-
);
|
|
303
|
-
console.log('[WORKER_DISPATCH] Queued: ' + workersToDispatch.join(', '));
|
|
304
|
-
}
|
|
305
|
-
} catch (e) { /* non-fatal */ }
|
|
306
|
-
|
|
307
160
|
// ── ADR Auto-Generation ────────────────────────────────────────────────
|
|
308
161
|
// When adr.autoGenerate is true and task involved architect-level work,
|
|
309
162
|
// create an ADR stub in the configured directory
|