@evomap/evolver 1.70.0-beta.1 → 1.70.0-beta.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.
@@ -1,3 +1,3 @@
1
- {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-04-23T06:02:57.897Z","signals":["bounty_task","external_task","what","understand","really","dont","explanation.","memory_missing","user_missing","session_logs_missing"],"tags":["bounty_task","external_task","what","understand","really","dont","explanation.","memory_missing","user_missing","session_logs_missing","area:orchestration","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: bounty_task, external_task, what, understand, really, dont, explanation., 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"}}
2
- {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-04-23T06:03:00.033Z","signals":["bounty_task","external_task","human","new","very","grow","how","memory_missing","user_missing","session_logs_missing"],"tags":["bounty_task","external_task","human","new","very","grow","how","memory_missing","user_missing","session_logs_missing","area:orchestration","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: bounty_task, external_task, human, new, very, grow, how, 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"}}
3
- {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-04-23T06:03:01.960Z","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-04-24T04:45:45.103Z","signals":["bounty_task","external_task","learning","for","library","resource","create","resource-list","Engine","Unreal","rendering","real-time","3d-modeling","3d","3d-generation","memory_missing","user_missing","session_logs_missing"],"tags":["bounty_task","external_task","learning","for","library","resource","create","resource-list","Engine","Unreal","rendering","real-time","3d-modeling","3d","3d-generation","memory_missing","user_missing","session_logs_missing","area:orchestration","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: bounty_task, external_task, learning, for, library, resource, create, resource-list, Engine, Unreal, rendering, real-time, 3d-modeling, 3d, 3d-generation, 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"}}
2
+ {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-04-24T04:45:47.032Z","signals":["bounty_task","external_task","learning","for","library","resource","create","resource-list","Engine","Unreal","rendering","real-time","3d-modeling","3d","3d-generation","memory_missing","user_missing","session_logs_missing"],"tags":["bounty_task","external_task","learning","for","library","resource","create","resource-list","Engine","Unreal","rendering","real-time","3d-modeling","3d","3d-generation","memory_missing","user_missing","session_logs_missing","area:orchestration","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: bounty_task, external_task, learning, for, library, resource, create, resource-list, Engine, Unreal, rendering, real-time, 3d-modeling, 3d, 3d-generation, 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"}}
3
+ {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-04-24T04:45:48.941Z","signals":["bounty_task","external_task","learning","for","library","resource","create","resource-list","Engine","Unreal","rendering","real-time","3d-modeling","3d","3d-generation","memory_missing","user_missing","session_logs_missing"],"tags":["bounty_task","external_task","learning","for","library","resource","create","resource-list","Engine","Unreal","rendering","real-time","3d-modeling","3d","3d-generation","memory_missing","user_missing","session_logs_missing","area:orchestration","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: bounty_task, external_task, learning, for, library, resource, create, resource-list, Engine, Unreal, rendering, real-time, 3d-modeling, 3d, 3d-generation, 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"}}
@@ -78,7 +78,8 @@
78
78
  "perf_bottleneck",
79
79
  "capability_gap",
80
80
  "stable_success_plateau",
81
- "external_opportunity"
81
+ "external_opportunity",
82
+ "bounty_task"
82
83
  ],
83
84
  "preconditions": [
84
85
  "at least one opportunity signal is present",
@@ -105,6 +106,43 @@
105
106
  "node scripts/validate-suite.js"
106
107
  ]
107
108
  },
109
+ {
110
+ "type": "Gene",
111
+ "id": "gene_gep_optimize_tool_usage",
112
+ "summary": "Optimize tool execution patterns by reducing redundant exec calls, improving tool selection strategy, and enforcing tool-use constraints to prevent bypass.",
113
+ "category": "optimize",
114
+ "signals_match": [
115
+ "high_tool_usage:exec",
116
+ "repeated_tool_usage:exec",
117
+ "tool_bypass",
118
+ "tool_loop",
119
+ "high_tool_usage"
120
+ ],
121
+ "preconditions": [
122
+ "agent repeatedly invokes the same tool (especially exec) without progress",
123
+ "tool execution bypass patterns detected",
124
+ "no active error signals (errors would take repair priority)"
125
+ ],
126
+ "strategy": [
127
+ "Analyze tool usage patterns to identify the root cause of repetition (wrong tool, missing context, or lack of guardrails)",
128
+ "Introduce strategy-level guardrails: prefer single-shot commands, batch related operations, add explicit retry limits",
129
+ "If tool_bypass detected, strengthen constraint enforcement in prompt assembly or tool routing",
130
+ "Estimate blast radius; changes should target tool routing, prompt constraints, or signal deduplication logic",
131
+ "Validate by confirming no regressions in existing tool tests and signal extraction accuracy",
132
+ "Solidify: record EvolutionEvent with intent=optimize, update Capsule on success"
133
+ ],
134
+ "constraints": {
135
+ "max_files": 15,
136
+ "forbidden_paths": [
137
+ ".git",
138
+ "node_modules"
139
+ ]
140
+ },
141
+ "validation": [
142
+ "node scripts/validate-modules.js ./src/gep/signals ./src/evolve",
143
+ "node scripts/validate-suite.js"
144
+ ]
145
+ },
108
146
  {
109
147
  "type": "Gene",
110
148
  "id": "gene_distilled_s2g-env-vars",
package/index.js CHANGED
@@ -143,6 +143,24 @@ async function main() {
143
143
  }
144
144
 
145
145
  console.log('Starting evolver...');
146
+
147
+ // Preflight: fail fast if git is not on PATH. On Windows in particular
148
+ // a missing git binary can cause evolver to hang silently (see #394),
149
+ // because several cycle-critical steps shell out to git early (repo
150
+ // resolution, diff, blast-radius). Catching this up front makes the
151
+ // failure mode obvious.
152
+ try {
153
+ const { execSync } = require('child_process');
154
+ execSync('git --version', { stdio: 'ignore', timeout: 5000 });
155
+ } catch (_gitErr) {
156
+ console.error('');
157
+ console.error('[Preflight] Could not run "git --version". Evolver requires git to be installed and available on PATH.');
158
+ console.error('[Preflight] On Windows: install Git from https://git-scm.com/download/win and make sure `git --version` works in a fresh terminal.');
159
+ console.error('[Preflight] On macOS: xcode-select --install (or `brew install git`)');
160
+ console.error('[Preflight] On Linux: sudo apt-get install -y git (or your distro equivalent)');
161
+ console.error('');
162
+ process.exit(1);
163
+ }
146
164
 
147
165
  if (isLoop) {
148
166
  // Internal daemon loop (no wrapper required).
@@ -250,6 +268,12 @@ async function main() {
250
268
 
251
269
  // ATP: opt-in capability-gap auto-buyer (default OFF, must be explicitly enabled).
252
270
  try {
271
+ try {
272
+ const { runPrompt } = require('./src/atp/cliAutobuyPrompt');
273
+ await runPrompt();
274
+ } catch (promptErr) {
275
+ console.warn('[ATP-AutoBuyer] first-run prompt failed: ' + (promptErr && promptErr.message || promptErr));
276
+ }
253
277
  const autoBuyRaw = (process.env.EVOLVER_ATP_AUTOBUY || 'off').toLowerCase().trim();
254
278
  const autoBuyOn = autoBuyRaw === 'on' || autoBuyRaw === '1' || autoBuyRaw === 'true';
255
279
  if (autoBuyOn) {
@@ -698,7 +722,13 @@ async function main() {
698
722
  console.log('\n[Review] Rejected. Rolling back changes...');
699
723
  try {
700
724
  execSync('git checkout -- .', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER });
701
- execSync('git clean -fd', { cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER });
725
+ // Preserve user state on reject: .env files, node_modules, runtime
726
+ // PID files, and a dedicated workspace/ dir (if one exists) MUST NOT
727
+ // be wiped by an automated rollback. Users have reported losing
728
+ // secrets and runtime caches to an aggressive git clean.
729
+ execSync('git clean -fd -e node_modules -e workspace -e .env -e ".env.*" -e "*.pid"', {
730
+ cwd: repoRoot, encoding: 'utf8', timeout: 30000, maxBuffer: MAX_EXEC_BUFFER,
731
+ });
702
732
  const evolDir = getEvolutionDir();
703
733
  const sp = path.join(evolDir, 'evolution_solidify_state.json');
704
734
  if (fs.existsSync(sp)) {
@@ -848,10 +878,30 @@ async function main() {
848
878
  fs.writeFileSync(path.join(outDir, 'SKILL.md'), data.content, 'utf8');
849
879
  }
850
880
 
881
+ const ALLOWED_SKILL_EXTENSIONS = new Set([
882
+ '.js', '.mjs', '.cjs', '.ts',
883
+ '.json', '.md', '.txt',
884
+ '.sh', '.py',
885
+ '.yml', '.yaml',
886
+ ]);
887
+ const MAX_SKILL_FILE_BYTES = 512 * 1024;
888
+
851
889
  const bundled = Array.isArray(data.bundled_files) ? data.bundled_files : [];
890
+ const skippedFiles = [];
852
891
  for (const file of bundled) {
853
892
  if (!file || !file.name || typeof file.content !== 'string') continue;
854
893
  const safeName = path.basename(file.name);
894
+ const ext = path.extname(safeName).toLowerCase();
895
+ if (!ALLOWED_SKILL_EXTENSIONS.has(ext)) {
896
+ console.warn('[fetch] Skipped skill file with disallowed extension: ' + safeName);
897
+ skippedFiles.push(safeName);
898
+ continue;
899
+ }
900
+ if (Buffer.byteLength(file.content, 'utf8') > MAX_SKILL_FILE_BYTES) {
901
+ console.warn('[fetch] Skipped skill file exceeding ' + MAX_SKILL_FILE_BYTES + ' bytes: ' + safeName);
902
+ skippedFiles.push(safeName);
903
+ continue;
904
+ }
855
905
  fs.writeFileSync(path.join(outDir, safeName), file.content, 'utf8');
856
906
  }
857
907
 
@@ -860,9 +910,9 @@ async function main() {
860
910
  console.log(' Version: ' + (data.version || '?'));
861
911
  console.log(' Files: SKILL.md' + (bundled.length > 0 ? ', ' + bundled.map(f => f.name).join(', ') : ''));
862
912
  if (data.already_purchased) {
863
- console.log(' Cost: free (already purchased)');
913
+ console.log(' Fetch cost: free (already purchased)');
864
914
  } else {
865
- console.log(' Cost: ' + (data.credit_cost || 0) + ' credits');
915
+ console.log(' Fetch cost: ' + (data.credit_cost || 0) + ' credits');
866
916
  }
867
917
  } catch (error) {
868
918
  if (error && error.name === 'TimeoutError') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evomap/evolver",
3
- "version": "1.70.0-beta.1",
3
+ "version": "1.70.0-beta.2",
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": {
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * First-run prompt that introduces the ATP autoBuyer to interactive users.
5
+ *
6
+ * Triggers when ALL conditions hold:
7
+ * - process.stdin.isTTY === true (skipped under systemd, Docker, CI)
8
+ * - EVOLVER_ATP_AUTOBUY is not already set (neither on nor off)
9
+ * - ack file memory/atp-autobuy-ack.json does not exist (already decided)
10
+ *
11
+ * Outcomes:
12
+ * - user answers y -> enabled=true written, session opts in immediately
13
+ * - user answers n -> enabled=false written, prompt never shown again
14
+ * - user answers later -> no file written, prompt shown next time
15
+ * - any non-TTY/ack branch -> silent no-op
16
+ */
17
+
18
+ const fs = require("fs");
19
+ const path = require("path");
20
+ const readline = require("readline");
21
+
22
+ const ACK_FILE_NAME = "atp-autobuy-ack.json";
23
+
24
+ function _getMemoryDir() {
25
+ try {
26
+ return require("../gep/paths").getMemoryDir();
27
+ } catch (_) {
28
+ return process.env.MEMORY_DIR || path.join(process.cwd(), "memory");
29
+ }
30
+ }
31
+
32
+ function _getAckPath() {
33
+ return path.join(_getMemoryDir(), ACK_FILE_NAME);
34
+ }
35
+
36
+ function _readAck() {
37
+ try {
38
+ const raw = fs.readFileSync(_getAckPath(), "utf8");
39
+ const parsed = JSON.parse(raw);
40
+ if (!parsed || typeof parsed !== "object") return null;
41
+ return parsed;
42
+ } catch (_) {
43
+ return null;
44
+ }
45
+ }
46
+
47
+ function _writeAck(enabled) {
48
+ const p = _getAckPath();
49
+ try {
50
+ fs.mkdirSync(path.dirname(p), { recursive: true });
51
+ const body = {
52
+ enabled: !!enabled,
53
+ acknowledged_at: new Date().toISOString(),
54
+ version: 1,
55
+ };
56
+ fs.writeFileSync(p, JSON.stringify(body, null, 2) + "\n", "utf8");
57
+ return true;
58
+ } catch (_) {
59
+ return false;
60
+ }
61
+ }
62
+
63
+ /**
64
+ * @returns {"ack_present"|"env_set"|"non_tty"|"eligible"}
65
+ */
66
+ function classify(env, stdin) {
67
+ const envVal = env && env.EVOLVER_ATP_AUTOBUY;
68
+ if (typeof envVal === "string" && envVal.trim().length > 0) {
69
+ return "env_set";
70
+ }
71
+ if (!stdin || !stdin.isTTY) {
72
+ return "non_tty";
73
+ }
74
+ if (_readAck()) {
75
+ return "ack_present";
76
+ }
77
+ return "eligible";
78
+ }
79
+
80
+ function _ask(question, { input, output }) {
81
+ return new Promise((resolve) => {
82
+ const rl = readline.createInterface({ input, output });
83
+ rl.question(question, (answer) => {
84
+ rl.close();
85
+ resolve((answer || "").trim().toLowerCase());
86
+ });
87
+ });
88
+ }
89
+
90
+ /**
91
+ * Synchronously decide whether to prompt (TTY + no ack + env unset) and,
92
+ * if prompting, block on user answer. Resolves with:
93
+ * { prompted: bool, decision: "yes"|"no"|"later"|null, reason: string }
94
+ *
95
+ * Should be called at most once per `evolver run` invocation, BEFORE the
96
+ * autoBuyer.start() branch in the run loop.
97
+ *
98
+ * @param {object} [opts]
99
+ * @param {NodeJS.ReadableStream} [opts.input]
100
+ * @param {NodeJS.WritableStream} [opts.output]
101
+ * @param {NodeJS.ProcessEnv} [opts.env]
102
+ * @param {(q: string, io: object) => Promise<string>} [opts.ask]
103
+ * @returns {Promise<{ prompted: boolean, decision: string|null, reason: string }>}
104
+ */
105
+ async function runPrompt(opts) {
106
+ opts = opts || {};
107
+ const input = opts.input || process.stdin;
108
+ const output = opts.output || process.stdout;
109
+ const env = opts.env || process.env;
110
+ const ask = typeof opts.ask === "function" ? opts.ask : _ask;
111
+
112
+ const state = classify(env, input);
113
+ if (state !== "eligible") {
114
+ return { prompted: false, decision: null, reason: state };
115
+ }
116
+
117
+ try {
118
+ output.write("\n");
119
+ output.write("[ATP-AutoBuyer] Your evolver can automatically place small-priced\n");
120
+ output.write("ATP orders when it detects a capability gap (default OFF).\n");
121
+ output.write(" - daily hard cap: ATP_AUTOBUY_DAILY_CAP_CREDITS (default applies)\n");
122
+ output.write(" - per-order cap: ATP_AUTOBUY_PER_ORDER_CAP_CREDITS\n");
123
+ output.write(" - unset EVOLVER_ATP_AUTOBUY and restart to disable at any time.\n");
124
+ output.write("\n");
125
+ } catch (_) {
126
+ return { prompted: false, decision: null, reason: "io_error" };
127
+ }
128
+
129
+ let answer;
130
+ try {
131
+ answer = await ask("Enable autoBuyer for this session? [y/n/later] ", {
132
+ input,
133
+ output,
134
+ });
135
+ } catch (_) {
136
+ return { prompted: true, decision: null, reason: "ask_error" };
137
+ }
138
+
139
+ if (answer === "y" || answer === "yes") {
140
+ _writeAck(true);
141
+ env.EVOLVER_ATP_AUTOBUY = "on";
142
+ return { prompted: true, decision: "yes", reason: "user_accepted" };
143
+ }
144
+ if (answer === "n" || answer === "no") {
145
+ _writeAck(false);
146
+ return { prompted: true, decision: "no", reason: "user_declined" };
147
+ }
148
+ return { prompted: true, decision: "later", reason: "user_postponed" };
149
+ }
150
+
151
+ module.exports = {
152
+ runPrompt,
153
+ classify,
154
+ __internals: {
155
+ ACK_FILE_NAME,
156
+ _readAck,
157
+ _writeAck,
158
+ _getAckPath,
159
+ },
160
+ };