@evomap/evolver 1.89.4 → 1.89.5
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/CONTRIBUTING.md +19 -0
- package/README.md +536 -86
- package/assets/cover.png +0 -0
- package/index.js +87 -7
- package/package.json +17 -6
- package/scripts/a2a_export.js +63 -0
- package/scripts/a2a_ingest.js +79 -0
- package/scripts/a2a_promote.js +118 -0
- package/scripts/analyze_by_skill.js +121 -0
- package/scripts/build_binaries.js +479 -0
- package/scripts/check-changelog.js +166 -0
- package/scripts/extract_log.js +85 -0
- package/scripts/generate_history.js +75 -0
- package/scripts/gep_append_event.js +96 -0
- package/scripts/gep_personality_report.js +234 -0
- package/scripts/human_report.js +147 -0
- package/scripts/recall-verify-report.js +234 -0
- package/scripts/recover_loop.js +61 -0
- package/scripts/refresh_stars_badge.js +168 -0
- package/scripts/seed-merchants.js +91 -0
- package/scripts/suggest_version.js +89 -0
- package/scripts/validate-modules.js +38 -0
- package/scripts/validate-suite.js +78 -0
- package/skills/index.json +14 -0
- package/src/adapters/scripts/_runtimePaths.js +1 -0
- package/src/adapters/scripts/evolver-session-end.js +1 -0
- package/src/adapters/scripts/evolver-session-start.js +1 -0
- package/src/evolve/guards.js +1 -721
- package/src/evolve/pipeline/collect.js +1 -1283
- package/src/evolve/pipeline/dispatch.js +1 -421
- package/src/evolve/pipeline/enrich.js +1 -440
- package/src/evolve/pipeline/hub.js +1 -319
- package/src/evolve/pipeline/select.js +1 -274
- package/src/evolve/pipeline/signals.js +1 -206
- package/src/evolve/utils.js +1 -264
- package/src/evolve.js +1 -350
- package/src/gep/a2aProtocol.js +1 -4455
- package/src/gep/antiAbuseTelemetry.js +1 -233
- package/src/gep/autoDistillConv.js +1 -205
- package/src/gep/autoDistillLlm.js +1 -315
- package/src/gep/candidateEval.js +1 -92
- package/src/gep/candidates.js +1 -198
- package/src/gep/contentHash.js +1 -30
- package/src/gep/conversationSniffer.js +1 -266
- package/src/gep/crypto.js +1 -89
- package/src/gep/curriculum.js +1 -163
- package/src/gep/deviceId.js +1 -218
- package/src/gep/envFingerprint.js +1 -118
- package/src/gep/epigenetics.js +1 -31
- package/src/gep/execBridge.js +1 -711
- package/src/gep/explore.js +1 -289
- package/src/gep/hash.js +1 -15
- package/src/gep/hubFetch.js +1 -359
- package/src/gep/hubReview.js +1 -207
- package/src/gep/hubSearch.js +1 -526
- package/src/gep/hubVerify.js +1 -306
- package/src/gep/idleScheduler.js +6 -1
- package/src/gep/learningSignals.js +1 -89
- package/src/gep/memoryGraph.js +1 -1374
- package/src/gep/memoryGraphAdapter.js +1 -203
- package/src/gep/mutation.js +1 -203
- package/src/gep/narrativeMemory.js +1 -108
- package/src/gep/openPRRegistry.js +1 -205
- package/src/gep/personality.js +1 -423
- package/src/gep/policyCheck.js +1 -599
- package/src/gep/prompt.js +1 -836
- package/src/gep/recallInject.js +1 -409
- package/src/gep/recallVerifier.js +1 -318
- package/src/gep/reflection.js +1 -177
- package/src/gep/selector.js +1 -602
- package/src/gep/skillDistiller.js +1 -1294
- package/src/gep/solidify.js +1 -1699
- package/src/gep/strategy.js +1 -136
- package/src/gep/tokenSavings.js +1 -88
- package/src/gep/workspaceKeychain.js +1 -174
- package/src/ops/lifecycle.js +17 -4
- package/src/proxy/extensions/traceControl.js +1 -99
- package/src/proxy/index.js +206 -1
- package/src/proxy/inject.js +1 -52
- package/src/proxy/lifecycle/manager.js +12 -0
- package/src/proxy/mailbox/store.js +29 -6
- package/src/proxy/router/responses_route.js +157 -0
- package/src/proxy/server/http.js +13 -4
- package/src/proxy/server/routes.js +11 -1
- package/src/proxy/sync/engine.js +7 -1
- package/src/proxy/sync/outbound.js +32 -4
- package/src/proxy/trace/extractor.js +1 -646
- package/src/proxy/trace/usage.js +1 -105
- package/.cursor/BUGBOT.md +0 -182
- package/.env.example +0 -68
- package/.git-commit-guard-token +0 -1
- package/.github/CODEOWNERS +0 -63
- package/.github/ISSUE_TEMPLATE/good_first_issue.md +0 -23
- package/.github/pull_request_template.md +0 -45
- package/.github/workflows/test.yml +0 -75
- package/CHANGELOG.md +0 -1237
- package/README.public.md +0 -569
- package/SECURITY.md +0 -108
- package/assets/gep/events.jsonl +0 -3
- package/examples/atp-consumer-quickstart.md +0 -100
- package/examples/hello-world.md +0 -38
- package/proxy-package.json +0 -39
- package/public.manifest.json +0 -143
- /package/assets/gep/{genes.json → genes.seed.json} +0 -0
- /package/{bundled-skills → skills}/_meta/SKILL.md +0 -0
package/assets/cover.png
ADDED
|
Binary file
|
package/index.js
CHANGED
|
@@ -1,4 +1,65 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
function _printProxyTokenUsage(out = process.stderr) {
|
|
3
|
+
out.write('Usage: node index.js proxy-token [--settings FILE]\n');
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function _readProxyTokenFromSettingsFile(fs, settingsFile) {
|
|
7
|
+
try {
|
|
8
|
+
const parsed = JSON.parse(fs.readFileSync(settingsFile, 'utf8'));
|
|
9
|
+
return parsed && parsed.proxy && typeof parsed.proxy.token === 'string'
|
|
10
|
+
? parsed.proxy.token
|
|
11
|
+
: '';
|
|
12
|
+
} catch {
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// `proxy-token` is a credential helper for Codex. Handle it before loading any
|
|
18
|
+
// project .env so a workspace cannot change EVOLVER_SETTINGS_DIR or other local
|
|
19
|
+
// state used to find the proxy token.
|
|
20
|
+
if (process.argv[2] === 'proxy-token') {
|
|
21
|
+
try {
|
|
22
|
+
const _fs = require('fs');
|
|
23
|
+
const _os = require('os');
|
|
24
|
+
const _path = require('path');
|
|
25
|
+
let settingsFile = '';
|
|
26
|
+
for (let i = 3; i < process.argv.length; i++) {
|
|
27
|
+
const arg = process.argv[i];
|
|
28
|
+
if (arg === '-h' || arg === '--help') {
|
|
29
|
+
_printProxyTokenUsage(process.stdout);
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
if (arg === '--settings') {
|
|
33
|
+
if (!process.argv[i + 1]) {
|
|
34
|
+
_printProxyTokenUsage();
|
|
35
|
+
console.error('[proxy-token] missing value for --settings');
|
|
36
|
+
process.exit(2);
|
|
37
|
+
}
|
|
38
|
+
settingsFile = process.argv[i + 1];
|
|
39
|
+
i++;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
_printProxyTokenUsage();
|
|
43
|
+
console.error('[proxy-token] unknown argument');
|
|
44
|
+
process.exit(2);
|
|
45
|
+
}
|
|
46
|
+
const defaultSettingsFile = _path.join(
|
|
47
|
+
process.env.EVOLVER_SETTINGS_DIR || _path.join(_os.homedir(), '.evolver'),
|
|
48
|
+
'settings.json',
|
|
49
|
+
);
|
|
50
|
+
const token = _readProxyTokenFromSettingsFile(_fs, settingsFile || defaultSettingsFile);
|
|
51
|
+
if (!token) {
|
|
52
|
+
console.error('[proxy-token] no active proxy token found; start evolver with EVOMAP_PROXY=1 first');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
process.stdout.write(token + '\n');
|
|
56
|
+
process.exit(0);
|
|
57
|
+
} catch (e) {
|
|
58
|
+
console.error('[proxy-token] Failed:', e && e.message || e);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
2
63
|
// Load .env BEFORE any internal require so that a2aProtocol and ATP
|
|
3
64
|
// modules see A2A_NODE_SECRET / A2A_NODE_ID / A2A_HUB_URL at first
|
|
4
65
|
// access and never fall back to a stale persisted/cached secret.
|
|
@@ -625,7 +686,7 @@ async function main() {
|
|
|
625
686
|
// failure mode obvious.
|
|
626
687
|
try {
|
|
627
688
|
const { execSync } = require('child_process');
|
|
628
|
-
execSync('git --version', { stdio: 'ignore', timeout: 5000 });
|
|
689
|
+
execSync('git --version', { stdio: 'ignore', timeout: 5000, windowsHide: true });
|
|
629
690
|
} catch (_gitErr) {
|
|
630
691
|
console.error('');
|
|
631
692
|
console.error('[Preflight] Could not run "git --version". Evolver requires git to be installed and available on PATH.');
|
|
@@ -1166,6 +1227,24 @@ async function main() {
|
|
|
1166
1227
|
const { registerMailboxTransport } = require('./src/gep/mailboxTransport');
|
|
1167
1228
|
registerMailboxTransport();
|
|
1168
1229
|
process.env.A2A_TRANSPORT = 'mailbox';
|
|
1230
|
+
try {
|
|
1231
|
+
const a2a = require('./src/gep/a2aProtocol');
|
|
1232
|
+
a2a.startSystemdNotifyWatchdog(function () {
|
|
1233
|
+
try {
|
|
1234
|
+
const proxy = proxyInfo && proxyInfo.proxy;
|
|
1235
|
+
const lifecycle = proxy && proxy.lifecycle;
|
|
1236
|
+
if (lifecycle && typeof lifecycle.getHeartbeatStats === 'function') {
|
|
1237
|
+
const stats = lifecycle.getHeartbeatStats();
|
|
1238
|
+
// Hub-backed lifecycle stats are authoritative even when stopped;
|
|
1239
|
+
// systemd should starve and restart instead of seeing a false ping.
|
|
1240
|
+
if (stats && (stats.running || proxy.hubUrl)) return stats;
|
|
1241
|
+
}
|
|
1242
|
+
} catch (_) {}
|
|
1243
|
+
return { running: true, consecutiveFailures: 0, lastTickAt: Date.now() };
|
|
1244
|
+
});
|
|
1245
|
+
} catch (sdErr) {
|
|
1246
|
+
console.warn('[Heartbeat] systemd notify/watchdog setup failed: ' + (sdErr && sdErr.message || sdErr));
|
|
1247
|
+
}
|
|
1169
1248
|
} else {
|
|
1170
1249
|
const a2a = require('./src/gep/a2aProtocol');
|
|
1171
1250
|
try { a2a.startHeartbeat(); }
|
|
@@ -1825,9 +1904,9 @@ async function main() {
|
|
|
1825
1904
|
const repoRoot = getRepoRoot();
|
|
1826
1905
|
let diff = '';
|
|
1827
1906
|
try {
|
|
1828
|
-
const unstaged = execSync('git diff', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER }).trim();
|
|
1829
|
-
const staged = execSync('git diff --cached', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER }).trim();
|
|
1830
|
-
const untracked = execSync('git ls-files --others --exclude-standard', { cwd: repoRoot, encoding: 'utf8', timeout: 10000, maxBuffer: MAX_EXEC_BUFFER }).trim();
|
|
1907
|
+
const unstaged = execSync('git diff', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER, windowsHide: true }).trim();
|
|
1908
|
+
const staged = execSync('git diff --cached', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER, windowsHide: true }).trim();
|
|
1909
|
+
const untracked = execSync('git ls-files --others --exclude-standard', { cwd: repoRoot, encoding: 'utf8', timeout: 10000, maxBuffer: MAX_EXEC_BUFFER, windowsHide: true }).trim();
|
|
1831
1910
|
if (staged) diff += '=== Staged Changes ===\n' + staged + '\n\n';
|
|
1832
1911
|
if (unstaged) diff += '=== Unstaged Changes ===\n' + unstaged + '\n\n';
|
|
1833
1912
|
if (untracked) diff += '=== Untracked Files ===\n' + untracked + '\n';
|
|
@@ -1909,13 +1988,13 @@ async function main() {
|
|
|
1909
1988
|
} else if (args.includes('--reject')) {
|
|
1910
1989
|
console.log('\n[Review] Rejected. Rolling back changes...');
|
|
1911
1990
|
try {
|
|
1912
|
-
execSync('git checkout -- .', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER });
|
|
1991
|
+
execSync('git checkout -- .', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER, windowsHide: true });
|
|
1913
1992
|
// Preserve user state on reject: .env files, node_modules, runtime
|
|
1914
1993
|
// PID files, and a dedicated workspace/ dir (if one exists) MUST NOT
|
|
1915
1994
|
// be wiped by an automated rollback. Users have reported losing
|
|
1916
1995
|
// secrets and runtime caches to an aggressive git clean.
|
|
1917
1996
|
execSync('git clean -fd -e node_modules -e workspace -e .env -e ".env.*" -e "*.pid"', {
|
|
1918
|
-
cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER,
|
|
1997
|
+
cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER, windowsHide: true,
|
|
1919
1998
|
});
|
|
1920
1999
|
const evolDir = getEvolutionDir();
|
|
1921
2000
|
const sp = path.join(evolDir, 'evolution_solidify_state.json');
|
|
@@ -2948,9 +3027,10 @@ async function main() {
|
|
|
2948
3027
|
}
|
|
2949
3028
|
|
|
2950
3029
|
} else {
|
|
2951
|
-
console.log(`Usage: node index.js [run|/evolve|login|logout|solidify|review|distill|fetch|sync|asset-log|webui|setup-hooks|recipe|buy|orders|verify|atp|atp-complete|experiment] [--loop]
|
|
3030
|
+
console.log(`Usage: node index.js [run|/evolve|login|logout|proxy-token|solidify|review|distill|fetch|sync|asset-log|webui|setup-hooks|recipe|buy|orders|verify|atp|atp-complete|experiment] [--loop]
|
|
2952
3031
|
- login (authorize this device via the hub, gh-auth-login style; stores an OAuth token used instead of node_secret)
|
|
2953
3032
|
- logout (remove the stored OAuth token)
|
|
3033
|
+
- proxy-token (print the local proxy bearer token for command-backed client auth)
|
|
2954
3034
|
- experiment flags:
|
|
2955
3035
|
- --task="..." --metric="..." (required; same task, baseline vs variant)
|
|
2956
3036
|
- --gene=<geneId> (variant arm reuses this gene's strategy)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evomap/evolver",
|
|
3
|
-
"version": "1.89.
|
|
3
|
+
"version": "1.89.5",
|
|
4
4
|
"description": "A GEP-powered self-evolution engine for AI agents. Features automated log analysis and Genome Evolution Protocol (GEP) for auditable, reusable evolution assets.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -28,12 +28,10 @@
|
|
|
28
28
|
"run": "node index.js run",
|
|
29
29
|
"solidify": "node index.js solidify",
|
|
30
30
|
"review": "node index.js review",
|
|
31
|
-
"distill": "node index.js distill",
|
|
32
|
-
"webui": "node index.js webui",
|
|
33
|
-
"test": "node -e \"const fs=require('fs'),cp=require('child_process');const all=fs.readdirSync('test').filter(f=>f.endsWith('.test.js'));const iso=new Set(['solidifyIntegration.test.js']);const others=all.filter(f=>!iso.has(f)).map(f=>'test/'+f);const isoFiles=all.filter(f=>iso.has(f)).map(f=>'test/'+f);if(others.length)cp.execSync('node --test '+others.join(' '),{stdio:'inherit'});if(isoFiles.length)cp.execSync('node --test '+isoFiles.join(' '),{stdio:'inherit'})\"",
|
|
34
31
|
"a2a:export": "node scripts/a2a_export.js",
|
|
35
32
|
"a2a:ingest": "node scripts/a2a_ingest.js",
|
|
36
|
-
"a2a:promote": "node scripts/a2a_promote.js"
|
|
33
|
+
"a2a:promote": "node scripts/a2a_promote.js",
|
|
34
|
+
"test": "node -e \"const fs=require('fs'),cp=require('child_process');const all=fs.readdirSync('test').filter(f=>f.endsWith('.test.js'));const iso=new Set(['solidifyIntegration.test.js']);const others=all.filter(f=>!iso.has(f)).map(f=>'test/'+f);const isoFiles=all.filter(f=>iso.has(f)).map(f=>'test/'+f);if(others.length)cp.execSync('node --test '+others.join(' '),{stdio:'inherit'});if(isoFiles.length)cp.execSync('node --test '+isoFiles.join(' '),{stdio:'inherit'})\""
|
|
37
35
|
},
|
|
38
36
|
"engines": {
|
|
39
37
|
"node": ">=22.12"
|
|
@@ -50,5 +48,18 @@
|
|
|
50
48
|
},
|
|
51
49
|
"optionalDependencies": {
|
|
52
50
|
"@napi-rs/keyring": "^1.1.6"
|
|
53
|
-
}
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"assets/",
|
|
54
|
+
"index.js",
|
|
55
|
+
"src/",
|
|
56
|
+
"scripts/",
|
|
57
|
+
"skills/",
|
|
58
|
+
"README.md",
|
|
59
|
+
"README.zh-CN.md",
|
|
60
|
+
"README.ja-JP.md",
|
|
61
|
+
"SKILL.md",
|
|
62
|
+
"CONTRIBUTING.md",
|
|
63
|
+
"LICENSE"
|
|
64
|
+
]
|
|
54
65
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const { loadGenes, loadCapsules, readAllEvents } = require('../src/gep/assetStore');
|
|
2
|
+
const { exportEligibleCapsules, exportEligibleGenes, isAllowedA2AAsset } = require('../src/gep/a2a');
|
|
3
|
+
const { buildPublish, buildHello, getTransport } = require('../src/gep/a2aProtocol');
|
|
4
|
+
const { computeAssetId, SCHEMA_VERSION } = require('../src/gep/contentHash');
|
|
5
|
+
|
|
6
|
+
function main() {
|
|
7
|
+
var args = process.argv.slice(2);
|
|
8
|
+
var asJson = args.includes('--json');
|
|
9
|
+
var asProtocol = args.includes('--protocol');
|
|
10
|
+
var withHello = args.includes('--hello');
|
|
11
|
+
var persist = args.includes('--persist');
|
|
12
|
+
var includeEvents = args.includes('--include-events');
|
|
13
|
+
|
|
14
|
+
var capsules = loadCapsules();
|
|
15
|
+
var genes = loadGenes();
|
|
16
|
+
var events = readAllEvents();
|
|
17
|
+
|
|
18
|
+
// Build eligible list: Capsules (filtered) + Genes (filtered) + Events (opt-in)
|
|
19
|
+
var eligibleCapsules = exportEligibleCapsules({ capsules: capsules, events: events });
|
|
20
|
+
var eligibleGenes = exportEligibleGenes({ genes: genes });
|
|
21
|
+
var eligible = eligibleCapsules.concat(eligibleGenes);
|
|
22
|
+
|
|
23
|
+
if (includeEvents) {
|
|
24
|
+
var eligibleEvents = (Array.isArray(events) ? events : []).filter(function (e) {
|
|
25
|
+
return isAllowedA2AAsset(e) && e.type === 'EvolutionEvent';
|
|
26
|
+
});
|
|
27
|
+
for (var ei = 0; ei < eligibleEvents.length; ei++) {
|
|
28
|
+
var ev = eligibleEvents[ei];
|
|
29
|
+
if (!ev.schema_version) ev.schema_version = SCHEMA_VERSION;
|
|
30
|
+
if (!ev.asset_id) { try { ev.asset_id = computeAssetId(ev); } catch (e) {} }
|
|
31
|
+
}
|
|
32
|
+
eligible = eligible.concat(eligibleEvents);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (withHello || asProtocol) {
|
|
36
|
+
var hello = buildHello({ geneCount: genes.length, capsuleCount: capsules.length });
|
|
37
|
+
process.stdout.write(JSON.stringify(hello) + '\n');
|
|
38
|
+
if (persist) { try { getTransport().send(hello); } catch (e) {} }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (asProtocol) {
|
|
42
|
+
for (var i = 0; i < eligible.length; i++) {
|
|
43
|
+
var msg = buildPublish({ asset: eligible[i] });
|
|
44
|
+
process.stdout.write(JSON.stringify(msg) + '\n');
|
|
45
|
+
if (persist) { try { getTransport().send(msg); } catch (e) {} }
|
|
46
|
+
}
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (asJson) {
|
|
51
|
+
process.stdout.write(JSON.stringify(eligible, null, 2) + '\n');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
for (var j = 0; j < eligible.length; j++) {
|
|
56
|
+
process.stdout.write(JSON.stringify(eligible[j]) + '\n');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
try { main(); } catch (e) {
|
|
61
|
+
process.stderr.write((e && e.message ? e.message : String(e)) + '\n');
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
var fs = require('fs');
|
|
2
|
+
var assetStore = require('../src/gep/assetStore');
|
|
3
|
+
var a2a = require('../src/gep/a2a');
|
|
4
|
+
var memGraph = require('../src/gep/memoryGraphAdapter');
|
|
5
|
+
var contentHash = require('../src/gep/contentHash');
|
|
6
|
+
var a2aProto = require('../src/gep/a2aProtocol');
|
|
7
|
+
|
|
8
|
+
function readStdin() {
|
|
9
|
+
try { return fs.readFileSync(0, 'utf8'); } catch (e) { return ''; }
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function parseSignalsFromEnv() {
|
|
13
|
+
var raw = process.env.A2A_SIGNALS || '';
|
|
14
|
+
if (!raw) return [];
|
|
15
|
+
try {
|
|
16
|
+
var maybe = JSON.parse(raw);
|
|
17
|
+
if (Array.isArray(maybe)) return maybe.map(String).filter(Boolean);
|
|
18
|
+
} catch (e) {}
|
|
19
|
+
return String(raw).split(',').map(function (s) { return s.trim(); }).filter(Boolean);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function main() {
|
|
23
|
+
var args = process.argv.slice(2);
|
|
24
|
+
var inputPath = '';
|
|
25
|
+
for (var i = 0; i < args.length; i++) {
|
|
26
|
+
if (args[i] && !args[i].startsWith('--')) { inputPath = args[i]; break; }
|
|
27
|
+
}
|
|
28
|
+
var source = process.env.A2A_SOURCE || 'external';
|
|
29
|
+
var factor = Number.isFinite(Number(process.env.A2A_EXTERNAL_CONFIDENCE_FACTOR))
|
|
30
|
+
? Number(process.env.A2A_EXTERNAL_CONFIDENCE_FACTOR) : 0.6;
|
|
31
|
+
|
|
32
|
+
var text = inputPath ? a2a.readTextIfExists(inputPath) : readStdin();
|
|
33
|
+
var parsed = a2a.parseA2AInput(text);
|
|
34
|
+
var signals = parseSignalsFromEnv();
|
|
35
|
+
|
|
36
|
+
var accepted = 0;
|
|
37
|
+
var rejected = 0;
|
|
38
|
+
var emitDecisions = process.env.A2A_EMIT_DECISIONS === 'true';
|
|
39
|
+
|
|
40
|
+
for (var j = 0; j < parsed.length; j++) {
|
|
41
|
+
var obj = parsed[j];
|
|
42
|
+
if (!a2a.isAllowedA2AAsset(obj)) continue;
|
|
43
|
+
|
|
44
|
+
if (obj.asset_id && typeof obj.asset_id === 'string') {
|
|
45
|
+
if (!contentHash.verifyAssetId(obj)) {
|
|
46
|
+
rejected += 1;
|
|
47
|
+
if (emitDecisions) {
|
|
48
|
+
try {
|
|
49
|
+
var dm = a2aProto.buildDecision({ assetId: obj.asset_id, localId: obj.id, decision: 'reject', reason: 'asset_id integrity check failed' });
|
|
50
|
+
a2aProto.getTransport().send(dm);
|
|
51
|
+
} catch (e) {}
|
|
52
|
+
}
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
var staged = a2a.lowerConfidence(obj, { source: source, factor: factor });
|
|
58
|
+
if (!staged) continue;
|
|
59
|
+
|
|
60
|
+
assetStore.appendExternalCandidateJsonl(staged);
|
|
61
|
+
try { memGraph.recordExternalCandidate({ asset: staged, source: source, signals: signals }); } catch (e) {}
|
|
62
|
+
|
|
63
|
+
if (emitDecisions) {
|
|
64
|
+
try {
|
|
65
|
+
var dm2 = a2aProto.buildDecision({ assetId: staged.asset_id, localId: staged.id, decision: 'quarantine', reason: 'staged as external candidate' });
|
|
66
|
+
a2aProto.getTransport().send(dm2);
|
|
67
|
+
} catch (e) {}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
accepted += 1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
process.stdout.write('accepted=' + accepted + ' rejected=' + rejected + '\n');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
try { main(); } catch (e) {
|
|
77
|
+
process.stderr.write((e && e.message ? e.message : String(e)) + '\n');
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
var assetStore = require('../src/gep/assetStore');
|
|
2
|
+
var solidifyMod = require('../src/gep/solidify');
|
|
3
|
+
var contentHash = require('../src/gep/contentHash');
|
|
4
|
+
var a2aProto = require('../src/gep/a2aProtocol');
|
|
5
|
+
|
|
6
|
+
function parseArgs(argv) {
|
|
7
|
+
var out = { flags: new Set(), kv: new Map(), positionals: [] };
|
|
8
|
+
for (var i = 0; i < argv.length; i++) {
|
|
9
|
+
var a = argv[i];
|
|
10
|
+
if (!a) continue;
|
|
11
|
+
if (a.startsWith('--')) {
|
|
12
|
+
var eq = a.indexOf('=');
|
|
13
|
+
if (eq > -1) { out.kv.set(a.slice(2, eq), a.slice(eq + 1)); }
|
|
14
|
+
else {
|
|
15
|
+
var key = a.slice(2);
|
|
16
|
+
var next = argv[i + 1];
|
|
17
|
+
if (next && !String(next).startsWith('--')) { out.kv.set(key, next); i++; }
|
|
18
|
+
else { out.flags.add(key); }
|
|
19
|
+
}
|
|
20
|
+
} else { out.positionals.push(a); }
|
|
21
|
+
}
|
|
22
|
+
return out;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function main() {
|
|
26
|
+
var args = parseArgs(process.argv.slice(2));
|
|
27
|
+
var id = String(args.kv.get('id') || '').trim();
|
|
28
|
+
var typeRaw = String(args.kv.get('type') || '').trim().toLowerCase();
|
|
29
|
+
var validated = args.flags.has('validated') || String(args.kv.get('validated') || '') === 'true';
|
|
30
|
+
var limit = Number.isFinite(Number(args.kv.get('limit'))) ? Number(args.kv.get('limit')) : 500;
|
|
31
|
+
|
|
32
|
+
if (!id || !typeRaw) throw new Error('Usage: node scripts/a2a_promote.js --type capsule|gene|event --id <id> --validated');
|
|
33
|
+
if (!validated) throw new Error('Refusing to promote without --validated (local verification must be done first).');
|
|
34
|
+
|
|
35
|
+
var type = typeRaw === 'capsule' ? 'Capsule' : typeRaw === 'gene' ? 'Gene' : typeRaw === 'event' ? 'EvolutionEvent' : '';
|
|
36
|
+
if (!type) throw new Error('Invalid --type. Use capsule, gene, or event.');
|
|
37
|
+
|
|
38
|
+
var external = assetStore.readRecentExternalCandidates(limit);
|
|
39
|
+
var candidate = null;
|
|
40
|
+
for (var i = 0; i < external.length; i++) {
|
|
41
|
+
if (external[i] && external[i].type === type && String(external[i].id) === id) { candidate = external[i]; break; }
|
|
42
|
+
}
|
|
43
|
+
if (!candidate) throw new Error('Candidate not found in external zone: type=' + type + ' id=' + id);
|
|
44
|
+
|
|
45
|
+
if (type === 'Gene') {
|
|
46
|
+
var validation = Array.isArray(candidate.validation) ? candidate.validation : [];
|
|
47
|
+
for (var j = 0; j < validation.length; j++) {
|
|
48
|
+
var c = String(validation[j] || '').trim();
|
|
49
|
+
if (!c) continue;
|
|
50
|
+
if (!solidifyMod.isValidationCommandAllowed(c)) {
|
|
51
|
+
throw new Error('Refusing to promote Gene ' + id + ': validation command rejected by safety check: "' + c + '". Only node/npm/npx commands without shell operators are allowed.');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
var promoted = JSON.parse(JSON.stringify(candidate));
|
|
57
|
+
if (!promoted.a2a || typeof promoted.a2a !== 'object') promoted.a2a = {};
|
|
58
|
+
promoted.a2a.status = 'promoted';
|
|
59
|
+
promoted.a2a.promoted_at = new Date().toISOString();
|
|
60
|
+
if (!promoted.schema_version) promoted.schema_version = contentHash.SCHEMA_VERSION;
|
|
61
|
+
promoted.asset_id = contentHash.computeAssetId(promoted);
|
|
62
|
+
|
|
63
|
+
var emitDecisions = process.env.A2A_EMIT_DECISIONS === 'true';
|
|
64
|
+
|
|
65
|
+
if (type === 'EvolutionEvent') {
|
|
66
|
+
assetStore.appendEventJsonl(promoted);
|
|
67
|
+
if (emitDecisions) {
|
|
68
|
+
try {
|
|
69
|
+
var dmEv = a2aProto.buildDecision({ assetId: promoted.asset_id, localId: id, decision: 'accept', reason: 'event promoted for provenance tracking' });
|
|
70
|
+
a2aProto.getTransport().send(dmEv);
|
|
71
|
+
} catch (e) {}
|
|
72
|
+
}
|
|
73
|
+
process.stdout.write('promoted_event=' + id + '\n');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (type === 'Capsule') {
|
|
78
|
+
assetStore.appendCapsule(promoted);
|
|
79
|
+
if (emitDecisions) {
|
|
80
|
+
try {
|
|
81
|
+
var dm = a2aProto.buildDecision({ assetId: promoted.asset_id, localId: id, decision: 'accept', reason: 'capsule promoted after validation' });
|
|
82
|
+
a2aProto.getTransport().send(dm);
|
|
83
|
+
} catch (e) {}
|
|
84
|
+
}
|
|
85
|
+
process.stdout.write('promoted_capsule=' + id + '\n');
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
var localGenes = assetStore.loadGenes();
|
|
90
|
+
var exists = false;
|
|
91
|
+
for (var k = 0; k < localGenes.length; k++) {
|
|
92
|
+
if (localGenes[k] && localGenes[k].type === 'Gene' && String(localGenes[k].id) === id) { exists = true; break; }
|
|
93
|
+
}
|
|
94
|
+
if (exists) {
|
|
95
|
+
if (emitDecisions) {
|
|
96
|
+
try {
|
|
97
|
+
var dm2 = a2aProto.buildDecision({ assetId: promoted.asset_id, localId: id, decision: 'reject', reason: 'local gene with same ID already exists' });
|
|
98
|
+
a2aProto.getTransport().send(dm2);
|
|
99
|
+
} catch (e) {}
|
|
100
|
+
}
|
|
101
|
+
process.stdout.write('conflict_keep_local_gene=' + id + '\n');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
assetStore.upsertGene(promoted);
|
|
106
|
+
if (emitDecisions) {
|
|
107
|
+
try {
|
|
108
|
+
var dm3 = a2aProto.buildDecision({ assetId: promoted.asset_id, localId: id, decision: 'accept', reason: 'gene promoted after safety audit' });
|
|
109
|
+
a2aProto.getTransport().send(dm3);
|
|
110
|
+
} catch (e) {}
|
|
111
|
+
}
|
|
112
|
+
process.stdout.write('promoted_gene=' + id + '\n');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
try { main(); } catch (e) {
|
|
116
|
+
process.stderr.write((e && e.message ? e.message : String(e)) + '\n');
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const REPO_ROOT = path.resolve(__dirname, '..');
|
|
5
|
+
const LOG_FILE = path.join(REPO_ROOT, 'evolution_history_full.md');
|
|
6
|
+
const OUT_FILE = path.join(REPO_ROOT, 'evolution_detailed_report.md');
|
|
7
|
+
|
|
8
|
+
function analyzeEvolution() {
|
|
9
|
+
if (!fs.existsSync(LOG_FILE)) {
|
|
10
|
+
console.error("Source file missing.");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const content = fs.readFileSync(LOG_FILE, 'utf8');
|
|
15
|
+
// Split by divider
|
|
16
|
+
const entries = content.split('---').map(e => e.trim()).filter(e => e.length > 0);
|
|
17
|
+
|
|
18
|
+
const skillUpdates = {}; // Map<SkillName, Array<Changes>>
|
|
19
|
+
const generalUpdates = []; // Array<Changes>
|
|
20
|
+
|
|
21
|
+
// Regex to detect skills/paths
|
|
22
|
+
// e.g. `skills/feishu-card/send.js` or **Target**: `skills/git-sync`
|
|
23
|
+
const skillRegex = /skills\/([a-zA-Z0-9\-_]+)/;
|
|
24
|
+
const actionRegex = /Action:\s*([\s\S]*?)(?=\n\n|\n[A-Z]|$)/i; // Capture Action text
|
|
25
|
+
const statusRegex = /Status:\s*\[?([A-Z\s_]+)\]?/i;
|
|
26
|
+
|
|
27
|
+
entries.forEach(entry => {
|
|
28
|
+
// Extract basic info
|
|
29
|
+
const statusMatch = entry.match(statusRegex);
|
|
30
|
+
const status = statusMatch ? statusMatch[1].trim().toUpperCase() : 'UNKNOWN';
|
|
31
|
+
|
|
32
|
+
// Skip routine checks if we want a *detailed evolution* report (focus on changes)
|
|
33
|
+
// But user asked for "what happened", so routine scans might be boring unless they found something.
|
|
34
|
+
// Let's filter out "STABILITY" or "RUNNING" unless there is a clear "Mutated" or "Fixed" keyword.
|
|
35
|
+
const isInteresting =
|
|
36
|
+
entry.includes('Fixed') ||
|
|
37
|
+
entry.includes('Hardened') ||
|
|
38
|
+
entry.includes('Optimized') ||
|
|
39
|
+
entry.includes('Patched') ||
|
|
40
|
+
entry.includes('Created') ||
|
|
41
|
+
entry.includes('Added') ||
|
|
42
|
+
status === 'SUCCESS' ||
|
|
43
|
+
status === 'COMPLETED';
|
|
44
|
+
|
|
45
|
+
if (!isInteresting) return;
|
|
46
|
+
|
|
47
|
+
// Find associated skill
|
|
48
|
+
const skillMatch = entry.match(skillRegex);
|
|
49
|
+
let skillName = 'General / System';
|
|
50
|
+
if (skillMatch) {
|
|
51
|
+
skillName = skillMatch[1];
|
|
52
|
+
} else {
|
|
53
|
+
// Try heuristics
|
|
54
|
+
if (entry.toLowerCase().includes('feishu card')) skillName = 'feishu-card';
|
|
55
|
+
else if (entry.toLowerCase().includes('git sync')) skillName = 'git-sync';
|
|
56
|
+
else if (entry.toLowerCase().includes('logger')) skillName = 'interaction-logger';
|
|
57
|
+
else if (entry.toLowerCase().includes('evolve')) skillName = 'capability-evolver';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Extract description
|
|
61
|
+
let description = "";
|
|
62
|
+
const actionMatch = entry.match(actionRegex);
|
|
63
|
+
if (actionMatch) {
|
|
64
|
+
description = actionMatch[1].trim();
|
|
65
|
+
} else {
|
|
66
|
+
// Fallback: take lines that look like bullet points or text after header
|
|
67
|
+
const lines = entry.split('\n');
|
|
68
|
+
description = lines.filter(l => l.match(/^[•\-\*]|\w/)).slice(1).join('\n').trim();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Clean up description (remove duplicate "Action:" prefix if captured)
|
|
72
|
+
description = description.replace(/^Action:\s*/i, '');
|
|
73
|
+
|
|
74
|
+
if (!skillUpdates[skillName]) skillUpdates[skillName] = [];
|
|
75
|
+
|
|
76
|
+
// Dedup descriptions slightly (simple check)
|
|
77
|
+
const isDuplicate = skillUpdates[skillName].some(u => u.desc.includes(description.substring(0, 20)));
|
|
78
|
+
if (!isDuplicate) {
|
|
79
|
+
// Extract Date if possible
|
|
80
|
+
const dateMatch = entry.match(/\((\d{4}\/\d{1,2}\/\d{1,2}.*?)\)/);
|
|
81
|
+
const date = dateMatch ? dateMatch[1] : 'Unknown';
|
|
82
|
+
|
|
83
|
+
skillUpdates[skillName].push({
|
|
84
|
+
date,
|
|
85
|
+
status,
|
|
86
|
+
desc: description
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Generate Markdown
|
|
92
|
+
let md = "# Detailed Evolution Report (By Skill)\n\n> Comprehensive breakdown of system changes.\n\n";
|
|
93
|
+
|
|
94
|
+
// Sort skills alphabetically
|
|
95
|
+
const sortedSkills = Object.keys(skillUpdates).sort();
|
|
96
|
+
|
|
97
|
+
sortedSkills.forEach(skill => {
|
|
98
|
+
md += `## ${skill}\n`;
|
|
99
|
+
const updates = skillUpdates[skill];
|
|
100
|
+
|
|
101
|
+
updates.forEach(u => {
|
|
102
|
+
// Icon based on content
|
|
103
|
+
let icon = '*';
|
|
104
|
+
const lowerDesc = u.desc.toLowerCase();
|
|
105
|
+
if (lowerDesc.includes('optimiz')) icon = '[optimize]';
|
|
106
|
+
if (lowerDesc.includes('secur') || lowerDesc.includes('harden') || lowerDesc.includes('permission')) icon = '[security]';
|
|
107
|
+
if (lowerDesc.includes('fix') || lowerDesc.includes('patch')) icon = '[repair]';
|
|
108
|
+
if (lowerDesc.includes('creat') || lowerDesc.includes('add')) icon = '[add]';
|
|
109
|
+
|
|
110
|
+
md += `### ${icon} ${u.date}\n`;
|
|
111
|
+
md += `${u.desc}\n\n`;
|
|
112
|
+
});
|
|
113
|
+
md += `---\n`;
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
fs.writeFileSync(OUT_FILE, md);
|
|
117
|
+
console.log(`Generated report for ${sortedSkills.length} skills.`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
analyzeEvolution();
|
|
121
|
+
|