monomind 1.11.13 → 1.11.14
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/commands/mastermind/idea.md +1 -1
- package/.claude/commands/mastermind/master.md +1 -1
- package/.claude/scheduled_tasks.lock +1 -1
- package/.claude/skills/mastermind/_protocol.md +4 -4
- package/.claude/skills/mastermind/architect.md +4 -7
- package/.claude/skills/mastermind/autodev.md +2 -4
- package/.claude/skills/mastermind/build.md +3 -3
- package/.claude/skills/mastermind/content.md +3 -3
- package/.claude/skills/mastermind/createorg.md +2 -2
- package/.claude/skills/mastermind/finance.md +3 -3
- package/.claude/skills/mastermind/idea.md +0 -8
- package/.claude/skills/mastermind/marketing.md +3 -3
- package/.claude/skills/mastermind/monitor.md +2 -2
- package/.claude/skills/mastermind/ops.md +3 -3
- package/.claude/skills/mastermind/release.md +3 -3
- package/.claude/skills/mastermind/research.md +3 -3
- package/.claude/skills/mastermind/review.md +3 -3
- package/.claude/skills/mastermind/sales.md +3 -3
- package/README.md +286 -129
- package/package.json +2 -2
- package/packages/@monomind/cli/README.md +286 -129
- package/packages/@monomind/cli/bundled-graph/dist/src/build.js +73 -0
- package/packages/@monomind/cli/bundled-graph/dist/src/cluster.js +120 -0
- package/packages/@monomind/cli/bundled-graph/package.json +57 -0
- package/packages/@monomind/cli/dist/src/agents/halt-signal.d.ts +25 -0
- package/packages/@monomind/cli/dist/src/agents/halt-signal.js +76 -0
- package/packages/@monomind/cli/dist/src/agents/index.d.ts +18 -0
- package/packages/@monomind/cli/dist/src/agents/index.js +13 -0
- package/packages/@monomind/cli/dist/src/agents/managed-agent.d.ts +41 -0
- package/packages/@monomind/cli/dist/src/agents/managed-agent.js +69 -0
- package/packages/@monomind/cli/dist/src/agents/prompt-experiment.d.ts +23 -0
- package/packages/@monomind/cli/dist/src/agents/prompt-experiment.js +49 -0
- package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.d.ts +22 -0
- package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.js +80 -0
- package/packages/@monomind/cli/dist/src/agents/registry-query.d.ts +71 -0
- package/packages/@monomind/cli/dist/src/agents/registry-query.js +125 -0
- package/packages/@monomind/cli/dist/src/agents/score-decay.d.ts +19 -0
- package/packages/@monomind/cli/dist/src/agents/score-decay.js +22 -0
- package/packages/@monomind/cli/dist/src/agents/shared-instructions-loader.d.ts +13 -0
- package/packages/@monomind/cli/dist/src/agents/shared-instructions-loader.js +40 -0
- package/packages/@monomind/cli/dist/src/agents/specialization-scorer.d.ts +54 -0
- package/packages/@monomind/cli/dist/src/agents/specialization-scorer.js +212 -0
- package/packages/@monomind/cli/dist/src/agents/termination-watcher.d.ts +30 -0
- package/packages/@monomind/cli/dist/src/agents/termination-watcher.js +84 -0
- package/packages/@monomind/cli/dist/src/agents/trigger-index.d.ts +20 -0
- package/packages/@monomind/cli/dist/src/agents/trigger-index.js +38 -0
- package/packages/@monomind/cli/dist/src/agents/trigger-scanner.d.ts +64 -0
- package/packages/@monomind/cli/dist/src/agents/trigger-scanner.js +308 -0
- package/packages/@monomind/cli/dist/src/agents/version-diff.d.ts +18 -0
- package/packages/@monomind/cli/dist/src/agents/version-diff.js +64 -0
- package/packages/@monomind/cli/dist/src/agents/version-store.d.ts +60 -0
- package/packages/@monomind/cli/dist/src/agents/version-store.js +235 -0
- package/packages/@monomind/cli/dist/src/benchmarks/pretrain/index.d.ts +45 -0
- package/packages/@monomind/cli/dist/src/benchmarks/pretrain/index.js +404 -0
- package/packages/@monomind/cli/dist/src/commands/agent-wasm.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/agent-wasm.js +333 -0
- package/packages/@monomind/cli/dist/src/commands/doctor.js +55 -1
- package/packages/@monomind/cli/dist/src/commands/ui.js +68 -0
- package/packages/@monomind/cli/dist/src/consensus/index.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/consensus/index.js +6 -0
- package/packages/@monomind/cli/dist/src/context/context-provider.d.ts +44 -0
- package/packages/@monomind/cli/dist/src/context/context-provider.js +25 -0
- package/packages/@monomind/cli/dist/src/context/git-state-provider.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/context/git-state-provider.js +34 -0
- package/packages/@monomind/cli/dist/src/context/index.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/context/index.js +12 -0
- package/packages/@monomind/cli/dist/src/context/project-conventions-provider.d.ts +15 -0
- package/packages/@monomind/cli/dist/src/context/project-conventions-provider.js +19 -0
- package/packages/@monomind/cli/dist/src/context/prompt-assembler.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/context/prompt-assembler.js +93 -0
- package/packages/@monomind/cli/dist/src/context/task-history-provider.d.ts +24 -0
- package/packages/@monomind/cli/dist/src/context/task-history-provider.js +32 -0
- package/packages/@monomind/cli/dist/src/context/user-preferences-provider.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/context/user-preferences-provider.js +27 -0
- package/packages/@monomind/cli/dist/src/dlq/dlq-reader.d.ts +31 -0
- package/packages/@monomind/cli/dist/src/dlq/dlq-reader.js +81 -0
- package/packages/@monomind/cli/dist/src/dlq/dlq-writer.d.ts +24 -0
- package/packages/@monomind/cli/dist/src/dlq/dlq-writer.js +65 -0
- package/packages/@monomind/cli/dist/src/dlq/index.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/dlq/index.js +7 -0
- package/packages/@monomind/cli/dist/src/eval/dataset-manager.d.ts +33 -0
- package/packages/@monomind/cli/dist/src/eval/dataset-manager.js +107 -0
- package/packages/@monomind/cli/dist/src/eval/dataset-runner.d.ts +23 -0
- package/packages/@monomind/cli/dist/src/eval/dataset-runner.js +59 -0
- package/packages/@monomind/cli/dist/src/eval/index.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/eval/index.js +7 -0
- package/packages/@monomind/cli/dist/src/eval/trace-collector.d.ts +40 -0
- package/packages/@monomind/cli/dist/src/eval/trace-collector.js +102 -0
- package/packages/@monomind/cli/dist/src/infrastructure/in-memory-repositories.d.ts +68 -0
- package/packages/@monomind/cli/dist/src/infrastructure/in-memory-repositories.js +264 -0
- package/packages/@monomind/cli/dist/src/init/statusline-generator.js +3 -3
- package/packages/@monomind/cli/dist/src/interactive/interrupt.d.ts +22 -0
- package/packages/@monomind/cli/dist/src/interactive/interrupt.js +71 -0
- package/packages/@monomind/cli/dist/src/mcp/deprecation-injector.d.ts +25 -0
- package/packages/@monomind/cli/dist/src/mcp/deprecation-injector.js +48 -0
- package/packages/@monomind/cli/dist/src/mcp/tool-registry.d.ts +61 -0
- package/packages/@monomind/cli/dist/src/mcp/tool-registry.js +246 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/wasm-agent-tools.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/wasm-agent-tools.js +230 -0
- package/packages/@monomind/cli/dist/src/model/complexity-scorer.d.ts +21 -0
- package/packages/@monomind/cli/dist/src/model/complexity-scorer.js +106 -0
- package/packages/@monomind/cli/dist/src/model/index.d.ts +4 -0
- package/packages/@monomind/cli/dist/src/model/index.js +4 -0
- package/packages/@monomind/cli/dist/src/model/model-settings.d.ts +22 -0
- package/packages/@monomind/cli/dist/src/model/model-settings.js +33 -0
- package/packages/@monomind/cli/dist/src/model/model-tier-resolver.d.ts +24 -0
- package/packages/@monomind/cli/dist/src/model/model-tier-resolver.js +65 -0
- package/packages/@monomind/cli/dist/src/monovector/capabilities.d.ts +34 -0
- package/packages/@monomind/cli/dist/src/monovector/capabilities.js +37 -0
- package/packages/@monomind/cli/dist/src/observability/replay-reader.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/orchestration/index.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/orchestration/index.js +6 -0
- package/packages/@monomind/cli/dist/src/orchestration/mode-dispatcher.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/orchestration/mode-dispatcher.js +31 -0
- package/packages/@monomind/cli/dist/src/orchestration/routing-modes.d.ts +68 -0
- package/packages/@monomind/cli/dist/src/orchestration/routing-modes.js +180 -0
- package/packages/@monomind/cli/dist/src/plugins/tests/demo-plugin-store.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/plugins/tests/demo-plugin-store.js +126 -0
- package/packages/@monomind/cli/dist/src/plugins/tests/standalone-test.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/plugins/tests/standalone-test.js +188 -0
- package/packages/@monomind/cli/dist/src/plugins/tests/test-plugin-store.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/plugins/tests/test-plugin-store.js +206 -0
- package/packages/@monomind/cli/dist/src/runtime/headless.d.ts +60 -0
- package/packages/@monomind/cli/dist/src/runtime/headless.js +284 -0
- package/packages/@monomind/cli/dist/src/services/agentic-flow-bridge.d.ts +50 -0
- package/packages/@monomind/cli/dist/src/services/agentic-flow-bridge.js +95 -0
- package/packages/@monomind/cli/dist/src/services/container-worker-pool.d.ts +197 -0
- package/packages/@monomind/cli/dist/src/services/container-worker-pool.js +623 -0
- package/packages/@monomind/cli/dist/src/services/index.d.ts +13 -0
- package/packages/@monomind/cli/dist/src/services/index.js +11 -0
- package/packages/@monomind/cli/dist/src/services/worker-queue.d.ts +201 -0
- package/packages/@monomind/cli/dist/src/services/worker-queue.js +594 -0
- package/packages/@monomind/cli/dist/src/swarm/communication-graph.d.ts +25 -0
- package/packages/@monomind/cli/dist/src/swarm/communication-graph.js +77 -0
- package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.d.ts +31 -0
- package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.js +61 -0
- package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.d.ts +19 -0
- package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.js +68 -0
- package/packages/@monomind/cli/dist/src/transfer/deploy-seraphine.d.ts +13 -0
- package/packages/@monomind/cli/dist/src/transfer/deploy-seraphine.js +205 -0
- package/packages/@monomind/cli/dist/src/transfer/store/tests/standalone-test.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/transfer/store/tests/standalone-test.js +190 -0
- package/packages/@monomind/cli/dist/src/transfer/test-seraphine.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/transfer/test-seraphine.js +105 -0
- package/packages/@monomind/cli/dist/src/transfer/tests/test-store.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/transfer/tests/test-store.js +214 -0
- package/packages/@monomind/cli/dist/src/workflow/condition-evaluator.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/workflow/condition-evaluator.js +82 -0
- package/packages/@monomind/cli/dist/src/workflow/context-resolver.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/workflow/context-resolver.js +23 -0
- package/packages/@monomind/cli/dist/src/workflow/dag-builder.d.ts +17 -0
- package/packages/@monomind/cli/dist/src/workflow/dag-builder.js +129 -0
- package/packages/@monomind/cli/dist/src/workflow/dag-executor.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/workflow/dag-executor.js +116 -0
- package/packages/@monomind/cli/dist/src/workflow/dag-types.d.ts +41 -0
- package/packages/@monomind/cli/dist/src/workflow/dag-types.js +8 -0
- package/packages/@monomind/cli/dist/src/workflow/dsl-parser.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/workflow/dsl-parser.js +20 -0
- package/packages/@monomind/cli/dist/src/workflow/dsl-schema.d.ts +165 -0
- package/packages/@monomind/cli/dist/src/workflow/dsl-schema.js +82 -0
- package/packages/@monomind/cli/dist/src/workflow/index.d.ts +13 -0
- package/packages/@monomind/cli/dist/src/workflow/index.js +11 -0
- package/packages/@monomind/cli/dist/src/workflow/template-engine.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/workflow/template-engine.js +40 -0
- package/packages/@monomind/cli/dist/src/workflow/workflow-executor.d.ts +29 -0
- package/packages/@monomind/cli/dist/src/workflow/workflow-executor.js +227 -0
- package/packages/@monomind/cli/package.json +9 -9
- package/packages/@monomind/guidance/dist/adversarial.d.ts +284 -0
- package/packages/@monomind/guidance/dist/adversarial.js +572 -0
- package/packages/@monomind/guidance/dist/analyzer.d.ts +530 -0
- package/packages/@monomind/guidance/dist/analyzer.js +2518 -0
- package/packages/@monomind/guidance/dist/artifacts.d.ts +283 -0
- package/packages/@monomind/guidance/dist/artifacts.js +356 -0
- package/packages/@monomind/guidance/dist/authority.d.ts +290 -0
- package/packages/@monomind/guidance/dist/authority.js +558 -0
- package/packages/@monomind/guidance/dist/capabilities.d.ts +209 -0
- package/packages/@monomind/guidance/dist/capabilities.js +485 -0
- package/packages/@monomind/guidance/dist/coherence.d.ts +233 -0
- package/packages/@monomind/guidance/dist/coherence.js +372 -0
- package/packages/@monomind/guidance/dist/compiler.d.ts +87 -0
- package/packages/@monomind/guidance/dist/compiler.js +419 -0
- package/packages/@monomind/guidance/dist/conformance-kit.d.ts +225 -0
- package/packages/@monomind/guidance/dist/conformance-kit.js +629 -0
- package/packages/@monomind/guidance/dist/continue-gate.d.ts +214 -0
- package/packages/@monomind/guidance/dist/continue-gate.js +353 -0
- package/packages/@monomind/guidance/dist/crypto-utils.d.ts +17 -0
- package/packages/@monomind/guidance/dist/crypto-utils.js +24 -0
- package/packages/@monomind/guidance/dist/evolution.d.ts +282 -0
- package/packages/@monomind/guidance/dist/evolution.js +500 -0
- package/packages/@monomind/guidance/dist/gates.d.ts +79 -0
- package/packages/@monomind/guidance/dist/gates.js +302 -0
- package/packages/@monomind/guidance/dist/gateway.d.ts +206 -0
- package/packages/@monomind/guidance/dist/gateway.js +452 -0
- package/packages/@monomind/guidance/dist/generators.d.ts +153 -0
- package/packages/@monomind/guidance/dist/generators.js +682 -0
- package/packages/@monomind/guidance/dist/headless.d.ts +177 -0
- package/packages/@monomind/guidance/dist/headless.js +342 -0
- package/packages/@monomind/guidance/dist/hooks.d.ts +109 -0
- package/packages/@monomind/guidance/dist/hooks.js +347 -0
- package/packages/@monomind/guidance/dist/index.d.ts +205 -0
- package/packages/@monomind/guidance/dist/index.js +321 -0
- package/packages/@monomind/guidance/dist/ledger.d.ts +162 -0
- package/packages/@monomind/guidance/dist/ledger.js +375 -0
- package/packages/@monomind/guidance/dist/manifest-validator.d.ts +289 -0
- package/packages/@monomind/guidance/dist/manifest-validator.js +838 -0
- package/packages/@monomind/guidance/dist/memory-gate.d.ts +222 -0
- package/packages/@monomind/guidance/dist/memory-gate.js +382 -0
- package/packages/@monomind/guidance/dist/meta-governance.d.ts +265 -0
- package/packages/@monomind/guidance/dist/meta-governance.js +348 -0
- package/packages/@monomind/guidance/dist/optimizer.d.ts +104 -0
- package/packages/@monomind/guidance/dist/optimizer.js +329 -0
- package/packages/@monomind/guidance/dist/persistence.d.ts +189 -0
- package/packages/@monomind/guidance/dist/persistence.js +464 -0
- package/packages/@monomind/guidance/dist/proof.d.ts +185 -0
- package/packages/@monomind/guidance/dist/proof.js +238 -0
- package/packages/@monomind/guidance/dist/retriever.d.ts +116 -0
- package/packages/@monomind/guidance/dist/retriever.js +394 -0
- package/packages/@monomind/guidance/dist/ruvbot-integration.d.ts +370 -0
- package/packages/@monomind/guidance/dist/ruvbot-integration.js +738 -0
- package/packages/@monomind/guidance/dist/temporal.d.ts +426 -0
- package/packages/@monomind/guidance/dist/temporal.js +658 -0
- package/packages/@monomind/guidance/dist/trust.d.ts +283 -0
- package/packages/@monomind/guidance/dist/trust.js +473 -0
- package/packages/@monomind/guidance/dist/truth-anchors.d.ts +276 -0
- package/packages/@monomind/guidance/dist/truth-anchors.js +488 -0
- package/packages/@monomind/guidance/dist/types.d.ts +378 -0
- package/packages/@monomind/guidance/dist/types.js +10 -0
- package/packages/@monomind/guidance/dist/uncertainty.d.ts +372 -0
- package/packages/@monomind/guidance/dist/uncertainty.js +619 -0
- package/packages/@monomind/guidance/dist/wasm-kernel.d.ts +48 -0
- package/packages/@monomind/guidance/dist/wasm-kernel.js +158 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import Graph from 'graphology';
|
|
2
|
+
export async function detectCommunities(graph) {
|
|
3
|
+
let louvainFn = null;
|
|
4
|
+
try {
|
|
5
|
+
const mod = await import('graphology-communities-louvain');
|
|
6
|
+
louvainFn = mod.default;
|
|
7
|
+
}
|
|
8
|
+
catch { /* louvain not available */ }
|
|
9
|
+
if (louvainFn) {
|
|
10
|
+
try {
|
|
11
|
+
const assignment = louvainFn(graph);
|
|
12
|
+
for (const [nodeId, communityId] of Object.entries(assignment)) {
|
|
13
|
+
graph.setNodeAttribute(nodeId, 'community', communityId);
|
|
14
|
+
}
|
|
15
|
+
const communities = {};
|
|
16
|
+
for (const [nodeId, communityId] of Object.entries(assignment)) {
|
|
17
|
+
if (!communities[communityId])
|
|
18
|
+
communities[communityId] = [];
|
|
19
|
+
communities[communityId].push(nodeId);
|
|
20
|
+
}
|
|
21
|
+
return splitOversizedCommunities(graph, communities, 0.25, louvainFn);
|
|
22
|
+
}
|
|
23
|
+
catch { /* fall through */ }
|
|
24
|
+
}
|
|
25
|
+
return splitOversizedCommunities(graph, fallbackCluster(graph), 0.25, louvainFn);
|
|
26
|
+
}
|
|
27
|
+
function fallbackCluster(graph) {
|
|
28
|
+
const dirMap = new Map();
|
|
29
|
+
let nextId = 0;
|
|
30
|
+
const communities = {};
|
|
31
|
+
graph.forEachNode((id, attrs) => {
|
|
32
|
+
const file = attrs.sourceFile || '';
|
|
33
|
+
const parts = file.split('/');
|
|
34
|
+
const dir = parts.length > 1 ? parts.slice(0, -1).join('/') : 'root';
|
|
35
|
+
if (!dirMap.has(dir))
|
|
36
|
+
dirMap.set(dir, nextId++);
|
|
37
|
+
const cid = dirMap.get(dir);
|
|
38
|
+
graph.setNodeAttribute(id, 'community', cid);
|
|
39
|
+
if (!communities[cid])
|
|
40
|
+
communities[cid] = [];
|
|
41
|
+
communities[cid].push(id);
|
|
42
|
+
});
|
|
43
|
+
return communities;
|
|
44
|
+
}
|
|
45
|
+
export function cohesionScore(graph, communityNodes) {
|
|
46
|
+
const memberSet = new Set(communityNodes);
|
|
47
|
+
let totalEdges = 0;
|
|
48
|
+
let internalEdges = 0;
|
|
49
|
+
graph.forEachEdge((_edge, _attrs, source, target) => {
|
|
50
|
+
const srcIn = memberSet.has(source);
|
|
51
|
+
const tgtIn = memberSet.has(target);
|
|
52
|
+
if (srcIn || tgtIn) {
|
|
53
|
+
totalEdges++;
|
|
54
|
+
if (srcIn && tgtIn)
|
|
55
|
+
internalEdges++;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return totalEdges === 0 ? 1.0 : internalEdges / totalEdges;
|
|
59
|
+
}
|
|
60
|
+
export function splitOversizedCommunities(graph, communities, threshold = 0.25, louvainFn = null) {
|
|
61
|
+
const maxSize = threshold * graph.order;
|
|
62
|
+
const allIds = Object.keys(communities).map(Number);
|
|
63
|
+
let nextId = allIds.length > 0 ? Math.max(...allIds) + 1 : 0;
|
|
64
|
+
for (const [cidStr, members] of Object.entries(communities)) {
|
|
65
|
+
if (members.length <= maxSize)
|
|
66
|
+
continue;
|
|
67
|
+
const cid = Number(cidStr);
|
|
68
|
+
// Attempt topology-based second pass via Louvain on the community subgraph
|
|
69
|
+
if (louvainFn && members.length >= 10) {
|
|
70
|
+
try {
|
|
71
|
+
const memberSet = new Set(members);
|
|
72
|
+
const subG = new Graph({ type: 'undirected', multi: false });
|
|
73
|
+
for (const nodeId of members)
|
|
74
|
+
subG.addNode(nodeId);
|
|
75
|
+
graph.forEachEdge((_e, _a, source, target) => {
|
|
76
|
+
if (memberSet.has(source) && memberSet.has(target) && source !== target && !subG.hasEdge(source, target))
|
|
77
|
+
subG.addEdge(source, target);
|
|
78
|
+
});
|
|
79
|
+
const subAssignment = louvainFn(subG);
|
|
80
|
+
const subCommunityCount = new Set(Object.values(subAssignment)).size;
|
|
81
|
+
if (subCommunityCount > 1 && subCommunityCount <= Math.ceil(members.length / 2)) {
|
|
82
|
+
const subIdMap = new Map();
|
|
83
|
+
const newSubIds = {};
|
|
84
|
+
for (const [nodeId, localId] of Object.entries(subAssignment)) {
|
|
85
|
+
if (!subIdMap.has(localId))
|
|
86
|
+
subIdMap.set(localId, nextId++);
|
|
87
|
+
const globalId = subIdMap.get(localId);
|
|
88
|
+
graph.setNodeAttribute(nodeId, 'community', globalId);
|
|
89
|
+
if (!newSubIds[globalId])
|
|
90
|
+
newSubIds[globalId] = [];
|
|
91
|
+
newSubIds[globalId].push(nodeId);
|
|
92
|
+
}
|
|
93
|
+
delete communities[cid];
|
|
94
|
+
Object.assign(communities, newSubIds);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch { /* fall through to directory heuristic */ }
|
|
99
|
+
}
|
|
100
|
+
// Directory heuristic fallback
|
|
101
|
+
const subMap = new Map();
|
|
102
|
+
const newSubIds = {};
|
|
103
|
+
for (const nodeId of members) {
|
|
104
|
+
const file = graph.getNodeAttribute(nodeId, 'sourceFile') || '';
|
|
105
|
+
const parts = file.split('/');
|
|
106
|
+
const parentDir = parts.length > 1 ? parts[parts.length - 2] : 'root';
|
|
107
|
+
if (!subMap.has(parentDir))
|
|
108
|
+
subMap.set(parentDir, nextId++);
|
|
109
|
+
const subId = subMap.get(parentDir);
|
|
110
|
+
graph.setNodeAttribute(nodeId, 'community', subId);
|
|
111
|
+
if (!newSubIds[subId])
|
|
112
|
+
newSubIds[subId] = [];
|
|
113
|
+
newSubIds[subId].push(nodeId);
|
|
114
|
+
}
|
|
115
|
+
delete communities[cid];
|
|
116
|
+
Object.assign(communities, newSubIds);
|
|
117
|
+
}
|
|
118
|
+
return communities;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=cluster.js.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@monomind/graph",
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Knowledge graph engine for monomind — AST extraction, graph construction, community detection, and persistent codebase understanding",
|
|
6
|
+
"main": "./dist/src/index.js",
|
|
7
|
+
"types": "./dist/src/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/src/index.d.ts",
|
|
11
|
+
"import": "./dist/src/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"clean": "rm -rf dist"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"graphology": "^0.25.4",
|
|
25
|
+
"graphology-types": "^0.24.7",
|
|
26
|
+
"graphology-communities-louvain": "^2.0.1",
|
|
27
|
+
"graphology-shortest-path": "^2.0.2",
|
|
28
|
+
"graphology-traversal": "^0.3.1",
|
|
29
|
+
"graphology-metrics": "^2.4.0",
|
|
30
|
+
"chokidar": "^3.6.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.0.0",
|
|
34
|
+
"typescript": "^5.3.0",
|
|
35
|
+
"vitest": "^4.1.4"
|
|
36
|
+
},
|
|
37
|
+
"optionalDependencies": {
|
|
38
|
+
"node-tree-sitter": "^0.22.4",
|
|
39
|
+
"tree-sitter-typescript": "^0.23.2",
|
|
40
|
+
"tree-sitter-javascript": "^0.23.1",
|
|
41
|
+
"tree-sitter-python": "^0.23.6",
|
|
42
|
+
"tree-sitter-go": "^0.23.4",
|
|
43
|
+
"tree-sitter-rust": "^0.23.2",
|
|
44
|
+
"tree-sitter-java": "^0.23.5",
|
|
45
|
+
"tree-sitter-c": "^0.23.4",
|
|
46
|
+
"tree-sitter-cpp": "^0.23.4",
|
|
47
|
+
"tree-sitter-ruby": "^0.23.1",
|
|
48
|
+
"tree-sitter-c-sharp": "^0.23.1",
|
|
49
|
+
"tree-sitter-kotlin": "^0.3.9",
|
|
50
|
+
"tree-sitter-swift": "^0.6.1",
|
|
51
|
+
"tree-sitter-scala": "^0.23.4",
|
|
52
|
+
"tree-sitter-php": "^0.23.11"
|
|
53
|
+
},
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Halt Signal (Task 35)
|
|
3
|
+
*
|
|
4
|
+
* JSONL-based broadcast/check for swarm-level halt signals.
|
|
5
|
+
* When an agent triggers a cascade halt, other agents in the same swarm
|
|
6
|
+
* can query whether a halt has been issued.
|
|
7
|
+
*/
|
|
8
|
+
import type { TerminationReason } from '../../../shared/src/types/termination.js';
|
|
9
|
+
/** Record written to the JSONL halt log. */
|
|
10
|
+
export interface HaltRecord {
|
|
11
|
+
id: string;
|
|
12
|
+
swarmId: string;
|
|
13
|
+
sourceAgentId: string;
|
|
14
|
+
reason: TerminationReason;
|
|
15
|
+
haltedAt: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Broadcast a halt signal for a swarm.
|
|
19
|
+
*/
|
|
20
|
+
export declare function broadcast(swarmId: string, sourceAgentId: string, reason: TerminationReason, filePath?: string): HaltRecord;
|
|
21
|
+
/**
|
|
22
|
+
* Check whether any halt signal exists for the given swarm.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isHalted(swarmId: string, filePath?: string): boolean;
|
|
25
|
+
//# sourceMappingURL=halt-signal.d.ts.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Halt Signal (Task 35)
|
|
3
|
+
*
|
|
4
|
+
* JSONL-based broadcast/check for swarm-level halt signals.
|
|
5
|
+
* When an agent triggers a cascade halt, other agents in the same swarm
|
|
6
|
+
* can query whether a halt has been issued.
|
|
7
|
+
*/
|
|
8
|
+
import { randomUUID } from 'crypto';
|
|
9
|
+
import { existsSync, mkdirSync, appendFileSync, readFileSync, statSync } from 'fs';
|
|
10
|
+
import { join, dirname, resolve, sep } from 'path';
|
|
11
|
+
const ALLOWED_ROOT = () => resolve(process.env.MONOMIND_DATA_DIR ?? process.cwd());
|
|
12
|
+
const DEFAULT_FILE = () => join(ALLOWED_ROOT(), 'data', 'halt-signals.jsonl');
|
|
13
|
+
function safeHaltFilePath(filePath) {
|
|
14
|
+
const allowedRoot = ALLOWED_ROOT();
|
|
15
|
+
const resolved = resolve(filePath);
|
|
16
|
+
if (resolved !== allowedRoot && !resolved.startsWith(allowedRoot + sep)) {
|
|
17
|
+
throw new Error(`Halt signal file path escapes allowed directory: ${filePath}`);
|
|
18
|
+
}
|
|
19
|
+
return resolved;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Broadcast a halt signal for a swarm.
|
|
23
|
+
*/
|
|
24
|
+
export function broadcast(swarmId, sourceAgentId, reason, filePath) {
|
|
25
|
+
const target = filePath ? safeHaltFilePath(filePath) : DEFAULT_FILE();
|
|
26
|
+
const dir = dirname(target);
|
|
27
|
+
if (!existsSync(dir)) {
|
|
28
|
+
mkdirSync(dir, { recursive: true });
|
|
29
|
+
}
|
|
30
|
+
const record = {
|
|
31
|
+
id: randomUUID(),
|
|
32
|
+
swarmId,
|
|
33
|
+
sourceAgentId,
|
|
34
|
+
reason,
|
|
35
|
+
haltedAt: new Date().toISOString(),
|
|
36
|
+
};
|
|
37
|
+
appendFileSync(target, JSON.stringify(record) + '\n', 'utf-8');
|
|
38
|
+
return record;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check whether any halt signal exists for the given swarm.
|
|
42
|
+
*/
|
|
43
|
+
export function isHalted(swarmId, filePath) {
|
|
44
|
+
const target = filePath ? safeHaltFilePath(filePath) : DEFAULT_FILE();
|
|
45
|
+
if (!existsSync(target)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
// Size cap. isHalted is on the swarm-coordination hot path; without this
|
|
49
|
+
// cap a planted multi-GB file (or unbounded broadcast accumulation over
|
|
50
|
+
// weeks) reliably OOMs the CLI on the next call. Treat oversized halt
|
|
51
|
+
// logs as "no halt" — fail-safe in the swarm-termination flow.
|
|
52
|
+
try {
|
|
53
|
+
const stat = statSync(target);
|
|
54
|
+
if (stat.size > 10 * 1024 * 1024)
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const raw = readFileSync(target, 'utf-8').trim();
|
|
61
|
+
if (!raw)
|
|
62
|
+
return false;
|
|
63
|
+
return raw
|
|
64
|
+
.split('\n')
|
|
65
|
+
.filter(Boolean)
|
|
66
|
+
.some((line) => {
|
|
67
|
+
try {
|
|
68
|
+
const rec = JSON.parse(line);
|
|
69
|
+
return rec.swarmId === swarmId;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=halt-signal.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent utilities — prompt versioning, experiment routing, managed agents.
|
|
3
|
+
*
|
|
4
|
+
* @module @monoes/cli/agents
|
|
5
|
+
*/
|
|
6
|
+
export { PromptExperimentRouter } from './prompt-experiment.js';
|
|
7
|
+
export type { ResolvedPrompt } from './prompt-experiment.js';
|
|
8
|
+
export { PromptVersionManager } from './prompt-version-manager.js';
|
|
9
|
+
export { spawnAndAwait } from './managed-agent.js';
|
|
10
|
+
export type { AgentRunResult, ManagedAgentOptions } from './managed-agent.js';
|
|
11
|
+
export { check as checkTermination, persistEvent } from './termination-watcher.js';
|
|
12
|
+
export type { AgentRunState } from './termination-watcher.js';
|
|
13
|
+
export { broadcast as broadcastHalt, isHalted } from './halt-signal.js';
|
|
14
|
+
export type { HaltRecord } from './halt-signal.js';
|
|
15
|
+
export { buildRegistry } from './registry-builder.js';
|
|
16
|
+
export { RegistryQuery } from './registry-query.js';
|
|
17
|
+
export type { RegistryValidationResult, RegistryConflict } from './registry-query.js';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent utilities — prompt versioning, experiment routing, managed agents.
|
|
3
|
+
*
|
|
4
|
+
* @module @monoes/cli/agents
|
|
5
|
+
*/
|
|
6
|
+
export { PromptExperimentRouter } from './prompt-experiment.js';
|
|
7
|
+
export { PromptVersionManager } from './prompt-version-manager.js';
|
|
8
|
+
export { spawnAndAwait } from './managed-agent.js';
|
|
9
|
+
export { check as checkTermination, persistEvent } from './termination-watcher.js';
|
|
10
|
+
export { broadcast as broadcastHalt, isHalted } from './halt-signal.js';
|
|
11
|
+
export { buildRegistry } from './registry-builder.js';
|
|
12
|
+
export { RegistryQuery } from './registry-query.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface AgentRunResult {
|
|
2
|
+
agentSlug: string;
|
|
3
|
+
taskId: string;
|
|
4
|
+
output: string;
|
|
5
|
+
status: 'success' | 'error' | 'timeout';
|
|
6
|
+
durationMs: number;
|
|
7
|
+
tokens?: {
|
|
8
|
+
inputTokens: number;
|
|
9
|
+
outputTokens: number;
|
|
10
|
+
};
|
|
11
|
+
error?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ManagedAgentOptions {
|
|
14
|
+
timeoutMs?: number;
|
|
15
|
+
pollIntervalMs?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Simulates spawn-and-await by creating a taskId, delegating to a runner function,
|
|
19
|
+
* and applying timeout.
|
|
20
|
+
*/
|
|
21
|
+
export declare function spawnAndAwait(agentSlug: string, task: string, runner: (agentSlug: string, taskId: string, task: string) => Promise<string>, options?: ManagedAgentOptions): Promise<AgentRunResult>;
|
|
22
|
+
export declare class ManagedAgent {
|
|
23
|
+
private readonly agentSlug;
|
|
24
|
+
private readonly runner;
|
|
25
|
+
private readonly options;
|
|
26
|
+
constructor(agentSlug: string, runner: (agentSlug: string, taskId: string, task: string) => Promise<string>, options?: ManagedAgentOptions);
|
|
27
|
+
run(task: string): Promise<AgentRunResult>;
|
|
28
|
+
/** Generate an MCP-style tool descriptor for this agent */
|
|
29
|
+
toToolDescriptor(): {
|
|
30
|
+
name: string;
|
|
31
|
+
description: string;
|
|
32
|
+
inputSchema: Record<string, unknown>;
|
|
33
|
+
};
|
|
34
|
+
static create(agentSlug: string, runner: (slug: string, id: string, task: string) => Promise<string>, options?: ManagedAgentOptions): ManagedAgent;
|
|
35
|
+
}
|
|
36
|
+
/** Run multiple agents in parallel */
|
|
37
|
+
export declare function runBatch(agents: Array<{
|
|
38
|
+
agentSlug: string;
|
|
39
|
+
task: string;
|
|
40
|
+
}>, runner: (agentSlug: string, taskId: string, task: string) => Promise<string>, options?: ManagedAgentOptions): Promise<AgentRunResult[]>;
|
|
41
|
+
//# sourceMappingURL=managed-agent.d.ts.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Simulates spawn-and-await by creating a taskId, delegating to a runner function,
|
|
4
|
+
* and applying timeout.
|
|
5
|
+
*/
|
|
6
|
+
export async function spawnAndAwait(agentSlug, task, runner, options = {}) {
|
|
7
|
+
const { timeoutMs = 120_000 } = options;
|
|
8
|
+
const startedAt = Date.now();
|
|
9
|
+
const taskId = `managed-${Date.now().toString(36)}-${randomBytes(4).toString('hex')}`;
|
|
10
|
+
try {
|
|
11
|
+
let timeoutHandle;
|
|
12
|
+
const output = await Promise.race([
|
|
13
|
+
runner(agentSlug, taskId, task),
|
|
14
|
+
new Promise((_, reject) => {
|
|
15
|
+
timeoutHandle = setTimeout(() => reject(new Error(`Timeout after ${timeoutMs}ms`)), timeoutMs);
|
|
16
|
+
}),
|
|
17
|
+
]).finally(() => clearTimeout(timeoutHandle));
|
|
18
|
+
return {
|
|
19
|
+
agentSlug, taskId, output, status: 'success',
|
|
20
|
+
durationMs: Date.now() - startedAt,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
const isTimeout = String(err).includes('Timeout');
|
|
25
|
+
return {
|
|
26
|
+
agentSlug, taskId, output: '',
|
|
27
|
+
status: isTimeout ? 'timeout' : 'error',
|
|
28
|
+
durationMs: Date.now() - startedAt,
|
|
29
|
+
error: String(err),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class ManagedAgent {
|
|
34
|
+
agentSlug;
|
|
35
|
+
runner;
|
|
36
|
+
options;
|
|
37
|
+
constructor(agentSlug, runner, options = {}) {
|
|
38
|
+
this.agentSlug = agentSlug;
|
|
39
|
+
this.runner = runner;
|
|
40
|
+
this.options = options;
|
|
41
|
+
}
|
|
42
|
+
async run(task) {
|
|
43
|
+
return spawnAndAwait(this.agentSlug, task, this.runner, this.options);
|
|
44
|
+
}
|
|
45
|
+
/** Generate an MCP-style tool descriptor for this agent */
|
|
46
|
+
toToolDescriptor() {
|
|
47
|
+
const toolName = `agent_${this.agentSlug.replace(/-/g, '_')}`;
|
|
48
|
+
return {
|
|
49
|
+
name: toolName,
|
|
50
|
+
description: `Delegate a task to the ${this.agentSlug} specialist agent`,
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: 'object',
|
|
53
|
+
properties: {
|
|
54
|
+
task: { type: 'string', description: 'Task description' },
|
|
55
|
+
timeoutMs: { type: 'number', description: 'Timeout in ms (default 120000)' },
|
|
56
|
+
},
|
|
57
|
+
required: ['task'],
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
static create(agentSlug, runner, options) {
|
|
62
|
+
return new ManagedAgent(agentSlug, runner, options);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Run multiple agents in parallel */
|
|
66
|
+
export async function runBatch(agents, runner, options = {}) {
|
|
67
|
+
return Promise.all(agents.map(({ agentSlug, task }) => spawnAndAwait(agentSlug, task, runner, options)));
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=managed-agent.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PromptExperimentRouter - A/B traffic splitting for prompt versions
|
|
3
|
+
*
|
|
4
|
+
* Checks for an active experiment on the given agent slug and probabilistically
|
|
5
|
+
* routes to the candidate or control version. Falls back to the active version
|
|
6
|
+
* when no experiment is running.
|
|
7
|
+
*
|
|
8
|
+
* @module @monomind/cli/agents/prompt-experiment
|
|
9
|
+
*/
|
|
10
|
+
type PromptVersionStore = any;
|
|
11
|
+
export interface ResolvedPrompt {
|
|
12
|
+
prompt: string;
|
|
13
|
+
version: string;
|
|
14
|
+
isCandidate: boolean;
|
|
15
|
+
agentSlug: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class PromptExperimentRouter {
|
|
18
|
+
private readonly store;
|
|
19
|
+
constructor(store: PromptVersionStore);
|
|
20
|
+
resolvePromptForSpawn(agentSlug: string): ResolvedPrompt;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=prompt-experiment.d.ts.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PromptExperimentRouter - A/B traffic splitting for prompt versions
|
|
3
|
+
*
|
|
4
|
+
* Checks for an active experiment on the given agent slug and probabilistically
|
|
5
|
+
* routes to the candidate or control version. Falls back to the active version
|
|
6
|
+
* when no experiment is running.
|
|
7
|
+
*
|
|
8
|
+
* @module @monomind/cli/agents/prompt-experiment
|
|
9
|
+
*/
|
|
10
|
+
export class PromptExperimentRouter {
|
|
11
|
+
store;
|
|
12
|
+
constructor(store) {
|
|
13
|
+
this.store = store;
|
|
14
|
+
}
|
|
15
|
+
resolvePromptForSpawn(agentSlug) {
|
|
16
|
+
const experiment = this.store.getExperiment(agentSlug);
|
|
17
|
+
if (experiment) {
|
|
18
|
+
const useCandidate = Math.random() < experiment.trafficPct;
|
|
19
|
+
const targetVersion = useCandidate ? experiment.candidate : experiment.control;
|
|
20
|
+
const versions = this.store.listVersions(agentSlug);
|
|
21
|
+
const found = versions.find((v) => v.version === targetVersion);
|
|
22
|
+
if (found) {
|
|
23
|
+
return {
|
|
24
|
+
prompt: found.prompt,
|
|
25
|
+
version: found.version,
|
|
26
|
+
isCandidate: useCandidate,
|
|
27
|
+
agentSlug,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Fallback to active version
|
|
32
|
+
const active = this.store.getActive(agentSlug);
|
|
33
|
+
if (active) {
|
|
34
|
+
return {
|
|
35
|
+
prompt: active.prompt,
|
|
36
|
+
version: active.version,
|
|
37
|
+
isCandidate: false,
|
|
38
|
+
agentSlug,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
prompt: '',
|
|
43
|
+
version: '',
|
|
44
|
+
isCandidate: false,
|
|
45
|
+
agentSlug,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=prompt-experiment.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PromptVersionManager - High-level prompt version lifecycle operations
|
|
3
|
+
*
|
|
4
|
+
* Provides publish-from-file, promote, rollback, and experiment
|
|
5
|
+
* start/stop workflows on top of PromptVersionStore.
|
|
6
|
+
*
|
|
7
|
+
* @module @monomind/cli/agents/prompt-version-manager
|
|
8
|
+
*/
|
|
9
|
+
type PromptVersionStore = any;
|
|
10
|
+
type PromptVersion = any;
|
|
11
|
+
type PromptExperiment = any;
|
|
12
|
+
export declare class PromptVersionManager {
|
|
13
|
+
private readonly store;
|
|
14
|
+
constructor(store: PromptVersionStore);
|
|
15
|
+
publishFromFile(agentSlug: string, filePath: string, newVersion: string, changelog: string): PromptVersion;
|
|
16
|
+
promote(agentSlug: string, version: string): void;
|
|
17
|
+
rollback(agentSlug: string, stepsBack?: number): void;
|
|
18
|
+
startExperiment(experiment: PromptExperiment): void;
|
|
19
|
+
stopExperiment(agentSlug: string, promoteWinner?: boolean): void;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=prompt-version-manager.d.ts.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PromptVersionManager - High-level prompt version lifecycle operations
|
|
3
|
+
*
|
|
4
|
+
* Provides publish-from-file, promote, rollback, and experiment
|
|
5
|
+
* start/stop workflows on top of PromptVersionStore.
|
|
6
|
+
*
|
|
7
|
+
* @module @monomind/cli/agents/prompt-version-manager
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'node:fs';
|
|
10
|
+
import * as path from 'node:path';
|
|
11
|
+
export class PromptVersionManager {
|
|
12
|
+
store;
|
|
13
|
+
constructor(store) {
|
|
14
|
+
this.store = store;
|
|
15
|
+
}
|
|
16
|
+
publishFromFile(agentSlug, filePath, newVersion, changelog) {
|
|
17
|
+
// Symlink-aware containment: path.resolve does NOT follow symlinks, so
|
|
18
|
+
// a symlink under cwd pointing at /etc/shadow would have passed the
|
|
19
|
+
// prefix-check below. Use realpathSync on both sides and reject symlinks
|
|
20
|
+
// at the leaf so the resolved file is provably inside the project.
|
|
21
|
+
const allowedRoot = fs.realpathSync(process.cwd());
|
|
22
|
+
const requested = path.resolve(filePath);
|
|
23
|
+
if (!fs.existsSync(requested)) {
|
|
24
|
+
throw new Error(`filePath does not exist: ${requested}`);
|
|
25
|
+
}
|
|
26
|
+
if (fs.lstatSync(requested).isSymbolicLink()) {
|
|
27
|
+
throw new Error('filePath must not be a symlink');
|
|
28
|
+
}
|
|
29
|
+
const resolved = fs.realpathSync(requested);
|
|
30
|
+
const rel = path.relative(allowedRoot, resolved);
|
|
31
|
+
if (rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
32
|
+
throw new Error(`filePath must be inside the project directory: ${allowedRoot}`);
|
|
33
|
+
}
|
|
34
|
+
const MAX_PROMPT_BYTES = 1 * 1024 * 1024;
|
|
35
|
+
const fileSize = fs.statSync(resolved).size;
|
|
36
|
+
if (fileSize > MAX_PROMPT_BYTES) {
|
|
37
|
+
throw new Error(`filePath exceeds maximum allowed size (${MAX_PROMPT_BYTES} bytes): ${resolved}`);
|
|
38
|
+
}
|
|
39
|
+
const prompt = fs.readFileSync(resolved, 'utf-8');
|
|
40
|
+
const version = {
|
|
41
|
+
agentSlug,
|
|
42
|
+
version: newVersion,
|
|
43
|
+
prompt,
|
|
44
|
+
changelog,
|
|
45
|
+
activeFrom: new Date(),
|
|
46
|
+
traceCount: 0,
|
|
47
|
+
publishedBy: 'prompt-version-manager',
|
|
48
|
+
createdAt: new Date(),
|
|
49
|
+
};
|
|
50
|
+
this.store.save(version);
|
|
51
|
+
return version;
|
|
52
|
+
}
|
|
53
|
+
promote(agentSlug, version) {
|
|
54
|
+
this.store.setActive(agentSlug, version);
|
|
55
|
+
}
|
|
56
|
+
rollback(agentSlug, stepsBack = 1) {
|
|
57
|
+
const versions = this.store.listVersions(agentSlug);
|
|
58
|
+
if (versions.length < stepsBack + 1) {
|
|
59
|
+
throw new Error(`Cannot rollback ${stepsBack} step(s): only ${versions.length} version(s) exist for "${agentSlug}"`);
|
|
60
|
+
}
|
|
61
|
+
// versions are sorted DESC by createdAt, so index 0 = newest
|
|
62
|
+
const target = versions[stepsBack];
|
|
63
|
+
this.store.setActive(agentSlug, target.version);
|
|
64
|
+
}
|
|
65
|
+
startExperiment(experiment) {
|
|
66
|
+
this.store.saveExperiment(experiment);
|
|
67
|
+
}
|
|
68
|
+
stopExperiment(agentSlug, promoteWinner) {
|
|
69
|
+
const experiment = this.store.getExperiment(agentSlug);
|
|
70
|
+
if (!experiment) {
|
|
71
|
+
throw new Error(`No active experiment for "${agentSlug}"`);
|
|
72
|
+
}
|
|
73
|
+
const winnerId = (experiment.winner ?? experiment.control);
|
|
74
|
+
this.store.concludeExperiment(agentSlug, winnerId);
|
|
75
|
+
if (promoteWinner) {
|
|
76
|
+
this.store.setActive(agentSlug, winnerId);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=prompt-version-manager.js.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry Query (Task 30)
|
|
3
|
+
*
|
|
4
|
+
* Provides query and validation utilities over an AgentRegistry.
|
|
5
|
+
* Supports loading from an in-memory object or a JSON file on disk.
|
|
6
|
+
*/
|
|
7
|
+
import type { AgentRegistry, AgentRegistryEntry } from '../../../shared/src/types/agent-registry.js';
|
|
8
|
+
/** Validation issue found during registry validation. */
|
|
9
|
+
export interface RegistryValidationResult {
|
|
10
|
+
slug: string;
|
|
11
|
+
field: string;
|
|
12
|
+
message: string;
|
|
13
|
+
severity: 'error' | 'warning';
|
|
14
|
+
}
|
|
15
|
+
/** Conflict entry for duplicate slug detection. */
|
|
16
|
+
export interface RegistryConflict {
|
|
17
|
+
slug: string;
|
|
18
|
+
entries: AgentRegistryEntry[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Query engine for the Central Agent Registry.
|
|
22
|
+
*/
|
|
23
|
+
export declare class RegistryQuery {
|
|
24
|
+
private agents;
|
|
25
|
+
private constructor();
|
|
26
|
+
/**
|
|
27
|
+
* Create a RegistryQuery from an in-memory AgentRegistry object.
|
|
28
|
+
*/
|
|
29
|
+
static loadFromJSON(registry: AgentRegistry): RegistryQuery;
|
|
30
|
+
/**
|
|
31
|
+
* Create a RegistryQuery by reading a registry JSON file from disk.
|
|
32
|
+
*/
|
|
33
|
+
static loadFromFile(path: string): RegistryQuery;
|
|
34
|
+
/**
|
|
35
|
+
* Find all agents that list the given capability.
|
|
36
|
+
*/
|
|
37
|
+
findByCapability(capability: string): AgentRegistryEntry[];
|
|
38
|
+
/**
|
|
39
|
+
* Find all agents that handle the given task type.
|
|
40
|
+
*/
|
|
41
|
+
findByTaskType(taskType: string): AgentRegistryEntry[];
|
|
42
|
+
/**
|
|
43
|
+
* Find an agent by its unique slug. Returns undefined if not found.
|
|
44
|
+
*/
|
|
45
|
+
findBySlug(slug: string): AgentRegistryEntry | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Find all agents that list the given tool.
|
|
48
|
+
*/
|
|
49
|
+
findByTool(tool: string): AgentRegistryEntry[];
|
|
50
|
+
/**
|
|
51
|
+
* Find micro-agents — agents that have at least one trigger pattern.
|
|
52
|
+
*/
|
|
53
|
+
findMicroAgents(): AgentRegistryEntry[];
|
|
54
|
+
/**
|
|
55
|
+
* Return all agent slugs in the registry.
|
|
56
|
+
*/
|
|
57
|
+
allSlugs(): string[];
|
|
58
|
+
/**
|
|
59
|
+
* Validate the registry, returning a list of validation issues.
|
|
60
|
+
* Checks:
|
|
61
|
+
* - version must be valid semver (X.Y.Z pattern)
|
|
62
|
+
* - slug must be non-empty
|
|
63
|
+
* - name must be non-empty
|
|
64
|
+
*/
|
|
65
|
+
validate(): RegistryValidationResult[];
|
|
66
|
+
/**
|
|
67
|
+
* Detect duplicate slugs across registry entries.
|
|
68
|
+
*/
|
|
69
|
+
conflicts(): RegistryConflict[];
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=registry-query.d.ts.map
|