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
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Monomind Hook Handler (Cross-Platform)
|
|
4
4
|
* Dispatches hook events to the appropriate helper modules.
|
|
5
|
+
*
|
|
6
|
+
* ARCHITECTURE NOTE — Two Hook Systems
|
|
7
|
+
* =====================================
|
|
8
|
+
* There are two independent hook systems in this project:
|
|
9
|
+
*
|
|
10
|
+
* 1. .claude/helpers/ CJS handlers (THIS FILE and ./handlers/*.cjs)
|
|
11
|
+
* These are the handlers that actually run via settings.json hook
|
|
12
|
+
* configuration. They are plain CommonJS scripts invoked directly
|
|
13
|
+
* by Claude Code's hook runtime. This is the "live" system.
|
|
14
|
+
*
|
|
15
|
+
* 2. @monomind/hooks TypeScript package (packages/@monomind/hooks/)
|
|
16
|
+
* A full TypeScript package with workers, learning services, and
|
|
17
|
+
* a WorkerManager. It compiles to dist/ but is only loaded
|
|
18
|
+
* optionally — currently at session-restore (to bridge pre-task /
|
|
19
|
+
* post-task into the hook registry) and at session-restore for a
|
|
20
|
+
* non-blocking security scan. The CJS handlers in system (1) are
|
|
21
|
+
* the authoritative dispatch path; system (2) provides optional
|
|
22
|
+
* enrichment when the package is installed and built.
|
|
5
23
|
*/
|
|
6
24
|
|
|
7
25
|
const path = require('path');
|
|
@@ -435,6 +453,44 @@ const handlers = {
|
|
|
435
453
|
}
|
|
436
454
|
}
|
|
437
455
|
}
|
|
456
|
+
|
|
457
|
+
// --- Strategy 9: alternation patterns (TODO\|FIXME, mock\|fake\|stub) ---
|
|
458
|
+
if (!graphAssisted && pattern.indexOf('|') !== -1) {
|
|
459
|
+
var altParts = pattern.split(/\\?\|/).map(function(p) {
|
|
460
|
+
return p.replace(/[^a-zA-Z0-9_$]/g, '');
|
|
461
|
+
}).filter(function(p) {
|
|
462
|
+
return p.length >= 4 && /^[a-zA-Z_$]/.test(p) && !_grepStop[p.toLowerCase()];
|
|
463
|
+
});
|
|
464
|
+
for (var ai = 0; ai < altParts.length && !graphAssisted; ai++) {
|
|
465
|
+
var arow = db.prepare(
|
|
466
|
+
'SELECT n.name, n.file_path, n.start_line FROM nodes n WHERE n.name = ? COLLATE NOCASE AND n.label NOT IN (\'Concept\',\'Community\',\'Folder\') AND n.file_path IS NOT NULL AND n.file_path NOT LIKE \'%.md\' LIMIT 1'
|
|
467
|
+
).get(altParts[ai]);
|
|
468
|
+
if (arow) {
|
|
469
|
+
graphAssisted = true;
|
|
470
|
+
var ahint = arow.file_path + (arow.start_line != null ? ':' + arow.start_line : '');
|
|
471
|
+
console.log('[MONOGRAPH_HINT] ' + arow.name + ' → ' + ahint);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
// --- Strategy 10: grep targeting a known source directory ---
|
|
479
|
+
// Runs outside `if (pattern)` so it works even when pattern extraction fails
|
|
480
|
+
if (!graphAssisted) {
|
|
481
|
+
var db10 = _openMonographDb();
|
|
482
|
+
if (db10) {
|
|
483
|
+
var dirMatch10 = cmdAfterTool.match(/\b(src|packages(?:\/[a-zA-Z0-9_@/-]*)?)\//);
|
|
484
|
+
if (dirMatch10) {
|
|
485
|
+
var dirPath10 = dirMatch10[1].replace(/\/$/, '');
|
|
486
|
+
var drow10 = db10.prepare(
|
|
487
|
+
'SELECT COUNT(*) AS c FROM nodes WHERE label = \'File\' AND file_path LIKE ? LIMIT 1'
|
|
488
|
+
).get('%' + dirPath10 + '/%');
|
|
489
|
+
if (drow10 && drow10.c > 0) {
|
|
490
|
+
graphAssisted = true;
|
|
491
|
+
console.log('[MONOGRAPH_HINT] grep scope ' + dirPath10 + ' has ' + drow10.c + ' indexed files');
|
|
492
|
+
}
|
|
493
|
+
}
|
|
438
494
|
}
|
|
439
495
|
}
|
|
440
496
|
} else {
|
|
@@ -452,6 +508,38 @@ const handlers = {
|
|
|
452
508
|
}
|
|
453
509
|
}
|
|
454
510
|
}
|
|
511
|
+
// find -name "*worker*" — extract core word from wildcard patterns
|
|
512
|
+
if (!graphAssisted) {
|
|
513
|
+
var wm = cmd.match(/-name\s+["'][*]?([a-zA-Z][a-zA-Z0-9_-]{3,})[*]?(?:\.[a-z]+)?["']/);
|
|
514
|
+
if (wm && wm[1]) {
|
|
515
|
+
var db = _openMonographDb();
|
|
516
|
+
if (db) {
|
|
517
|
+
var wrow = db.prepare(
|
|
518
|
+
'SELECT n.name, n.file_path FROM nodes n WHERE n.name LIKE ? AND n.label = \'File\' AND n.file_path NOT LIKE \'%.md\' LIMIT 1'
|
|
519
|
+
).get('%' + wm[1] + '%');
|
|
520
|
+
if (wrow) {
|
|
521
|
+
graphAssisted = true;
|
|
522
|
+
console.log('[MONOGRAPH_HINT] file *' + wm[1] + '* → ' + wrow.file_path);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
// find with -type f in a known directory scope
|
|
528
|
+
if (!graphAssisted) {
|
|
529
|
+
var fdm = cmd.match(/\bfind\s+(\S*(?:src|packages|lib|app)[a-zA-Z0-9_@/-]*)/);
|
|
530
|
+
if (fdm && fdm[1]) {
|
|
531
|
+
var db = _openMonographDb();
|
|
532
|
+
if (db) {
|
|
533
|
+
var fdrow = db.prepare(
|
|
534
|
+
'SELECT COUNT(*) AS c FROM nodes WHERE label = \'File\' AND file_path LIKE ? LIMIT 1'
|
|
535
|
+
).get(fdm[1].replace(/\/$/, '') + '/%');
|
|
536
|
+
if (fdrow && fdrow.c > 0) {
|
|
537
|
+
graphAssisted = true;
|
|
538
|
+
console.log('[MONOGRAPH_HINT] find scope ' + fdm[1] + ' has ' + fdrow.c + ' indexed files');
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
455
543
|
}
|
|
456
544
|
} catch (e) { /* non-fatal */ }
|
|
457
545
|
}
|
|
@@ -647,10 +735,6 @@ const handlers = {
|
|
|
647
735
|
h.handle(hCtx);
|
|
648
736
|
},
|
|
649
737
|
|
|
650
|
-
'status': () => {
|
|
651
|
-
console.log('[OK] Status check');
|
|
652
|
-
},
|
|
653
|
-
|
|
654
738
|
'stats': async () => {
|
|
655
739
|
const h = require('./handlers/stats-handler.cjs');
|
|
656
740
|
await h.handle(hCtx);
|
|
@@ -669,7 +753,7 @@ if (command && handlers[command]) {
|
|
|
669
753
|
} else if (command) {
|
|
670
754
|
console.log('[OK] Hook: ' + command);
|
|
671
755
|
} else {
|
|
672
|
-
console.log('Usage: hook-handler.cjs <route|pre-bash|pre-search|post-edit|post-
|
|
756
|
+
console.log('Usage: hook-handler.cjs <route|pre-bash|pre-search|post-edit|post-graph-tool|session-restore|session-end|pre-task|post-task|compact-manual|compact-auto|stats>');
|
|
673
757
|
}
|
|
674
758
|
}
|
|
675
759
|
|
|
@@ -22,12 +22,14 @@ const STORE_FILE = path.join(DATA_DIR, 'auto-memory-store.json');
|
|
|
22
22
|
const RANKED_FILE = path.join(DATA_DIR, 'ranked-context.json');
|
|
23
23
|
const PENDING_FILE = path.join(DATA_DIR, 'pending-insights.jsonl');
|
|
24
24
|
const OUTCOMES_FILE = path.join(DATA_DIR, 'intelligence-outcomes.jsonl');
|
|
25
|
+
const RECENT_EDITS_FILE = path.join(DATA_DIR, 'recent-edits.jsonl');
|
|
25
26
|
|
|
26
27
|
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MiB guard
|
|
27
28
|
const RING_BUFFER_MAX = 50;
|
|
28
29
|
|
|
29
30
|
var _entries = []; // deduplicated memory entries loaded from store
|
|
30
|
-
var _recentEdits = []; // ring buffer of recently edited paths
|
|
31
|
+
var _recentEdits = []; // ring buffer of recently edited paths (in-memory, may be empty across subprocesses)
|
|
32
|
+
var _lastContext = null; // last non-null context returned by getContext()
|
|
31
33
|
|
|
32
34
|
function ensureDataDir() {
|
|
33
35
|
try { fs.mkdirSync(DATA_DIR, { recursive: true }); } catch (_) {}
|
|
@@ -70,6 +72,8 @@ function init() {
|
|
|
70
72
|
return true;
|
|
71
73
|
});
|
|
72
74
|
|
|
75
|
+
// Bootstrap from monograph when store is sparse — called externally via bootstrapFromDb(db)
|
|
76
|
+
|
|
73
77
|
// Write ranked-context.json (sorted by confidence desc) with version envelope
|
|
74
78
|
var ranked = _entries.slice().sort(function(a, b) {
|
|
75
79
|
return (b.confidence || 0) - (a.confidence || 0);
|
|
@@ -87,28 +91,50 @@ function getContext(prompt) {
|
|
|
87
91
|
if (!prompt || typeof prompt !== 'string' || prompt.trim() === '') return null;
|
|
88
92
|
if (_entries.length === 0) return null;
|
|
89
93
|
|
|
90
|
-
var promptWords = prompt.toLowerCase().split(/\W+/).filter(
|
|
94
|
+
var promptWords = prompt.toLowerCase().split(/\W+/).filter(function(w) { return w.length >= 3; });
|
|
91
95
|
var promptSet = new Set(promptWords);
|
|
96
|
+
if (promptSet.size < 2) return null; // need at least 2 meaningful words
|
|
92
97
|
|
|
93
|
-
var
|
|
98
|
+
var scored = [];
|
|
99
|
+
for (var i = 0; i < _entries.length; i++) {
|
|
100
|
+
var e = _entries[i];
|
|
94
101
|
var content = ((e.content || '') + ' ' + (e.summary || '')).toLowerCase();
|
|
95
|
-
var words = content.split(/\W+/).filter(
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
var words = content.split(/\W+/).filter(function(w) { return w.length >= 3; });
|
|
103
|
+
var hits = 0;
|
|
104
|
+
for (var j = 0; j < words.length; j++) {
|
|
105
|
+
if (promptSet.has(words[j])) hits++;
|
|
106
|
+
}
|
|
107
|
+
// Require at least 2 distinct word matches to reduce false positives
|
|
108
|
+
if (hits >= 2) {
|
|
109
|
+
scored.push({ entry: e, hits: hits });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
98
112
|
|
|
99
|
-
if (
|
|
113
|
+
if (scored.length === 0) return null;
|
|
114
|
+
|
|
115
|
+
// Sort by hit count descending, then by confidence
|
|
116
|
+
scored.sort(function(a, b) {
|
|
117
|
+
if (b.hits !== a.hits) return b.hits - a.hits;
|
|
118
|
+
return (b.entry.confidence || 0) - (a.entry.confidence || 0);
|
|
119
|
+
});
|
|
100
120
|
|
|
101
|
-
var top =
|
|
102
|
-
|
|
121
|
+
var top = scored[0].entry;
|
|
122
|
+
var result = '[INTELLIGENCE] ' + (top.summary || top.content || top.id || 'context match');
|
|
123
|
+
_lastContext = result;
|
|
124
|
+
return result;
|
|
103
125
|
}
|
|
104
126
|
|
|
105
127
|
// ── recordEdit ────────────────────────────────────────────────────────────────
|
|
106
128
|
|
|
107
129
|
function recordEdit(filePath) {
|
|
108
|
-
|
|
130
|
+
var entry = { path: String(filePath || ''), ts: Date.now() };
|
|
131
|
+
_recentEdits.push(entry);
|
|
109
132
|
if (_recentEdits.length > RING_BUFFER_MAX) {
|
|
110
133
|
_recentEdits = _recentEdits.slice(-RING_BUFFER_MAX);
|
|
111
134
|
}
|
|
135
|
+
// Persist to disk so other subprocesses (e.g. feedback()) can read edits
|
|
136
|
+
ensureDataDir();
|
|
137
|
+
try { fs.appendFileSync(RECENT_EDITS_FILE, JSON.stringify(entry) + '\n', 'utf-8'); } catch (_) {}
|
|
112
138
|
}
|
|
113
139
|
|
|
114
140
|
// ── consolidate ───────────────────────────────────────────────────────────────
|
|
@@ -121,18 +147,103 @@ function consolidate() {
|
|
|
121
147
|
// Clear the pending file
|
|
122
148
|
try { fs.writeFileSync(PENDING_FILE, '', 'utf-8'); } catch (_) {}
|
|
123
149
|
|
|
124
|
-
|
|
150
|
+
// Read accumulated session edits (not yet consumed by feedback)
|
|
151
|
+
var sessionEdits = [];
|
|
152
|
+
var editLines = safeReadLines(RECENT_EDITS_FILE);
|
|
153
|
+
for (var ei = 0; ei < editLines.length; ei++) {
|
|
154
|
+
try { sessionEdits.push(JSON.parse(editLines[ei])); } catch (_) {}
|
|
155
|
+
}
|
|
156
|
+
// Clear recent-edits after consolidation (session boundary)
|
|
157
|
+
try { fs.writeFileSync(RECENT_EDITS_FILE, '', 'utf-8'); } catch (_) {}
|
|
158
|
+
|
|
159
|
+
// Synthesize successful patterns from outcomes into auto-memory-store.json
|
|
160
|
+
var outcomeLines = safeReadLines(OUTCOMES_FILE);
|
|
161
|
+
var newStoreEntries = [];
|
|
162
|
+
for (var i = 0; i < outcomeLines.length; i++) {
|
|
163
|
+
try {
|
|
164
|
+
var outcome = JSON.parse(outcomeLines[i]);
|
|
165
|
+
if (!outcome.success) continue;
|
|
166
|
+
// Use outcome's own edits if present, otherwise use session-level edits
|
|
167
|
+
var edits = (Array.isArray(outcome.recentEdits) && outcome.recentEdits.length > 0)
|
|
168
|
+
? outcome.recentEdits
|
|
169
|
+
: sessionEdits;
|
|
170
|
+
if (edits.length === 0) continue;
|
|
171
|
+
var editPaths = edits.map(function(e) {
|
|
172
|
+
// e is either { path: '...', ts: ... } or a raw string
|
|
173
|
+
if (typeof e === 'string') return e;
|
|
174
|
+
// Use e.path if it's a non-empty string; skip objects without a valid path
|
|
175
|
+
return (e && typeof e.path === 'string' && e.path.length > 0) ? e.path : null;
|
|
176
|
+
}).filter(function(p) { return p !== null; });
|
|
177
|
+
// Deduplicate paths
|
|
178
|
+
var uniquePaths = [];
|
|
179
|
+
var pathSeen = {};
|
|
180
|
+
for (var pi = 0; pi < editPaths.length; pi++) {
|
|
181
|
+
var p = String(editPaths[pi]);
|
|
182
|
+
if (!pathSeen[p]) { pathSeen[p] = true; uniquePaths.push(p); }
|
|
183
|
+
}
|
|
184
|
+
newStoreEntries.push({
|
|
185
|
+
id: 'auto-' + (outcome.ts || Date.now()) + '-' + i,
|
|
186
|
+
type: 'pattern',
|
|
187
|
+
content: 'Successful edit pattern: ' + uniquePaths.map(function(p) { return path.basename(p); }).join(', '),
|
|
188
|
+
summary: outcome.context || 'Successful task editing ' + uniquePaths.length + ' files: ' + uniquePaths.slice(0, 5).map(function(p) { return path.basename(p); }).join(', '),
|
|
189
|
+
confidence: 0.6,
|
|
190
|
+
files: uniquePaths,
|
|
191
|
+
ts: outcome.ts || Date.now(),
|
|
192
|
+
});
|
|
193
|
+
} catch (_) {}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (newStoreEntries.length > 0) {
|
|
197
|
+
// Merge with existing store entries
|
|
198
|
+
var existing = safeReadJson(STORE_FILE);
|
|
199
|
+
var store = Array.isArray(existing) ? existing : [];
|
|
200
|
+
var existingIds = new Set(store.map(function(e) { return e && e.id; }));
|
|
201
|
+
for (var j = 0; j < newStoreEntries.length; j++) {
|
|
202
|
+
if (!existingIds.has(newStoreEntries[j].id)) {
|
|
203
|
+
store.push(newStoreEntries[j]);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Cap store at 200 entries to prevent unbounded growth
|
|
207
|
+
if (store.length > 200) {
|
|
208
|
+
store.sort(function(a, b) { return (b.ts || 0) - (a.ts || 0); });
|
|
209
|
+
store = store.slice(0, 200);
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
fs.writeFileSync(STORE_FILE, JSON.stringify(store, null, 2), 'utf-8');
|
|
213
|
+
} catch (_) {}
|
|
214
|
+
count += newStoreEntries.length;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Rotate outcomes: keep last 500 lines to prevent unbounded growth
|
|
218
|
+
if (outcomeLines.length > 500) {
|
|
219
|
+
try {
|
|
220
|
+
fs.writeFileSync(OUTCOMES_FILE, outcomeLines.slice(-500).join('\n') + '\n', 'utf-8');
|
|
221
|
+
} catch (_) {}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return { entries: count, edges: 0, newEntries: newStoreEntries.length };
|
|
125
225
|
}
|
|
126
226
|
|
|
127
227
|
// ── feedback ──────────────────────────────────────────────────────────────────
|
|
128
228
|
|
|
129
229
|
function feedback(success) {
|
|
130
230
|
ensureDataDir();
|
|
231
|
+
// Read persisted edits from disk (survives subprocess boundaries).
|
|
232
|
+
// We intentionally do NOT clear recent-edits.jsonl here — that is done by
|
|
233
|
+
// consolidate() at session-end. This prevents post-task (subagent completion)
|
|
234
|
+
// from clearing edits that belong to the broader session's work.
|
|
235
|
+
var diskEdits = [];
|
|
236
|
+
var diskLines = safeReadLines(RECENT_EDITS_FILE);
|
|
237
|
+
for (var i = 0; i < diskLines.length; i++) {
|
|
238
|
+
try { diskEdits.push(JSON.parse(diskLines[i])); } catch (_) {}
|
|
239
|
+
}
|
|
240
|
+
// Use disk edits if available, fall back to in-memory buffer
|
|
241
|
+
var edits = diskEdits.length > 0 ? diskEdits.slice(-RING_BUFFER_MAX) : _recentEdits.slice();
|
|
131
242
|
var record = JSON.stringify({
|
|
132
243
|
ts: Date.now(),
|
|
133
244
|
success: !!success,
|
|
134
|
-
context:
|
|
135
|
-
recentEdits:
|
|
245
|
+
context: _lastContext,
|
|
246
|
+
recentEdits: edits,
|
|
136
247
|
}) + '\n';
|
|
137
248
|
try { fs.appendFileSync(OUTCOMES_FILE, record, 'utf-8'); } catch (_) {}
|
|
138
249
|
}
|
|
@@ -161,7 +272,8 @@ function storePattern(pattern) {
|
|
|
161
272
|
void pattern;
|
|
162
273
|
}
|
|
163
274
|
|
|
164
|
-
// ── AutoMem bridges
|
|
275
|
+
// ── AutoMem bridges — lazy-load the compiled intelligence module and expose ──
|
|
276
|
+
// ── its pattern-recall/decision-recording helpers to the .cjs hook handlers ──
|
|
165
277
|
|
|
166
278
|
var _intelligenceMod = null;
|
|
167
279
|
|
|
@@ -186,4 +298,41 @@ async function recordMemoryDecision(input) {
|
|
|
186
298
|
if (mod && mod.recordMemoryDecision) return mod.recordMemoryDecision(input);
|
|
187
299
|
}
|
|
188
300
|
|
|
189
|
-
|
|
301
|
+
// Bootstrap intelligence store from an already-open monograph DB handle.
|
|
302
|
+
// Called from route-handler on first prompt when store is sparse.
|
|
303
|
+
function bootstrapFromDb(db) {
|
|
304
|
+
if (!db || _entries.length >= 5) return 0;
|
|
305
|
+
try {
|
|
306
|
+
var hubs = db.prepare(
|
|
307
|
+
"SELECT n.name, n.label, n.file, COUNT(e.id) AS deg " +
|
|
308
|
+
"FROM nodes n JOIN edges e ON (e.source = n.id OR e.target = n.id) " +
|
|
309
|
+
"WHERE n.label IN ('File','Function','Class') AND n.file NOT LIKE '%node_modules%' AND n.file NOT LIKE '%dist/%' " +
|
|
310
|
+
"GROUP BY n.id ORDER BY deg DESC LIMIT 10"
|
|
311
|
+
).all();
|
|
312
|
+
if (hubs.length === 0) return 0;
|
|
313
|
+
var existingIds = new Set(_entries.map(function(e) { return e.id; }));
|
|
314
|
+
var added = 0;
|
|
315
|
+
for (var hi = 0; hi < hubs.length; hi++) {
|
|
316
|
+
var h = hubs[hi];
|
|
317
|
+
var bId = 'bootstrap-hub-' + hi;
|
|
318
|
+
if (existingIds.has(bId)) continue;
|
|
319
|
+
_entries.push({
|
|
320
|
+
id: bId,
|
|
321
|
+
type: 'hub',
|
|
322
|
+
content: h.name + ' (' + h.label + ') — ' + (h.file || '').replace(CWD + '/', '') + ' (' + h.deg + ' connections)',
|
|
323
|
+
summary: 'Key codebase hub: ' + h.name + ' with ' + h.deg + ' dependencies',
|
|
324
|
+
confidence: 0.4,
|
|
325
|
+
files: h.file ? [h.file] : [],
|
|
326
|
+
ts: Date.now(),
|
|
327
|
+
});
|
|
328
|
+
added++;
|
|
329
|
+
}
|
|
330
|
+
if (added > 0) {
|
|
331
|
+
ensureDataDir();
|
|
332
|
+
try { fs.writeFileSync(STORE_FILE, JSON.stringify(_entries, null, 2), 'utf-8'); } catch (_) {}
|
|
333
|
+
}
|
|
334
|
+
return added;
|
|
335
|
+
} catch (_) { return 0; }
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
module.exports = { init, getContext, recordEdit, consolidate, feedback, stats, logTrajectory, storePattern, findSimilarPatterns, recordMemoryDecision, bootstrapFromDb };
|
|
@@ -1,53 +1,35 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
// monolean: 207-line protocol replaced with compact routing table.
|
|
3
|
+
// The enforcement prose, anti-drift guards, iron laws, and mandatory patterns
|
|
4
|
+
// are redundant with using-superpowers skill and add ~4K tokens per session.
|
|
5
|
+
// The routing table is the unique value — tells Claude which skill for which task.
|
|
6
|
+
// Full protocol loads on-demand via /mastermind.
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const masterPath = findMasterPath();
|
|
36
|
-
if (!masterPath) {
|
|
37
|
-
process.stderr.write('[mastermind-activate] master.md not found — skipping injection\n');
|
|
38
|
-
process.exit(0);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
let raw;
|
|
42
|
-
try {
|
|
43
|
-
raw = fs.readFileSync(masterPath, 'utf8');
|
|
44
|
-
} catch (e) {
|
|
45
|
-
process.stderr.write('[mastermind-activate] Could not read master.md: ' + e.message + '\n');
|
|
46
|
-
process.exit(0);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Strip YAML frontmatter
|
|
50
|
-
const body = raw.replace(/^---[\s\S]*?---\s*/, '');
|
|
51
|
-
const protocol = extractProtocol(body);
|
|
52
|
-
|
|
53
|
-
process.stdout.write(protocol + '\n');
|
|
8
|
+
process.stdout.write(
|
|
9
|
+
'## Mastermind Skill Router\n\n' +
|
|
10
|
+
'Invoke the matching skill BEFORE responding. If unsure, check — invoking and finding it irrelevant costs less than skipping it.\n\n' +
|
|
11
|
+
'| Task | Skill |\n|---|---|\n' +
|
|
12
|
+
'| Debug/fix bug | `mastermind:debug` |\n' +
|
|
13
|
+
'| Verify claim/test/fix | `mastermind:verify` |\n' +
|
|
14
|
+
'| TDD (red-green-refactor) | `mastermind:tdd` |\n' +
|
|
15
|
+
'| Write implementation plan | `mastermind:plan` |\n' +
|
|
16
|
+
'| Execute a plan | `mastermind:execute` |\n' +
|
|
17
|
+
'| Subagent-driven plan execution | `mastermind:taskdev` |\n' +
|
|
18
|
+
'| Ingest spec → agent tasks | `mastermind:createtask` |\n' +
|
|
19
|
+
'| Execute task file/board | `mastermind:do` |\n' +
|
|
20
|
+
'| Design before code | `mastermind:design` |\n' +
|
|
21
|
+
'| Build feature/fix | `mastermind:build` |\n' +
|
|
22
|
+
'| Code/content review | `mastermind:review` |\n' +
|
|
23
|
+
'| Apply received review | `mastermind:receive-review` |\n' +
|
|
24
|
+
'| Architecture/DDD | `mastermind:architect` |\n' +
|
|
25
|
+
'| Research/analysis | `mastermind:research` |\n' +
|
|
26
|
+
'| Ideation | `mastermind:idea` / `mastermind:ideate` |\n' +
|
|
27
|
+
'| Improvement analysis | `mastermind:improve` |\n' +
|
|
28
|
+
'| Marketing/sales/content | `mastermind:marketing` / `mastermind:sales` / `mastermind:content` |\n' +
|
|
29
|
+
'| Release/finish branch | `mastermind:release` / `mastermind:finish` |\n' +
|
|
30
|
+
'| Autonomous build+review | `mastermind:autodev` |\n' +
|
|
31
|
+
'| Isolated work | `mastermind:worktree` |\n' +
|
|
32
|
+
'| Brain/memory inspect | `mastermind:brain` |\n\n' +
|
|
33
|
+
'Process skills (debug, idea, architect, research) set the approach. Execution skills (build, review, release) carry it out.\n' +
|
|
34
|
+
'Subagents with `<SUBAGENT-STOP>` gate skip this routing.\n'
|
|
35
|
+
);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const { getDefaultMode, setMode, clearMode } = require('./monolean-config.cjs');
|
|
3
|
-
const { getMonoleanInstructions } = require('./monolean-instructions.cjs');
|
|
4
3
|
const fs = require('fs');
|
|
5
4
|
const path = require('path');
|
|
6
5
|
|
|
@@ -16,5 +15,16 @@ try {
|
|
|
16
15
|
fs.writeFileSync(path.join(metricsDir, 'monolean-mode.json'), JSON.stringify({ mode, ts: Date.now() }));
|
|
17
16
|
} catch {}
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
// monolean: compact session-start directive. The full SKILL.md loads on-demand
|
|
19
|
+
// via /monolean — session context just needs the core rules.
|
|
20
|
+
process.stdout.write(
|
|
21
|
+
'MONOLEAN MODE ACTIVE — level: ' + mode + '\n\n' +
|
|
22
|
+
'Lazy senior dev mode. Lazy = efficient. Best code = code never written.\n' +
|
|
23
|
+
'The ladder (stop at first rung that holds): ' +
|
|
24
|
+
'1) YAGNI 2) Already in codebase? Reuse 3) Stdlib 4) Native platform 5) Installed dep 6) One line 7) Minimum code.\n' +
|
|
25
|
+
'Read the code first, trace the real flow, THEN climb the ladder.\n' +
|
|
26
|
+
'Bug fix = root cause fix. No unrequested abstractions. Deletion > addition. Fewest files. Code first, 3 lines max explanation.\n' +
|
|
27
|
+
'Never lean away: trust-boundary validation, data-loss prevention, security, accessibility, explicit user requests.\n' +
|
|
28
|
+
'Mark deliberate simplifications: `// monolean: [ceiling] — [upgrade path]`\n' +
|
|
29
|
+
'Off: "stop monolean". Switch: `/monolean lite|full|ultra`.\n'
|
|
30
|
+
);
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const { readMode } = require('./monolean-config.cjs');
|
|
3
|
-
const { getMonoleanInstructions } = require('./monolean-instructions.cjs');
|
|
4
3
|
|
|
5
4
|
const mode = readMode();
|
|
6
5
|
if (!mode || mode === 'off') process.exit(0);
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
// monolean: full manifesto replaced with compact directive. Subagents get a
|
|
8
|
+
// focused task — they don't need 100 lines of philosophy to write lean code.
|
|
9
|
+
process.stdout.write(
|
|
10
|
+
'MONOLEAN MODE ACTIVE — level: ' + mode + '. ' +
|
|
11
|
+
'Write the minimum code that works. Stdlib over deps. Delete over add. ' +
|
|
12
|
+
'No unrequested abstractions, no scaffolding, no boilerplate.\n'
|
|
13
|
+
);
|
|
@@ -159,10 +159,27 @@ var MARKETING_OPTIN = /\b(marketing|seo|social media|advertising|campaign|conten
|
|
|
159
159
|
// ── Skills registry ────────────────────────────────────────────────────────────
|
|
160
160
|
|
|
161
161
|
var SKILLS = [
|
|
162
|
-
{ skill: 'mastermind', invoke: '/mastermind', description: 'Select swarm topology',
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
{ skill: '
|
|
162
|
+
{ skill: 'mastermind', invoke: '/mastermind', description: 'Select swarm topology',
|
|
163
|
+
keywords: /\b(swarm|topology|hive|mastermind|multi.agent)\b/ig,
|
|
164
|
+
_terms: ['swarm','topology','hive','mastermind','multi-agent','multi agent'] },
|
|
165
|
+
{ skill: 'monodesign', invoke: '/monodesign', description: 'Frontend design and UI',
|
|
166
|
+
keywords: /\b(design|ui|ux|component|visual|layout|css|theme)\b/ig,
|
|
167
|
+
_terms: ['design','ui','ux','component','visual','layout','css','theme'] },
|
|
168
|
+
{ skill: 'monomotion', invoke: '/monomotion', description: 'Web animations and motion',
|
|
169
|
+
keywords: /\b(animate|animation|motion|gsap|transition|scroll)\b/ig,
|
|
170
|
+
_terms: ['animate','animation','motion','gsap','transition','scroll'] },
|
|
171
|
+
{ skill: 'graphify', invoke: '/graphify', description: 'Input to knowledge graph',
|
|
172
|
+
keywords: /\b(graph|knowledge|monograph|node|edge|visualize)\b/ig,
|
|
173
|
+
_terms: ['graph','knowledge','monograph','node','edge','visualize'] },
|
|
174
|
+
{ skill: 'sparc', invoke: '/sparc', description: 'SPARC methodology',
|
|
175
|
+
keywords: /\b(sparc|specification|pseudocode|refinement|methodology)\b/ig,
|
|
176
|
+
_terms: ['sparc','specification','pseudocode','refinement','methodology'] },
|
|
177
|
+
{ skill: 'monobrowse', invoke: '/monobrowse', description: 'Browser automation via CDP',
|
|
178
|
+
keywords: /\b(browse|browser|webpage|screenshot|navigate|selenium|puppeteer|cdp)\b/ig,
|
|
179
|
+
_terms: ['browse','browser','webpage','screenshot','navigate','selenium','puppeteer','cdp'] },
|
|
180
|
+
{ skill: 'tokens', invoke: '/tokens', description: 'Token usage and cost tracking',
|
|
181
|
+
keywords: /\b(tokens|token.usage|cost|spending|budget)\b/ig,
|
|
182
|
+
_terms: ['tokens','token-usage','cost','spending','budget'] },
|
|
166
183
|
];
|
|
167
184
|
|
|
168
185
|
// ── Utilities ─────────────────────────────────────────────────────────────────
|
|
@@ -188,6 +205,9 @@ function routeTask(prompt) {
|
|
|
188
205
|
|
|
189
206
|
var safePrompt = prompt.slice(0, MAX_PROMPT);
|
|
190
207
|
|
|
208
|
+
// Skills are always checked — they're the primary value of routing now.
|
|
209
|
+
var skills = matchSkills(safePrompt);
|
|
210
|
+
|
|
191
211
|
// Check non-dev domain agents first (only if opt-in keywords match)
|
|
192
212
|
var extras = matchExtras(safePrompt);
|
|
193
213
|
if (extras.length > 0) {
|
|
@@ -199,18 +219,25 @@ function routeTask(prompt) {
|
|
|
199
219
|
reason: 'Domain: ' + topExtra.category,
|
|
200
220
|
semanticRouting: false,
|
|
201
221
|
specificAgents: extras,
|
|
202
|
-
skillMatches:
|
|
222
|
+
skillMatches: skills,
|
|
203
223
|
extrasMatches: extras,
|
|
204
224
|
};
|
|
205
225
|
}
|
|
206
226
|
|
|
227
|
+
// Check if a skill matched strongly (score >= 2) — if so, skip broad catch-all agents
|
|
228
|
+
var hasStrongSkill = false;
|
|
229
|
+
for (var si = 0; si < skills.length; si++) {
|
|
230
|
+
if (skills[si].score >= 2) { hasStrongSkill = true; break; }
|
|
231
|
+
}
|
|
232
|
+
|
|
207
233
|
// Check dev patterns in priority order
|
|
208
234
|
for (var i = 0; i < DEV_PRIORITY.length; i++) {
|
|
209
235
|
var slug = DEV_PRIORITY[i];
|
|
236
|
+
// Skip the broad "coder" catch-all when a specialized skill matched strongly
|
|
237
|
+
if (slug === 'coder' && hasStrongSkill) continue;
|
|
210
238
|
var pattern = _ROUTING_PATTERNS[slug];
|
|
211
239
|
if (pattern && pattern.test(safePrompt)) {
|
|
212
240
|
var confidence = TASK_CONFIDENCES[slug] || 0.75;
|
|
213
|
-
var skills = matchSkills(safePrompt);
|
|
214
241
|
return {
|
|
215
242
|
agent: TASK_AGENTS[slug],
|
|
216
243
|
agentSlug: slug,
|
|
@@ -232,7 +259,7 @@ function routeTask(prompt) {
|
|
|
232
259
|
reason: 'Default routing — no strong keyword match',
|
|
233
260
|
semanticRouting: false,
|
|
234
261
|
specificAgents: [],
|
|
235
|
-
skillMatches:
|
|
262
|
+
skillMatches: skills,
|
|
236
263
|
extrasMatches: [],
|
|
237
264
|
};
|
|
238
265
|
}
|
|
@@ -243,13 +270,24 @@ function matchSkills(prompt, topN) {
|
|
|
243
270
|
if (!prompt || typeof prompt !== 'string') return [];
|
|
244
271
|
topN = topN || 5;
|
|
245
272
|
var safePrompt = prompt.slice(0, MAX_PROMPT);
|
|
273
|
+
var promptLower = safePrompt.toLowerCase();
|
|
246
274
|
|
|
247
275
|
var scored = [];
|
|
248
276
|
for (var i = 0; i < SKILLS.length; i++) {
|
|
249
277
|
var s = SKILLS[i];
|
|
250
|
-
|
|
251
|
-
|
|
278
|
+
// Reset regex lastIndex (global flag) before testing
|
|
279
|
+
s.keywords.lastIndex = 0;
|
|
280
|
+
if (!s.keywords.test(safePrompt)) continue;
|
|
281
|
+
|
|
282
|
+
// Count distinct keyword hits for scoring
|
|
283
|
+
var hits = 0;
|
|
284
|
+
var terms = s._terms || [];
|
|
285
|
+
for (var t = 0; t < terms.length; t++) {
|
|
286
|
+
if (promptLower.indexOf(terms[t]) !== -1) hits++;
|
|
252
287
|
}
|
|
288
|
+
// Score: 1 base + 1 per additional keyword hit (min 1, max = term count)
|
|
289
|
+
var score = Math.max(1, hits);
|
|
290
|
+
scored.push({ skill: s.skill, invoke: s.invoke, description: s.description, score: score });
|
|
253
291
|
}
|
|
254
292
|
|
|
255
293
|
scored.sort(function(a, b) { return b.score - a.score; });
|
package/.claude/settings.json
CHANGED
|
@@ -108,16 +108,6 @@
|
|
|
108
108
|
}
|
|
109
109
|
]
|
|
110
110
|
},
|
|
111
|
-
{
|
|
112
|
-
"matcher": "Read",
|
|
113
|
-
"hooks": [
|
|
114
|
-
{
|
|
115
|
-
"type": "command",
|
|
116
|
-
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/hook-handler.cjs\" post-read",
|
|
117
|
-
"timeout": 4000
|
|
118
|
-
}
|
|
119
|
-
]
|
|
120
|
-
},
|
|
121
111
|
{
|
|
122
112
|
"matcher": "mcp__monomind__monograph_.*",
|
|
123
113
|
"hooks": [
|
|
@@ -200,11 +190,6 @@
|
|
|
200
190
|
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/hook-handler.cjs\" session-restore",
|
|
201
191
|
"timeout": 15000
|
|
202
192
|
},
|
|
203
|
-
{
|
|
204
|
-
"type": "command",
|
|
205
|
-
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/auto-memory-hook.mjs\" import",
|
|
206
|
-
"timeout": 8000
|
|
207
|
-
},
|
|
208
193
|
{
|
|
209
194
|
"type": "command",
|
|
210
195
|
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/graphify-freshen.cjs\"",
|
|
@@ -242,11 +227,6 @@
|
|
|
242
227
|
"Stop": [
|
|
243
228
|
{
|
|
244
229
|
"hooks": [
|
|
245
|
-
{
|
|
246
|
-
"type": "command",
|
|
247
|
-
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/auto-memory-hook.mjs\" sync",
|
|
248
|
-
"timeout": 10000
|
|
249
|
-
},
|
|
250
230
|
{
|
|
251
231
|
"type": "command",
|
|
252
232
|
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/helpers/event-logger.cjs\" stop",
|