@evomap/evolver 1.91.2 β 1.92.1
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/README.md +13 -7
- package/index.js +150 -71
- package/package.json +2 -1
- package/src/adapters/scripts/_runtimePaths.js +10 -1
- package/src/adapters/scripts/evolver-session-end.js +10 -1
- package/src/canonicalIdentityLock.js +455 -0
- 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 -5175
- package/src/gep/antiAbuseTelemetry.js +1 -233
- package/src/gep/assetStore.js +56 -12
- 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 -1
- package/src/gep/contentHash.js +1 -30
- package/src/gep/conversationDistiller.js +1 -270
- package/src/gep/conversationSniffer.js +1 -266
- package/src/gep/crypto.js +1 -93
- package/src/gep/curriculum.js +1 -1
- 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 -712
- package/src/gep/explore.js +1 -289
- package/src/gep/hash.js +1 -15
- package/src/gep/hubFetch.js +1 -672
- package/src/gep/hubReview.js +1 -212
- package/src/gep/hubSearch.js +1 -544
- package/src/gep/hubVerify.js +1 -306
- package/src/gep/learningSignals.js +1 -1
- package/src/gep/memoryGraph.js +1 -1449
- package/src/gep/memoryGraphAdapter.js +1 -203
- package/src/gep/mutation.js +1 -1
- package/src/gep/narrativeMemory.js +1 -1
- package/src/gep/openPRRegistry.js +1 -205
- package/src/gep/personality.js +1 -1
- package/src/gep/policyCheck.js +1 -599
- package/src/gep/prompt.js +1 -1
- package/src/gep/recallInject.js +1 -409
- package/src/gep/recallVerifier.js +1 -318
- package/src/gep/reflection.js +1 -1
- package/src/gep/savingsCore.js +1 -1
- package/src/gep/schemas/gene.js +2 -0
- package/src/gep/selector.js +1 -1
- package/src/gep/skillDistiller.js +1 -1294
- package/src/gep/solidify.js +1 -1
- package/src/gep/strategy.js +1 -136
- package/src/gep/syncAsset.js +1 -0
- package/src/gep/tokenSavings.js +1 -1
- package/src/gep/trajectoryExport.js +1 -3841
- package/src/gep/workspaceKeychain.js +1 -174
- package/src/proxy/extensions/traceControl.js +1 -123
- package/src/proxy/index.js +136 -8
- package/src/proxy/inject.js +1 -52
- package/src/proxy/lifecycle/manager.js +279 -18
- package/src/proxy/mailbox/state.js +60 -29
- package/src/proxy/trace/extractor.js +1 -2355
- package/src/proxy/trace/usage.js +1 -105
package/README.md
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+

|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[](https://opensource.org/licenses/GPL-3.0)
|
|
5
|
-
[](https://nodejs.org/)
|
|
6
|
-
[](https://www.npmjs.com/package/@evomap/evolver)
|
|
7
|
-
[](https://arxiv.org/abs/2604.15097)
|
|
3
|
+
<h1 align="center">𧬠Evolver</h1>
|
|
8
4
|
|
|
9
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://trendshift.io/repositories/26015?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-26015" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/26015" alt="EvoMap%2Fevolver | Trendshift" width="250" height="55"/></a>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://github.com/EvoMap/evolver/stargazers"><img src="https://img.shields.io/badge/Stars-8.9k-2b3137?logo=github&logoColor=white" alt="GitHub stars"/></a>
|
|
11
|
+
<a href="https://opensource.org/licenses/GPL-3.0"><img src="https://img.shields.io/badge/License-GPL--3.0-blue.svg" alt="License: GPL-3.0"/></a>
|
|
12
|
+
<a href="https://nodejs.org/"><img src="https://img.shields.io/badge/Node.js-%3E%3D%2018-green.svg" alt="Node.js >= 18"/></a>
|
|
13
|
+
<a href="https://www.npmjs.com/package/@evomap/evolver"><img src="https://img.shields.io/npm/dm/@evomap/evolver.svg" alt="npm downloads"/></a>
|
|
14
|
+
<a href="https://arxiv.org/abs/2604.15097"><img src="https://img.shields.io/badge/arXiv-2604.15097-b31b1b.svg" alt="arXiv"/></a>
|
|
15
|
+
</p>
|
|
10
16
|
|
|
11
17
|
**[evomap.ai](https://evomap.ai)** | [Documentation](https://evomap.ai/wiki) | [Chinese / δΈζζζ‘£](README.zh-CN.md) | [Japanese / ζ₯ζ¬θͺγγγ₯γ‘γ³γ](README.ja-JP.md) | [Korean / νκ΅μ΄ λ¬Έμ](README.ko-KR.md) | [GitHub](https://github.com/EvoMap/evolver) | [Releases](https://github.com/EvoMap/evolver/releases)
|
|
12
18
|
|
package/index.js
CHANGED
|
@@ -1111,11 +1111,14 @@ async function main() {
|
|
|
1111
1111
|
if (_keepAliveTimer) { clearInterval(_keepAliveTimer); _keepAliveTimer = null; }
|
|
1112
1112
|
stopLockRefresh();
|
|
1113
1113
|
releaseLock();
|
|
1114
|
+
// Stop event delivery independently because proxy mode owns its own
|
|
1115
|
+
// lifecycle heartbeat and never starts the a2a heartbeat. This clears
|
|
1116
|
+
// both managed SSE and the self-driving poll on every daemon path.
|
|
1117
|
+
try { require('./src/gep/a2aProtocol').stopEventDelivery(); } catch (e) {}
|
|
1114
1118
|
// stopHeartbeat() clears the drift detector interval and the heartbeat
|
|
1115
1119
|
// timer, preventing "ghost tick" log noise after exit and ensuring a
|
|
1116
1120
|
// clean state if the process is somehow continued (test harness, etc.).
|
|
1117
1121
|
try { require('./src/gep/a2aProtocol').stopHeartbeat(); } catch (e) {}
|
|
1118
|
-
try { require('./src/gep/a2aProtocol').stopEventStream(); } catch (e) {}
|
|
1119
1122
|
}
|
|
1120
1123
|
process.on('exit', shutdown);
|
|
1121
1124
|
process.on('SIGINT', () => { shutdown(); process.exit(); });
|
|
@@ -1450,6 +1453,29 @@ async function main() {
|
|
|
1450
1453
|
clientSettings: {},
|
|
1451
1454
|
});
|
|
1452
1455
|
console.log('[Proxy] Started on ' + proxyInfo.url);
|
|
1456
|
+
const a2a = require('./src/gep/a2aProtocol');
|
|
1457
|
+
try {
|
|
1458
|
+
const lifecycle = proxyInfo && proxyInfo.proxy && proxyInfo.proxy.lifecycle;
|
|
1459
|
+
a2a.startEventDelivery({
|
|
1460
|
+
hubUrl: proxyInfo && proxyInfo.proxy && proxyInfo.proxy.hubUrl,
|
|
1461
|
+
nodeId: proxyInfo && proxyInfo.nodeId,
|
|
1462
|
+
// Proxy delivery uses SSE by default for real-time events. Operators
|
|
1463
|
+
// can explicitly disable the additional authenticated connection.
|
|
1464
|
+
enableSse: parseBoolEnv(process.env.EVOLVER_PROXY_SSE_ENABLED, true),
|
|
1465
|
+
identityProvider: lifecycle ? {
|
|
1466
|
+
getNodeId: function () { return lifecycle.nodeId; },
|
|
1467
|
+
getHeaders: function () { return lifecycle._buildHeaders(); },
|
|
1468
|
+
subscribe: function (listener) { return lifecycle.onDeliveryIdentityChange(listener); },
|
|
1469
|
+
} : null,
|
|
1470
|
+
onEventsAccepted: proxyInfo && proxyInfo.proxy
|
|
1471
|
+
? function (events) { proxyInfo.proxy.acceptHubEvents(events); }
|
|
1472
|
+
: null,
|
|
1473
|
+
});
|
|
1474
|
+
}
|
|
1475
|
+
catch (deliveryErr) {
|
|
1476
|
+
console.warn('[Events] startEventDelivery failed: ' +
|
|
1477
|
+
(deliveryErr && deliveryErr.message || deliveryErr));
|
|
1478
|
+
}
|
|
1453
1479
|
try {
|
|
1454
1480
|
const { injectProxyEnv } = require('./src/proxy/inject');
|
|
1455
1481
|
const injected = injectProxyEnv(proxyInfo);
|
|
@@ -1465,7 +1491,6 @@ async function main() {
|
|
|
1465
1491
|
registerMailboxTransport();
|
|
1466
1492
|
process.env.A2A_TRANSPORT = 'mailbox';
|
|
1467
1493
|
try {
|
|
1468
|
-
const a2a = require('./src/gep/a2aProtocol');
|
|
1469
1494
|
a2a.startSystemdNotifyWatchdog(function () {
|
|
1470
1495
|
try {
|
|
1471
1496
|
const proxy = proxyInfo && proxyInfo.proxy;
|
|
@@ -2552,10 +2577,27 @@ async function main() {
|
|
|
2552
2577
|
}
|
|
2553
2578
|
|
|
2554
2579
|
} else if (command === 'sync') {
|
|
2555
|
-
const {
|
|
2580
|
+
const {
|
|
2581
|
+
getHubUrl,
|
|
2582
|
+
getNodeId,
|
|
2583
|
+
buildHubHeaders,
|
|
2584
|
+
buildHubHeadersReadOnly,
|
|
2585
|
+
sendHelloToHub,
|
|
2586
|
+
getHubNodeSecret,
|
|
2587
|
+
getHubIdentityTupleReadOnly,
|
|
2588
|
+
} = require('./src/gep/a2aProtocol');
|
|
2556
2589
|
const { hubFetch } = require('./src/gep/hubFetch');
|
|
2557
|
-
const {
|
|
2590
|
+
const {
|
|
2591
|
+
upsertSyncedGene,
|
|
2592
|
+
upsertCapsule,
|
|
2593
|
+
loadGenes,
|
|
2594
|
+
loadGenesReadOnly,
|
|
2595
|
+
loadCapsules,
|
|
2596
|
+
loadCapsulesReadOnly,
|
|
2597
|
+
} = require('./src/gep/assetStore');
|
|
2598
|
+
const { prepareSyncAsset } = require('./src/gep/syncAsset');
|
|
2558
2599
|
const { getGepAssetsDir, getMemoryDir } = require('./src/gep/paths');
|
|
2600
|
+
const dryRun = args.includes('--dry-run');
|
|
2559
2601
|
|
|
2560
2602
|
const hubUrl = getHubUrl();
|
|
2561
2603
|
if (!hubUrl) {
|
|
@@ -2564,7 +2606,10 @@ async function main() {
|
|
|
2564
2606
|
}
|
|
2565
2607
|
|
|
2566
2608
|
try {
|
|
2567
|
-
|
|
2609
|
+
const readOnlyIdentity = dryRun ? getHubIdentityTupleReadOnly() : null;
|
|
2610
|
+
const nodeSecret = dryRun ? readOnlyIdentity.secret : getHubNodeSecret();
|
|
2611
|
+
const nodeSecretVersion = dryRun ? readOnlyIdentity.version : null;
|
|
2612
|
+
if (!nodeSecret && !dryRun) {
|
|
2568
2613
|
// Round-7 (Β§20.7): refuse a fresh hello if a live daemon owns
|
|
2569
2614
|
// the lock; the daemon's secret will appear shortly.
|
|
2570
2615
|
refuseHelloIfDaemonRunning('sync');
|
|
@@ -2577,7 +2622,21 @@ async function main() {
|
|
|
2577
2622
|
console.log('[sync] Registered as ' + getNodeId());
|
|
2578
2623
|
}
|
|
2579
2624
|
|
|
2580
|
-
const
|
|
2625
|
+
const hubHeaders = dryRun
|
|
2626
|
+
? function () {
|
|
2627
|
+
const headers = buildHubHeadersReadOnly(nodeSecret, nodeSecretVersion);
|
|
2628
|
+
if (!headers.Authorization) {
|
|
2629
|
+
throw new Error('Dry-run requires an existing node_secret or a valid OAuth access token; refusing an unauthenticated Hub request.');
|
|
2630
|
+
}
|
|
2631
|
+
return headers;
|
|
2632
|
+
}
|
|
2633
|
+
: buildHubHeaders;
|
|
2634
|
+
if (dryRun) hubHeaders();
|
|
2635
|
+
const nodeId = dryRun ? readOnlyIdentity.nodeId : getNodeId();
|
|
2636
|
+
if (dryRun && !nodeId) {
|
|
2637
|
+
console.error('[sync] Dry-run requires an existing node_id; refusing to generate identity state.');
|
|
2638
|
+
process.exit(1);
|
|
2639
|
+
}
|
|
2581
2640
|
const baseUrl = hubUrl.replace(/\/+$/, '');
|
|
2582
2641
|
const typeFilter = (function () {
|
|
2583
2642
|
const f = args.find(function (a) { return typeof a === 'string' && a.startsWith('--type='); });
|
|
@@ -2595,7 +2654,6 @@ async function main() {
|
|
|
2595
2654
|
const f = args.find(function (a) { return typeof a === 'string' && a.startsWith('--export='); });
|
|
2596
2655
|
return f ? f.slice('--export='.length) : null;
|
|
2597
2656
|
})();
|
|
2598
|
-
const dryRun = args.includes('--dry-run');
|
|
2599
2657
|
const listUnpublished = !args.includes('--no-unpublished-list');
|
|
2600
2658
|
const force = args.includes('--force');
|
|
2601
2659
|
const limitPerPage = 100;
|
|
@@ -2624,7 +2682,7 @@ async function main() {
|
|
|
2624
2682
|
}
|
|
2625
2683
|
const resp = await hubFetch(url, {
|
|
2626
2684
|
method: 'GET',
|
|
2627
|
-
headers:
|
|
2685
|
+
headers: hubHeaders(),
|
|
2628
2686
|
signal: AbortSignal.timeout(30000),
|
|
2629
2687
|
});
|
|
2630
2688
|
if (!resp.ok) {
|
|
@@ -2672,8 +2730,8 @@ async function main() {
|
|
|
2672
2730
|
}
|
|
2673
2731
|
}
|
|
2674
2732
|
|
|
2675
|
-
const existingGenes = dryRun ?
|
|
2676
|
-
const existingCapsules = loadCapsules();
|
|
2733
|
+
const existingGenes = dryRun ? loadGenesReadOnly() : loadGenes();
|
|
2734
|
+
const existingCapsules = dryRun ? loadCapsulesReadOnly() : loadCapsules();
|
|
2677
2735
|
// Dedup by Hub asset_id is the only safe key. Local-facing `id` (e.g.
|
|
2678
2736
|
// `gene_gep_repair_from_errors`) collides between bundled default seed
|
|
2679
2737
|
// genes and identically-named assets that the user later published, so
|
|
@@ -2689,6 +2747,8 @@ async function main() {
|
|
|
2689
2747
|
}
|
|
2690
2748
|
const localGeneIds = new Set(existingGenes.filter(function (g) { return g && g.id; }).map(function (g) { return g.id; }));
|
|
2691
2749
|
const localCapsuleIds = new Set(existingCapsules.filter(function (c) { return c && c.id; }).map(function (c) { return c.id; }));
|
|
2750
|
+
const batchGeneIds = new Map();
|
|
2751
|
+
const batchCapsuleIds = new Map();
|
|
2692
2752
|
|
|
2693
2753
|
let synced = 0;
|
|
2694
2754
|
let skippedAlreadySynced = 0;
|
|
@@ -2713,81 +2773,99 @@ async function main() {
|
|
|
2713
2773
|
continue;
|
|
2714
2774
|
}
|
|
2715
2775
|
|
|
2716
|
-
|
|
2717
|
-
//
|
|
2718
|
-
//
|
|
2719
|
-
//
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
continue;
|
|
2776
|
+
const localIds = assetType === 'Gene' ? localGeneIds : localCapsuleIds;
|
|
2777
|
+
// The list response is the only identity hint available until detail
|
|
2778
|
+
// fetch and payload validation succeed. If it already names a local
|
|
2779
|
+
// entry, fail closed on those preliminary failures: preserve the local
|
|
2780
|
+
// copy and let --force make the overwrite intent explicit.
|
|
2781
|
+
const hasListIdCollision = !force && localIds.has(localId);
|
|
2782
|
+
function skipUnverifiedListIdCollision(stage) {
|
|
2783
|
+
if (isVerbose) {
|
|
2784
|
+
console.warn(
|
|
2785
|
+
' [sync] Skipping ' + JSON.stringify(String(localId)) +
|
|
2786
|
+
' (local id collision; ' + stage +
|
|
2787
|
+
'; pass --force to overwrite with Hub copy)'
|
|
2788
|
+
);
|
|
2730
2789
|
}
|
|
2790
|
+
skippedIdCollision++;
|
|
2731
2791
|
}
|
|
2732
2792
|
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
continue;
|
|
2737
|
-
}
|
|
2738
|
-
|
|
2739
|
-
try {
|
|
2740
|
-
let payload = asset.payload;
|
|
2741
|
-
if (!payload) {
|
|
2793
|
+
let payload = asset.payload;
|
|
2794
|
+
if (!payload) {
|
|
2795
|
+
try {
|
|
2742
2796
|
const detailResp = await hubFetch(baseUrl + '/a2a/assets/' + encodeURIComponent(assetId) + '?detailed=true', {
|
|
2743
2797
|
method: 'GET',
|
|
2744
|
-
headers:
|
|
2798
|
+
headers: hubHeaders(),
|
|
2745
2799
|
signal: AbortSignal.timeout(15000),
|
|
2746
2800
|
});
|
|
2747
2801
|
if (!detailResp.ok) {
|
|
2748
|
-
|
|
2749
|
-
fetchErrors++;
|
|
2750
|
-
continue;
|
|
2802
|
+
throw new Error('detail HTTP ' + detailResp.status);
|
|
2751
2803
|
}
|
|
2752
2804
|
const detail = await detailResp.json();
|
|
2753
|
-
payload = detail.payload
|
|
2805
|
+
payload = detail && detail.payload;
|
|
2806
|
+
} catch (detailErr) {
|
|
2807
|
+
if (hasListIdCollision) {
|
|
2808
|
+
skipUnverifiedListIdCollision('could not fetch Hub detail');
|
|
2809
|
+
} else {
|
|
2810
|
+
if (isVerbose) console.warn(' [sync] Error fetching ' + assetId + ': ' + (detailErr && detailErr.message || detailErr));
|
|
2811
|
+
fetchErrors++;
|
|
2812
|
+
}
|
|
2813
|
+
continue;
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
|
|
2817
|
+
let syncAsset;
|
|
2818
|
+
try {
|
|
2819
|
+
const syncedAt = new Date().toISOString();
|
|
2820
|
+
syncAsset = prepareSyncAsset({
|
|
2821
|
+
assetType,
|
|
2822
|
+
payload,
|
|
2823
|
+
assetId,
|
|
2824
|
+
localId,
|
|
2825
|
+
summary: asset.summary || '',
|
|
2826
|
+
syncedAt,
|
|
2827
|
+
});
|
|
2828
|
+
} catch (prepareErr) {
|
|
2829
|
+
if (hasListIdCollision) {
|
|
2830
|
+
skipUnverifiedListIdCollision('could not validate Hub payload');
|
|
2831
|
+
} else {
|
|
2832
|
+
if (isVerbose) console.warn(' [sync] Error fetching ' + assetId + ': ' + (prepareErr && prepareErr.message || prepareErr));
|
|
2833
|
+
fetchErrors++;
|
|
2834
|
+
}
|
|
2835
|
+
continue;
|
|
2836
|
+
}
|
|
2837
|
+
|
|
2838
|
+
try {
|
|
2839
|
+
const effectiveLocalId = syncAsset.id;
|
|
2840
|
+
const batchIds = assetType === 'Gene' ? batchGeneIds : batchCapsuleIds;
|
|
2841
|
+
const batchAssetId = batchIds.get(effectiveLocalId);
|
|
2842
|
+
|
|
2843
|
+
if (batchAssetId && batchAssetId !== String(assetId)) {
|
|
2844
|
+
throw new Error('duplicate local id ' + effectiveLocalId + ' in Hub batch (' + batchAssetId + ', ' + assetId + ')');
|
|
2845
|
+
}
|
|
2846
|
+
batchIds.set(effectiveLocalId, String(assetId));
|
|
2847
|
+
|
|
2848
|
+
// Local-id collision: a local entry with the same user-facing id
|
|
2849
|
+
// already exists but has no matching hub_asset_id. Without --force
|
|
2850
|
+
// we keep the local entry and report the collision.
|
|
2851
|
+
if (!force && localIds.has(effectiveLocalId)) {
|
|
2852
|
+
if (isVerbose) console.warn(' [sync] Skipping ' + effectiveLocalId + ' (local id collision; pass --force to overwrite with Hub copy)');
|
|
2853
|
+
skippedIdCollision++;
|
|
2854
|
+
continue;
|
|
2754
2855
|
}
|
|
2755
2856
|
|
|
2756
|
-
if (
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
category: payload.category || 'unknown',
|
|
2761
|
-
signals: Array.isArray(payload.signals) ? payload.signals : [],
|
|
2762
|
-
strategy: Array.isArray(payload.strategy) ? payload.strategy : [],
|
|
2763
|
-
avoid: Array.isArray(payload.avoid) ? payload.avoid : [],
|
|
2764
|
-
validation: payload.validation || {},
|
|
2765
|
-
summary: payload.summary || asset.summary || '',
|
|
2766
|
-
hub_asset_id: assetId,
|
|
2767
|
-
synced_at: new Date().toISOString(),
|
|
2768
|
-
};
|
|
2769
|
-
upsertGene(geneObj);
|
|
2770
|
-
localGeneIds.add(geneObj.id);
|
|
2771
|
-
localHubAssetIds.add(String(assetId));
|
|
2857
|
+
if (dryRun) {
|
|
2858
|
+
console.log(' [dry-run] Would sync: ' + assetType + ' ' + assetId + (force ? ' (force)' : ''));
|
|
2859
|
+
} else if (assetType === 'Gene') {
|
|
2860
|
+
upsertSyncedGene(syncAsset);
|
|
2772
2861
|
} else {
|
|
2773
|
-
|
|
2774
|
-
type: 'Capsule',
|
|
2775
|
-
id: payload.id || localId,
|
|
2776
|
-
gene: payload.gene || null,
|
|
2777
|
-
genes_used: Array.isArray(payload.genes_used) ? payload.genes_used : [],
|
|
2778
|
-
outcome: payload.outcome || {},
|
|
2779
|
-
execution_trace: payload.execution_trace || {},
|
|
2780
|
-
summary: payload.summary || asset.summary || '',
|
|
2781
|
-
hub_asset_id: assetId,
|
|
2782
|
-
synced_at: new Date().toISOString(),
|
|
2783
|
-
};
|
|
2784
|
-
upsertCapsule(capsuleObj);
|
|
2785
|
-
localCapsuleIds.add(capsuleObj.id);
|
|
2786
|
-
localHubAssetIds.add(String(assetId));
|
|
2862
|
+
upsertCapsule(syncAsset);
|
|
2787
2863
|
}
|
|
2864
|
+
localIds.add(effectiveLocalId);
|
|
2865
|
+
localHubAssetIds.add(String(assetId));
|
|
2788
2866
|
synced++;
|
|
2789
|
-
} catch (
|
|
2790
|
-
if (isVerbose) console.warn(' [sync] Error
|
|
2867
|
+
} catch (syncErr) {
|
|
2868
|
+
if (isVerbose) console.warn(' [sync] Error syncing ' + assetId + ': ' + (syncErr && syncErr.message || syncErr));
|
|
2791
2869
|
fetchErrors++;
|
|
2792
2870
|
}
|
|
2793
2871
|
}
|
|
@@ -2798,7 +2876,7 @@ async function main() {
|
|
|
2798
2876
|
console.log('[sync] ' + skippedIdCollision + ' Hub asset(s) share a local id with an existing local entry that has no hub_asset_id.');
|
|
2799
2877
|
console.log('[sync] Re-run with --force to overwrite those local entries with the Hub copies.');
|
|
2800
2878
|
}
|
|
2801
|
-
if (dryRun) console.log('[sync] (dry-run mode: no files were modified)');
|
|
2879
|
+
if (dryRun) console.log('[sync] (dry-run mode: no asset-store or export files were modified)');
|
|
2802
2880
|
|
|
2803
2881
|
if (listUnpublished && doPublished) {
|
|
2804
2882
|
const hubGeneIds = new Set();
|
|
@@ -2849,6 +2927,7 @@ async function main() {
|
|
|
2849
2927
|
}
|
|
2850
2928
|
}
|
|
2851
2929
|
}
|
|
2930
|
+
if (fetchErrors > 0) process.exitCode = 1;
|
|
2852
2931
|
} catch (error) {
|
|
2853
2932
|
if (error && error.name === 'TimeoutError') {
|
|
2854
2933
|
console.error('[sync] Request timed out. Check your network and A2A_HUB_URL.');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evomap/evolver",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.92.1",
|
|
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": {
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"@evomap/atp-sdk": "^0.1.0",
|
|
42
42
|
"@evomap/gep-sdk": "^1.5.0",
|
|
43
43
|
"dotenv": "^16.4.7",
|
|
44
|
+
"eventsource": "^4.1.0",
|
|
44
45
|
"undici": "^7.28.0"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
@@ -402,6 +402,15 @@ function findMemoryGraph(evolverRoot) {
|
|
|
402
402
|
return path.join(userDir, 'memory_graph.jsonl');
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
+
function gitExecutable() {
|
|
406
|
+
if (process.platform !== 'win32') {
|
|
407
|
+
const xcodeGit = '/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git';
|
|
408
|
+
if (fs.existsSync(xcodeGit)) return xcodeGit;
|
|
409
|
+
if (fs.existsSync('/usr/bin/git')) return '/usr/bin/git';
|
|
410
|
+
}
|
|
411
|
+
return 'git';
|
|
412
|
+
}
|
|
413
|
+
|
|
405
414
|
// Is `dir` inside a git work tree? Cheap, no-shell `git rev-parse`. Returns
|
|
406
415
|
// false on any error (git missing, not a repo, timeout) and never throws.
|
|
407
416
|
// The session-start hook uses this only to decide whether to surface a
|
|
@@ -409,7 +418,7 @@ function findMemoryGraph(evolverRoot) {
|
|
|
409
418
|
// suppresses the notice rather than breaking anything.
|
|
410
419
|
function isGitWorkspace(dir) {
|
|
411
420
|
try {
|
|
412
|
-
const res = spawnSync(
|
|
421
|
+
const res = spawnSync(gitExecutable(), ['rev-parse', '--is-inside-work-tree'], {
|
|
413
422
|
cwd: dir,
|
|
414
423
|
encoding: 'utf8',
|
|
415
424
|
timeout: 5000,
|
|
@@ -24,12 +24,21 @@ const { findEvolverRoot, findMemoryGraph, resolveProjectDir, resolveWorkspaceId
|
|
|
24
24
|
// consistent with the review-time reader in src/evolve/pipeline/collect.js
|
|
25
25
|
// (Bugbot PR #109 round-1 MEDIUM; reader/writer drift flagged on PR #555).
|
|
26
26
|
|
|
27
|
+
function gitExecutable() {
|
|
28
|
+
if (process.platform !== 'win32') {
|
|
29
|
+
const xcodeGit = '/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git';
|
|
30
|
+
if (fs.existsSync(xcodeGit)) return xcodeGit;
|
|
31
|
+
if (fs.existsSync('/usr/bin/git')) return '/usr/bin/git';
|
|
32
|
+
}
|
|
33
|
+
return 'git';
|
|
34
|
+
}
|
|
35
|
+
|
|
27
36
|
function runGit(args, cwd) {
|
|
28
37
|
// Argv-array form, no shell. Avoids POSIX `2>/dev/null` redirects that
|
|
29
38
|
// break on Windows cmd.exe (#537). Failures (e.g. no HEAD~1 in a fresh
|
|
30
39
|
// repo) are surfaced as a non-zero status; callers distinguish them
|
|
31
40
|
// from successful empty output via the `ok` flag (PR #94 round-6 LOW).
|
|
32
|
-
const res = spawnSync(
|
|
41
|
+
const res = spawnSync(gitExecutable(), args, {
|
|
33
42
|
cwd,
|
|
34
43
|
encoding: 'utf8',
|
|
35
44
|
timeout: 5000,
|