@evomap/evolver 1.84.1 → 1.84.2
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/assets/gep/genes.seed.json +17 -15
- package/index.js +45 -8
- package/package.json +4 -3
- package/src/adapters/claudeCode.js +44 -31
- package/src/adapters/codex.js +70 -26
- package/src/adapters/cursor.js +3 -1
- package/src/adapters/hookAdapter.js +142 -2
- package/src/adapters/kiro.js +6 -14
- package/src/adapters/opencode.js +6 -14
- package/src/adapters/scripts/_runtimePaths.js +114 -0
- package/src/adapters/scripts/evolver-session-end.js +37 -61
- package/src/adapters/scripts/evolver-session-start.js +1 -31
- package/src/config.js +20 -1
- package/src/evolve/guards.js +1 -1
- package/src/evolve/pipeline/collect.js +1 -1
- package/src/evolve/pipeline/dispatch.js +1 -1
- package/src/evolve/pipeline/enrich.js +1 -1
- package/src/evolve/pipeline/hub.js +1 -1
- package/src/evolve/pipeline/select.js +1 -1
- package/src/evolve/pipeline/signals.js +1 -1
- package/src/evolve/utils.js +1 -1
- package/src/evolve.js +1 -1
- package/src/gep/a2aProtocol.js +1 -1
- package/src/gep/assetStore.js +27 -6
- package/src/gep/candidateEval.js +1 -1
- package/src/gep/candidates.js +1 -1
- package/src/gep/contentHash.js +1 -1
- package/src/gep/crypto.js +1 -1
- package/src/gep/curriculum.js +1 -1
- package/src/gep/deviceId.js +1 -1
- package/src/gep/directoryClient.js +4 -3
- package/src/gep/envFingerprint.js +1 -1
- package/src/gep/epigenetics.js +1 -1
- package/src/gep/explore.js +1 -1
- package/src/gep/hash.js +1 -1
- package/src/gep/hubFetch.js +1 -0
- package/src/gep/hubReview.js +1 -1
- package/src/gep/hubSearch.js +1 -1
- package/src/gep/hubVerify.js +1 -1
- package/src/gep/learningSignals.js +1 -1
- package/src/gep/memoryGraph.js +1 -1
- package/src/gep/memoryGraphAdapter.js +1 -1
- package/src/gep/mutation.js +1 -1
- package/src/gep/narrativeMemory.js +1 -1
- package/src/gep/openPRRegistry.js +1 -1
- package/src/gep/personality.js +1 -1
- package/src/gep/policyCheck.js +1 -1
- package/src/gep/prompt.js +1 -1
- package/src/gep/recallVerifier.js +1 -1
- package/src/gep/reflection.js +1 -1
- package/src/gep/schemas/gene.js +70 -1
- package/src/gep/schemas/protocol.js +9 -1
- package/src/gep/selector.js +1 -1
- package/src/gep/selfPR.js +62 -32
- package/src/gep/skillDistiller.js +1 -1
- package/src/gep/skillPublisher.js +3 -2
- package/src/gep/solidify.js +1 -1
- package/src/gep/strategy.js +1 -1
- package/src/gep/taskReceiver.js +6 -5
- package/src/gep/validator/index.js +10 -6
- package/src/gep/validator/reporter.js +2 -1
- package/src/gep/validator/stakeBootstrap.js +2 -1
- package/src/proxy/index.js +69 -0
- package/src/proxy/lifecycle/manager.js +3 -2
- package/src/proxy/router/cache_passthrough.js +26 -0
- package/src/proxy/router/features.js +84 -0
- package/src/proxy/router/messages_route.js +242 -0
- package/src/proxy/router/model_router.js +113 -0
- package/src/proxy/server/http.js +92 -5
- package/src/proxy/server/routes.js +12 -2
- package/src/proxy/server/settings.js +37 -11
- package/src/proxy/sync/inbound.js +3 -2
- package/src/proxy/sync/outbound.js +2 -1
package/src/adapters/kiro.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const { copyHookScripts, removeHookScripts } = require('./hookAdapter');
|
|
3
|
+
const { copyHookScripts, removeHookScripts, removeMarkedSection, assertSafeConfigDir } = require('./hookAdapter');
|
|
4
4
|
|
|
5
5
|
const HOOK_SCRIPTS_DIR_NAME = 'hooks';
|
|
6
6
|
const EVOLVER_MARKER = '<!-- evolver-evolution-memory -->';
|
|
@@ -110,6 +110,7 @@ function install({ configRoot, evolverRoot, force }) {
|
|
|
110
110
|
const hooksDir = path.join(kiroDir, HOOK_SCRIPTS_DIR_NAME);
|
|
111
111
|
const agentsMdPath = path.join(configRoot, 'AGENTS.md');
|
|
112
112
|
const scriptsBase = '.kiro/hooks';
|
|
113
|
+
assertSafeConfigDir(kiroDir, '.kiro', { subdirs: [HOOK_SCRIPTS_DIR_NAME] });
|
|
113
114
|
|
|
114
115
|
const hookPaths = Object.values(HOOK_FILES).map(name => path.join(hooksDir, name));
|
|
115
116
|
|
|
@@ -153,6 +154,7 @@ function uninstall({ configRoot }) {
|
|
|
153
154
|
const kiroDir = path.join(configRoot, '.kiro');
|
|
154
155
|
const hooksDir = path.join(kiroDir, HOOK_SCRIPTS_DIR_NAME);
|
|
155
156
|
const agentsMdPath = path.join(configRoot, 'AGENTS.md');
|
|
157
|
+
assertSafeConfigDir(kiroDir, '.kiro', { subdirs: [HOOK_SCRIPTS_DIR_NAME] });
|
|
156
158
|
|
|
157
159
|
let changed = false;
|
|
158
160
|
let removedCount = 0;
|
|
@@ -173,19 +175,9 @@ function uninstall({ configRoot }) {
|
|
|
173
175
|
const scripts = removeHookScripts(hooksDir);
|
|
174
176
|
if (scripts > 0) changed = true;
|
|
175
177
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (content.includes(EVOLVER_MARKER)) {
|
|
180
|
-
const idx = content.indexOf(EVOLVER_MARKER);
|
|
181
|
-
const nextSection = content.indexOf('\n## ', idx + EVOLVER_MARKER.length);
|
|
182
|
-
const endIdx = nextSection !== -1 ? nextSection : content.length;
|
|
183
|
-
content = content.slice(0, idx).trimEnd() + (nextSection !== -1 ? content.slice(endIdx) : '');
|
|
184
|
-
fs.writeFileSync(agentsMdPath, content.trimEnd() + '\n', 'utf8');
|
|
185
|
-
changed = true;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
} catch { /* ignore */ }
|
|
178
|
+
if (removeMarkedSection(agentsMdPath, EVOLVER_MARKER)) {
|
|
179
|
+
changed = true;
|
|
180
|
+
}
|
|
189
181
|
|
|
190
182
|
console.log(changed
|
|
191
183
|
? `[kiro] Uninstalled evolver hooks (${removedCount} hook files + ${scripts} scripts removed).`
|
package/src/adapters/opencode.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const { copyHookScripts, removeHookScripts } = require('./hookAdapter');
|
|
3
|
+
const { copyHookScripts, removeHookScripts, removeMarkedSection, assertSafeConfigDir } = require('./hookAdapter');
|
|
4
4
|
|
|
5
5
|
const HOOK_SCRIPTS_DIR_NAME = 'hooks';
|
|
6
6
|
const PLUGINS_DIR_NAME = 'plugins';
|
|
@@ -124,6 +124,7 @@ function install({ configRoot, evolverRoot, force }) {
|
|
|
124
124
|
const pluginsDir = path.join(opencodeDir, PLUGINS_DIR_NAME);
|
|
125
125
|
const pluginPath = path.join(pluginsDir, PLUGIN_FILE_NAME);
|
|
126
126
|
const agentsMdPath = path.join(configRoot, 'AGENTS.md');
|
|
127
|
+
assertSafeConfigDir(opencodeDir, '.opencode', { subdirs: [HOOK_SCRIPTS_DIR_NAME, PLUGINS_DIR_NAME] });
|
|
127
128
|
|
|
128
129
|
if (!force && isEvolverManagedPluginFile(pluginPath)) {
|
|
129
130
|
console.log('[opencode] Evolver plugin already installed. Use --force to overwrite.');
|
|
@@ -292,6 +293,7 @@ function uninstall({ configRoot }) {
|
|
|
292
293
|
const pluginsDir = path.join(opencodeDir, PLUGINS_DIR_NAME);
|
|
293
294
|
const pluginPath = path.join(pluginsDir, PLUGIN_FILE_NAME);
|
|
294
295
|
const agentsMdPath = path.join(configRoot, 'AGENTS.md');
|
|
296
|
+
assertSafeConfigDir(opencodeDir, '.opencode', { subdirs: [HOOK_SCRIPTS_DIR_NAME, PLUGINS_DIR_NAME] });
|
|
295
297
|
|
|
296
298
|
let changed = false;
|
|
297
299
|
|
|
@@ -302,19 +304,9 @@ function uninstall({ configRoot }) {
|
|
|
302
304
|
const scripts = removeHookScripts(hooksDir);
|
|
303
305
|
if (scripts > 0) changed = true;
|
|
304
306
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if (content.includes(EVOLVER_MARKER)) {
|
|
309
|
-
const idx = content.indexOf(EVOLVER_MARKER);
|
|
310
|
-
const nextSection = content.indexOf('\n## ', idx + EVOLVER_MARKER.length);
|
|
311
|
-
const endIdx = nextSection !== -1 ? nextSection : content.length;
|
|
312
|
-
content = content.slice(0, idx).trimEnd() + (nextSection !== -1 ? content.slice(endIdx) : '');
|
|
313
|
-
fs.writeFileSync(agentsMdPath, content.trimEnd() + '\n', 'utf8');
|
|
314
|
-
changed = true;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
} catch { /* ignore */ }
|
|
307
|
+
if (removeMarkedSection(agentsMdPath, EVOLVER_MARKER)) {
|
|
308
|
+
changed = true;
|
|
309
|
+
}
|
|
318
310
|
|
|
319
311
|
console.log(changed
|
|
320
312
|
? '[opencode] Uninstalled evolver plugin and hooks.'
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// _runtimePaths.js
|
|
2
|
+
// Shared path resolution for evolver hook scripts.
|
|
3
|
+
//
|
|
4
|
+
// Two responsibilities:
|
|
5
|
+
// 1. Locate the evolver package root, supporting:
|
|
6
|
+
// - $EVOLVER_ROOT explicit override
|
|
7
|
+
// - The "scripts colocated with src" layout used during dev (../../..)
|
|
8
|
+
// - The npm-global install layout, where the hook script lives under
|
|
9
|
+
// `<prefix>/lib/node_modules/<host>/.../hooks/` and `..` walks lead
|
|
10
|
+
// somewhere outside the evolver package. We resolve via
|
|
11
|
+
// `require.resolve('@evomap/evolver/package.json')` instead.
|
|
12
|
+
// - The `~/skills/evolver` fallback (some users symlink there).
|
|
13
|
+
//
|
|
14
|
+
// 2. Locate (or pick a writable default for) the evolution memory graph,
|
|
15
|
+
// so that hook scripts in environments without an evolver-managed
|
|
16
|
+
// project directory still record outcomes somewhere instead of
|
|
17
|
+
// reporting "nowhere (no Hub or local path)" (#536).
|
|
18
|
+
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
const path = require('path');
|
|
21
|
+
const os = require('os');
|
|
22
|
+
|
|
23
|
+
function isEvolverPackageJson(filePath) {
|
|
24
|
+
try {
|
|
25
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
26
|
+
const pkg = JSON.parse(raw);
|
|
27
|
+
return pkg && (pkg.name === '@evomap/evolver' || pkg.name === 'evolver');
|
|
28
|
+
} catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function findEvolverRoot() {
|
|
34
|
+
if (process.env.EVOLVER_ROOT) {
|
|
35
|
+
const explicit = process.env.EVOLVER_ROOT;
|
|
36
|
+
if (fs.existsSync(path.join(explicit, 'package.json')) &&
|
|
37
|
+
isEvolverPackageJson(path.join(explicit, 'package.json'))) {
|
|
38
|
+
return explicit;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Dev/repo layout: this file lives at src/adapters/scripts/_runtimePaths.js,
|
|
43
|
+
// so `../../..` is the package root.
|
|
44
|
+
const repoRoot = path.resolve(__dirname, '..', '..', '..');
|
|
45
|
+
if (fs.existsSync(path.join(repoRoot, 'package.json')) &&
|
|
46
|
+
isEvolverPackageJson(path.join(repoRoot, 'package.json'))) {
|
|
47
|
+
return repoRoot;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// npm-global / npm-local install layout. The hook script may have been
|
|
51
|
+
// copied out of the package into `.claude/hooks/` etc., breaking relative
|
|
52
|
+
// walks. Use require.resolve to find the installed package authoritatively.
|
|
53
|
+
//
|
|
54
|
+
// SECURITY: do NOT include `process.cwd()` here. A hostile workspace can
|
|
55
|
+
// place its own `node_modules/@evomap/evolver/package.json`, which would
|
|
56
|
+
// be selected here and control `findMemoryGraph()` -> the memory graph
|
|
57
|
+
// contents become attacker-controlled prompt-injection material in
|
|
58
|
+
// `evolver-session-start.js`'s `additionalContext`. Restrict to trusted,
|
|
59
|
+
// user/system-scoped install roots.
|
|
60
|
+
try {
|
|
61
|
+
const pkgJson = require.resolve('@evomap/evolver/package.json', {
|
|
62
|
+
paths: [
|
|
63
|
+
path.join(os.homedir(), '.npm-global', 'lib', 'node_modules'),
|
|
64
|
+
path.join(os.homedir(), '.local', 'lib', 'node_modules'),
|
|
65
|
+
'/usr/lib/node_modules',
|
|
66
|
+
'/usr/local/lib/node_modules',
|
|
67
|
+
],
|
|
68
|
+
});
|
|
69
|
+
if (pkgJson && isEvolverPackageJson(pkgJson)) {
|
|
70
|
+
return path.dirname(pkgJson);
|
|
71
|
+
}
|
|
72
|
+
} catch { /* not installed via npm */ }
|
|
73
|
+
|
|
74
|
+
const homeSkills = path.join(os.homedir(), 'skills', 'evolver');
|
|
75
|
+
if (fs.existsSync(path.join(homeSkills, 'package.json')) &&
|
|
76
|
+
isEvolverPackageJson(path.join(homeSkills, 'package.json'))) {
|
|
77
|
+
return homeSkills;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Returns a path to the evolution memory graph, or a fallback location that
|
|
84
|
+
// is guaranteed to be writable. Never returns null — when no evolver root is
|
|
85
|
+
// available, we fall back to `~/.evolver/memory/evolution/memory_graph.jsonl`
|
|
86
|
+
// so npm-global installs without a project-local evolver still capture
|
|
87
|
+
// outcomes (#536). Callers that need a "does the file already exist" check
|
|
88
|
+
// should use `fs.existsSync()` separately.
|
|
89
|
+
function findMemoryGraph(evolverRoot) {
|
|
90
|
+
if (process.env.MEMORY_GRAPH_PATH) {
|
|
91
|
+
return process.env.MEMORY_GRAPH_PATH;
|
|
92
|
+
}
|
|
93
|
+
if (evolverRoot) {
|
|
94
|
+
const lower = path.join(evolverRoot, 'memory', 'evolution', 'memory_graph.jsonl');
|
|
95
|
+
if (fs.existsSync(lower)) return lower;
|
|
96
|
+
const upper = path.join(evolverRoot, 'MEMORY', 'evolution', 'memory_graph.jsonl');
|
|
97
|
+
if (fs.existsSync(upper)) return upper;
|
|
98
|
+
// Neither exists yet — prefer lowercase under the evolver root if the
|
|
99
|
+
// root itself is writable (dev/local install case).
|
|
100
|
+
try {
|
|
101
|
+
fs.accessSync(evolverRoot, fs.constants.W_OK);
|
|
102
|
+
const dir = path.dirname(lower);
|
|
103
|
+
try { fs.mkdirSync(dir, { recursive: true }); } catch { /* fall through */ }
|
|
104
|
+
return lower;
|
|
105
|
+
} catch { /* not writable, fall through to user-level */ }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// User-level fallback. Always writable, consistent across platforms.
|
|
109
|
+
const userDir = path.join(os.homedir(), '.evolver', 'memory', 'evolution');
|
|
110
|
+
try { fs.mkdirSync(userDir, { recursive: true }); } catch { /* best-effort */ }
|
|
111
|
+
return path.join(userDir, 'memory_graph.jsonl');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = { findEvolverRoot, findMemoryGraph };
|
|
@@ -5,75 +5,51 @@
|
|
|
5
5
|
// Input: stdin JSON. Output: stdout JSON with followup_message.
|
|
6
6
|
|
|
7
7
|
const fs = require('fs');
|
|
8
|
-
const
|
|
9
|
-
const { execSync, spawnSync } = require('child_process');
|
|
8
|
+
const { spawnSync } = require('child_process');
|
|
10
9
|
// 10 MB — prevents RangeError on large child process output (e.g. git log/diff
|
|
11
10
|
// on large repos). See GHSA reports / issue #451.
|
|
12
11
|
const MAX_EXEC_BUFFER = 10 * 1024 * 1024;
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function findMemoryGraph(evolverRoot) {
|
|
34
|
-
if (process.env.MEMORY_GRAPH_PATH && fs.existsSync(process.env.MEMORY_GRAPH_PATH)) {
|
|
35
|
-
return process.env.MEMORY_GRAPH_PATH;
|
|
36
|
-
}
|
|
37
|
-
const candidates = [
|
|
38
|
-
evolverRoot && path.join(evolverRoot, 'memory', 'evolution', 'memory_graph.jsonl'),
|
|
39
|
-
evolverRoot && path.join(evolverRoot, 'MEMORY', 'evolution', 'memory_graph.jsonl'),
|
|
40
|
-
];
|
|
41
|
-
for (const c of candidates) {
|
|
42
|
-
if (c && fs.existsSync(c)) return c;
|
|
43
|
-
}
|
|
44
|
-
if (evolverRoot) {
|
|
45
|
-
const defaultPath = path.join(evolverRoot, 'memory', 'evolution', 'memory_graph.jsonl');
|
|
46
|
-
fs.mkdirSync(path.dirname(defaultPath), { recursive: true });
|
|
47
|
-
return defaultPath;
|
|
13
|
+
const { findEvolverRoot, findMemoryGraph } = require('./_runtimePaths');
|
|
14
|
+
|
|
15
|
+
function runGit(args, cwd) {
|
|
16
|
+
// Argv-array form, no shell. Avoids POSIX `2>/dev/null` redirects that
|
|
17
|
+
// break on Windows cmd.exe (#537). Failures (e.g. no HEAD~1 in a fresh
|
|
18
|
+
// repo) are surfaced as a non-zero status; callers distinguish them
|
|
19
|
+
// from successful empty output via the `ok` flag (PR #94 round-6 LOW).
|
|
20
|
+
const res = spawnSync('git', args, {
|
|
21
|
+
cwd,
|
|
22
|
+
encoding: 'utf8',
|
|
23
|
+
timeout: 5000,
|
|
24
|
+
maxBuffer: MAX_EXEC_BUFFER,
|
|
25
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
26
|
+
shell: false,
|
|
27
|
+
});
|
|
28
|
+
if (res.status === 0 && typeof res.stdout === 'string') {
|
|
29
|
+
return { ok: true, out: res.stdout.trim() };
|
|
48
30
|
}
|
|
49
|
-
return
|
|
31
|
+
return { ok: false, out: '' };
|
|
50
32
|
}
|
|
51
33
|
|
|
52
34
|
function getGitDiffStats() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
diffSnippet: diffContent.slice(0, 2000),
|
|
72
|
-
hasChanges: stat.length > 0,
|
|
73
|
-
};
|
|
74
|
-
} catch {
|
|
75
|
-
return { stat: '', summary: 'unknown', diffSnippet: '', hasChanges: false };
|
|
76
|
-
}
|
|
35
|
+
const cwd = process.cwd();
|
|
36
|
+
// Distinguish "git failed (no HEAD~1, etc.)" from "git succeeded with
|
|
37
|
+
// empty output (e.g. empty merge)". The previous `||` chain treated
|
|
38
|
+
// both as falsy and fell through to the working-tree diff, which can
|
|
39
|
+
// surface unrelated unstaged changes as the session outcome.
|
|
40
|
+
const statHead1 = runGit(['diff', '--stat', 'HEAD~1'], cwd);
|
|
41
|
+
const stat = statHead1.ok ? statHead1.out : runGit(['diff', '--stat'], cwd).out;
|
|
42
|
+
const diffHead1 = runGit(['diff', '--no-color', 'HEAD~1'], cwd);
|
|
43
|
+
const diffContent = diffHead1.ok ? diffHead1.out : runGit(['diff', '--no-color'], cwd).out;
|
|
44
|
+
const filesChanged = (stat.match(/\d+ files? changed/) || ['0'])[0];
|
|
45
|
+
const insertions = (stat.match(/(\d+) insertions?/) || [null, '0'])[1];
|
|
46
|
+
const deletions = (stat.match(/(\d+) deletions?/) || [null, '0'])[1];
|
|
47
|
+
return {
|
|
48
|
+
stat,
|
|
49
|
+
summary: `${filesChanged}, +${insertions}/-${deletions}`,
|
|
50
|
+
diffSnippet: diffContent.slice(0, 2000),
|
|
51
|
+
hasChanges: stat.length > 0,
|
|
52
|
+
};
|
|
77
53
|
}
|
|
78
54
|
|
|
79
55
|
function detectSignals(text) {
|
|
@@ -7,37 +7,7 @@ const fs = require('fs');
|
|
|
7
7
|
const path = require('path');
|
|
8
8
|
const os = require('os');
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
const candidates = [
|
|
12
|
-
process.env.EVOLVER_ROOT,
|
|
13
|
-
path.resolve(__dirname, '..', '..', '..'),
|
|
14
|
-
];
|
|
15
|
-
for (const c of candidates) {
|
|
16
|
-
if (c && fs.existsSync(path.join(c, 'package.json'))) {
|
|
17
|
-
try {
|
|
18
|
-
const pkg = JSON.parse(fs.readFileSync(path.join(c, 'package.json'), 'utf8'));
|
|
19
|
-
if (pkg.name === '@evomap/evolver' || pkg.name === 'evolver') return c;
|
|
20
|
-
} catch { /* skip */ }
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
const homeSkills = path.join(require('os').homedir(), 'skills', 'evolver');
|
|
24
|
-
if (fs.existsSync(path.join(homeSkills, 'package.json'))) return homeSkills;
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function findMemoryGraph(evolverRoot) {
|
|
29
|
-
if (process.env.MEMORY_GRAPH_PATH && fs.existsSync(process.env.MEMORY_GRAPH_PATH)) {
|
|
30
|
-
return process.env.MEMORY_GRAPH_PATH;
|
|
31
|
-
}
|
|
32
|
-
const candidates = [
|
|
33
|
-
evolverRoot && path.join(evolverRoot, 'memory', 'evolution', 'memory_graph.jsonl'),
|
|
34
|
-
evolverRoot && path.join(evolverRoot, 'MEMORY', 'evolution', 'memory_graph.jsonl'),
|
|
35
|
-
];
|
|
36
|
-
for (const c of candidates) {
|
|
37
|
-
if (c && fs.existsSync(c)) return c;
|
|
38
|
-
}
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
10
|
+
const { findEvolverRoot, findMemoryGraph } = require('./_runtimePaths');
|
|
41
11
|
|
|
42
12
|
function readLastN(filePath, n) {
|
|
43
13
|
try {
|
package/src/config.js
CHANGED
|
@@ -51,10 +51,29 @@ const HUB_SEARCH_TIMEOUT_MS = envInt('EVOLVER_HUB_SEARCH_TIMEOUT_MS', 8000);
|
|
|
51
51
|
const PUBLIC_DEFAULT_HUB_URL = 'https://evomap.ai';
|
|
52
52
|
|
|
53
53
|
function resolveHubUrl() {
|
|
54
|
-
|
|
54
|
+
const raw = process.env.A2A_HUB_URL
|
|
55
55
|
|| process.env.EVOMAP_HUB_URL
|
|
56
56
|
|| process.env.EVOLVER_DEFAULT_HUB_URL
|
|
57
57
|
|| PUBLIC_DEFAULT_HUB_URL;
|
|
58
|
+
|
|
59
|
+
if (process.env.EVOMAP_HUB_ALLOW_INSECURE !== '1') {
|
|
60
|
+
let parsed;
|
|
61
|
+
try {
|
|
62
|
+
parsed = new URL(raw);
|
|
63
|
+
} catch {
|
|
64
|
+
throw new Error(
|
|
65
|
+
'[config] Hub URL is not a valid URL: ' + JSON.stringify(raw) + '. ' +
|
|
66
|
+
'Set EVOMAP_HUB_ALLOW_INSECURE=1 to bypass (local dev / mock hub only).'
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
if (parsed.protocol !== 'https:') {
|
|
70
|
+
throw new Error(
|
|
71
|
+
'[config] Hub URL must use https:// — got ' + JSON.stringify(raw) + '. ' +
|
|
72
|
+
'Set EVOMAP_HUB_ALLOW_INSECURE=1 to bypass (local dev / mock hub only).'
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return raw;
|
|
58
77
|
}
|
|
59
78
|
|
|
60
79
|
// --- Solidify & Validation ---
|