@evomap/evolver 1.90.0 → 2.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/README.md +27 -564
  2. package/bin/evolver-llm-proxy.js +3 -0
  3. package/bin/evolver-mcp.js +2 -0
  4. package/bin/evolver-proxy.js +3 -0
  5. package/bin/evolver.js +4 -0
  6. package/index.js +1 -3670
  7. package/package.json +32 -62
  8. package/CONTRIBUTING.md +0 -19
  9. package/LICENSE +0 -641
  10. package/README.ja-JP.md +0 -521
  11. package/README.ko-KR.md +0 -520
  12. package/README.zh-CN.md +0 -531
  13. package/SKILL.md +0 -365
  14. package/assets/cover.png +0 -0
  15. package/assets/gep/genes.seed.json +0 -496
  16. package/conformance/savings-core/constants.json +0 -30
  17. package/conformance/savings-core/golden-vectors.json +0 -333
  18. package/scripts/a2a_export.js +0 -63
  19. package/scripts/a2a_ingest.js +0 -79
  20. package/scripts/a2a_promote.js +0 -118
  21. package/scripts/analyze_by_skill.js +0 -121
  22. package/scripts/build_binaries.js +0 -479
  23. package/scripts/check-changelog.js +0 -166
  24. package/scripts/extract_log.js +0 -85
  25. package/scripts/generate_history.js +0 -75
  26. package/scripts/gep_append_event.js +0 -96
  27. package/scripts/gep_personality_report.js +0 -234
  28. package/scripts/human_report.js +0 -147
  29. package/scripts/recall-verify-report.js +0 -234
  30. package/scripts/recover_loop.js +0 -61
  31. package/scripts/refresh_stars_badge.js +0 -168
  32. package/scripts/seed-merchants.js +0 -91
  33. package/scripts/skill2recipes.js +0 -118
  34. package/scripts/suggest_version.js +0 -89
  35. package/scripts/validate-modules.js +0 -38
  36. package/scripts/validate-suite.js +0 -78
  37. package/src/adapters/claudeCode.js +0 -194
  38. package/src/adapters/codex.js +0 -216
  39. package/src/adapters/cursor.js +0 -91
  40. package/src/adapters/hookAdapter.js +0 -469
  41. package/src/adapters/kiro.js +0 -195
  42. package/src/adapters/opencode.js +0 -326
  43. package/src/adapters/scripts/_lockPaths.js +0 -74
  44. package/src/adapters/scripts/_memoryFiltering.js +0 -35
  45. package/src/adapters/scripts/_runtimePaths.js +0 -440
  46. package/src/adapters/scripts/evolver-session-end.js +0 -321
  47. package/src/adapters/scripts/evolver-session-start.js +0 -587
  48. package/src/adapters/scripts/evolver-signal-detect.js +0 -98
  49. package/src/adapters/scripts/evolver-task-recall.js +0 -173
  50. package/src/atp/atpExecute.js +0 -283
  51. package/src/atp/atpTaskPickup.js +0 -233
  52. package/src/atp/autoBuyer.js +0 -382
  53. package/src/atp/autoDeliver.js +0 -215
  54. package/src/atp/cli.js +0 -354
  55. package/src/atp/cliAutobuyPrompt.js +0 -154
  56. package/src/atp/consumerAgent.js +0 -157
  57. package/src/atp/defaultHandler.js +0 -69
  58. package/src/atp/heartbeatSignalsHandler.js +0 -254
  59. package/src/atp/hubClient.js +0 -317
  60. package/src/atp/index.js +0 -38
  61. package/src/atp/merchantAgent.js +0 -118
  62. package/src/atp/protocol.js +0 -41
  63. package/src/atp/questionComposer.js +0 -133
  64. package/src/atp/serviceHelper.js +0 -92
  65. package/src/canary.js +0 -13
  66. package/src/config.js +0 -351
  67. package/src/evolve/guards.js +0 -1
  68. package/src/evolve/pipeline/collect.js +0 -1
  69. package/src/evolve/pipeline/dispatch.js +0 -1
  70. package/src/evolve/pipeline/enrich.js +0 -1
  71. package/src/evolve/pipeline/hub.js +0 -1
  72. package/src/evolve/pipeline/select.js +0 -1
  73. package/src/evolve/pipeline/signals.js +0 -1
  74. package/src/evolve/utils.js +0 -1
  75. package/src/evolve.js +0 -1
  76. package/src/experiment/agentRunner.js +0 -229
  77. package/src/experiment/cli.js +0 -159
  78. package/src/experiment/comparison.js +0 -233
  79. package/src/experiment/metrics.js +0 -75
  80. package/src/forceUpdate.js +0 -991
  81. package/src/gep/a2a.js +0 -173
  82. package/src/gep/a2aProtocol.js +0 -1
  83. package/src/gep/analyzer.js +0 -35
  84. package/src/gep/antiAbuseTelemetry.js +0 -1
  85. package/src/gep/assetCallLog.js +0 -197
  86. package/src/gep/assetStore.js +0 -723
  87. package/src/gep/assets.js +0 -36
  88. package/src/gep/autoDistillConv.js +0 -1
  89. package/src/gep/autoDistillLlm.js +0 -1
  90. package/src/gep/bridge.js +0 -138
  91. package/src/gep/candidateEval.js +0 -1
  92. package/src/gep/candidates.js +0 -1
  93. package/src/gep/claimNudge.js +0 -121
  94. package/src/gep/cliContracts.js +0 -1190
  95. package/src/gep/contentHash.js +0 -1
  96. package/src/gep/conversationDistiller.js +0 -1
  97. package/src/gep/conversationSniffer.js +0 -1
  98. package/src/gep/crypto.js +0 -1
  99. package/src/gep/curriculum.js +0 -1
  100. package/src/gep/deviceId.js +0 -1
  101. package/src/gep/directoryClient.js +0 -115
  102. package/src/gep/envFingerprint.js +0 -1
  103. package/src/gep/epigenetics.js +0 -1
  104. package/src/gep/execBridge.js +0 -1
  105. package/src/gep/executionTrace.js +0 -291
  106. package/src/gep/explore.js +0 -1
  107. package/src/gep/featureFlags.js +0 -121
  108. package/src/gep/gitOps.js +0 -265
  109. package/src/gep/hash.js +0 -1
  110. package/src/gep/hostErrorClassifier.js +0 -34
  111. package/src/gep/hubFetch.js +0 -1
  112. package/src/gep/hubReview.js +0 -1
  113. package/src/gep/hubSearch.js +0 -1
  114. package/src/gep/hubVerify.js +0 -1
  115. package/src/gep/idleScheduler.js +0 -400
  116. package/src/gep/issueReporter.js +0 -416
  117. package/src/gep/learningSignals.js +0 -1
  118. package/src/gep/llmReview.js +0 -92
  119. package/src/gep/localStateAwareness.js +0 -243
  120. package/src/gep/mailboxTransport.js +0 -119
  121. package/src/gep/memoryGraph.js +0 -1
  122. package/src/gep/memoryGraphAdapter.js +0 -1
  123. package/src/gep/mutation.js +0 -1
  124. package/src/gep/narrativeMemory.js +0 -1
  125. package/src/gep/oauthLogin.js +0 -181
  126. package/src/gep/openPRRegistry.js +0 -1
  127. package/src/gep/paths.js +0 -522
  128. package/src/gep/personality.js +0 -1
  129. package/src/gep/policyCheck.js +0 -1
  130. package/src/gep/portable.js +0 -103
  131. package/src/gep/privacyClient.js +0 -235
  132. package/src/gep/prompt.js +0 -1
  133. package/src/gep/questionGenerator.js +0 -518
  134. package/src/gep/recallInject.js +0 -1
  135. package/src/gep/recallVerifier.js +0 -1
  136. package/src/gep/reflection.js +0 -1
  137. package/src/gep/sanitize.js +0 -264
  138. package/src/gep/savingsCore.js +0 -1
  139. package/src/gep/schemas/capsule.js +0 -170
  140. package/src/gep/schemas/gene.js +0 -154
  141. package/src/gep/schemas/index.js +0 -8
  142. package/src/gep/schemas/protocol.js +0 -51
  143. package/src/gep/schemas/task.js +0 -74
  144. package/src/gep/selector.js +0 -1
  145. package/src/gep/selfPR.js +0 -469
  146. package/src/gep/signals.js +0 -776
  147. package/src/gep/skill2gep.js +0 -1056
  148. package/src/gep/skill2gepAudit.js +0 -303
  149. package/src/gep/skill2recipes.js +0 -511
  150. package/src/gep/skillDistiller.js +0 -1
  151. package/src/gep/skillPublisher.js +0 -358
  152. package/src/gep/solidify.js +0 -1
  153. package/src/gep/strategy.js +0 -1
  154. package/src/gep/taskReceiver.js +0 -575
  155. package/src/gep/tokenSavings.js +0 -1
  156. package/src/gep/trajectoryExport.js +0 -1
  157. package/src/gep/validationReport.js +0 -55
  158. package/src/gep/validator/index.js +0 -411
  159. package/src/gep/validator/reporter.js +0 -210
  160. package/src/gep/validator/sandboxExecutor.js +0 -480
  161. package/src/gep/validator/stakeBootstrap.js +0 -357
  162. package/src/gep/workspaceKeychain.js +0 -1
  163. package/src/ops/cleanup.js +0 -80
  164. package/src/ops/commentary.js +0 -60
  165. package/src/ops/health_check.js +0 -104
  166. package/src/ops/index.js +0 -11
  167. package/src/ops/innovation.js +0 -67
  168. package/src/ops/lifecycle.js +0 -798
  169. package/src/ops/self_repair.js +0 -76
  170. package/src/ops/skills_monitor.js +0 -147
  171. package/src/ops/trigger.js +0 -33
  172. package/src/proxy/clientSettings.js +0 -405
  173. package/src/proxy/envelope.js +0 -59
  174. package/src/proxy/extensions/dmHandler.js +0 -45
  175. package/src/proxy/extensions/sessionHandler.js +0 -141
  176. package/src/proxy/extensions/skillUpdater.js +0 -64
  177. package/src/proxy/extensions/traceControl.js +0 -1
  178. package/src/proxy/index.js +0 -1395
  179. package/src/proxy/inject.js +0 -1
  180. package/src/proxy/lifecycle/manager.js +0 -1568
  181. package/src/proxy/mailbox/state.js +0 -207
  182. package/src/proxy/mailbox/store.js +0 -602
  183. package/src/proxy/router/cache_passthrough.js +0 -26
  184. package/src/proxy/router/features.js +0 -84
  185. package/src/proxy/router/gemini_route.js +0 -154
  186. package/src/proxy/router/messages_route.js +0 -535
  187. package/src/proxy/router/model_router.js +0 -113
  188. package/src/proxy/router/models_route.js +0 -52
  189. package/src/proxy/router/ollama_route.js +0 -103
  190. package/src/proxy/router/responses_route.js +0 -170
  191. package/src/proxy/router/vertex_route.js +0 -110
  192. package/src/proxy/server/http.js +0 -363
  193. package/src/proxy/server/routes.js +0 -558
  194. package/src/proxy/server/settings.js +0 -115
  195. package/src/proxy/sync/engine.js +0 -179
  196. package/src/proxy/sync/inbound.js +0 -211
  197. package/src/proxy/sync/outbound.js +0 -361
  198. package/src/proxy/task/monitor.js +0 -131
  199. package/src/proxy/trace/extractor.js +0 -1
  200. package/src/proxy/trace/usage.js +0 -1
  201. package/src/solo/breaker.js +0 -25
  202. package/src/solo/gitGuard.js +0 -65
  203. package/src/webui/client/clientJs/assets.js +0 -111
  204. package/src/webui/client/clientJs/bootstrap.js +0 -92
  205. package/src/webui/client/clientJs/common.js +0 -77
  206. package/src/webui/client/clientJs/i18n.js +0 -366
  207. package/src/webui/client/clientJs/index.js +0 -35
  208. package/src/webui/client/clientJs/interactions.js +0 -351
  209. package/src/webui/client/clientJs/overview.js +0 -152
  210. package/src/webui/client/clientJs/personality.js +0 -285
  211. package/src/webui/client/clientJs/pipelines.js +0 -330
  212. package/src/webui/client/indexHtml.js +0 -221
  213. package/src/webui/client/static.js +0 -23
  214. package/src/webui/client/stylesCss.js +0 -639
  215. package/src/webui/client/vendor/README.md +0 -15
  216. package/src/webui/client/vendor/echarts.min.js +0 -45
  217. package/src/webui/index.js +0 -14
  218. package/src/webui/observer/assets.js +0 -146
  219. package/src/webui/observer/index.js +0 -37
  220. package/src/webui/observer/interactions.js +0 -127
  221. package/src/webui/observer/jsonl.js +0 -75
  222. package/src/webui/observer/paths.js +0 -46
  223. package/src/webui/observer/personality.js +0 -43
  224. package/src/webui/observer/pipelineEvents.js +0 -58
  225. package/src/webui/observer/redact.js +0 -63
  226. package/src/webui/observer/runs.js +0 -356
  227. package/src/webui/observer/safety.js +0 -57
  228. package/src/webui/observer/skills.js +0 -70
  229. package/src/webui/observer/status.js +0 -71
  230. package/src/webui/server/http.js +0 -138
  231. package/src/webui/server/routes.js +0 -41
@@ -1,147 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- const REPO_ROOT = path.resolve(__dirname, '..');
5
- const IN_FILE = path.join(REPO_ROOT, 'evolution_history_full.md');
6
- const OUT_FILE = path.join(REPO_ROOT, 'evolution_human_summary.md');
7
-
8
- function generateHumanReport() {
9
- if (!fs.existsSync(IN_FILE)) return console.error("No input file");
10
-
11
- const content = fs.readFileSync(IN_FILE, 'utf8');
12
- const entries = content.split('---').map(e => e.trim()).filter(e => e.length > 0);
13
-
14
- const categories = {
15
- 'Security & Stability': [],
16
- 'Performance & Optimization': [],
17
- 'Tooling & Features': [],
18
- 'Documentation & Process': []
19
- };
20
-
21
- const componentMap = {}; // Component -> Change List
22
-
23
- entries.forEach(entry => {
24
- // Extract basic info
25
- const lines = entry.split('\n');
26
- const header = lines[0]; // ### Title (Date)
27
- const body = lines.slice(1).join('\n');
28
-
29
- const dateMatch = header.match(/\((.*?)\)/);
30
- const dateStr = dateMatch ? dateMatch[1] : '';
31
- const time = dateStr.split(' ')[1] || ''; // HH:mm:ss
32
-
33
- // Classify
34
- let category = 'Tooling & Features';
35
- let component = 'System';
36
- let summary = '';
37
-
38
- const lowerBody = body.toLowerCase();
39
-
40
- // Detect Component
41
- if (lowerBody.includes('feishu-card')) component = 'feishu-card';
42
- else if (lowerBody.includes('feishu-sticker')) component = 'feishu-sticker';
43
- else if (lowerBody.includes('git-sync')) component = 'git-sync';
44
- else if (lowerBody.includes('capability-evolver') || lowerBody.includes('evolve.js')) component = 'capability-evolver';
45
- else if (lowerBody.includes('interaction-logger')) component = 'interaction-logger';
46
- else if (lowerBody.includes('chat-to-image')) component = 'chat-to-image';
47
- else if (lowerBody.includes('safe_publish')) component = 'capability-evolver';
48
-
49
- // Detect Category
50
- if (lowerBody.includes('security') || lowerBody.includes('permission') || lowerBody.includes('auth') || lowerBody.includes('harden')) {
51
- category = 'Security & Stability';
52
- } else if (lowerBody.includes('optimiz') || lowerBody.includes('performance') || lowerBody.includes('memory') || lowerBody.includes('fast')) {
53
- category = 'Performance & Optimization';
54
- } else if (lowerBody.includes('doc') || lowerBody.includes('readme')) {
55
- category = 'Documentation & Process';
56
- }
57
-
58
- // Extract Human Summary (First meaningful line that isn't Status/Action/Date)
59
- const summaryLines = lines.filter(l =>
60
- !l.startsWith('###') &&
61
- !l.startsWith('Status:') &&
62
- !l.startsWith('Action:') &&
63
- l.trim().length > 10
64
- );
65
-
66
- if (summaryLines.length > 0) {
67
- // Clean up the line
68
- summary = summaryLines[0]
69
- .replace(/^-\s*/, '') // Remove bullets
70
- .replace(/\*\*/g, '') // Remove bold
71
- .replace(/`/, '')
72
- .trim();
73
-
74
- // Deduplicate
75
- const key = `${component}:${summary.substring(0, 20)}`;
76
- const exists = categories[category].some(i => i.key === key);
77
-
78
- if (!exists && !summary.includes("Stability Scan OK") && !summary.includes("Workspace Sync")) {
79
- categories[category].push({ time, component, summary, key });
80
-
81
- if (!componentMap[component]) componentMap[component] = [];
82
- componentMap[component].push(summary);
83
- }
84
- }
85
- });
86
-
87
- // --- Generate Markdown ---
88
- const today = new Date().toISOString().slice(0, 10);
89
- let md = `# Evolution Summary: The Day in Review (${today})\n\n`;
90
- md += `> Overview: Grouped summary of changes extracted from evolution history.\n\n`;
91
-
92
- // Section 1: By Theme (Evolution Direction)
93
- md += `## 1. Evolution Direction\n`;
94
-
95
- for (const [cat, items] of Object.entries(categories)) {
96
- if (items.length === 0) continue;
97
- md += `### ${cat}\n`;
98
- // Group by component within theme
99
- const compGroup = {};
100
- items.forEach(i => {
101
- if (!compGroup[i.component]) compGroup[i.component] = [];
102
- compGroup[i.component].push(i.summary);
103
- });
104
-
105
- for (const [comp, sums] of Object.entries(compGroup)) {
106
- // Unique summaries only
107
- const uniqueSums = [...new Set(sums)];
108
- uniqueSums.forEach(s => {
109
- md += `- **${comp}**: ${s}\n`;
110
- });
111
- }
112
- md += `\n`;
113
- }
114
-
115
- // Section 2: By Timeline (High Level)
116
- md += `## 2. Timeline of Critical Events\n`;
117
- // Flatten and sort all items by time
118
- const allItems = [];
119
- Object.values(categories).forEach(list => allItems.push(...list));
120
- allItems.sort((a, b) => a.time.localeCompare(b.time));
121
-
122
- // Filter for "Critical" keywords
123
- const criticalItems = allItems.filter(i =>
124
- i.summary.toLowerCase().includes('fix') ||
125
- i.summary.toLowerCase().includes('patch') ||
126
- i.summary.toLowerCase().includes('create') ||
127
- i.summary.toLowerCase().includes('optimiz')
128
- );
129
-
130
- criticalItems.forEach(i => {
131
- md += `- \`${i.time}\` (${i.component}): ${i.summary}\n`;
132
- });
133
-
134
- // Section 3: Package Adjustments
135
- md += `\n## 3. Package & Documentation Adjustments\n`;
136
- const comps = Object.keys(componentMap).sort();
137
- comps.forEach(comp => {
138
- const count = new Set(componentMap[comp]).size;
139
- md += `- **${comp}**: Received ${count} significant updates.\n`;
140
- });
141
-
142
- fs.writeFileSync(OUT_FILE, md);
143
- console.log("Human report generated.");
144
- }
145
-
146
- generateHumanReport();
147
-
@@ -1,234 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- // recall-verify-report — aggregate kind=recall_verify events from the
5
- // memory graph jsonl into a Markdown table. Exit 0 = ship gate green
6
- // (every asset_type has success_rate >= 0.95 and 0 mismatches), exit 2
7
- // otherwise. Designed to be scripted into deploy.sh as a pre-publish gate.
8
- //
9
- // Usage:
10
- // node scripts/recall-verify-report.js # all events
11
- // node scripts/recall-verify-report.js --since 1h # last hour
12
- // node scripts/recall-verify-report.js --since 30m
13
- // node scripts/recall-verify-report.js --since 2026-05-16T10:00:00Z
14
- // node scripts/recall-verify-report.js --json # raw JSON for piping
15
-
16
- const { tryReadMemoryGraphEvents } = require('../src/gep/memoryGraph');
17
-
18
- const SUCCESS_THRESHOLD = 0.95;
19
-
20
- function parseSince(value) {
21
- if (!value) return null;
22
- // Try relative duration first (1h / 30m / 2d / 45s) — unambiguous.
23
- const m = String(value).match(/^(\d+)\s*(s|m|h|d)$/i);
24
- if (m) {
25
- const n = Number(m[1]);
26
- const unit = m[2].toLowerCase();
27
- const factor = unit === 's' ? 1000 : unit === 'm' ? 60000 : unit === 'h' ? 3600000 : 86400000;
28
- return Date.now() - (n * factor);
29
- }
30
- // Then ISO-8601. Require '-' or 'T' so we don't accept loose numeric
31
- // strings like "5" → year 2001.
32
- if (/[-T]/.test(String(value))) {
33
- const iso = Date.parse(value);
34
- if (!Number.isNaN(iso)) return iso;
35
- }
36
- return undefined;
37
- }
38
-
39
- function parseArgs(argv) {
40
- const args = { since: null, json: false };
41
- for (let i = 2; i < argv.length; i++) {
42
- const a = argv[i];
43
- if (a === '--json') args.json = true;
44
- else if (a === '--since') {
45
- args.since = argv[++i];
46
- } else if (a.startsWith('--since=')) {
47
- args.since = a.slice('--since='.length);
48
- } else if (a === '--help' || a === '-h') {
49
- args.help = true;
50
- }
51
- }
52
- return args;
53
- }
54
-
55
- function percentile(sorted, p) {
56
- if (!sorted.length) return 0;
57
- const idx = Math.min(sorted.length - 1, Math.floor(sorted.length * p));
58
- return sorted[idx];
59
- }
60
-
61
- function aggregate(events) {
62
- const byType = new Map();
63
- for (const ev of events) {
64
- if (!ev || ev.kind !== 'recall_verify') continue;
65
- const type = (ev.asset && ev.asset.type) || 'Unknown';
66
- if (!byType.has(type)) {
67
- byType.set(type, {
68
- type,
69
- total: 0,
70
- ok: 0,
71
- missing: 0,
72
- mismatch: 0,
73
- skipped: 0,
74
- latencies: [],
75
- ages: [],
76
- });
77
- }
78
- const bucket = byType.get(type);
79
- bucket.total += 1;
80
- const v = ev.verification || {};
81
- if (v.outcome === 'roundtrip_ok') bucket.ok += 1;
82
- else if (v.outcome === 'roundtrip_missing') bucket.missing += 1;
83
- else if (v.outcome === 'roundtrip_mismatch') bucket.mismatch += 1;
84
- else bucket.skipped += 1;
85
- if (Number.isFinite(v.latency_ms)) bucket.latencies.push(v.latency_ms);
86
- if (Number.isFinite(v.age_at_verify_ms)) bucket.ages.push(v.age_at_verify_ms);
87
- }
88
- const rows = [];
89
- for (const bucket of byType.values()) {
90
- const denom = bucket.ok + bucket.missing + bucket.mismatch;
91
- bucket.success_rate = denom > 0 ? bucket.ok / denom : 0;
92
- bucket.latencies.sort(function (a, b) { return a - b; });
93
- bucket.ages.sort(function (a, b) { return a - b; });
94
- bucket.p50_latency_ms = percentile(bucket.latencies, 0.5);
95
- bucket.p95_latency_ms = percentile(bucket.latencies, 0.95);
96
- bucket.p99_latency_ms = percentile(bucket.latencies, 0.99);
97
- bucket.p50_age_ms = percentile(bucket.ages, 0.5);
98
- bucket.p95_age_ms = percentile(bucket.ages, 0.95);
99
- bucket.p99_age_ms = percentile(bucket.ages, 0.99);
100
- delete bucket.latencies;
101
- delete bucket.ages;
102
- rows.push(bucket);
103
- }
104
- rows.sort(function (a, b) { return a.type.localeCompare(b.type); });
105
-
106
- const totals = { type: 'TOTAL', total: 0, ok: 0, missing: 0, mismatch: 0, skipped: 0 };
107
- for (const r of rows) {
108
- totals.total += r.total;
109
- totals.ok += r.ok;
110
- totals.missing += r.missing;
111
- totals.mismatch += r.mismatch;
112
- totals.skipped += r.skipped;
113
- }
114
- const totalsDenom = totals.ok + totals.missing + totals.mismatch;
115
- totals.success_rate = totalsDenom > 0 ? totals.ok / totalsDenom : 0;
116
-
117
- // Gate severity is monotonic: once a row triggers a worse state, later
118
- // rows cannot downgrade it. Without this, AntiPattern@0% (RED) followed
119
- // by Capsule@90% (YELLOW) would report YELLOW — misleading dashboards
120
- // even though the exit code still reflects RED. (Bugbot review on PR #53.)
121
- // RANK is the comparison ordinal: GREEN(0) < YELLOW(1) < RED(2).
122
- const RANK = { GREEN: 0, YELLOW: 1, RED: 2 };
123
- function escalate(current, candidate) {
124
- return RANK[candidate] > RANK[current] ? candidate : current;
125
- }
126
- let gate = 'GREEN';
127
- if (rows.length === 0) gate = 'RED';
128
- else {
129
- for (const r of rows) {
130
- if (r.mismatch > 0) { gate = 'RED'; break; }
131
- if (r.success_rate < SUCCESS_THRESHOLD) {
132
- gate = escalate(gate, r.success_rate >= 0.85 ? 'YELLOW' : 'RED');
133
- }
134
- }
135
- }
136
- return { rows, totals, gate };
137
- }
138
-
139
- function fmtPct(rate) {
140
- return (rate * 100).toFixed(1) + '%';
141
- }
142
-
143
- function fmtMs(n) {
144
- if (!Number.isFinite(n) || n === 0) return '—';
145
- if (n < 1000) return Math.round(n) + 'ms';
146
- return (n / 1000).toFixed(1) + 's';
147
- }
148
-
149
- function printMarkdown(result, since) {
150
- const sinceStr = since ? new Date(since).toISOString() : 'all time';
151
- console.log('# RecallVerify Report (since ' + sinceStr + ')');
152
- console.log('');
153
- if (result.rows.length === 0) {
154
- console.log('_No `recall_verify` events found in memory graph._');
155
- console.log('');
156
- console.log('Ship gate: **RED** (no data — feature may be disabled or daemon has not run a publish cycle yet)');
157
- return;
158
- }
159
- console.log('| asset_type | total | ok | missing | mismatch | skipped | success_rate | p50_latency | p99_latency | p50_age | p99_age |');
160
- console.log('|--------------|------:|----:|--------:|---------:|--------:|-------------:|------------:|------------:|--------:|--------:|');
161
- for (const r of result.rows) {
162
- console.log('| ' + r.type.padEnd(12) +
163
- ' | ' + String(r.total).padStart(5) +
164
- ' | ' + String(r.ok).padStart(3) +
165
- ' | ' + String(r.missing).padStart(7) +
166
- ' | ' + String(r.mismatch).padStart(8) +
167
- ' | ' + String(r.skipped).padStart(7) +
168
- ' | ' + fmtPct(r.success_rate).padStart(12) +
169
- ' | ' + fmtMs(r.p50_latency_ms).padStart(11) +
170
- ' | ' + fmtMs(r.p99_latency_ms).padStart(11) +
171
- ' | ' + fmtMs(r.p50_age_ms).padStart(7) +
172
- ' | ' + fmtMs(r.p99_age_ms).padStart(7) +
173
- ' |');
174
- }
175
- const t = result.totals;
176
- console.log('| ' + 'TOTAL'.padEnd(12) +
177
- ' | ' + String(t.total).padStart(5) +
178
- ' | ' + String(t.ok).padStart(3) +
179
- ' | ' + String(t.missing).padStart(7) +
180
- ' | ' + String(t.mismatch).padStart(8) +
181
- ' | ' + String(t.skipped).padStart(7) +
182
- ' | ' + fmtPct(t.success_rate).padStart(12) +
183
- ' | ' + '—'.padStart(11) +
184
- ' | ' + '—'.padStart(11) +
185
- ' | ' + '—'.padStart(7) +
186
- ' | ' + '—'.padStart(7) +
187
- ' |');
188
- console.log('');
189
- console.log('Ship gate: **' + result.gate + '**' + (result.gate === 'GREEN' ? ' (exit 0)' : ' (exit 2)'));
190
- }
191
-
192
- function main() {
193
- const args = parseArgs(process.argv);
194
- if (args.help) {
195
- console.log('Usage: node scripts/recall-verify-report.js [--since <Nh|Nm|Nd|ISO>] [--json]');
196
- process.exit(0);
197
- }
198
-
199
- let sinceMs = null;
200
- if (args.since) {
201
- const parsed = parseSince(args.since);
202
- if (parsed === undefined) {
203
- console.error('Error: --since must be ISO-8601 or a duration like 1h / 30m / 2d (got: ' + args.since + ')');
204
- process.exit(1);
205
- }
206
- sinceMs = parsed;
207
- }
208
-
209
- const allEvents = tryReadMemoryGraphEvents(20000);
210
- const filtered = allEvents.filter(function (ev) {
211
- if (!ev || ev.kind !== 'recall_verify') return false;
212
- if (sinceMs != null && Number.isFinite(ev.ts) && ev.ts < sinceMs) return false;
213
- return true;
214
- });
215
-
216
- const result = aggregate(filtered);
217
-
218
- if (args.json) {
219
- console.log(JSON.stringify({
220
- since: sinceMs ? new Date(sinceMs).toISOString() : null,
221
- ...result,
222
- }, null, 2));
223
- } else {
224
- printMarkdown(result, sinceMs);
225
- }
226
-
227
- process.exit(result.gate === 'GREEN' ? 0 : 2);
228
- }
229
-
230
- if (require.main === module) {
231
- main();
232
- }
233
-
234
- module.exports = { aggregate, parseSince, parseArgs };
@@ -1,61 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console */
3
- const fs = require('fs');
4
- const path = require('path');
5
- const { spawnSync } = require('child_process');
6
-
7
- function exists(p) {
8
- try {
9
- return fs.existsSync(p);
10
- } catch (e) {
11
- return false;
12
- }
13
- }
14
-
15
- function sleepMs(ms) {
16
- const n = Number(ms);
17
- const t = Number.isFinite(n) ? Math.max(0, n) : 0;
18
- if (t <= 0) return;
19
- spawnSync('sleep', [String(Math.ceil(t / 1000))], { stdio: 'ignore' });
20
- }
21
-
22
- function resolveWorkspaceRoot() {
23
- // In OpenClaw exec, cwd is usually the workspace root.
24
- // Keep it simple: do not try to walk up arbitrarily.
25
- return process.cwd();
26
- }
27
-
28
- function resolveEvolverEntry(workspaceRoot) {
29
- const candidates = [
30
- path.join(workspaceRoot, 'skills', 'evolver', 'index.js'),
31
- path.join(workspaceRoot, 'skills', 'capability-evolver', 'index.js'),
32
- ];
33
- for (const p of candidates) {
34
- if (exists(p)) return p;
35
- }
36
- return null;
37
- }
38
-
39
- function main() {
40
- const waitMs = parseInt(String(process.env.EVOLVER_RECOVER_WAIT_MS || '10000'), 10);
41
- const wait = Number.isFinite(waitMs) ? Math.max(0, waitMs) : 10000;
42
-
43
- console.log(`[RECOVERY] Waiting ${wait}ms before restart...`);
44
- sleepMs(wait);
45
-
46
- const workspaceRoot = resolveWorkspaceRoot();
47
- const entry = resolveEvolverEntry(workspaceRoot);
48
- if (!entry) {
49
- console.error('[RECOVERY] Failed: cannot locate evolver entry under skills/.');
50
- process.exit(2);
51
- }
52
-
53
- console.log(`[RECOVERY] Restarting loop via ${path.relative(workspaceRoot, entry)} ...`);
54
- const r = spawnSync(process.execPath, [entry, '--loop'], { stdio: 'inherit' });
55
- process.exit(typeof r.status === 'number' ? r.status : 1);
56
- }
57
-
58
- if (require.main === module) {
59
- main();
60
- }
61
-
@@ -1,168 +0,0 @@
1
- // refresh_stars_badge.js -- Refresh the static "Stars" badge count in the
2
- // public README sources to the live GitHub star count.
3
- //
4
- // Why this exists:
5
- // The README stars badge is intentionally STATIC (a plain shields `badge/`
6
- // URL, not a dynamic `github/stars` one) so it never renders shields.io's
7
- // "Unable to select next GitHub token from pool" error when their shared
8
- // GitHub token pool is rate-limited. The trade-off is that the number goes
9
- // stale. This script re-stamps it at release time so the badge stays current
10
- // without ever depending on the GitHub API to *render*.
11
- //
12
- // Usage:
13
- // node scripts/refresh_stars_badge.js # update in place
14
- // node scripts/refresh_stars_badge.js --dry-run # print, write nothing
15
- // node scripts/refresh_stars_badge.js --repo=O/N # override repo
16
- // node scripts/refresh_stars_badge.js --count=12345 # skip fetch (testing)
17
- //
18
- // Design notes:
19
- // - Counts come from the PUBLIC repo (default EvoMap/evolver), not this
20
- // private dev repo.
21
- // - Fetch uses the already-authenticated `gh` CLI first (deploy.sh preflight
22
- // guarantees gh auth), falling back to the unauthenticated GitHub REST API.
23
- // - A fetch failure is NON-FATAL: we warn and exit 0, leaving the badge as
24
- // is. A flaky GitHub API must never break a release -- avoiding exactly
25
- // that fragility is the whole reason the badge is static.
26
- // - It rewrites every README*.md in the repo root that contains the badge,
27
- // so new translations are picked up automatically.
28
-
29
- const fs = require('fs');
30
- const path = require('path');
31
- const https = require('https');
32
- const { execSync } = require('child_process');
33
-
34
- const REPO_ROOT = path.resolve(__dirname, '..');
35
- const DEFAULT_REPO = 'EvoMap/evolver';
36
-
37
- // Matches the value segment of `.../badge/Stars-<value>-<color>...` in a
38
- // shields static badge URL. The value never contains `-` or `/`. Returns a
39
- // fresh regex each call so callers never share `lastIndex` state.
40
- const starsBadgeRe = () => /(img\.shields\.io\/badge\/Stars-)([^-/)]+)(-)/g;
41
-
42
- // Replace the Stars badge value in `content` with `value`. Pure; returns the
43
- // rewritten string (unchanged if there is no badge or it already matches).
44
- function rewriteStarsValue(content, value) {
45
- return content.replace(starsBadgeRe(), (_m, pre, _old, post) => `${pre}${value}${post}`);
46
- }
47
-
48
- function parseArgs(argv) {
49
- const opts = { dryRun: false, repo: DEFAULT_REPO, count: null };
50
- for (const arg of argv) {
51
- if (arg === '--dry-run' || arg === '-n') opts.dryRun = true;
52
- else if (arg.startsWith('--repo=')) opts.repo = arg.slice('--repo='.length);
53
- else if (arg.startsWith('--count=')) opts.count = Number(arg.slice('--count='.length));
54
- }
55
- return opts;
56
- }
57
-
58
- // Format an integer the way shields.io's `metric` text formatter does, so the
59
- // static badge is visually indistinguishable from a dynamic one:
60
- // 8336 -> "8.3k", 12345 -> "12k", 1100 -> "1.1k", 999 -> "999".
61
- function metric(n) {
62
- n = Number(n);
63
- if (!Number.isFinite(n) || n < 0) return String(n);
64
- for (const [suffix, size] of [['G', 1e9], ['M', 1e6], ['k', 1e3]]) {
65
- if (n >= size) {
66
- const value = n / size;
67
- const text = value < 10
68
- ? value.toFixed(1).replace(/\.0$/, '')
69
- : String(Math.round(value));
70
- return text + suffix;
71
- }
72
- }
73
- return String(Math.round(n));
74
- }
75
-
76
- function fetchStarsViaGh(repo) {
77
- try {
78
- const out = execSync(`gh api repos/${repo} --jq .stargazers_count`, {
79
- encoding: 'utf8',
80
- stdio: ['ignore', 'pipe', 'ignore'],
81
- }).trim();
82
- const n = Number(out);
83
- return Number.isFinite(n) && n > 0 ? n : null;
84
- } catch {
85
- return null;
86
- }
87
- }
88
-
89
- function fetchStarsViaApi(repo) {
90
- return new Promise((resolve) => {
91
- const req = https.get(
92
- `https://api.github.com/repos/${repo}`,
93
- { headers: { 'User-Agent': 'evolver-refresh-stars-badge', Accept: 'application/vnd.github+json' } },
94
- (res) => {
95
- if (res.statusCode !== 200) { res.resume(); return resolve(null); }
96
- let body = '';
97
- res.on('data', (c) => (body += c));
98
- res.on('end', () => {
99
- try {
100
- const n = Number(JSON.parse(body).stargazers_count);
101
- resolve(Number.isFinite(n) && n > 0 ? n : null);
102
- } catch { resolve(null); }
103
- });
104
- },
105
- );
106
- req.on('error', () => resolve(null));
107
- req.setTimeout(10000, () => { req.destroy(); resolve(null); });
108
- });
109
- }
110
-
111
- async function resolveStarCount(opts) {
112
- if (Number.isFinite(opts.count) && opts.count > 0) return opts.count;
113
- return fetchStarsViaGh(opts.repo) || (await fetchStarsViaApi(opts.repo));
114
- }
115
-
116
- function readmeFilesWithBadge() {
117
- return fs
118
- .readdirSync(REPO_ROOT)
119
- .filter((f) => /^README.*\.md$/.test(f))
120
- .map((f) => path.join(REPO_ROOT, f))
121
- .filter((p) => starsBadgeRe().test(fs.readFileSync(p, 'utf8')));
122
- }
123
-
124
- async function main() {
125
- const opts = parseArgs(process.argv.slice(2));
126
-
127
- const count = await resolveStarCount(opts);
128
- if (count == null) {
129
- console.warn('[refresh-stars-badge] could not resolve star count (gh + API both failed); leaving badge unchanged');
130
- return; // non-fatal
131
- }
132
- const value = metric(count);
133
- console.log(`[refresh-stars-badge] ${opts.repo} = ${count} stars -> "${value}"`);
134
-
135
- const files = readmeFilesWithBadge();
136
- if (files.length === 0) {
137
- console.warn('[refresh-stars-badge] no README*.md with a Stars badge found; nothing to do');
138
- return;
139
- }
140
-
141
- let changed = 0;
142
- for (const file of files) {
143
- const before = fs.readFileSync(file, 'utf8');
144
- const after = rewriteStarsValue(before, value);
145
- const rel = path.relative(REPO_ROOT, file);
146
- if (after === before) {
147
- console.log(` ${rel}: already "${value}"`);
148
- continue;
149
- }
150
- if (opts.dryRun) {
151
- console.log(` [dry-run] ${rel}: would set Stars -> "${value}"`);
152
- } else {
153
- fs.writeFileSync(file, after);
154
- console.log(` ${rel}: Stars -> "${value}"`);
155
- }
156
- changed++;
157
- }
158
- console.log(`[refresh-stars-badge] ${changed} file(s) ${opts.dryRun ? 'would change' : 'updated'}`);
159
- }
160
-
161
- if (require.main === module) {
162
- main().catch((e) => {
163
- // Never fail the release over a badge refresh.
164
- console.warn(`[refresh-stars-badge] unexpected error (ignored): ${e && e.message}`);
165
- });
166
- }
167
-
168
- module.exports = { metric, rewriteStarsValue };