@evomap/evolver 1.76.0 → 1.78.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.
@@ -1 +1 @@
1
- {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-04-30T03:41:51.291Z","signals":["memory_missing","user_missing","session_logs_missing"],"tags":["memory_missing","user_missing","session_logs_missing","area:memory"],"shape":{"title":"Harden session log detection and fallback behavior","input":"Recent session transcript + memory snippets + user instructions","output":"A safe, auditable evolution patch guided by GEP assets","invariants":"Protocol order, small reversible patches, validation, append-only events","params":"Signals: memory_missing, user_missing, session_logs_missing","failure_points":"Missing signals, over-broad changes, skipped validation, missing knowledge solidification","evidence":"Signal present: session_logs_missing"}}
1
+ {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-05-01T10:17:21.517Z","signals":["memory_missing","user_missing","session_logs_missing"],"tags":["memory_missing","user_missing","session_logs_missing","area:memory"],"shape":{"title":"Harden session log detection and fallback behavior","input":"Recent session transcript + memory snippets + user instructions","output":"A safe, auditable evolution patch guided by GEP assets","invariants":"Protocol order, small reversible patches, validation, append-only events","params":"Signals: memory_missing, user_missing, session_logs_missing","failure_points":"Missing signals, over-broad changes, skipped validation, missing knowledge solidification","evidence":"Signal present: session_logs_missing"}}
package/index.js CHANGED
@@ -1028,6 +1028,7 @@ async function main() {
1028
1028
  } else if (command === 'sync') {
1029
1029
  const { getHubUrl, getNodeId, buildHubHeaders, sendHelloToHub, getHubNodeSecret } = require('./src/gep/a2aProtocol');
1030
1030
  const { upsertGene, upsertCapsule, loadGenes, loadCapsules } = require('./src/gep/assetStore');
1031
+ const { getGepAssetsDir, getMemoryDir } = require('./src/gep/paths');
1031
1032
 
1032
1033
  const hubUrl = getHubUrl();
1033
1034
  if (!hubUrl) {
@@ -1052,52 +1053,92 @@ async function main() {
1052
1053
  const f = args.find(function (a) { return typeof a === 'string' && a.startsWith('--type='); });
1053
1054
  return f ? f.slice('--type='.length) : null;
1054
1055
  })();
1056
+ const scopeArg = (function () {
1057
+ const f = args.find(function (a) { return typeof a === 'string' && a.startsWith('--scope='); });
1058
+ return f ? f.slice('--scope='.length) : 'all';
1059
+ })();
1060
+ const statusFilter = (function () {
1061
+ const f = args.find(function (a) { return typeof a === 'string' && a.startsWith('--status='); });
1062
+ return f ? f.slice('--status='.length) : null;
1063
+ })();
1064
+ const exportPath = (function () {
1065
+ const f = args.find(function (a) { return typeof a === 'string' && a.startsWith('--export='); });
1066
+ return f ? f.slice('--export='.length) : null;
1067
+ })();
1055
1068
  const dryRun = args.includes('--dry-run');
1069
+ const listUnpublished = !args.includes('--no-unpublished-list');
1056
1070
  const limitPerPage = 100;
1057
1071
 
1058
- console.log('[sync] Fetching purchased assets from Hub...');
1059
- let allAssets = [];
1060
- let cursor = null;
1061
- let page = 0;
1062
-
1063
- while (true) {
1064
- page++;
1065
- let url = baseUrl + '/a2a/assets/purchased?node_id=' + encodeURIComponent(nodeId) + '&limit=' + limitPerPage;
1066
- if (cursor) url += '&cursor=' + encodeURIComponent(cursor);
1067
- if (typeFilter) url += '&type=' + encodeURIComponent(typeFilter);
1068
-
1069
- const resp = await fetch(url, {
1070
- method: 'GET',
1071
- headers: buildHubHeaders(),
1072
- signal: AbortSignal.timeout(30000),
1073
- });
1072
+ const validScopes = new Set(['all', 'purchased', 'published']);
1073
+ if (!validScopes.has(scopeArg)) {
1074
+ console.error('[sync] Invalid --scope=' + scopeArg + '. Expected: all, purchased, published.');
1075
+ process.exit(1);
1076
+ }
1077
+ const doPurchased = scopeArg === 'all' || scopeArg === 'purchased';
1078
+ const doPublished = scopeArg === 'all' || scopeArg === 'published';
1074
1079
 
1075
- if (!resp.ok) {
1076
- const body = await resp.text().catch(function () { return ''; });
1077
- console.error('[sync] Hub returned HTTP ' + resp.status + ': ' + body.slice(0, 500));
1078
- process.exit(1);
1080
+ async function fetchAllPages(endpoint, extraParams) {
1081
+ const out = [];
1082
+ let cursor = null;
1083
+ let page = 0;
1084
+ while (true) {
1085
+ page++;
1086
+ let url = baseUrl + endpoint + '?node_id=' + encodeURIComponent(nodeId) + '&limit=' + limitPerPage;
1087
+ if (cursor) url += '&cursor=' + encodeURIComponent(cursor);
1088
+ if (typeFilter) url += '&type=' + encodeURIComponent(typeFilter);
1089
+ if (extraParams) {
1090
+ for (const [k, v] of Object.entries(extraParams)) {
1091
+ if (v != null) url += '&' + k + '=' + encodeURIComponent(v);
1092
+ }
1093
+ }
1094
+ const resp = await fetch(url, {
1095
+ method: 'GET',
1096
+ headers: buildHubHeaders(),
1097
+ signal: AbortSignal.timeout(30000),
1098
+ });
1099
+ if (!resp.ok) {
1100
+ const body = await resp.text().catch(function () { return ''; });
1101
+ throw new Error('Hub HTTP ' + resp.status + ' on ' + endpoint + ': ' + body.slice(0, 500));
1102
+ }
1103
+ const data = await resp.json();
1104
+ if (Array.isArray(data.assets)) out.push.apply(out, data.assets);
1105
+ if (isVerbose) console.log('[sync] ' + endpoint + ' page ' + page + ': ' + (data.count || 0) + ' (total ' + out.length + ')');
1106
+ if (data.has_more && data.next_cursor) cursor = data.next_cursor;
1107
+ else break;
1079
1108
  }
1109
+ return out;
1110
+ }
1080
1111
 
1081
- const data = await resp.json();
1082
- if (Array.isArray(data.assets)) {
1083
- allAssets = allAssets.concat(data.assets);
1084
- }
1085
- if (isVerbose) console.log('[sync] Page ' + page + ': ' + (data.count || 0) + ' assets (total so far: ' + allAssets.length + ')');
1112
+ let purchasedAssets = [];
1113
+ let publishedAssets = [];
1086
1114
 
1087
- if (data.has_more && data.next_cursor) {
1088
- cursor = data.next_cursor;
1089
- } else {
1090
- break;
1115
+ if (doPurchased) {
1116
+ console.log('[sync] Fetching purchased assets from Hub...');
1117
+ purchasedAssets = await fetchAllPages('/a2a/assets/purchased');
1118
+ console.log('[sync] purchased: ' + purchasedAssets.length + ' asset(s)');
1119
+ }
1120
+ if (doPublished) {
1121
+ console.log('[sync] Fetching published-by-me assets from Hub (includes drafts)...');
1122
+ publishedAssets = await fetchAllPages('/a2a/assets/published-by-me', { status: statusFilter });
1123
+ console.log('[sync] published: ' + publishedAssets.length + ' asset(s)');
1124
+ }
1125
+
1126
+ const seen = new Set();
1127
+ const allAssets = [];
1128
+ for (const src of [purchasedAssets, publishedAssets]) {
1129
+ for (const asset of src) {
1130
+ if (!asset || !asset.asset_id) continue;
1131
+ if (seen.has(asset.asset_id)) continue;
1132
+ seen.add(asset.asset_id);
1133
+ allAssets.push(asset);
1091
1134
  }
1092
1135
  }
1093
1136
 
1094
- if (allAssets.length === 0) {
1095
- console.log('[sync] No purchased assets found on Hub.');
1137
+ if (allAssets.length === 0 && !exportPath) {
1138
+ console.log('[sync] No assets to sync.');
1096
1139
  process.exit(0);
1097
1140
  }
1098
1141
 
1099
- console.log('[sync] Found ' + allAssets.length + ' purchased asset(s). Syncing to local store...');
1100
-
1101
1142
  const existingGenes = loadGenes();
1102
1143
  const existingCapsules = loadCapsules();
1103
1144
  const localGeneIds = new Set(existingGenes.filter(function (g) { return g && g.id; }).map(function (g) { return g.id; }));
@@ -1110,19 +1151,14 @@ async function main() {
1110
1151
  for (const asset of allAssets) {
1111
1152
  const assetId = asset.asset_id;
1112
1153
  const assetType = asset.asset_type;
1154
+ const localId = asset.local_id || assetId;
1113
1155
 
1114
- if (assetType === 'Gene' && localGeneIds.has(asset.local_id || assetId)) {
1115
- skipped++;
1116
- continue;
1117
- }
1118
- if (assetType === 'Capsule' && localCapsuleIds.has(asset.local_id || assetId)) {
1119
- skipped++;
1120
- continue;
1121
- }
1122
1156
  if (assetType !== 'Gene' && assetType !== 'Capsule') {
1123
1157
  skipped++;
1124
1158
  continue;
1125
1159
  }
1160
+ if (assetType === 'Gene' && localGeneIds.has(localId)) { skipped++; continue; }
1161
+ if (assetType === 'Capsule' && localCapsuleIds.has(localId)) { skipped++; continue; }
1126
1162
 
1127
1163
  if (dryRun) {
1128
1164
  console.log(' [dry-run] Would sync: ' + assetType + ' ' + assetId);
@@ -1131,31 +1167,32 @@ async function main() {
1131
1167
  }
1132
1168
 
1133
1169
  try {
1134
- const detailResp = await fetch(baseUrl + '/a2a/assets/' + encodeURIComponent(assetId) + '?detailed=true', {
1135
- method: 'GET',
1136
- headers: buildHubHeaders(),
1137
- signal: AbortSignal.timeout(15000),
1138
- });
1139
-
1140
- if (!detailResp.ok) {
1141
- if (isVerbose) console.warn(' [sync] Failed to fetch detail for ' + assetId + ' (HTTP ' + detailResp.status + ')');
1142
- fetchErrors++;
1143
- continue;
1170
+ let payload = asset.payload;
1171
+ if (!payload) {
1172
+ const detailResp = await fetch(baseUrl + '/a2a/assets/' + encodeURIComponent(assetId) + '?detailed=true', {
1173
+ method: 'GET',
1174
+ headers: buildHubHeaders(),
1175
+ signal: AbortSignal.timeout(15000),
1176
+ });
1177
+ if (!detailResp.ok) {
1178
+ if (isVerbose) console.warn(' [sync] Failed to fetch detail for ' + assetId + ' (HTTP ' + detailResp.status + ')');
1179
+ fetchErrors++;
1180
+ continue;
1181
+ }
1182
+ const detail = await detailResp.json();
1183
+ payload = detail.payload || {};
1144
1184
  }
1145
1185
 
1146
- const detail = await detailResp.json();
1147
- const payload = detail.payload || {};
1148
-
1149
1186
  if (assetType === 'Gene') {
1150
1187
  const geneObj = {
1151
1188
  type: 'Gene',
1152
- id: payload.id || asset.local_id || assetId,
1189
+ id: payload.id || localId,
1153
1190
  category: payload.category || 'unknown',
1154
1191
  signals: Array.isArray(payload.signals) ? payload.signals : [],
1155
1192
  strategy: Array.isArray(payload.strategy) ? payload.strategy : [],
1156
1193
  avoid: Array.isArray(payload.avoid) ? payload.avoid : [],
1157
1194
  validation: payload.validation || {},
1158
- summary: payload.summary || detail.summary || asset.summary || '',
1195
+ summary: payload.summary || asset.summary || '',
1159
1196
  hub_asset_id: assetId,
1160
1197
  synced_at: new Date().toISOString(),
1161
1198
  };
@@ -1164,12 +1201,12 @@ async function main() {
1164
1201
  } else {
1165
1202
  const capsuleObj = {
1166
1203
  type: 'Capsule',
1167
- id: payload.id || asset.local_id || assetId,
1204
+ id: payload.id || localId,
1168
1205
  gene: payload.gene || null,
1169
1206
  genes_used: Array.isArray(payload.genes_used) ? payload.genes_used : [],
1170
1207
  outcome: payload.outcome || {},
1171
1208
  execution_trace: payload.execution_trace || {},
1172
- summary: payload.summary || detail.summary || asset.summary || '',
1209
+ summary: payload.summary || asset.summary || '',
1173
1210
  hub_asset_id: assetId,
1174
1211
  synced_at: new Date().toISOString(),
1175
1212
  };
@@ -1183,8 +1220,58 @@ async function main() {
1183
1220
  }
1184
1221
  }
1185
1222
 
1186
- console.log('[sync] Done. synced=' + synced + ' skipped=' + skipped + ' errors=' + fetchErrors);
1223
+ console.log('[sync] Done. scope=' + scopeArg + ' synced=' + synced + ' skipped=' + skipped + ' errors=' + fetchErrors);
1187
1224
  if (dryRun) console.log('[sync] (dry-run mode: no files were modified)');
1225
+
1226
+ if (listUnpublished && doPublished) {
1227
+ const hubGeneIds = new Set();
1228
+ const hubCapsuleIds = new Set();
1229
+ for (const a of publishedAssets) {
1230
+ const lid = a.local_id || a.asset_id;
1231
+ if (a.asset_type === 'Gene') hubGeneIds.add(lid);
1232
+ else if (a.asset_type === 'Capsule') hubCapsuleIds.add(lid);
1233
+ }
1234
+ const unpublishedGenes = existingGenes.filter(function (g) {
1235
+ return g && g.id && !hubGeneIds.has(g.id) && !g.hub_asset_id;
1236
+ });
1237
+ const unpublishedCapsules = existingCapsules.filter(function (c) {
1238
+ return c && c.id && !hubCapsuleIds.has(c.id) && !c.hub_asset_id;
1239
+ });
1240
+ if (unpublishedGenes.length || unpublishedCapsules.length) {
1241
+ console.log('[sync] Local-only (not on Hub): genes=' + unpublishedGenes.length + ' capsules=' + unpublishedCapsules.length);
1242
+ if (isVerbose) {
1243
+ for (const g of unpublishedGenes.slice(0, 20)) console.log(' gene: ' + g.id);
1244
+ for (const c of unpublishedCapsules.slice(0, 20)) console.log(' capsule: ' + c.id);
1245
+ if (unpublishedGenes.length + unpublishedCapsules.length > 40) {
1246
+ console.log(' ... (truncated; use --export=<path>.gepx to bundle all)');
1247
+ }
1248
+ }
1249
+ }
1250
+ }
1251
+
1252
+ if (exportPath) {
1253
+ if (dryRun) {
1254
+ console.log('[sync] [dry-run] Would export to ' + exportPath);
1255
+ } else {
1256
+ const { exportGepx } = require('./src/gep/portable');
1257
+ const assetsDir = getGepAssetsDir();
1258
+ const memoryGraphPath = require('path').join(getMemoryDir(), 'memory_graph.jsonl');
1259
+ try {
1260
+ const result = exportGepx({
1261
+ assetsDir,
1262
+ memoryGraphPath,
1263
+ outputPath: exportPath,
1264
+ agentId: nodeId,
1265
+ agentName: process.env.AGENT_NAME || 'evolver',
1266
+ });
1267
+ console.log('[sync] Exported .gepx -> ' + result.outputPath);
1268
+ console.log('[sync] stats: ' + JSON.stringify(result.manifest.statistics));
1269
+ } catch (exportErr) {
1270
+ console.error('[sync] Export failed: ' + (exportErr && exportErr.message || exportErr));
1271
+ process.exit(1);
1272
+ }
1273
+ }
1274
+ }
1188
1275
  } catch (error) {
1189
1276
  if (error && error.name === 'TimeoutError') {
1190
1277
  console.error('[sync] Request timed out. Check your network and A2A_HUB_URL.');
@@ -1343,8 +1430,12 @@ async function main() {
1343
1430
  - --skill=<id> | -s <id> (skill ID to download)
1344
1431
  - --out=<dir> (output directory, default: ./skills/<skill_id>)
1345
1432
  - sync flags:
1346
- - --type=Gene|Capsule (filter by asset type)
1347
- - --dry-run (preview without writing to local store)
1433
+ - --scope=all|purchased|published (default: all)
1434
+ - --type=Gene|Capsule (filter by asset type)
1435
+ - --status=draft,promoted,all (only for published scope; default promoted+draft)
1436
+ - --export=<path.gepx> (also bundle local assets into a .gepx archive)
1437
+ - --no-unpublished-list (suppress local-only asset list)
1438
+ - --dry-run (preview without writing to local store)
1348
1439
  - solidify flags:
1349
1440
  - --dry-run
1350
1441
  - --no-rollback
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evomap/evolver",
3
- "version": "1.76.0",
3
+ "version": "1.78.0",
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": {