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.
Files changed (50) hide show
  1. package/.mindforge/MINDFORGE-V2-SCHEMA.json +43 -10
  2. package/.mindforge/config.json +6 -1
  3. package/CHANGELOG.md +64 -0
  4. package/MINDFORGE.md +3 -3
  5. package/README.md +49 -4
  6. package/RELEASENOTES.md +80 -0
  7. package/SECURITY.md +20 -8
  8. package/bin/autonomous/audit-writer.js +13 -0
  9. package/bin/autonomous/auto-runner.js +74 -16
  10. package/bin/autonomous/context-refactorer.js +26 -11
  11. package/bin/autonomous/state-manager.js +62 -6
  12. package/bin/autonomous/stuck-monitor.js +46 -7
  13. package/bin/autonomous/wave-executor.js +66 -25
  14. package/bin/dashboard/api-router.js +43 -0
  15. package/bin/dashboard/metrics-aggregator.js +28 -1
  16. package/bin/dashboard/server.js +67 -4
  17. package/bin/dashboard/sse-bridge.js +4 -4
  18. package/bin/engine/feedback-loop.js +8 -0
  19. package/bin/engine/intelligence-interlock.js +32 -15
  20. package/bin/engine/logic-drift-detector.js +2 -1
  21. package/bin/engine/nexus-tracer.js +3 -2
  22. package/bin/engine/remediation-engine.js +155 -32
  23. package/bin/engine/self-corrective-synthesizer.js +84 -10
  24. package/bin/engine/sre-manager.js +12 -4
  25. package/bin/engine/temporal-hub.js +131 -34
  26. package/bin/governance/approve.js +41 -5
  27. package/bin/governance/impact-analyzer.js +28 -0
  28. package/bin/governance/policy-engine.js +10 -3
  29. package/bin/governance/quantum-crypto.js +32 -19
  30. package/bin/governance/rbac-manager.js +74 -2
  31. package/bin/governance/ztai-manager.js +49 -7
  32. package/bin/hindsight-injector.js +3 -3
  33. package/bin/memory/eis-client.js +71 -34
  34. package/bin/memory/embedding-engine.js +61 -0
  35. package/bin/memory/knowledge-graph.js +58 -5
  36. package/bin/memory/knowledge-indexer.js +53 -6
  37. package/bin/memory/knowledge-store.js +22 -0
  38. package/bin/migrations/10.7.0-to-11.0.0.js +110 -0
  39. package/bin/migrations/schema-versions.js +13 -0
  40. package/bin/models/anthropic-provider.js +45 -0
  41. package/bin/models/cloud-broker.js +68 -20
  42. package/bin/models/gemini-provider.js +51 -0
  43. package/bin/models/model-client.js +20 -0
  44. package/bin/models/model-router.js +28 -8
  45. package/bin/models/openai-provider.js +44 -0
  46. package/bin/utils/file-io.js +63 -1
  47. package/bin/utils/index.js +58 -0
  48. package/docs/getting-started.md +1 -1
  49. package/docs/user-guide.md +2 -2
  50. 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 readMindforgeSettings() {
41
- if (_settingsCache) return _settingsCache;
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;
@@ -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
- module.exports = { AuditWriter, readJSON, writeJSON, readJSONL, readJSONSync };
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 };
@@ -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')
@@ -1,4 +1,4 @@
1
- # MindForge — Getting Started (v10.0.1)
1
+ # MindForge — Getting Started (v11.0.0)
2
2
 
3
3
  This guide gets you from zero to a working MindForge project in under five minutes.
4
4
 
@@ -1,4 +1,4 @@
1
- # MindForge User Guide (v10.0.1)
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 (v10.0.1+):** 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.
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": "10.7.0",
4
- "description": "MindForge \u2014 Sovereign Agentic Intelligence Framework. Bedrock Fortified: Production-Grade Architecture (v10)",
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"