mindforge-cc 10.7.0 → 11.0.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/.mindforge/MINDFORGE-V2-SCHEMA.json +43 -10
- package/.mindforge/config.json +6 -1
- package/CHANGELOG.md +64 -0
- package/MINDFORGE.md +3 -3
- package/README.md +49 -4
- package/RELEASENOTES.md +80 -0
- package/SECURITY.md +20 -8
- package/bin/autonomous/audit-writer.js +13 -0
- package/bin/autonomous/auto-runner.js +74 -16
- package/bin/autonomous/context-refactorer.js +26 -11
- package/bin/autonomous/state-manager.js +62 -6
- package/bin/autonomous/stuck-monitor.js +46 -7
- package/bin/autonomous/wave-executor.js +66 -25
- package/bin/dashboard/api-router.js +43 -0
- package/bin/dashboard/metrics-aggregator.js +28 -1
- package/bin/dashboard/server.js +67 -4
- package/bin/dashboard/sse-bridge.js +4 -4
- package/bin/engine/feedback-loop.js +8 -0
- package/bin/engine/intelligence-interlock.js +32 -15
- package/bin/engine/logic-drift-detector.js +2 -1
- package/bin/engine/nexus-tracer.js +3 -2
- package/bin/engine/remediation-engine.js +155 -32
- package/bin/engine/self-corrective-synthesizer.js +84 -10
- package/bin/engine/sre-manager.js +12 -4
- package/bin/engine/temporal-hub.js +131 -34
- package/bin/governance/approve.js +41 -5
- package/bin/governance/impact-analyzer.js +28 -0
- package/bin/governance/policy-engine.js +10 -3
- package/bin/governance/quantum-crypto.js +32 -19
- package/bin/governance/rbac-manager.js +74 -2
- package/bin/governance/ztai-manager.js +49 -7
- package/bin/hindsight-injector.js +3 -3
- package/bin/memory/eis-client.js +71 -34
- package/bin/memory/embedding-engine.js +61 -0
- package/bin/memory/knowledge-graph.js +58 -5
- package/bin/memory/knowledge-indexer.js +53 -6
- package/bin/memory/knowledge-store.js +22 -0
- package/bin/migrations/10.7.0-to-11.0.0.js +110 -0
- package/bin/migrations/schema-versions.js +13 -0
- package/bin/models/anthropic-provider.js +45 -0
- package/bin/models/cloud-broker.js +68 -20
- package/bin/models/gemini-provider.js +51 -0
- package/bin/models/model-client.js +20 -0
- package/bin/models/model-router.js +28 -8
- package/bin/models/openai-provider.js +44 -0
- package/bin/utils/file-io.js +63 -1
- package/bin/utils/index.js +58 -0
- package/docs/getting-started.md +1 -1
- package/docs/user-guide.md +2 -2
- package/package.json +2 -2
|
@@ -36,15 +36,13 @@ const PERSONA_MAP = {
|
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
let _settingsCache = null;
|
|
39
|
+
let _settingsMtime = 0;
|
|
40
|
+
const CACHE_CHECK_INTERVAL_MS = 60000;
|
|
41
|
+
let _lastCacheCheck = 0;
|
|
39
42
|
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
const configPath = path.join(process.cwd(), 'MINDFORGE.md');
|
|
43
|
-
if (!fs.existsSync(configPath)) return DEFAULTS;
|
|
44
|
-
|
|
45
|
-
const content = fs.readFileSync(configPath, 'utf8');
|
|
43
|
+
function parseSettings(filePath) {
|
|
44
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
46
45
|
const settings = { ...DEFAULTS };
|
|
47
|
-
|
|
48
46
|
const lines = content.split('\n');
|
|
49
47
|
for (const line of lines) {
|
|
50
48
|
const match = line.match(/^([A-Z0-9_]+)=(.*)$/);
|
|
@@ -52,10 +50,30 @@ function readMindforgeSettings() {
|
|
|
52
50
|
settings[match[1]] = match[2].trim();
|
|
53
51
|
}
|
|
54
52
|
}
|
|
55
|
-
_settingsCache = settings;
|
|
56
53
|
return settings;
|
|
57
54
|
}
|
|
58
55
|
|
|
56
|
+
function readMindforgeSettings() {
|
|
57
|
+
const now = Date.now();
|
|
58
|
+
if (now - _lastCacheCheck < CACHE_CHECK_INTERVAL_MS && _settingsCache) {
|
|
59
|
+
return _settingsCache;
|
|
60
|
+
}
|
|
61
|
+
_lastCacheCheck = now;
|
|
62
|
+
|
|
63
|
+
const configPath = path.join(process.cwd(), 'MINDFORGE.md');
|
|
64
|
+
try {
|
|
65
|
+
const stat = fs.statSync(configPath);
|
|
66
|
+
if (stat.mtimeMs !== _settingsMtime) {
|
|
67
|
+
_settingsMtime = stat.mtimeMs;
|
|
68
|
+
_settingsCache = parseSettings(configPath);
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
if (!_settingsCache) _settingsCache = { ...DEFAULTS };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return _settingsCache;
|
|
75
|
+
}
|
|
76
|
+
|
|
59
77
|
function route(persona = 'developer', tier = 1) {
|
|
60
78
|
const settings = readMindforgeSettings();
|
|
61
79
|
|
|
@@ -105,6 +123,8 @@ function getModel(settingKey) {
|
|
|
105
123
|
|
|
106
124
|
function clearCache() {
|
|
107
125
|
_settingsCache = null;
|
|
126
|
+
_settingsMtime = 0;
|
|
127
|
+
_lastCacheCheck = 0;
|
|
108
128
|
}
|
|
109
129
|
|
|
110
130
|
function getAllSettings() {
|
|
@@ -73,6 +73,50 @@ class OpenAIProvider {
|
|
|
73
73
|
req.end();
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
|
+
|
|
77
|
+
async streamComplete(messages, options = {}) {
|
|
78
|
+
const model = options.model || 'gpt-4o';
|
|
79
|
+
const maxTokens = options.maxTokens || 4096;
|
|
80
|
+
|
|
81
|
+
const data = JSON.stringify({
|
|
82
|
+
model,
|
|
83
|
+
messages,
|
|
84
|
+
max_tokens: maxTokens,
|
|
85
|
+
stream: true,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return new Promise((resolve, reject) => {
|
|
89
|
+
const req = https.request({
|
|
90
|
+
hostname: 'api.openai.com',
|
|
91
|
+
path: '/v1/chat/completions',
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers: {
|
|
94
|
+
'Content-Type': 'application/json',
|
|
95
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
96
|
+
'Content-Length': Buffer.byteLength(data),
|
|
97
|
+
},
|
|
98
|
+
timeout: 300_000,
|
|
99
|
+
}, res => {
|
|
100
|
+
if (res.statusCode !== 200) {
|
|
101
|
+
let body = '';
|
|
102
|
+
res.on('data', chunk => body += chunk);
|
|
103
|
+
res.on('end', () => {
|
|
104
|
+
reject(new Error(`OpenAI streaming failed: ${res.statusCode}`));
|
|
105
|
+
});
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
resolve(res);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
req.on('error', reject);
|
|
112
|
+
req.on('timeout', () => {
|
|
113
|
+
req.destroy();
|
|
114
|
+
reject(new Error('OpenAI stream timeout'));
|
|
115
|
+
});
|
|
116
|
+
req.write(data);
|
|
117
|
+
req.end();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
76
120
|
}
|
|
77
121
|
|
|
78
122
|
module.exports = OpenAIProvider;
|
package/bin/utils/file-io.js
CHANGED
|
@@ -4,6 +4,7 @@ const fs = require('fs');
|
|
|
4
4
|
const fsp = require('fs/promises');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const crypto = require('crypto');
|
|
7
|
+
const zlib = require('zlib');
|
|
7
8
|
|
|
8
9
|
class AuditWriter {
|
|
9
10
|
constructor(filePath) {
|
|
@@ -99,4 +100,65 @@ function readJSONSync(filePath) {
|
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
function atomicWriteJSON(filePath, data) {
|
|
104
|
+
const tmpPath = filePath + '.tmp.' + process.pid;
|
|
105
|
+
const content = JSON.stringify(data, null, 2) + '\n';
|
|
106
|
+
const fd = fs.openSync(tmpPath, 'w');
|
|
107
|
+
fs.writeSync(fd, content);
|
|
108
|
+
fs.fsyncSync(fd);
|
|
109
|
+
fs.closeSync(fd);
|
|
110
|
+
fs.renameSync(tmpPath, filePath);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function atomicWriteJSONAsync(filePath, data) {
|
|
114
|
+
const tmpPath = filePath + '.tmp.' + process.pid;
|
|
115
|
+
const content = JSON.stringify(data, null, 2) + '\n';
|
|
116
|
+
const fh = await fsp.open(tmpPath, 'w');
|
|
117
|
+
await fh.write(content);
|
|
118
|
+
await fh.sync();
|
|
119
|
+
await fh.close();
|
|
120
|
+
await fsp.rename(tmpPath, filePath);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
class AuditRotator {
|
|
124
|
+
constructor(options = {}) {
|
|
125
|
+
this.maxLines = options.maxLines || 5000;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
shouldRotate(filePath) {
|
|
129
|
+
if (!fs.existsSync(filePath)) return false;
|
|
130
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
131
|
+
const lineCount = content.split('\n').filter(l => l.trim()).length;
|
|
132
|
+
return lineCount >= this.maxLines;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
rotate(filePath, archiveDir) {
|
|
136
|
+
const dir = archiveDir || path.join(path.dirname(filePath), '..', 'audit-archive');
|
|
137
|
+
if (!fs.existsSync(dir)) {
|
|
138
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
142
|
+
const baseName = path.basename(filePath, path.extname(filePath));
|
|
143
|
+
const archiveName = `${baseName}-${timestamp}.jsonl.gz`;
|
|
144
|
+
const archivePath = path.join(dir, archiveName);
|
|
145
|
+
|
|
146
|
+
// Crash-safe: write archive FIRST, then truncate source
|
|
147
|
+
const content = fs.readFileSync(filePath);
|
|
148
|
+
const compressed = zlib.gzipSync(content);
|
|
149
|
+
fs.writeFileSync(archivePath, compressed);
|
|
150
|
+
|
|
151
|
+
const lines = content.toString('utf8').split('\n').filter(l => l.trim());
|
|
152
|
+
const carryover = lines.slice(-100).join('\n') + '\n';
|
|
153
|
+
const tmpPath = filePath + '.tmp.' + process.pid;
|
|
154
|
+
const fd = fs.openSync(tmpPath, 'w');
|
|
155
|
+
fs.writeSync(fd, carryover);
|
|
156
|
+
fs.fsyncSync(fd);
|
|
157
|
+
fs.closeSync(fd);
|
|
158
|
+
fs.renameSync(tmpPath, filePath);
|
|
159
|
+
|
|
160
|
+
return archivePath;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
module.exports = { AuditWriter, AuditRotator, readJSON, writeJSON, readJSONL, readJSONSync, atomicWriteJSON, atomicWriteJSONAsync };
|
package/bin/utils/index.js
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
|
|
3
|
+
class LRUMap {
|
|
4
|
+
constructor(maxSize, options = {}) {
|
|
5
|
+
this._max = maxSize;
|
|
6
|
+
this._onEvict = options.onEvict || null;
|
|
7
|
+
this._map = new Map();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
get(key) {
|
|
11
|
+
if (!this._map.has(key)) return undefined;
|
|
12
|
+
const value = this._map.get(key);
|
|
13
|
+
this._map.delete(key);
|
|
14
|
+
this._map.set(key, value);
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
set(key, value) {
|
|
19
|
+
if (this._map.has(key)) {
|
|
20
|
+
this._map.delete(key);
|
|
21
|
+
} else if (this._map.size >= this._max) {
|
|
22
|
+
const oldest = this._map.keys().next().value;
|
|
23
|
+
const oldestValue = this._map.get(oldest);
|
|
24
|
+
this._map.delete(oldest);
|
|
25
|
+
if (this._onEvict) this._onEvict(oldest, oldestValue);
|
|
26
|
+
}
|
|
27
|
+
this._map.set(key, value);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
has(key) {
|
|
31
|
+
return this._map.has(key);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
delete(key) {
|
|
35
|
+
return this._map.delete(key);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
clear() {
|
|
39
|
+
this._map.clear();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
get size() {
|
|
43
|
+
return this._map.size;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
keys() {
|
|
47
|
+
return this._map.keys();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
values() {
|
|
51
|
+
return this._map.values();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
entries() {
|
|
55
|
+
return this._map.entries();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
2
59
|
module.exports = {
|
|
60
|
+
LRUMap,
|
|
3
61
|
...require('./paths'),
|
|
4
62
|
...require('./file-io'),
|
|
5
63
|
...require('./errors')
|
package/docs/getting-started.md
CHANGED
package/docs/user-guide.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# MindForge User Guide (
|
|
1
|
+
# MindForge User Guide (v11.0.0)
|
|
2
2
|
|
|
3
3
|
This guide gets you from install to productive, with the minimum needed to run MindForge in a real project.
|
|
4
4
|
|
|
@@ -136,7 +136,7 @@ Observe your agent waves, token spend, and milestone progress in real-time.
|
|
|
136
136
|
|
|
137
137
|
The dashboard provides a premium web interface at `http://localhost:7339`.
|
|
138
138
|
|
|
139
|
-
> **Authentication (
|
|
139
|
+
> **Authentication (v11.0.0+):** The dashboard now requires a bearer token for access. The token is printed to the console at startup. Pass it in the `Authorization` header or use the login prompt in the browser UI.
|
|
140
140
|
|
|
141
141
|
---
|
|
142
142
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindforge-cc",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "MindForge \u2014 Sovereign Agentic Intelligence Framework.
|
|
3
|
+
"version": "11.0.0",
|
|
4
|
+
"description": "MindForge \u2014 Sovereign Agentic Intelligence Framework. Sovereign Stability: Production-Hardened Agentic Intelligence (v11)",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mindforge-cc": "bin/install.js",
|
|
7
7
|
"mindforge": "bin/mindforge-cli.js"
|