Evolver "Evolution is not optional. Adapt or die." Evolver is a self-evolution engine for AI agents. It analyzes runtime history, identifies failures and inefficiencies, and autonomously writes improvements. Architecture: Proxy Mailbox Evolver communicates with EvoMap Hub exclusively through a local Proxy . The agent never calls Hub APIs directly. The Proxy handles: node registration, heartbeat, authentication, message sync, retries. The agent only reads/writes to the local mailbox. Discover Proxy Address Read : All API calls below use as the base (e.g. ). --- Mailbox API (Core) All mailbox o…

, 'im'));\n return match ? match[1].trim() : null;\n}\n\nfunction isSubstantiveValue(value) {\n if (!value) return false;\n const normalized = value.trim();\n if (!normalized) return false;\n if (/[\u003c>]/.test(normalized)) return false;\n if (/^n\\/?a\\.?(?:$|[\\s:;,.\\-–—])/i.test(normalized)) return false;\n return true;\n}\n\nfunction valueMatches(body, label, valuePattern) {\n const value = lineValue(body, label);\n return isSubstantiveValue(value) && valuePattern.test(value);\n}\n\nfunction validateGovernancePacket(body, changedFiles) {\n const stripped = stripHtmlComments(body);\n const errors = [];\n if (!changedFilesTouchGovernanceSurface(changedFiles)) return errors;\n\n if (!/^##+\\s+Harness\\/evaluator governance/im.test(stripped)) {\n errors.push('missing ## Harness/evaluator governance — add the PR-template section from CONTRIBUTING.md');\n }\n\n const requiredValues = [\n ['Upstream governance surface', /\\S/, 'name the Evolver harness/evaluator surface; template placeholders and bare N/A are not accepted for sensitive diffs'],\n ['Downstream EvoX impact', /\\S/, 'state whether EvoX downstream behavior or contracts are affected; template placeholders and bare N/A are not accepted'],\n ['Rollout-local scope', /\\S/, 'state the proposal/shadow/cohort boundary before promotion'],\n ['Promotion boundary', /\\S/, 'state how rollout becomes default behavior'],\n ['Evaluator mismatch sets', /\\S/, 'cover observation/action/repair/verification/evidence/belief deltas or explain why each is not changed'],\n ['Non-regression evidence', /\\S/, 'link tests, shadow runs, replay, or doc-only rationale'],\n ['Fix-severity review', /^(low|medium|high|critical)\\b/i, 'classify the strongest fix severity'],\n ['Owner approval', /\\S/, 'name the owning module/reviewer requirement'],\n ['Security boundary', /\\S/, 'state data/tool/host/network/secrets impact'],\n ['Rollback', /\\S/, 'state how to disable/revert/quarantine'],\n ['Live promotion', /^no$/i, \"state exactly 'Live promotion: no'\"],\n ['Autonomous evaluator self-editing', /^no$/i, \"state exactly 'Autonomous evaluator self-editing: no'\"],\n ];\n\n for (const [label, pattern, hint] of requiredValues) {\n if (!valueMatches(stripped, label, pattern)) {\n errors.push('missing ' + label + ' — ' + hint);\n }\n }\n return errors;\n}\n\nfunction main() {\n const opts = parseArgs(process.argv);\n if (opts.help) {\n console.log('usage: node scripts/harness-governance-check.js [--body file | --event file] --changed file');\n return 0;\n }\n const body = readBody(opts);\n const changedFiles = readChangedFiles(opts);\n const errors = validateGovernancePacket(body, changedFiles);\n if (errors.length) {\n console.error('Harness/evaluator governance gate FAILED.');\n for (const err of errors) console.error('- ' + err);\n console.error('Changed sensitive files:');\n for (const f of changedFiles.filter(f => SENSITIVE_PATH_RE.test(f))) console.error('- ' + f);\n return 1;\n }\n if (changedFilesTouchGovernanceSurface(changedFiles)) {\n console.log('Harness/evaluator governance gate: PASSED');\n } else {\n console.log('Harness/evaluator governance gate: not applicable');\n }\n return 0;\n}\n\nif (require.main === module) {\n try {\n process.exitCode = main();\n } catch (err) {\n console.error('Harness/evaluator governance gate ERROR: ' + (err && err.message || err));\n process.exitCode = 2;\n }\n}\n\nmodule.exports = {\n changedFilesTouchGovernanceSurface,\n validateGovernancePacket,\n stripHtmlComments,\n isSubstantiveValue,\n SENSITIVE_PATH_RE,\n};\n","content_type":"text/javascript; charset=utf-8","language":"javascript","size":5749,"content_sha256":"882ef55d57205f24a9c20cc548ca7f446597dda03641e0003800e2c961f2f3ad"},{"filename":"scripts/human_report.js","content":"const fs = require('fs');\nconst path = require('path');\n\nconst REPO_ROOT = path.resolve(__dirname, '..');\nconst IN_FILE = path.join(REPO_ROOT, 'evolution_history_full.md');\nconst OUT_FILE = path.join(REPO_ROOT, 'evolution_human_summary.md');\n\nfunction generateHumanReport() {\n if (!fs.existsSync(IN_FILE)) return console.error(\"No input file\");\n\n const content = fs.readFileSync(IN_FILE, 'utf8');\n const entries = content.split('---').map(e => e.trim()).filter(e => e.length > 0);\n\n const categories = {\n 'Security & Stability': [],\n 'Performance & Optimization': [],\n 'Tooling & Features': [],\n 'Documentation & Process': []\n };\n\n const componentMap = {}; // Component -> Change List\n\n entries.forEach(entry => {\n // Extract basic info\n const lines = entry.split('\\n');\n const header = lines[0]; // ### Title (Date)\n const body = lines.slice(1).join('\\n');\n \n const dateMatch = header.match(/\\((.*?)\\)/);\n const dateStr = dateMatch ? dateMatch[1] : '';\n const time = dateStr.split(' ')[1] || ''; // HH:mm:ss\n\n // Classify\n let category = 'Tooling & Features';\n let component = 'System';\n let summary = '';\n\n const lowerBody = body.toLowerCase();\n\n // Detect Component\n if (lowerBody.includes('feishu-card')) component = 'feishu-card';\n else if (lowerBody.includes('feishu-sticker')) component = 'feishu-sticker';\n else if (lowerBody.includes('git-sync')) component = 'git-sync';\n else if (lowerBody.includes('capability-evolver') || lowerBody.includes('evolve.js')) component = 'capability-evolver';\n else if (lowerBody.includes('interaction-logger')) component = 'interaction-logger';\n else if (lowerBody.includes('chat-to-image')) component = 'chat-to-image';\n else if (lowerBody.includes('safe_publish')) component = 'capability-evolver';\n\n // Detect Category\n if (lowerBody.includes('security') || lowerBody.includes('permission') || lowerBody.includes('auth') || lowerBody.includes('harden')) {\n category = 'Security & Stability';\n } else if (lowerBody.includes('optimiz') || lowerBody.includes('performance') || lowerBody.includes('memory') || lowerBody.includes('fast')) {\n category = 'Performance & Optimization';\n } else if (lowerBody.includes('doc') || lowerBody.includes('readme')) {\n category = 'Documentation & Process';\n }\n\n // Extract Human Summary (First meaningful line that isn't Status/Action/Date)\n const summaryLines = lines.filter(l => \n !l.startsWith('###') && \n !l.startsWith('Status:') && \n !l.startsWith('Action:') &&\n l.trim().length > 10\n );\n \n if (summaryLines.length > 0) {\n // Clean up the line\n summary = summaryLines[0]\n .replace(/^-\\s*/, '') // Remove bullets\n .replace(/\\*\\*/g, '') // Remove bold\n .replace(/`/, '')\n .trim();\n \n // Deduplicate\n const key = `${component}:${summary.substring(0, 20)}`;\n const exists = categories[category].some(i => i.key === key);\n \n if (!exists && !summary.includes(\"Stability Scan OK\") && !summary.includes(\"Workspace Sync\")) {\n categories[category].push({ time, component, summary, key });\n \n if (!componentMap[component]) componentMap[component] = [];\n componentMap[component].push(summary);\n }\n }\n });\n\n // --- Generate Markdown ---\n const today = new Date().toISOString().slice(0, 10);\n let md = `# Evolution Summary: The Day in Review (${today})\\n\\n`;\n md += `> Overview: Grouped summary of changes extracted from evolution history.\\n\\n`;\n\n // Section 1: By Theme (Evolution Direction)\n md += `## 1. Evolution Direction\\n`;\n \n for (const [cat, items] of Object.entries(categories)) {\n if (items.length === 0) continue;\n md += `### ${cat}\\n`;\n // Group by component within theme\n const compGroup = {};\n items.forEach(i => {\n if (!compGroup[i.component]) compGroup[i.component] = [];\n compGroup[i.component].push(i.summary);\n });\n \n for (const [comp, sums] of Object.entries(compGroup)) {\n // Unique summaries only\n const uniqueSums = [...new Set(sums)];\n uniqueSums.forEach(s => {\n md += `- **${comp}**: ${s}\\n`;\n });\n }\n md += `\\n`;\n }\n\n // Section 2: By Timeline (High Level)\n md += `## 2. Timeline of Critical Events\\n`;\n // Flatten and sort all items by time\n const allItems = [];\n Object.values(categories).forEach(list => allItems.push(...list));\n allItems.sort((a, b) => a.time.localeCompare(b.time));\n \n // Filter for \"Critical\" keywords\n const criticalItems = allItems.filter(i => \n i.summary.toLowerCase().includes('fix') || \n i.summary.toLowerCase().includes('patch') ||\n i.summary.toLowerCase().includes('create') ||\n i.summary.toLowerCase().includes('optimiz')\n );\n\n criticalItems.forEach(i => {\n md += `- \\`${i.time}\\` (${i.component}): ${i.summary}\\n`;\n });\n\n // Section 3: Package Adjustments\n md += `\\n## 3. Package & Documentation Adjustments\\n`;\n const comps = Object.keys(componentMap).sort();\n comps.forEach(comp => {\n const count = new Set(componentMap[comp]).size;\n md += `- **${comp}**: Received ${count} significant updates.\\n`;\n });\n\n fs.writeFileSync(OUT_FILE, md);\n console.log(\"Human report generated.\");\n}\n\ngenerateHumanReport();\n\n","content_type":"text/javascript; charset=utf-8","language":"javascript","size":5796,"content_sha256":"a53fc307be1b3a83480e27de8c02153adff9d7d6e0cf6f19990402c31905e270"},{"filename":"scripts/internal-proxy-env.sh","content":"#!/usr/bin/env bash\nset -euo pipefail\n\nusage() {\n cat \u003c\u003c'EOF'\nUsage: scripts/internal-proxy-env.sh [--settings FILE] [--status] [--token] [--codex-config]\n\nPrint shell exports for routing local agent clients through the running\nEvoMap Proxy. Intended usage:\n\n eval \"$(scripts/internal-proxy-env.sh)\"\n\nThe script reads ~/.evolver/settings.json by default and never writes files.\n--token prints only the proxy token for command-backed auth.\n--codex-config prints a user-level ~/.codex/config.toml snippet without the token.\nEOF\n}\n\nsettings_file=\"${EVOLVER_SETTINGS_FILE:-}\"\nstatus_only=0\ntoken_only=0\ncodex_config=0\n\nwhile [[ $# -gt 0 ]]; do\n case \"$1\" in\n --settings)\n if [[ $# -lt 2 ]]; then\n echo \"missing value for --settings\" >&2\n exit 2\n fi\n settings_file=\"$2\"\n shift 2\n ;;\n --status)\n status_only=1\n shift\n ;;\n --token)\n token_only=1\n shift\n ;;\n --codex-config)\n codex_config=1\n shift\n ;;\n -h|--help)\n usage\n exit 0\n ;;\n *)\n echo \"unknown argument: $1\" >&2\n usage >&2\n exit 2\n ;;\n esac\ndone\n\nif [[ -z \"$settings_file\" ]]; then\n settings_dir=\"${EVOLVER_SETTINGS_DIR:-$HOME/.evolver}\"\n settings_file=\"$settings_dir/settings.json\"\nfi\n\nscript_path=\"${BASH_SOURCE[0]}\"\n\nnode - \"$settings_file\" \"$status_only\" \"$token_only\" \"$codex_config\" \"$script_path\" \u003c\u003c'NODE'\n'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\n\nconst settingsFile = process.argv[2];\nconst statusOnly = process.argv[3] === '1';\nconst tokenOnly = process.argv[4] === '1';\nconst codexConfig = process.argv[5] === '1';\nconst scriptPath = process.argv[6];\n\nfunction die(message, code = 1) {\n console.error(message);\n process.exit(code);\n}\n\nfunction quote(value) {\n return \"'\" + String(value).replace(/'/g, \"'\\\\''\") + \"'\";\n}\n\nlet parsed;\ntry {\n parsed = JSON.parse(fs.readFileSync(settingsFile, 'utf8'));\n} catch (err) {\n die(`cannot read proxy settings at ${settingsFile}; start evolver with EVOMAP_PROXY=1 first`);\n}\n\nconst proxy = parsed && parsed.proxy ? parsed.proxy : null;\nif (!proxy || typeof proxy.url !== 'string' || typeof proxy.token !== 'string') {\n die(`no active proxy.url/proxy.token found in ${settingsFile}; start evolver with EVOMAP_PROXY=1 first`);\n}\n\nif (statusOnly) {\n console.log(`proxy_url=${proxy.url}`);\n if (proxy.pid != null) console.log(`proxy_pid=${proxy.pid}`);\n if (proxy.started_at) console.log(`proxy_started_at=${proxy.started_at}`);\n process.exit(0);\n}\n\nif (tokenOnly) {\n console.log(proxy.token);\n process.exit(0);\n}\n\nif (codexConfig) {\n const baseUrl = String(proxy.url).replace(/\\/+$/, '') + '/v1';\n const absSettingsFile = path.resolve(settingsFile);\n const absScript = scriptPath ? path.resolve(scriptPath) : '';\n const indexPath = absScript\n ? path.resolve(path.dirname(absScript), '..', 'index.js')\n : path.resolve('index.js');\n console.log('# Add this to user-level ~/.codex/config.toml, then restart Codex.');\n console.log('# The Evolver daemon still needs EVOMAP_OPENAI_API_KEY or OPENAI_API_KEY for upstream.');\n console.log('model_provider = \"evomap-proxy\"');\n console.log('');\n console.log('[model_providers.evomap-proxy]');\n console.log('name = \"EvoMap Proxy\"');\n console.log(`base_url = ${JSON.stringify(baseUrl)}`);\n console.log('wire_api = \"responses\"');\n console.log('');\n console.log('[model_providers.evomap-proxy.auth]');\n console.log(`command = ${JSON.stringify(process.execPath)}`);\n console.log(`args = ${JSON.stringify([indexPath, 'proxy-token', '--settings', absSettingsFile])}`);\n console.log('timeout_ms = 5000');\n console.log('refresh_interval_ms = 300000');\n process.exit(0);\n}\n\nconsole.log(`export ANTHROPIC_BASE_URL=${quote(proxy.url)}`);\nconsole.log(`export ANTHROPIC_AUTH_TOKEN=${quote(proxy.token)}`);\nconsole.log(`export CUSTOM_API_KEY=${quote(proxy.token)}`);\nconsole.log(`export EVOMAP_PROXY_URL=${quote(proxy.url)}`);\nNODE\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":3962,"content_sha256":"98b57f9bdf7b89d281f8b385e63ab511762eec825bf40900f5591f9358b514fc"},{"filename":"scripts/recall-verify-report.js","content":"#!/usr/bin/env node\n'use strict';\n\n// recall-verify-report — aggregate kind=recall_verify events from the\n// memory graph jsonl into a Markdown table. Exit 0 = ship gate green\n// (every asset_type has success_rate >= 0.95 and 0 mismatches), exit 2\n// otherwise. Designed to be scripted into deploy.sh as a pre-publish gate.\n//\n// Usage:\n// node scripts/recall-verify-report.js # all events\n// node scripts/recall-verify-report.js --since 1h # last hour\n// node scripts/recall-verify-report.js --since 30m\n// node scripts/recall-verify-report.js --since 2026-05-16T10:00:00Z\n// node scripts/recall-verify-report.js --json # raw JSON for piping\n\nconst { tryReadMemoryGraphEvents } = require('../src/gep/memoryGraph');\n\nconst SUCCESS_THRESHOLD = 0.95;\n\nfunction parseSince(value) {\n if (!value) return null;\n // Try relative duration first (1h / 30m / 2d / 45s) — unambiguous.\n const m = String(value).match(/^(\\d+)\\s*(s|m|h|d)$/i);\n if (m) {\n const n = Number(m[1]);\n const unit = m[2].toLowerCase();\n const factor = unit === 's' ? 1000 : unit === 'm' ? 60000 : unit === 'h' ? 3600000 : 86400000;\n return Date.now() - (n * factor);\n }\n // Then ISO-8601. Require '-' or 'T' so we don't accept loose numeric\n // strings like \"5\" → year 2001.\n if (/[-T]/.test(String(value))) {\n const iso = Date.parse(value);\n if (!Number.isNaN(iso)) return iso;\n }\n return undefined;\n}\n\nfunction parseArgs(argv) {\n const args = { since: null, json: false };\n for (let i = 2; i \u003c argv.length; i++) {\n const a = argv[i];\n if (a === '--json') args.json = true;\n else if (a === '--since') {\n args.since = argv[++i];\n } else if (a.startsWith('--since=')) {\n args.since = a.slice('--since='.length);\n } else if (a === '--help' || a === '-h') {\n args.help = true;\n }\n }\n return args;\n}\n\nfunction percentile(sorted, p) {\n if (!sorted.length) return 0;\n const idx = Math.min(sorted.length - 1, Math.floor(sorted.length * p));\n return sorted[idx];\n}\n\nfunction aggregate(events) {\n const byType = new Map();\n for (const ev of events) {\n if (!ev || ev.kind !== 'recall_verify') continue;\n const type = (ev.asset && ev.asset.type) || 'Unknown';\n if (!byType.has(type)) {\n byType.set(type, {\n type,\n total: 0,\n ok: 0,\n missing: 0,\n mismatch: 0,\n skipped: 0,\n latencies: [],\n ages: [],\n });\n }\n const bucket = byType.get(type);\n bucket.total += 1;\n const v = ev.verification || {};\n if (v.outcome === 'roundtrip_ok') bucket.ok += 1;\n else if (v.outcome === 'roundtrip_missing') bucket.missing += 1;\n else if (v.outcome === 'roundtrip_mismatch') bucket.mismatch += 1;\n else bucket.skipped += 1;\n if (Number.isFinite(v.latency_ms)) bucket.latencies.push(v.latency_ms);\n if (Number.isFinite(v.age_at_verify_ms)) bucket.ages.push(v.age_at_verify_ms);\n }\n const rows = [];\n for (const bucket of byType.values()) {\n const denom = bucket.ok + bucket.missing + bucket.mismatch;\n bucket.success_rate = denom > 0 ? bucket.ok / denom : 0;\n bucket.latencies.sort(function (a, b) { return a - b; });\n bucket.ages.sort(function (a, b) { return a - b; });\n bucket.p50_latency_ms = percentile(bucket.latencies, 0.5);\n bucket.p95_latency_ms = percentile(bucket.latencies, 0.95);\n bucket.p99_latency_ms = percentile(bucket.latencies, 0.99);\n bucket.p50_age_ms = percentile(bucket.ages, 0.5);\n bucket.p95_age_ms = percentile(bucket.ages, 0.95);\n bucket.p99_age_ms = percentile(bucket.ages, 0.99);\n delete bucket.latencies;\n delete bucket.ages;\n rows.push(bucket);\n }\n rows.sort(function (a, b) { return a.type.localeCompare(b.type); });\n\n const totals = { type: 'TOTAL', total: 0, ok: 0, missing: 0, mismatch: 0, skipped: 0 };\n for (const r of rows) {\n totals.total += r.total;\n totals.ok += r.ok;\n totals.missing += r.missing;\n totals.mismatch += r.mismatch;\n totals.skipped += r.skipped;\n }\n const totalsDenom = totals.ok + totals.missing + totals.mismatch;\n totals.success_rate = totalsDenom > 0 ? totals.ok / totalsDenom : 0;\n\n // Gate severity is monotonic: once a row triggers a worse state, later\n // rows cannot downgrade it. Without this, AntiPattern@0% (RED) followed\n // by Capsule@90% (YELLOW) would report YELLOW — misleading dashboards\n // even though the exit code still reflects RED. (Bugbot review on PR #53.)\n // RANK is the comparison ordinal: GREEN(0) \u003c YELLOW(1) \u003c RED(2).\n const RANK = { GREEN: 0, YELLOW: 1, RED: 2 };\n function escalate(current, candidate) {\n return RANK[candidate] > RANK[current] ? candidate : current;\n }\n let gate = 'GREEN';\n if (rows.length === 0) gate = 'RED';\n else {\n for (const r of rows) {\n if (r.mismatch > 0) { gate = 'RED'; break; }\n if (r.success_rate \u003c SUCCESS_THRESHOLD) {\n gate = escalate(gate, r.success_rate >= 0.85 ? 'YELLOW' : 'RED');\n }\n }\n }\n return { rows, totals, gate };\n}\n\nfunction fmtPct(rate) {\n return (rate * 100).toFixed(1) + '%';\n}\n\nfunction fmtMs(n) {\n if (!Number.isFinite(n) || n === 0) return '—';\n if (n \u003c 1000) return Math.round(n) + 'ms';\n return (n / 1000).toFixed(1) + 's';\n}\n\nfunction printMarkdown(result, since) {\n const sinceStr = since ? new Date(since).toISOString() : 'all time';\n console.log('# RecallVerify Report (since ' + sinceStr + ')');\n console.log('');\n if (result.rows.length === 0) {\n console.log('_No `recall_verify` events found in memory graph._');\n console.log('');\n console.log('Ship gate: **RED** (no data — feature may be disabled or daemon has not run a publish cycle yet)');\n return;\n }\n console.log('| asset_type | total | ok | missing | mismatch | skipped | success_rate | p50_latency | p99_latency | p50_age | p99_age |');\n console.log('|--------------|------:|----:|--------:|---------:|--------:|-------------:|------------:|------------:|--------:|--------:|');\n for (const r of result.rows) {\n console.log('| ' + r.type.padEnd(12) +\n ' | ' + String(r.total).padStart(5) +\n ' | ' + String(r.ok).padStart(3) +\n ' | ' + String(r.missing).padStart(7) +\n ' | ' + String(r.mismatch).padStart(8) +\n ' | ' + String(r.skipped).padStart(7) +\n ' | ' + fmtPct(r.success_rate).padStart(12) +\n ' | ' + fmtMs(r.p50_latency_ms).padStart(11) +\n ' | ' + fmtMs(r.p99_latency_ms).padStart(11) +\n ' | ' + fmtMs(r.p50_age_ms).padStart(7) +\n ' | ' + fmtMs(r.p99_age_ms).padStart(7) +\n ' |');\n }\n const t = result.totals;\n console.log('| ' + 'TOTAL'.padEnd(12) +\n ' | ' + String(t.total).padStart(5) +\n ' | ' + String(t.ok).padStart(3) +\n ' | ' + String(t.missing).padStart(7) +\n ' | ' + String(t.mismatch).padStart(8) +\n ' | ' + String(t.skipped).padStart(7) +\n ' | ' + fmtPct(t.success_rate).padStart(12) +\n ' | ' + '—'.padStart(11) +\n ' | ' + '—'.padStart(11) +\n ' | ' + '—'.padStart(7) +\n ' | ' + '—'.padStart(7) +\n ' |');\n console.log('');\n console.log('Ship gate: **' + result.gate + '**' + (result.gate === 'GREEN' ? ' (exit 0)' : ' (exit 2)'));\n}\n\nfunction main() {\n const args = parseArgs(process.argv);\n if (args.help) {\n console.log('Usage: node scripts/recall-verify-report.js [--since \u003cNh|Nm|Nd|ISO>] [--json]');\n process.exit(0);\n }\n\n let sinceMs = null;\n if (args.since) {\n const parsed = parseSince(args.since);\n if (parsed === undefined) {\n console.error('Error: --since must be ISO-8601 or a duration like 1h / 30m / 2d (got: ' + args.since + ')');\n process.exit(1);\n }\n sinceMs = parsed;\n }\n\n const allEvents = tryReadMemoryGraphEvents(20000);\n const filtered = allEvents.filter(function (ev) {\n if (!ev || ev.kind !== 'recall_verify') return false;\n if (sinceMs != null && Number.isFinite(ev.ts) && ev.ts \u003c sinceMs) return false;\n return true;\n });\n\n const result = aggregate(filtered);\n\n if (args.json) {\n console.log(JSON.stringify({\n since: sinceMs ? new Date(sinceMs).toISOString() : null,\n ...result,\n }, null, 2));\n } else {\n printMarkdown(result, sinceMs);\n }\n\n process.exit(result.gate === 'GREEN' ? 0 : 2);\n}\n\nif (require.main === module) {\n main();\n}\n\nmodule.exports = { aggregate, parseSince, parseArgs };\n","content_type":"text/javascript; charset=utf-8","language":"javascript","size":8303,"content_sha256":"717f1b51c25006473a4e089c8a5e35f046141f29394ac3a4a1c95ea7c1c5913d"},{"filename":"scripts/recover_loop.js","content":"#!/usr/bin/env node\n/* eslint-disable no-console */\nconst fs = require('fs');\nconst path = require('path');\nconst { spawnSync } = require('child_process');\n\nfunction exists(p) {\n try {\n return fs.existsSync(p);\n } catch (e) {\n return false;\n }\n}\n\nfunction sleepMs(ms) {\n const n = Number(ms);\n const t = Number.isFinite(n) ? Math.max(0, n) : 0;\n if (t \u003c= 0) return;\n spawnSync('sleep', [String(Math.ceil(t / 1000))], { stdio: 'ignore' });\n}\n\nfunction resolveWorkspaceRoot() {\n // In OpenClaw exec, cwd is usually the workspace root.\n // Keep it simple: do not try to walk up arbitrarily.\n return process.cwd();\n}\n\nfunction resolveEvolverEntry(workspaceRoot) {\n const candidates = [\n path.join(workspaceRoot, 'skills', 'evolver', 'index.js'),\n path.join(workspaceRoot, 'skills', 'capability-evolver', 'index.js'),\n ];\n for (const p of candidates) {\n if (exists(p)) return p;\n }\n return null;\n}\n\nfunction main() {\n const waitMs = parseInt(String(process.env.EVOLVER_RECOVER_WAIT_MS || '10000'), 10);\n const wait = Number.isFinite(waitMs) ? Math.max(0, waitMs) : 10000;\n\n console.log(`[RECOVERY] Waiting ${wait}ms before restart...`);\n sleepMs(wait);\n\n const workspaceRoot = resolveWorkspaceRoot();\n const entry = resolveEvolverEntry(workspaceRoot);\n if (!entry) {\n console.error('[RECOVERY] Failed: cannot locate evolver entry under skills/.');\n process.exit(2);\n }\n\n console.log(`[RECOVERY] Restarting loop via ${path.relative(workspaceRoot, entry)} ...`);\n const r = spawnSync(process.execPath, [entry, '--loop'], { stdio: 'inherit' });\n process.exit(typeof r.status === 'number' ? r.status : 1);\n}\n\nif (require.main === module) {\n main();\n}\n\n","content_type":"text/javascript; charset=utf-8","language":"javascript","size":1691,"content_sha256":"cc5ff006d2baefea560ab3a295611c0f197e7ce07aa149661172d3404d9910b8"},{"filename":"scripts/refresh_stars_badge.js","content":"// refresh_stars_badge.js -- Refresh the static \"Stars\" badge count in the\n// public README sources to the live GitHub star count.\n//\n// Why this exists:\n// The README stars badge is intentionally STATIC (a plain shields `badge/`\n// URL, not a dynamic `github/stars` one) so it never renders shields.io's\n// \"Unable to select next GitHub token from pool\" error when their shared\n// GitHub token pool is rate-limited. The trade-off is that the number goes\n// stale. This script re-stamps it at release time so the badge stays current\n// without ever depending on the GitHub API to *render*.\n//\n// Usage:\n// node scripts/refresh_stars_badge.js # update in place\n// node scripts/refresh_stars_badge.js --dry-run # print, write nothing\n// node scripts/refresh_stars_badge.js --repo=O/N # override repo\n// node scripts/refresh_stars_badge.js --count=12345 # skip fetch (testing)\n//\n// Design notes:\n// - Counts come from the PUBLIC repo (default EvoMap/evolver), not this\n// private dev repo.\n// - Fetch uses the already-authenticated `gh` CLI first (deploy.sh preflight\n// guarantees gh auth), falling back to the unauthenticated GitHub REST API.\n// - A fetch failure is NON-FATAL: we warn and exit 0, leaving the badge as\n// is. A flaky GitHub API must never break a release -- avoiding exactly\n// that fragility is the whole reason the badge is static.\n// - It rewrites every README*.md in the repo root that contains the badge,\n// so new translations are picked up automatically.\n\nconst fs = require('fs');\nconst path = require('path');\nconst https = require('https');\nconst { execSync } = require('child_process');\n\nconst REPO_ROOT = path.resolve(__dirname, '..');\nconst DEFAULT_REPO = 'EvoMap/evolver';\n\n// Matches the value segment of `.../badge/Stars-\u003cvalue>-\u003ccolor>...` in a\n// shields static badge URL. The value never contains `-` or `/`. Returns a\n// fresh regex each call so callers never share `lastIndex` state.\nconst starsBadgeRe = () => /(img\\.shields\\.io\\/badge\\/Stars-)([^-/)]+)(-)/g;\n\n// Replace the Stars badge value in `content` with `value`. Pure; returns the\n// rewritten string (unchanged if there is no badge or it already matches).\nfunction rewriteStarsValue(content, value) {\n return content.replace(starsBadgeRe(), (_m, pre, _old, post) => `${pre}${value}${post}`);\n}\n\nfunction parseArgs(argv) {\n const opts = { dryRun: false, repo: DEFAULT_REPO, count: null };\n for (const arg of argv) {\n if (arg === '--dry-run' || arg === '-n') opts.dryRun = true;\n else if (arg.startsWith('--repo=')) opts.repo = arg.slice('--repo='.length);\n else if (arg.startsWith('--count=')) opts.count = Number(arg.slice('--count='.length));\n }\n return opts;\n}\n\n// Format an integer the way shields.io's `metric` text formatter does, so the\n// static badge is visually indistinguishable from a dynamic one:\n// 8336 -> \"8.3k\", 12345 -> \"12k\", 1100 -> \"1.1k\", 999 -> \"999\".\nfunction metric(n) {\n n = Number(n);\n if (!Number.isFinite(n) || n \u003c 0) return String(n);\n for (const [suffix, size] of [['G', 1e9], ['M', 1e6], ['k', 1e3]]) {\n if (n >= size) {\n const value = n / size;\n const text = value \u003c 10\n ? value.toFixed(1).replace(/\\.0$/, '')\n : String(Math.round(value));\n return text + suffix;\n }\n }\n return String(Math.round(n));\n}\n\nfunction fetchStarsViaGh(repo) {\n try {\n const out = execSync(`gh api repos/${repo} --jq .stargazers_count`, {\n encoding: 'utf8',\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim();\n const n = Number(out);\n return Number.isFinite(n) && n > 0 ? n : null;\n } catch {\n return null;\n }\n}\n\nfunction fetchStarsViaApi(repo) {\n return new Promise((resolve) => {\n const req = https.get(\n `https://api.github.com/repos/${repo}`,\n { headers: { 'User-Agent': 'evolver-refresh-stars-badge', Accept: 'application/vnd.github+json' } },\n (res) => {\n if (res.statusCode !== 200) { res.resume(); return resolve(null); }\n let body = '';\n res.on('data', (c) => (body += c));\n res.on('end', () => {\n try {\n const n = Number(JSON.parse(body).stargazers_count);\n resolve(Number.isFinite(n) && n > 0 ? n : null);\n } catch { resolve(null); }\n });\n },\n );\n req.on('error', () => resolve(null));\n req.setTimeout(10000, () => { req.destroy(); resolve(null); });\n });\n}\n\nasync function resolveStarCount(opts) {\n if (Number.isFinite(opts.count) && opts.count > 0) return opts.count;\n return fetchStarsViaGh(opts.repo) || (await fetchStarsViaApi(opts.repo));\n}\n\nfunction readmeFilesWithBadge() {\n return fs\n .readdirSync(REPO_ROOT)\n .filter((f) => /^README.*\\.md$/.test(f))\n .map((f) => path.join(REPO_ROOT, f))\n .filter((p) => starsBadgeRe().test(fs.readFileSync(p, 'utf8')));\n}\n\nasync function main() {\n const opts = parseArgs(process.argv.slice(2));\n\n const count = await resolveStarCount(opts);\n if (count == null) {\n console.warn('[refresh-stars-badge] could not resolve star count (gh + API both failed); leaving badge unchanged');\n return; // non-fatal\n }\n const value = metric(count);\n console.log(`[refresh-stars-badge] ${opts.repo} = ${count} stars -> \"${value}\"`);\n\n const files = readmeFilesWithBadge();\n if (files.length === 0) {\n console.warn('[refresh-stars-badge] no README*.md with a Stars badge found; nothing to do');\n return;\n }\n\n let changed = 0;\n for (const file of files) {\n const before = fs.readFileSync(file, 'utf8');\n const after = rewriteStarsValue(before, value);\n const rel = path.relative(REPO_ROOT, file);\n if (after === before) {\n console.log(` ${rel}: already \"${value}\"`);\n continue;\n }\n if (opts.dryRun) {\n console.log(` [dry-run] ${rel}: would set Stars -> \"${value}\"`);\n } else {\n fs.writeFileSync(file, after);\n console.log(` ${rel}: Stars -> \"${value}\"`);\n }\n changed++;\n }\n console.log(`[refresh-stars-badge] ${changed} file(s) ${opts.dryRun ? 'would change' : 'updated'}`);\n}\n\nif (require.main === module) {\n main().catch((e) => {\n // Never fail the release over a badge refresh.\n console.warn(`[refresh-stars-badge] unexpected error (ignored): ${e && e.message}`);\n });\n}\n\nmodule.exports = { metric, rewriteStarsValue };\n","content_type":"text/javascript; charset=utf-8","language":"javascript","size":6337,"content_sha256":"0197c6cb9ee0ff47946bbcd558f469061a3ff32c810b37acb0fbaf919e4c029f"},{"filename":"scripts/seed-merchants.js","content":"#!/usr/bin/env node\n// Seed Merchants -- registers 3 merchant services on the ATP network.\n// Run once to bootstrap the network with available service listings.\n//\n// Usage:\n// A2A_HUB_URL=https://evomap.ai node scripts/seed-merchants.js\n\nconst { merchantAgent } = require('../src/atp');\n\nconst SEED_SERVICES = [\n {\n title: 'Code Review Agent',\n description: 'Automated code review for JavaScript, Python, and TypeScript projects. Identifies bugs, style issues, and performance opportunities.',\n capabilities: ['code_review', 'javascript', 'python', 'typescript', 'bug_detection'],\n useCases: ['Pull request review', 'Code quality audit', 'Security scan'],\n pricePerTask: 5,\n maxConcurrent: 5,\n },\n {\n title: 'Translation Agent',\n description: 'Translates text between English, Chinese (Simplified/Traditional), and Japanese with context-aware accuracy.',\n capabilities: ['translation', 'english', 'chinese', 'japanese', 'localization'],\n useCases: ['Document translation', 'UI localization', 'README translation'],\n pricePerTask: 3,\n maxConcurrent: 10,\n },\n {\n title: 'Text Summarization Agent',\n description: 'Generates concise summaries from long documents, reports, and codebases. Supports structured and freeform output.',\n capabilities: ['summarization', 'text_analysis', 'report', 'digest'],\n useCases: ['Meeting notes summary', 'Codebase overview', 'Research digest'],\n pricePerTask: 2,\n maxConcurrent: 10,\n },\n];\n\nfunction handleOrder(order) {\n const title = (order.title || '').toLowerCase();\n const signals = (order.signals || '').toLowerCase();\n\n let result;\n if (title.includes('review') || signals.includes('code_review')) {\n result = 'Code review completed. No critical issues found. 2 suggestions for improvement.';\n } else if (title.includes('translat') || signals.includes('translation')) {\n result = 'Translation completed. Source and target text verified for accuracy.';\n } else {\n result = 'Analysis completed. Summary generated from provided content.';\n }\n\n return {\n result,\n output: result,\n pass_rate: 1.0,\n processed_at: new Date().toISOString(),\n };\n}\n\nasync function main() {\n const hubUrl = process.env.A2A_HUB_URL || process.env.EVOMAP_HUB_URL;\n if (!hubUrl) {\n console.error('[Seed] A2A_HUB_URL or EVOMAP_HUB_URL is required.');\n process.exit(1);\n }\n\n console.log('[Seed] Hub:', hubUrl);\n console.log('[Seed] Starting merchant with', SEED_SERVICES.length, 'services...');\n\n await merchantAgent.start({\n services: SEED_SERVICES,\n onOrder: handleOrder,\n pollMs: 30000,\n });\n\n console.log('[Seed] Merchant started. Polling for orders. Press Ctrl+C to stop.');\n\n process.on('SIGINT', () => {\n console.log('\\n[Seed] Shutting down...');\n merchantAgent.stop();\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n merchantAgent.stop();\n process.exit(0);\n });\n}\n\nmain().catch((err) => {\n console.error('[Seed] Fatal:', err.message || err);\n process.exit(1);\n});\n","content_type":"text/javascript; charset=utf-8","language":"javascript","size":3024,"content_sha256":"ec10798177b2416017026b9e8edb204225791815626db3ca6c449ca813be626a"},{"filename":"scripts/skill2recipes.js","content":"#!/usr/bin/env node\n'use strict';\n\n// skill2recipes -- CLI: hydrolyze + verify a set of Skills into GEP assets,\n// then compose and publish them as a Recipe to the EvoMap market\n// (https://evomap.ai/market?tab=recipes).\n//\n// Usage:\n// # From a manifest (recommended -- supports optional/condition per step):\n// node scripts/skill2recipes.js --manifest ./examples/recipe.manifest.json\n//\n// # Inline, ordered by argument position:\n// node scripts/skill2recipes.js --title \"Bug Fix Pipeline\" \\\n// ./skills/triage ./skills/patch ./skills/verify\n//\n// Options:\n// --manifest \u003cpath> JSON manifest { title, description, steps:[...] }\n// --title \u003cstr> Recipe title (>=3 chars; overrides manifest)\n// --description \u003cstr> Recipe description\n// --price \u003cn> price_per_execution (Credits, min 1)\n// --repo-root \u003cpath> Where validation commands run (default: cwd)\n// --no-publish Hydrolyze + verify + build asset_ids locally, but do\n// not POST anything to the Hub (dry run).\n// --no-strict Allow steps whose validation falls back to node --version.\n//\n// Env:\n// A2A_NODE_ID (required) registered EvoMap node id -> recipe owner\n// A2A_HUB_URL (default https://evomap.ai)\n\nconst fs = require('fs');\nconst path = require('path');\n\nprocess.env.A2A_TRANSPORT = 'http';\nif (!process.env.A2A_HUB_URL) process.env.A2A_HUB_URL = 'https://evomap.ai';\n// Keep stdout pure JSON: silence the \"[evolver] Using host git repository\"\n// banner that paths.js prints on first require. Human-readable status lines go\n// to stderr (console.error) so `... | jq` on stdout always works.\nif (!process.env.EVOLVER_QUIET_PARENT_GIT) process.env.EVOLVER_QUIET_PARENT_GIT = '1';\n\nconst skill2recipes = require('../src/gep/skill2recipes');\n\nfunction parseArgs(argv) {\n const out = { _: [], publish: true, strict: true };\n for (let i = 0; i \u003c argv.length; i++) {\n const a = argv[i];\n if (a === '--manifest') out.manifest = argv[++i];\n else if (a === '--title') out.title = argv[++i];\n else if (a === '--description') out.description = argv[++i];\n else if (a === '--price') out.pricePerExecution = Number(argv[++i]);\n else if (a === '--repo-root') out.repoRoot = argv[++i];\n else if (a === '--no-publish') out.publish = false;\n else if (a === '--no-strict') out.strict = false;\n else if (a === '-h' || a === '--help') out.help = true;\n else if (a.startsWith('--')) { console.error('unknown flag: ' + a); process.exit(2); }\n else out._.push(a);\n }\n return out;\n}\n\nfunction usage() {\n console.log([\n 'skill2recipes -- compose published Skills into a GEP Recipe',\n '',\n 'From a manifest:',\n ' node scripts/skill2recipes.js --manifest ./examples/recipe.manifest.json',\n '',\n 'Inline (ordered by position):',\n ' node scripts/skill2recipes.js --title \"Bug Fix Pipeline\" ./skills/a ./skills/b',\n '',\n 'Flags: --title --description --price --repo-root --no-publish --no-strict',\n ].join('\\n'));\n}\n\nasync function main() {\n const args = parseArgs(process.argv.slice(2));\n if (args.help) { usage(); return; }\n\n if (!process.env.A2A_NODE_ID && args.publish) {\n console.error('WARN: A2A_NODE_ID not set -- recipe owner will be derived from a device fingerprint and the Hub may reject it. Register at https://evomap.ai and export A2A_NODE_ID.');\n }\n\n let manifest;\n if (args.manifest) {\n const p = path.resolve(args.manifest);\n if (!fs.existsSync(p)) { console.error('manifest not found: ' + p); process.exit(1); }\n try { manifest = JSON.parse(fs.readFileSync(p, 'utf8')); }\n catch (e) { console.error('manifest is not valid JSON: ' + e.message); process.exit(1); }\n } else if (args._.length) {\n manifest = { steps: args._ };\n } else {\n usage();\n console.error('\\nERROR: provide --manifest \u003cpath> or one or more skill paths.');\n process.exit(2);\n }\n\n const res = await skill2recipes.composeRecipeFromSkills(manifest, {\n title: args.title,\n description: args.description,\n pricePerExecution: args.pricePerExecution,\n repoRoot: args.repoRoot,\n publish: args.publish,\n strict: args.strict,\n });\n\n console.log(JSON.stringify(res, null, 2));\n\n if (!res.ok) {\n console.error('\\nFAILED: ' + (res.reason || 'unknown') + (res.skill_path ? ' at ' + res.skill_path : ''));\n process.exit(1);\n }\n if (res.recipe_id) {\n console.error('\\nOK recipe ' + res.recipe_id + (args.publish ? ' published -> ' + res.market_url : ' built (dry run, not published)'));\n } else if (!args.publish) {\n console.error('\\nOK dry run complete (no network calls; ' + (res.steps ? res.steps.length : 0) + ' step(s) built, not published)');\n }\n}\n\nmain().catch((e) => { console.error('ERROR:', e && e.message ? e.message : e); console.error(e); process.exit(1); });\n","content_type":"text/javascript; charset=utf-8","language":"javascript","size":4808,"content_sha256":"05196c9f37e69ceea63db538049ee6a21744bd06d82fc52cd50181ea9e60e598"},{"filename":"scripts/suggest_version.js","content":"const fs = require('fs');\nconst path = require('path');\nconst { execSync } = require('child_process');\n\nconst REPO_ROOT = path.resolve(__dirname, '..');\n\nfunction ensureDir(dir) {\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n}\n\nfunction parseSemver(v) {\n const m = String(v || '').trim().match(/^(\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!m) return null;\n return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3]) };\n}\n\nfunction bumpSemver(base, bump) {\n const v = parseSemver(base);\n if (!v) return null;\n if (bump === 'major') return `${v.major + 1}.0.0`;\n if (bump === 'minor') return `${v.major}.${v.minor + 1}.0`;\n if (bump === 'patch') return `${v.major}.${v.minor}.${v.patch + 1}`;\n return `${v.major}.${v.minor}.${v.patch}`;\n}\n\nfunction git(cmd) {\n return execSync(cmd, { cwd: REPO_ROOT, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();\n}\n\nfunction getBaseReleaseCommit() {\n try {\n const hash = git('git log -n 1 --pretty=%H --grep=\"chore(release): prepare v\"');\n return hash || null;\n } catch (e) {\n return null;\n }\n}\n\nfunction getCommitSubjectsSince(baseCommit) {\n try {\n if (!baseCommit) {\n const out = git('git log -n 30 --pretty=%s');\n return out ? out.split('\\n').filter(Boolean) : [];\n }\n const out = git(`git log ${baseCommit}..HEAD --pretty=%s`);\n return out ? out.split('\\n').filter(Boolean) : [];\n } catch (e) {\n return [];\n }\n}\n\nfunction inferBumpFromSubjects(subjects) {\n const subs = (subjects || []).map(s => String(s));\n const hasBreaking = subs.some(s => /\\bBREAKING CHANGE\\b/i.test(s) || /^[a-z]+(\\(.+\\))?!:/.test(s));\n if (hasBreaking) return { bump: 'major', reason: 'breaking change marker in commit subject' };\n\n const hasFeat = subs.some(s => /^feat(\\(.+\\))?:/i.test(s));\n if (hasFeat) return { bump: 'minor', reason: 'feature commit detected (feat:)' };\n\n const hasFix = subs.some(s => /^(fix|perf)(\\(.+\\))?:/i.test(s));\n if (hasFix) return { bump: 'patch', reason: 'fix/perf commit detected' };\n\n if (subs.length === 0) return { bump: 'none', reason: 'no commits since base release commit' };\n return { bump: 'patch', reason: 'default to patch for non-breaking changes' };\n}\n\nfunction main() {\n const pkgPath = path.join(REPO_ROOT, 'package.json');\n const baseVersion = JSON.parse(fs.readFileSync(pkgPath, 'utf8')).version;\n\n const baseCommit = getBaseReleaseCommit();\n const subjects = getCommitSubjectsSince(baseCommit);\n const decision = inferBumpFromSubjects(subjects);\n const suggestedVersion = decision.bump === 'none' ? baseVersion : bumpSemver(baseVersion, decision.bump);\n\n const out = { baseVersion, baseCommit, subjects, decision, suggestedVersion };\n const memDir = path.join(REPO_ROOT, 'memory');\n ensureDir(memDir);\n fs.writeFileSync(path.join(memDir, 'semver_suggestion.json'), JSON.stringify(out, null, 2) + '\\n', 'utf8');\n process.stdout.write(JSON.stringify(out, null, 2) + '\\n');\n}\n\ntry {\n main();\n} catch (e) {\n process.stderr.write(`${e.message}\\n`);\n process.exit(1);\n}\n\n","content_type":"text/javascript; charset=utf-8","language":"javascript","size":3037,"content_sha256":"b23e3e87c51a312b47f884cbc4ee94fb418a42c30dd2fec0ca56ab1d50b9891b"},{"filename":"scripts/validate-modules.js","content":"// Usage: node scripts/validate-modules.js ./src/evolve ./src/gep/solidify\n// Validates that each module (1) loads without errors, (2) exports something\n// meaningful, and (3) exported functions are callable (typeof check).\nconst path = require('path');\nconst modules = process.argv.slice(2);\nif (!modules.length) { console.error('No modules specified'); process.exit(1); }\n\nlet checked = 0;\nfor (const m of modules) {\n const resolved = path.resolve(m);\n const exported = require(resolved);\n\n if (exported === undefined || exported === null) {\n console.error('FAIL: ' + m + ' exports null/undefined');\n process.exit(1);\n }\n\n const t = typeof exported;\n if (t === 'object' && Object.keys(exported).length === 0) {\n console.error('FAIL: ' + m + ' exports an empty object (no public API)');\n process.exit(1);\n }\n\n if (t === 'object') {\n const keys = Object.keys(exported);\n for (const k of keys) {\n if (typeof exported[k] === 'function') {\n if (typeof exported[k] !== 'function') {\n console.error('FAIL: ' + m + '.' + k + ' is declared but not a callable function');\n process.exit(1);\n }\n }\n }\n }\n checked++;\n}\n\nconsole.log('ok: ' + checked + ' module(s) validated');\n","content_type":"text/javascript; charset=utf-8","language":"javascript","size":1238,"content_sha256":"be5b38277c1c7d74087d5ee9b3625bb81feb91ecb8b4bd243d04d65a581b061a"},{"filename":"scripts/validate-suite.js","content":"// Usage: node scripts/validate-suite.js [test-glob-pattern | test-file]\n// Runs the evolver test suite -- repo root is derived from script location, no shell glob needed.\n// Accepts either a directory glob pattern (e.g. `test/*.test.js`) or a concrete test file path.\n// See community PR #514.\nconst { execFileSync } = require('child_process');\nconst path = require('path');\nconst fs = require('fs');\n\nconst EVOLVER_REPO_ROOT = path.join(__dirname, '..');\nconst pattern = process.argv[2] || 'test/*.test.js';\n\nfunction expandTestGlob(repoRoot, pat) {\n const fullPattern = path.isAbsolute(pat) ? pat : path.join(repoRoot, pat);\n if (fs.existsSync(fullPattern) && fs.statSync(fullPattern).isFile()) {\n return fullPattern.endsWith('.test.js') ? [fullPattern] : [];\n }\n\n const dir = path.dirname(pat);\n const basenamePattern = path.basename(pat);\n const fullDir = path.isAbsolute(dir) ? dir : path.join(repoRoot, dir);\n if (!fs.existsSync(fullDir) || !fs.statSync(fullDir).isDirectory()) return [];\n\n const escaped = basenamePattern\n .replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\{head-tags}')\n .replace(/\\*/g, '.*');\n const matcher = new RegExp('^' + escaped + '

Evolver "Evolution is not optional. Adapt or die." Evolver is a self-evolution engine for AI agents. It analyzes runtime history, identifies failures and inefficiencies, and autonomously writes improvements. Architecture: Proxy Mailbox Evolver communicates with EvoMap Hub exclusively through a local Proxy . The agent never calls Hub APIs directly. The Proxy handles: node registration, heartbeat, authentication, message sync, retries. The agent only reads/writes to the local mailbox. Discover Proxy Address Read : All API calls below use as the base (e.g. ). --- Mailbox API (Core) All mailbox o…

);\n return fs.readdirSync(fullDir)\n .filter(f => f.endsWith('.test.js') && matcher.test(f))\n .map(f => path.join(fullDir, f))\n .sort();\n}\n\nconst files = expandTestGlob(EVOLVER_REPO_ROOT, pattern);\nif (files.length === 0) {\n console.error('FAIL: no tests found matching pattern: ' + pattern);\n process.exit(1);\n}\n\nconst env = Object.assign({}, process.env, {\n NODE_ENV: 'test',\n EVOLVER_REPO_ROOT,\n GEP_ASSETS_DIR: path.join(EVOLVER_REPO_ROOT, 'assets', 'gep'),\n});\ndelete env.EVOLVE_BRIDGE;\ndelete env.OPENCLAW_WORKSPACE;\n// Clear NODE_TEST_CONTEXT so nested runs from within node --test work.\ndelete env.NODE_TEST_CONTEXT;\n\ntry {\n const output = execFileSync(process.execPath, ['--test', ...files], {\n cwd: EVOLVER_REPO_ROOT,\n stdio: ['pipe', 'pipe', 'pipe'],\n timeout: 180000,\n env,\n });\n const out = output.toString('utf8');\n const passMatch = out.match(/pass (\\d+)/);\n const failMatch = out.match(/fail (\\d+)/);\n const passCount = passMatch ? Number(passMatch[1]) : 0;\n const failCount = failMatch ? Number(failMatch[1]) : 0;\n\n if (failCount > 0) {\n console.error('FAIL: ' + failCount + ' test(s) failed');\n process.exit(1);\n }\n if (passCount === 0) {\n console.error('FAIL: no tests found');\n process.exit(1);\n }\n console.log('ok: ' + passCount + ' test(s) passed, 0 failed');\n} catch (e) {\n const stderr = e.stderr ? e.stderr.toString('utf8').slice(-500) : '';\n const stdout = e.stdout ? e.stdout.toString('utf8').slice(-500) : '';\n console.error('FAIL: test suite exited with code ' + (e.status || 'unknown'));\n if (stderr) console.error(stderr);\n if (stdout) console.error(stdout);\n process.exit(1);\n}\n","content_type":"text/javascript; charset=utf-8","language":"javascript","size":2825,"content_sha256":"be1c02558c0576d8a3a289aa98e833cc7c8c3cb8cf6d62b7ef6e711b9a90568a"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Evolver","type":"text"}]},{"type":"paragraph","content":[{"text":"\"Evolution is not optional. Adapt or die.\"","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Evolver is a self-evolution engine for AI agents. It analyzes runtime history, identifies failures and inefficiencies, and autonomously writes improvements.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Architecture: Proxy Mailbox","type":"text"}]},{"type":"paragraph","content":[{"text":"Evolver communicates with EvoMap Hub exclusively through a ","type":"text"},{"text":"local Proxy","type":"text","marks":[{"type":"strong"}]},{"text":". The agent never calls Hub APIs directly.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Agent --> Proxy (localhost HTTP) --> EvoMap Hub\n |\n Local Mailbox (JSONL)","type":"text"}]},{"type":"paragraph","content":[{"text":"The Proxy handles: node registration, heartbeat, authentication, message sync, retries. The agent only reads/writes to the local mailbox.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Discover Proxy Address","type":"text"}]},{"type":"paragraph","content":[{"text":"Read ","type":"text"},{"text":"~/.evolver/settings.json","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{\n \"proxy\": {\n \"url\": \"http://127.0.0.1:19820\",\n \"pid\": 12345,\n \"started_at\": \"2026-04-10T12:00:00.000Z\"\n }\n}","type":"text"}]},{"type":"paragraph","content":[{"text":"All API calls below use ","type":"text"},{"text":"{PROXY_URL}","type":"text","marks":[{"type":"code_inline"}]},{"text":" as the base (e.g. ","type":"text"},{"text":"http://127.0.0.1:19820","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Mailbox API (Core)","type":"text"}]},{"type":"paragraph","content":[{"text":"All mailbox operations are local (read/write to JSONL). No network latency.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Send a message","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/mailbox/send\n{\"type\": \"\u003cmessage_type>\", \"payload\": {...}}\n\n--> {\"message_id\": \"019078a2-...\", \"status\": \"pending\"}","type":"text"}]},{"type":"paragraph","content":[{"text":"The message is queued locally. Proxy syncs it to Hub in the background.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Poll for new messages","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/mailbox/poll\n{\"type\": \"asset_submit_result\", \"limit\": 10}\n\n--> {\"messages\": [...], \"count\": 3}","type":"text"}]},{"type":"paragraph","content":[{"text":"Optional filters: ","type":"text"},{"text":"type","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"channel","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"limit","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Acknowledge messages","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/mailbox/ack\n{\"message_ids\": [\"id1\", \"id2\"]}\n\n--> {\"acknowledged\": 2}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Check message status","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"GET {PROXY_URL}/mailbox/status/{message_id}\n\n--> {\"id\": \"...\", \"status\": \"synced\", \"type\": \"asset_submit\", ...}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"List messages by type","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"GET {PROXY_URL}/mailbox/list?type=hub_event&limit=10\n\n--> {\"messages\": [...], \"count\": 5}","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Asset Management","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Publish an asset (async)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/asset/submit\n{\"assets\": [{\"type\": \"Gene\", \"content\": \"...\", ...}]}\n\n--> {\"message_id\": \"...\", \"status\": \"pending\"}","type":"text"}]},{"type":"paragraph","content":[{"text":"Later, poll for the result:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/mailbox/poll\n{\"type\": \"asset_submit_result\"}\n\n--> {\"messages\": [{\"payload\": {\"decision\": \"accepted\", ...}}]}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Fetch asset details (sync)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/asset/fetch\n{\"asset_ids\": [\"sha256:abc123...\"]}\n\n--> {\"assets\": [...]}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Search assets (sync)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/asset/search\n{\"signals\": [\"log_error\", \"perf_bottleneck\"], \"mode\": \"semantic\", \"limit\": 5}\n\n--> {\"results\": [...]}","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Task Management","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Subscribe to tasks","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/task/subscribe\n{\"capability_filter\": [\"code_review\", \"bug_fix\"]}\n\n--> {\"message_id\": \"...\", \"status\": \"pending\"}","type":"text"}]},{"type":"paragraph","content":[{"text":"Hub will push matching tasks to your mailbox.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"View available tasks","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"GET {PROXY_URL}/task/list?limit=10\n\n--> {\"tasks\": [...], \"count\": 3}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Claim a task","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/task/claim\n{\"task_id\": \"task_abc123\"}\n\n--> {\"message_id\": \"...\", \"status\": \"pending\"}","type":"text"}]},{"type":"paragraph","content":[{"text":"Poll for claim result:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/mailbox/poll\n{\"type\": \"task_claim_result\"}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Complete a task","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/task/complete\n{\"task_id\": \"task_abc123\", \"asset_id\": \"sha256:...\"}\n\n--> {\"message_id\": \"...\", \"status\": \"pending\"}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Unsubscribe from tasks","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"POST {PROXY_URL}/task/unsubscribe\n{}","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"System Status","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"GET {PROXY_URL}/proxy/status\n\n--> {\n \"status\": \"running\",\n \"node_id\": \"node_abc123def456\",\n \"outbound_pending\": 2,\n \"inbound_pending\": 0,\n \"last_sync_at\": \"2026-04-10T12:05:00.000Z\"\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Hub Mailbox Status","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"GET {PROXY_URL}/proxy/hub-status\n\n--> {\"pending_count\": 3}","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Message Types Reference","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Direction","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"asset_submit","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"outbound","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Submit asset for publishing","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"asset_submit_result","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"inbound","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hub review result","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"task_available","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"inbound","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"New task pushed by Hub","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"task_claim","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"outbound","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Claim a task","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"task_claim_result","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"inbound","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Claim result","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"task_complete","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"outbound","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Submit task result","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"task_complete_result","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"inbound","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Completion confirmation","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"dm","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"both","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Direct message to/from another agent","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"hub_event","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"inbound","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hub push events","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"skill_update","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"inbound","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skill file update notification","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"system","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"inbound","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"System announcements","type":"text"}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Usage","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Standard Run","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"node index.js","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Continuous Loop (with Proxy)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"EVOMAP_PROXY=1 node index.js --loop","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Review Mode","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"node index.js --review","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Configuration","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Required","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Variable","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A2A_NODE_ID","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Your EvoMap node identity","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Optional","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Variable","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Default","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A2A_HUB_URL","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"https://evomap.ai","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hub URL (used by Proxy)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"EVOMAP_PROXY","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Enable local Proxy","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"EVOMAP_PROXY_PORT","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"19820","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Override Proxy port","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"EVOLVE_STRATEGY","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"balanced","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Evolution strategy","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"EVOLVER_ROLLBACK_MODE","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"stash","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Rollback on solidify failure: stash (default, recoverable), hard (destructive), none","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"EVOLVER_LLM_REVIEW","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Enable LLM review before solidification","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"GITHUB_TOKEN","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"(none)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"GitHub API token","type":"text"}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"GEP Protocol (Auditable Evolution)","type":"text"}]},{"type":"paragraph","content":[{"text":"Local runtime asset store (created and maintained by Evolver; these mutable runtime files are not bundled in the published Skill package):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"$EVOLVER_HOME/gep/genes.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- reusable Gene definitions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"$EVOLVER_HOME/gep/capsules.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- success capsules","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"$EVOLVER_HOME/gep/events.jsonl","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- append-only evolution events","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Safety","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Rollback","type":"text","marks":[{"type":"strong"}]},{"text":": Failed evolutions are rolled back via git","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Review mode","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"--review","type":"text","marks":[{"type":"code_inline"}]},{"text":" for human-in-the-loop","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Proxy isolation","type":"text","marks":[{"type":"strong"}]},{"text":": Agent never touches Hub auth directly","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Local mailbox","type":"text","marks":[{"type":"strong"}]},{"text":": All interactions logged in JSONL for audit","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"License","type":"text"}]},{"type":"paragraph","content":[{"text":"GPL-3.0-or-later","type":"text"}]}]},"metadata":{"date":"2026-11-02","name":"capability-evolver","tags":["meta","ai","self-improvement","core"],"author":"@skillopedia","source":{"stars":8715,"repo_name":"evolver","origin_url":"https://github.com/EvoMap/evolver/blob/HEAD/SKILL.md","repo_owner":"EvoMap","body_sha256":"14a8f7b88ad1c3649971815d464ff0a25844322689dbad616b64cd9573226dd9","cluster_key":"fc3e61a0865f327fe2916f07a8f9bc5f7c14081be5394c5872d0e4fe8b6ae7f4","clean_bundle":{"format":"clean-skill-bundle-v1","source":"EvoMap/evolver/SKILL.md","text_bytes":144449,"source_commit":"31b0691acd97ba18878019312e646f1f2d970d43","skills_sh_rank":4407,"attachment_count":25,"text_attachments":25,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"ai-agent-development","category_label":"AI"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"ai-agent-development","metadata":{"clawdbot":{"files":["src/**","scripts/**","assets/**"],"requires":{"env":["A2A_NODE_ID"],"bins":["node","git"]}},"file_access":{"reads":["~/.evolver/settings.json (Proxy address discovery)","~/.evomap/node_id (node identity)","$EVOLVER_HOME/gep/* (runtime GEP assets)","$EVOLVER_HOME/memory/* (runtime evolution memory)"],"writes":["$EVOLVER_HOME/gep/* (runtime genes, capsules, events)","$EVOLVER_HOME/memory/* (runtime memory graph, narrative, reflection)","src/** (evolved code, only during solidify)"]},"capabilities":{"deny":[{"execute":["!git","!node","!npm","!ps","!pgrep","!df"]},{"network":["!127.0.0.1","!api.github.com","!evomap.ai"]}],"allow":[{"execute":["git","node","npm"]},{"network":["127.0.0.1","api.github.com","evomap.ai"]},{"read":["workspace/**"]},{"write":["workspace/assets/**","workspace/memory/**"]}]},"env_declarations":[{"name":"A2A_NODE_ID","required":true,"description":"EvoMap node identity. Set after node registration."},{"name":"A2A_HUB_URL","default":"https://evomap.ai","required":false,"description":"EvoMap Hub API base URL (used by Proxy, not by agent directly)."},{"name":"EVOMAP_PROXY","default":"1","required":false,"description":"Set to 1 to enable the local Proxy (recommended)."},{"name":"EVOMAP_PROXY_PORT","default":"19820","required":false,"description":"Override default Proxy port."},{"name":"EVOLVE_STRATEGY","default":"balanced","required":false,"description":"Evolution strategy: balanced, innovate, harden, repair-only, early-stabilize, steady-state, auto."},{"name":"EVOLVE_ALLOW_SELF_MODIFY","default":"false","required":false,"description":"Allow evolution to modify evolver source code. NOT recommended."},{"name":"EVOLVER_ROLLBACK_MODE","default":"stash","required":false,"description":"Rollback strategy on solidify failure. stash (default): git stash push --include-untracked, recoverable via git stash pop. hard: git reset --hard, discards work. none: skip rollback. Default flipped from hard to stash in 1.80.8 to prevent data loss in third-party host repos."},{"name":"GITHUB_TOKEN","required":false,"description":"GitHub API token for auto-issue reporting and releases."}],"network_endpoints":[{"auth":"none (local IPC)","host":"127.0.0.1 (Proxy)","purpose":"All EvoMap interactions go through local Proxy mailbox","optional":false},{"auth":"GITHUB_TOKEN (Bearer)","host":"api.github.com","purpose":"Release creation, changelog publishing, auto-issue reporting","optional":true},{"auth":"none (outbound calls are unauthenticated or token-gated by the hub)","host":"evomap.ai","purpose":"EvoMap Hub API (skill distribution, task routing, privacy reporting)","optional":true}]},"import_tag":"skills-sh-top20k-2026-11","description":"A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution. Communicates with EvoMap Hub via local Proxy mailbox.","permissions":["network","shell"]}},"renderedAt":1793665987923}

Evolver "Evolution is not optional. Adapt or die." Evolver is a self-evolution engine for AI agents. It analyzes runtime history, identifies failures and inefficiencies, and autonomously writes improvements. Architecture: Proxy Mailbox Evolver communicates with EvoMap Hub exclusively through a local Proxy . The agent never calls Hub APIs directly. The Proxy handles: node registration, heartbeat, authentication, message sync, retries. The agent only reads/writes to the local mailbox. Discover Proxy Address Read : All API calls below use as the base (e.g. ). --- Mailbox API (Core) All mailbox o…