@evomap/evolver 1.80.6 → 1.80.8

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.
Files changed (76) hide show
  1. package/README.zh-CN.md +18 -11
  2. package/assets/gep/candidates.jsonl +3 -2
  3. package/index.js +55 -2
  4. package/package.json +1 -1
  5. package/src/adapters/opencode.js +137 -2
  6. package/src/config.js +5 -0
  7. package/src/evolve/guards.js +1 -1
  8. package/src/evolve/pipeline/collect.js +1 -1
  9. package/src/evolve/pipeline/dispatch.js +1 -1
  10. package/src/evolve/pipeline/enrich.js +1 -1
  11. package/src/evolve/pipeline/hub.js +1 -1
  12. package/src/evolve/pipeline/select.js +1 -1
  13. package/src/evolve/pipeline/signals.js +1 -1
  14. package/src/evolve/utils.js +1 -1
  15. package/src/evolve.js +1 -1
  16. package/src/gep/.integrity +0 -0
  17. package/src/gep/a2aProtocol.js +1 -1
  18. package/src/gep/assetStore.js +59 -5
  19. package/src/gep/candidateEval.js +1 -1
  20. package/src/gep/candidates.js +1 -1
  21. package/src/gep/contentHash.js +1 -1
  22. package/src/gep/crypto.js +1 -1
  23. package/src/gep/curriculum.js +1 -1
  24. package/src/gep/deviceId.js +1 -1
  25. package/src/gep/envFingerprint.js +1 -1
  26. package/src/gep/epigenetics.js +1 -0
  27. package/src/gep/explore.js +1 -1
  28. package/src/gep/hash.js +1 -0
  29. package/src/gep/hubReview.js +1 -1
  30. package/src/gep/hubSearch.js +1 -1
  31. package/src/gep/hubVerify.js +1 -1
  32. package/src/gep/integrityCheck.js +1 -1
  33. package/src/gep/learningSignals.js +1 -1
  34. package/src/gep/memoryGraph.js +1 -1
  35. package/src/gep/memoryGraphAdapter.js +1 -1
  36. package/src/gep/mutation.js +1 -1
  37. package/src/gep/narrativeMemory.js +1 -1
  38. package/src/gep/personality.js +1 -1
  39. package/src/gep/policyCheck.js +1 -1
  40. package/src/gep/prompt.js +1 -1
  41. package/src/gep/reflection.js +1 -1
  42. package/src/gep/selector.js +1 -1
  43. package/src/gep/shield.js +1 -1
  44. package/src/gep/skillDistiller.js +1 -1
  45. package/src/gep/solidify.js +1 -1
  46. package/src/gep/strategy.js +1 -1
  47. package/src/gep/taskReceiver.js +7 -2
  48. package/src/webui/client/clientJs/assets.js +111 -0
  49. package/src/webui/client/clientJs/bootstrap.js +92 -0
  50. package/src/webui/client/clientJs/common.js +77 -0
  51. package/src/webui/client/clientJs/i18n.js +366 -0
  52. package/src/webui/client/clientJs/index.js +35 -0
  53. package/src/webui/client/clientJs/interactions.js +351 -0
  54. package/src/webui/client/clientJs/overview.js +152 -0
  55. package/src/webui/client/clientJs/personality.js +285 -0
  56. package/src/webui/client/clientJs/pipelines.js +330 -0
  57. package/src/webui/client/indexHtml.js +221 -0
  58. package/src/webui/client/static.js +23 -0
  59. package/src/webui/client/stylesCss.js +639 -0
  60. package/src/webui/client/vendor/README.md +15 -0
  61. package/src/webui/client/vendor/echarts.min.js +45 -0
  62. package/src/webui/index.js +14 -0
  63. package/src/webui/observer/assets.js +146 -0
  64. package/src/webui/observer/index.js +37 -0
  65. package/src/webui/observer/interactions.js +120 -0
  66. package/src/webui/observer/jsonl.js +75 -0
  67. package/src/webui/observer/paths.js +46 -0
  68. package/src/webui/observer/personality.js +43 -0
  69. package/src/webui/observer/pipelineEvents.js +58 -0
  70. package/src/webui/observer/redact.js +63 -0
  71. package/src/webui/observer/runs.js +356 -0
  72. package/src/webui/observer/safety.js +57 -0
  73. package/src/webui/observer/skills.js +70 -0
  74. package/src/webui/observer/status.js +71 -0
  75. package/src/webui/server/http.js +138 -0
  76. package/src/webui/server/routes.js +41 -0
package/README.zh-CN.md CHANGED
@@ -198,7 +198,7 @@ evolver --loop
198
198
  - **自我修复引导**:从信号中生成面向修复的指令。
199
199
  - **[GEP 协议](https://evomap.ai/wiki)**:标准化进化流程与可复用资产,支持可审计与可共享。
200
200
  - **突变协议与人格进化**:每次进化必须显式声明 Mutation,并维护可进化的 PersonalityState。
201
- - **可配置进化策略**:通过 `EVOLVE_STRATEGY` 环境变量选择 `balanced`/`innovate`/`harden`/`repair-only` 模式。
201
+ - **可配置进化策略**:通过 `EVOLVE_STRATEGY` 环境变量选择 `balanced`/`innovate`/`harden`/`repair-only`/`early-stabilize`/`steady-state` 模式,每个策略都同时分配 repair/optimize/innovate/explore 四类意图的比例。
202
202
  - **信号去重**:自动检测修复循环,防止反复修同一个问题。
203
203
  - **运维模块** (`src/ops/`):6 个可移植的运维工具(生命周期管理、技能健康监控、磁盘清理、Git 自修复等),零平台依赖。
204
204
  - **源码保护**:防止自治代理覆写核心进化引擎源码。
@@ -235,17 +235,24 @@ evolver --loop
235
235
 
236
236
  ### 指定进化策略
237
237
  ```bash
238
- EVOLVE_STRATEGY=innovate evolver --loop # 最大化创新
239
- EVOLVE_STRATEGY=harden evolver --loop # 聚焦稳定性
240
- EVOLVE_STRATEGY=repair-only evolver --loop # 紧急修复模式
238
+ EVOLVE_STRATEGY=innovate evolver --loop # 最大化创新
239
+ EVOLVE_STRATEGY=harden evolver --loop # 聚焦稳定性
240
+ EVOLVE_STRATEGY=repair-only evolver --loop # 紧急修复模式
241
+ EVOLVE_STRATEGY=steady-state evolver --loop # 进化饱和后切换到探索为主
241
242
  ```
242
243
 
243
- | 策略 | 创新 | 优化 | 修复 | 适用场景 |
244
- | :--- | :--- | :--- | :--- | :--- |
245
- | `balanced`(默认) | 50% | 30% | 20% | 日常运行,稳步成长 |
246
- | `innovate` | 80% | 15% | 5% | 系统稳定,快速出新功能 |
247
- | `harden` | 20% | 40% | 40% | 大改动后,聚焦稳固 |
248
- | `repair-only` | 0% | 20% | 80% | 紧急状态,全力修复 |
244
+ 每个策略都会同时分配 4 类意图(**repair / optimize / innovate / explore**)的目标比例,并写入 GEP prompt 影响 LLM 选择:
245
+
246
+ | 策略 | 修复 | 优化 | 创新 | 探索 | 适用场景 |
247
+ | :--- | :--- | :--- | :--- | :--- | :--- |
248
+ | `balanced`(默认) | 20% | 20% | 50% | 10% | 日常运行,稳步成长 |
249
+ | `innovate` | 5% | 10% | 80% | 5% | 系统稳定,快速出新功能 |
250
+ | `harden` | 40% | 35% | 20% | 5% | 大改动后,聚焦稳固 |
251
+ | `repair-only` | 80% | 18% | 0% | 2% | 紧急状态,全力修复 |
252
+ | `early-stabilize` | 60% | 22% | 15% | 3% | 初期循环,先把存量问题压下去 |
253
+ | `steady-state` | 55% | 25% | 5% | 15% | 进化饱和,少改动多探索新方向 |
254
+
255
+ **意图说明**:`repair` 修复明确错误;`optimize` 优化既有路径;`innovate` 引入新能力 / 新技能;`explore` 不做侵入式改动,主动扫描代码库与外部知识,把发现的机会转写为新的信号或低风险 Capsule,为后续 innovate 储备题目。
249
256
 
250
257
  ### 运维管理(生命周期)
251
258
  ```bash
@@ -373,7 +380,7 @@ Evolver 能自动适应不同环境。
373
380
 
374
381
  | 变量 | 说明 | 默认值 |
375
382
  | :--- | :--- | :--- |
376
- | `EVOLVE_STRATEGY` | 进化策略预设(`balanced` / `innovate` / `harden` / `repair-only`) | `balanced` |
383
+ | `EVOLVE_STRATEGY` | 进化策略预设(`balanced` / `innovate` / `harden` / `repair-only` / `early-stabilize` / `steady-state`) | `balanced` |
377
384
  | `A2A_HUB_URL` | [EvoMap Hub](https://evomap.ai) 地址 | _(未设置,离线模式)_ |
378
385
  | `A2A_NODE_ID` | 你在网络中的节点身份 | _(根据设备指纹自动生成)_ |
379
386
  | `HEARTBEAT_INTERVAL_MS` | Hub 心跳间隔 | `360000`(6 分钟) |
@@ -1,2 +1,3 @@
1
- {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-05-09T09:04:20.466Z","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"}}
2
- {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-05-09T09:04:49.711Z","signals":["memory_missing","user_missing","session_logs_missing"],"tags":["memory_missing","user_missing","session_logs_missing","area:memory"],"shape":{"title":"Harden session log detection and fallback behavior","input":"Recent session transcript + memory snippets + user instructions","output":"A safe, auditable evolution patch guided by GEP assets","invariants":"Protocol order, small reversible patches, validation, append-only events","params":"Signals: memory_missing, user_missing, session_logs_missing","failure_points":"Missing signals, over-broad changes, skipped validation, missing knowledge solidification","evidence":"Signal present: session_logs_missing"}}
1
+ {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-05-16T05:34:39.331Z","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"}}
2
+ {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-05-16T05:35:04.849Z","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"}}
3
+ {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-05-16T05:35:34.632Z","signals":["memory_missing","user_missing","session_logs_missing"],"tags":["memory_missing","user_missing","session_logs_missing","area:memory"],"shape":{"title":"Harden session log detection and fallback behavior","input":"Recent session transcript + memory snippets + user instructions","output":"A safe, auditable evolution patch guided by GEP assets","invariants":"Protocol order, small reversible patches, validation, append-only events","params":"Signals: memory_missing, user_missing, session_logs_missing","failure_points":"Missing signals, over-broad changes, skipped validation, missing knowledge solidification","evidence":"Signal present: session_logs_missing"}}
package/index.js CHANGED
@@ -1558,13 +1558,63 @@ async function main() {
1558
1558
  console.log('');
1559
1559
  }
1560
1560
 
1561
+ } else if (command === 'webui') {
1562
+ const portFlag = args.find(a => typeof a === 'string' && a.startsWith('--port='));
1563
+ const port = portFlag ? Number(portFlag.slice('--port='.length)) : undefined;
1564
+ const { startWebUi } = require('./src/webui');
1565
+ try {
1566
+ const info = await startWebUi({ port });
1567
+ console.log('[webui] Open ' + info.url);
1568
+ const shutdown = async () => {
1569
+ try { await info.server.stop(); } catch (_) {}
1570
+ process.exit(0);
1571
+ };
1572
+ process.on('SIGINT', shutdown);
1573
+ process.on('SIGTERM', shutdown);
1574
+ await new Promise(() => {});
1575
+ } catch (error) {
1576
+ console.error('[webui] Failed: ' + (error && error.message || error));
1577
+ process.exit(1);
1578
+ }
1579
+
1561
1580
  } else if (command === 'setup-hooks') {
1562
- const { setupHooks } = require('./src/adapters/hookAdapter');
1581
+ const hookAdapter = require('./src/adapters/hookAdapter');
1582
+ const { setupHooks, resolveConfigRoot, detectPlatform, loadAdapter } = hookAdapter;
1563
1583
 
1564
1584
  const platformFlag = args.find(a => typeof a === 'string' && a.startsWith('--platform='));
1565
1585
  const platform = platformFlag ? platformFlag.slice('--platform='.length) : undefined;
1566
1586
  const force = args.includes('--force');
1567
1587
  const uninstall = args.includes('--uninstall');
1588
+ const verifyOnly = args.includes('--verify');
1589
+
1590
+ if (verifyOnly) {
1591
+ // Read-only verification: do not touch any files, just report whether
1592
+ // the previously-installed hooks/plugin look healthy. Lets users answer
1593
+ // "is the plugin actually loaded?" without grepping opencode logs.
1594
+ try {
1595
+ const platformId = platform || detectPlatform(process.cwd());
1596
+ if (!platformId) {
1597
+ console.error('[setup-hooks] --verify: could not detect platform. Pass --platform=opencode|cursor|claude-code|codex|kiro');
1598
+ process.exit(2);
1599
+ }
1600
+ const adapter = loadAdapter(platformId);
1601
+ if (!adapter || typeof adapter.verify !== 'function') {
1602
+ console.error('[setup-hooks] --verify: platform ' + platformId + ' does not support verification yet.');
1603
+ process.exit(2);
1604
+ }
1605
+ const configRoot = resolveConfigRoot(platformId, process.cwd());
1606
+ const report = adapter.verify({ configRoot });
1607
+ if (typeof adapter.printVerifyReport === 'function') {
1608
+ adapter.printVerifyReport(report);
1609
+ } else {
1610
+ console.log(JSON.stringify(report, null, 2));
1611
+ }
1612
+ process.exit(report.ok ? 0 : 1);
1613
+ } catch (verifyErr) {
1614
+ console.error('[setup-hooks] --verify error:', verifyErr && verifyErr.message || verifyErr);
1615
+ process.exit(1);
1616
+ }
1617
+ }
1568
1618
 
1569
1619
  try {
1570
1620
  const result = await setupHooks({
@@ -1659,7 +1709,7 @@ async function main() {
1659
1709
  }
1660
1710
 
1661
1711
  } else {
1662
- console.log(`Usage: node index.js [run|/evolve|solidify|review|distill|fetch|sync|asset-log|setup-hooks|buy|orders|verify|atp-complete] [--loop]
1712
+ console.log(`Usage: node index.js [run|/evolve|solidify|review|distill|fetch|sync|asset-log|webui|setup-hooks|buy|orders|verify|atp-complete] [--loop]
1663
1713
  - fetch flags:
1664
1714
  - --skill=<id> | -s <id> (skill ID to download)
1665
1715
  - --out=<dir> (output directory, default: ./skills/<skill_id>)
@@ -1685,12 +1735,15 @@ async function main() {
1685
1735
  - --platform=cursor|claude-code|codex|kiro|opencode (auto-detect if omitted)
1686
1736
  - --force (overwrite existing config)
1687
1737
  - --uninstall (remove evolver hooks)
1738
+ - --verify (read-only: print install health for the chosen platform)
1688
1739
  - asset-log flags:
1689
1740
  - --run=<run_id> (filter by run ID)
1690
1741
  - --action=<action> (filter: hub_search_hit, hub_search_miss, asset_reuse, asset_reference, asset_publish, asset_publish_skip)
1691
1742
  - --last=<N> (show last N entries)
1692
1743
  - --since=<ISO_date> (entries after date)
1693
1744
  - --json (raw JSON output)
1745
+ - webui flags:
1746
+ - --port=<N> (local Web UI port, default 19821)
1694
1747
 
1695
1748
  ATP (Agent Transaction Protocol) subcommands:
1696
1749
  - buy <caps> (place an ATP order; caps is comma-separated)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evomap/evolver",
3
- "version": "1.80.6",
3
+ "version": "1.80.8",
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": {
@@ -127,7 +127,8 @@ function install({ configRoot, evolverRoot, force }) {
127
127
 
128
128
  if (!force && isEvolverManagedPluginFile(pluginPath)) {
129
129
  console.log('[opencode] Evolver plugin already installed. Use --force to overwrite.');
130
- return { ok: true, skipped: true };
130
+ printPostInstallNotice(pluginPath);
131
+ return { ok: true, skipped: true, plugin_path: pluginPath };
131
132
  }
132
133
 
133
134
  fs.mkdirSync(opencodeDir, { recursive: true });
@@ -144,15 +145,147 @@ function install({ configRoot, evolverRoot, force }) {
144
145
  }
145
146
 
146
147
  console.log('[opencode] Installation complete.');
147
- console.log('[opencode] opencode auto-loads plugins from .opencode/plugins/ -- restart opencode to activate.');
148
+ printPostInstallNotice(written);
148
149
 
149
150
  return {
150
151
  ok: true,
151
152
  platform: 'opencode',
153
+ plugin_path: written,
152
154
  files: [written, agentsMdPath, ...copied],
153
155
  };
154
156
  }
155
157
 
158
+ function printPostInstallNotice(pluginPath) {
159
+ // The opencode TUI "Plugins" tab only lists TUI plugins (registered via
160
+ // tui.json with `default export { id, tui }`). Server plugins like ours,
161
+ // auto-loaded from .opencode/plugins/, are functional but invisible in
162
+ // that tab. This is by opencode design, not a bug. See:
163
+ // https://github.com/sst/opencode -> packages/opencode/specs/tui-plugins.md
164
+ // Surfacing this proactively here prevents the "is it actually loaded?"
165
+ // confusion that motivated EvoMap/evolver issue #531.
166
+ console.log('');
167
+ console.log('[opencode] Restart opencode for the plugin to take effect.');
168
+ console.log('[opencode] Note: this is a SERVER plugin (event hooks). It will NOT appear in');
169
+ console.log('[opencode] the TUI "Plugins" tab -- that tab only lists TUI plugins');
170
+ console.log('[opencode] (registered via tui.json). The plugin is still loaded and');
171
+ console.log('[opencode] running silently in the background.');
172
+ console.log('[opencode] To verify the plugin is loaded, run:');
173
+ console.log('[opencode] opencode --print-logs --log-level INFO debug config 2>&1 | grep ' + JSON.stringify(pluginPath));
174
+ console.log('[opencode] Or run:');
175
+ console.log('[opencode] evolver setup-hooks --platform=opencode --verify');
176
+ }
177
+
178
+ // Walk the install state and report what is healthy / what is missing.
179
+ // Used by the `--verify` flag to give users a definitive answer to
180
+ // "is the plugin actually installed and loadable?". Returns a structured
181
+ // result so callers (CLI, future TUI plugin) can format it as they like.
182
+ function verify({ configRoot }) {
183
+ const opencodeDir = path.join(configRoot, '.opencode');
184
+ const hooksDir = path.join(opencodeDir, HOOK_SCRIPTS_DIR_NAME);
185
+ const pluginsDir = path.join(opencodeDir, PLUGINS_DIR_NAME);
186
+ const pluginPath = path.join(pluginsDir, PLUGIN_FILE_NAME);
187
+ const agentsMdPath = path.join(configRoot, 'AGENTS.md');
188
+ const expectedScripts = [
189
+ 'evolver-session-start.js',
190
+ 'evolver-signal-detect.js',
191
+ 'evolver-session-end.js',
192
+ ];
193
+
194
+ const checks = [];
195
+
196
+ const pluginExists = fs.existsSync(pluginPath);
197
+ checks.push({
198
+ id: 'plugin_file_present',
199
+ ok: pluginExists,
200
+ detail: pluginExists ? pluginPath : 'missing: ' + pluginPath,
201
+ });
202
+
203
+ const managed = pluginExists && isEvolverManagedPluginFile(pluginPath);
204
+ checks.push({
205
+ id: 'plugin_managed_marker',
206
+ ok: managed,
207
+ detail: managed
208
+ ? 'first line contains _evolver_managed: true'
209
+ : 'plugin file is not evolver-managed (was it edited or replaced by another tool?)',
210
+ });
211
+
212
+ let pluginLoadable = false;
213
+ let pluginLoadError = null;
214
+ if (pluginExists) {
215
+ try {
216
+ // Require the plugin in an isolated module cache slot to confirm it
217
+ // parses and exports the expected shape. opencode does an ESM dynamic
218
+ // import; CommonJS require here is a strict subset of that, so a
219
+ // failure here is a guaranteed failure under opencode too.
220
+ delete require.cache[require.resolve(pluginPath)];
221
+ const mod = require(pluginPath);
222
+ const fn = mod && (mod.Evolver || mod.default);
223
+ pluginLoadable = typeof fn === 'function';
224
+ if (!pluginLoadable) pluginLoadError = 'no Evolver/default function export';
225
+ } catch (err) {
226
+ pluginLoadError = (err && err.message) || String(err);
227
+ }
228
+ }
229
+ checks.push({
230
+ id: 'plugin_loadable',
231
+ ok: pluginLoadable,
232
+ detail: pluginLoadable
233
+ ? 'require() succeeded and exports Evolver()'
234
+ : 'require() failed: ' + (pluginLoadError || 'unknown'),
235
+ });
236
+
237
+ const missingScripts = expectedScripts.filter(
238
+ (name) => !fs.existsSync(path.join(hooksDir, name))
239
+ );
240
+ checks.push({
241
+ id: 'hook_scripts_present',
242
+ ok: missingScripts.length === 0,
243
+ detail: missingScripts.length === 0
244
+ ? 'all 3 hook scripts present in ' + hooksDir
245
+ : 'missing: ' + missingScripts.join(', '),
246
+ });
247
+
248
+ let agentsMdHasSection = false;
249
+ try {
250
+ if (fs.existsSync(agentsMdPath)) {
251
+ agentsMdHasSection = fs.readFileSync(agentsMdPath, 'utf8').includes(EVOLVER_MARKER);
252
+ }
253
+ } catch { /* ignore */ }
254
+ checks.push({
255
+ id: 'agents_md_section',
256
+ ok: agentsMdHasSection,
257
+ detail: agentsMdHasSection
258
+ ? 'AGENTS.md contains evolution memory section'
259
+ : 'AGENTS.md is missing or has no evolution section (re-run install)',
260
+ });
261
+
262
+ const allOk = checks.every((c) => c.ok);
263
+
264
+ return {
265
+ ok: allOk,
266
+ plugin_path: pluginPath,
267
+ hooks_dir: hooksDir,
268
+ config_root: configRoot,
269
+ checks,
270
+ note: allOk
271
+ ? 'Plugin is installed and loadable. opencode\'s TUI "Plugins" tab will not list it -- that tab only shows TUI plugins. Run `opencode --print-logs --log-level INFO debug config` and grep for the plugin path to confirm opencode loads it at startup.'
272
+ : 'One or more checks failed. Re-run `evolver setup-hooks --platform=opencode --force` to repair.',
273
+ };
274
+ }
275
+
276
+ function printVerifyReport(report) {
277
+ console.log('[opencode] Verify report');
278
+ console.log('[opencode] plugin path : ' + report.plugin_path);
279
+ console.log('[opencode] hooks dir : ' + report.hooks_dir);
280
+ console.log('[opencode] config root : ' + report.config_root);
281
+ console.log('[opencode] Checks:');
282
+ for (const c of report.checks) {
283
+ console.log('[opencode] ' + (c.ok ? '[OK] ' : '[FAIL]') + ' ' + c.id + ' -- ' + c.detail);
284
+ }
285
+ console.log('[opencode] ' + (report.ok ? 'All checks passed.' : 'Some checks failed.'));
286
+ console.log('[opencode] ' + report.note);
287
+ }
288
+
156
289
  function uninstall({ configRoot }) {
157
290
  const opencodeDir = path.join(configRoot, '.opencode');
158
291
  const hooksDir = path.join(opencodeDir, HOOK_SCRIPTS_DIR_NAME);
@@ -193,6 +326,8 @@ function uninstall({ configRoot }) {
193
326
  module.exports = {
194
327
  install,
195
328
  uninstall,
329
+ verify,
330
+ printVerifyReport,
196
331
  buildPluginSource,
197
332
  isEvolverManagedPluginFile,
198
333
  PLUGIN_FILE_NAME,
package/src/config.js CHANGED
@@ -59,6 +59,8 @@ function resolveHubUrl() {
59
59
 
60
60
  // --- Solidify & Validation ---
61
61
 
62
+ const BLAST_RADIUS_HARD_CAP_FILES = envInt('EVOLVER_HARD_CAP_FILES', 60);
63
+ const BLAST_RADIUS_HARD_CAP_LINES = envInt('EVOLVER_HARD_CAP_LINES', 20000);
62
64
  const VALIDATION_TIMEOUT_MS = envInt('EVOLVER_VALIDATION_TIMEOUT_MS', 180000);
63
65
  const CANARY_TIMEOUT_MS = envInt('EVOLVER_CANARY_TIMEOUT_MS', 30000);
64
66
  const CAPSULE_CONTENT_MAX_CHARS = envInt('EVOLVER_CAPSULE_MAX_CHARS', 8000);
@@ -197,6 +199,9 @@ module.exports = {
197
199
  SELF_PR_COOLDOWN_MS,
198
200
  SELF_PR_REPO,
199
201
  SELF_PR_TIMEOUT_MS,
202
+ // Policy
203
+ BLAST_RADIUS_HARD_CAP_FILES,
204
+ BLAST_RADIUS_HARD_CAP_LINES,
200
205
  // Security
201
206
  LEAK_CHECK_MODE,
202
207
  // Validator (opt-in role)