@evomap/evolver 1.89.20 → 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 -3586
  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/skills/_meta/SKILL.md +0 -41
  38. package/skills/index.json +0 -14
  39. package/src/adapters/claudeCode.js +0 -194
  40. package/src/adapters/codex.js +0 -216
  41. package/src/adapters/cursor.js +0 -91
  42. package/src/adapters/hookAdapter.js +0 -469
  43. package/src/adapters/kiro.js +0 -195
  44. package/src/adapters/opencode.js +0 -326
  45. package/src/adapters/scripts/_lockPaths.js +0 -74
  46. package/src/adapters/scripts/_memoryFiltering.js +0 -35
  47. package/src/adapters/scripts/_runtimePaths.js +0 -440
  48. package/src/adapters/scripts/evolver-session-end.js +0 -321
  49. package/src/adapters/scripts/evolver-session-start.js +0 -587
  50. package/src/adapters/scripts/evolver-signal-detect.js +0 -98
  51. package/src/adapters/scripts/evolver-task-recall.js +0 -173
  52. package/src/atp/atpExecute.js +0 -283
  53. package/src/atp/atpTaskPickup.js +0 -233
  54. package/src/atp/autoBuyer.js +0 -382
  55. package/src/atp/autoDeliver.js +0 -215
  56. package/src/atp/cli.js +0 -354
  57. package/src/atp/cliAutobuyPrompt.js +0 -154
  58. package/src/atp/consumerAgent.js +0 -157
  59. package/src/atp/defaultHandler.js +0 -69
  60. package/src/atp/heartbeatSignalsHandler.js +0 -254
  61. package/src/atp/hubClient.js +0 -317
  62. package/src/atp/index.js +0 -38
  63. package/src/atp/merchantAgent.js +0 -118
  64. package/src/atp/protocol.js +0 -41
  65. package/src/atp/questionComposer.js +0 -133
  66. package/src/atp/serviceHelper.js +0 -92
  67. package/src/canary.js +0 -13
  68. package/src/config.js +0 -351
  69. package/src/evolve/guards.js +0 -1
  70. package/src/evolve/pipeline/collect.js +0 -1
  71. package/src/evolve/pipeline/dispatch.js +0 -1
  72. package/src/evolve/pipeline/enrich.js +0 -1
  73. package/src/evolve/pipeline/hub.js +0 -1
  74. package/src/evolve/pipeline/select.js +0 -1
  75. package/src/evolve/pipeline/signals.js +0 -1
  76. package/src/evolve/utils.js +0 -1
  77. package/src/evolve.js +0 -1
  78. package/src/experiment/agentRunner.js +0 -229
  79. package/src/experiment/cli.js +0 -159
  80. package/src/experiment/comparison.js +0 -233
  81. package/src/experiment/metrics.js +0 -75
  82. package/src/forceUpdate.js +0 -991
  83. package/src/gep/a2a.js +0 -173
  84. package/src/gep/a2aProtocol.js +0 -1
  85. package/src/gep/analyzer.js +0 -35
  86. package/src/gep/antiAbuseTelemetry.js +0 -1
  87. package/src/gep/assetCallLog.js +0 -197
  88. package/src/gep/assetStore.js +0 -723
  89. package/src/gep/assets.js +0 -36
  90. package/src/gep/autoDistillConv.js +0 -1
  91. package/src/gep/autoDistillLlm.js +0 -1
  92. package/src/gep/bridge.js +0 -138
  93. package/src/gep/candidateEval.js +0 -1
  94. package/src/gep/candidates.js +0 -1
  95. package/src/gep/claimNudge.js +0 -121
  96. package/src/gep/cliContracts.js +0 -1190
  97. package/src/gep/contentHash.js +0 -1
  98. package/src/gep/conversationDistiller.js +0 -1
  99. package/src/gep/conversationSniffer.js +0 -1
  100. package/src/gep/crypto.js +0 -1
  101. package/src/gep/curriculum.js +0 -1
  102. package/src/gep/deviceId.js +0 -1
  103. package/src/gep/directoryClient.js +0 -115
  104. package/src/gep/envFingerprint.js +0 -1
  105. package/src/gep/epigenetics.js +0 -1
  106. package/src/gep/execBridge.js +0 -1
  107. package/src/gep/executionTrace.js +0 -291
  108. package/src/gep/explore.js +0 -1
  109. package/src/gep/featureFlags.js +0 -121
  110. package/src/gep/gitOps.js +0 -265
  111. package/src/gep/hash.js +0 -1
  112. package/src/gep/hostErrorClassifier.js +0 -34
  113. package/src/gep/hubFetch.js +0 -1
  114. package/src/gep/hubReview.js +0 -1
  115. package/src/gep/hubSearch.js +0 -1
  116. package/src/gep/hubVerify.js +0 -1
  117. package/src/gep/idleScheduler.js +0 -400
  118. package/src/gep/issueReporter.js +0 -416
  119. package/src/gep/learningSignals.js +0 -1
  120. package/src/gep/llmReview.js +0 -92
  121. package/src/gep/localStateAwareness.js +0 -243
  122. package/src/gep/mailboxTransport.js +0 -119
  123. package/src/gep/memoryGraph.js +0 -1
  124. package/src/gep/memoryGraphAdapter.js +0 -1
  125. package/src/gep/mutation.js +0 -1
  126. package/src/gep/narrativeMemory.js +0 -1
  127. package/src/gep/oauthLogin.js +0 -181
  128. package/src/gep/openPRRegistry.js +0 -1
  129. package/src/gep/paths.js +0 -522
  130. package/src/gep/personality.js +0 -1
  131. package/src/gep/policyCheck.js +0 -1
  132. package/src/gep/portable.js +0 -103
  133. package/src/gep/privacyClient.js +0 -235
  134. package/src/gep/prompt.js +0 -1
  135. package/src/gep/questionGenerator.js +0 -518
  136. package/src/gep/recallInject.js +0 -1
  137. package/src/gep/recallVerifier.js +0 -1
  138. package/src/gep/reflection.js +0 -1
  139. package/src/gep/sanitize.js +0 -264
  140. package/src/gep/savingsCore.js +0 -1
  141. package/src/gep/schemas/capsule.js +0 -170
  142. package/src/gep/schemas/gene.js +0 -154
  143. package/src/gep/schemas/index.js +0 -8
  144. package/src/gep/schemas/protocol.js +0 -51
  145. package/src/gep/schemas/task.js +0 -74
  146. package/src/gep/selector.js +0 -1
  147. package/src/gep/selfPR.js +0 -469
  148. package/src/gep/signals.js +0 -776
  149. package/src/gep/skill2gep.js +0 -1056
  150. package/src/gep/skill2gepAudit.js +0 -303
  151. package/src/gep/skill2recipes.js +0 -511
  152. package/src/gep/skillDistiller.js +0 -1
  153. package/src/gep/skillPublisher.js +0 -358
  154. package/src/gep/solidify.js +0 -1
  155. package/src/gep/strategy.js +0 -1
  156. package/src/gep/taskReceiver.js +0 -575
  157. package/src/gep/tokenSavings.js +0 -1
  158. package/src/gep/trajectoryExport.js +0 -1
  159. package/src/gep/validationReport.js +0 -55
  160. package/src/gep/validator/index.js +0 -411
  161. package/src/gep/validator/reporter.js +0 -210
  162. package/src/gep/validator/sandboxExecutor.js +0 -480
  163. package/src/gep/validator/stakeBootstrap.js +0 -357
  164. package/src/gep/workspaceKeychain.js +0 -1
  165. package/src/ops/cleanup.js +0 -80
  166. package/src/ops/commentary.js +0 -60
  167. package/src/ops/health_check.js +0 -104
  168. package/src/ops/index.js +0 -11
  169. package/src/ops/innovation.js +0 -67
  170. package/src/ops/lifecycle.js +0 -798
  171. package/src/ops/self_repair.js +0 -76
  172. package/src/ops/skills_monitor.js +0 -147
  173. package/src/ops/trigger.js +0 -33
  174. package/src/proxy/clientSettings.js +0 -405
  175. package/src/proxy/envelope.js +0 -59
  176. package/src/proxy/extensions/dmHandler.js +0 -45
  177. package/src/proxy/extensions/sessionHandler.js +0 -141
  178. package/src/proxy/extensions/skillUpdater.js +0 -64
  179. package/src/proxy/extensions/traceControl.js +0 -1
  180. package/src/proxy/index.js +0 -1395
  181. package/src/proxy/inject.js +0 -1
  182. package/src/proxy/lifecycle/manager.js +0 -1568
  183. package/src/proxy/mailbox/state.js +0 -207
  184. package/src/proxy/mailbox/store.js +0 -590
  185. package/src/proxy/router/cache_passthrough.js +0 -26
  186. package/src/proxy/router/features.js +0 -84
  187. package/src/proxy/router/gemini_route.js +0 -154
  188. package/src/proxy/router/messages_route.js +0 -535
  189. package/src/proxy/router/model_router.js +0 -113
  190. package/src/proxy/router/models_route.js +0 -52
  191. package/src/proxy/router/ollama_route.js +0 -103
  192. package/src/proxy/router/responses_route.js +0 -170
  193. package/src/proxy/router/vertex_route.js +0 -110
  194. package/src/proxy/server/http.js +0 -363
  195. package/src/proxy/server/routes.js +0 -558
  196. package/src/proxy/server/settings.js +0 -115
  197. package/src/proxy/sync/engine.js +0 -179
  198. package/src/proxy/sync/inbound.js +0 -211
  199. package/src/proxy/sync/outbound.js +0 -320
  200. package/src/proxy/task/monitor.js +0 -131
  201. package/src/proxy/trace/extractor.js +0 -1
  202. package/src/proxy/trace/usage.js +0 -1
  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,358 +0,0 @@
1
- 'use strict';
2
-
3
- var { getHubUrl, buildHubHeaders, buildNodeScopedHubHeaders, getNodeId } = require('./a2aProtocol');
4
- var { hubFetch } = require('./hubFetch');
5
-
6
- function buildSkillStoreHeaders() {
7
- var buildHeaders = buildNodeScopedHubHeaders || buildHubHeaders;
8
- return buildHeaders();
9
- }
10
-
11
- /**
12
- * Sanitize a raw gene id into a human-readable kebab-case skill name.
13
- * Returns null if the name is unsalvageable (pure numbers, tool name, etc.).
14
- */
15
- function sanitizeSkillName(rawName) {
16
- var name = rawName.replace(/[\r\n]+/g, '-').replace(/^gene_distilled_/, '').replace(/^gene_/, '').replace(/_/g, '-');
17
- // Strip ALL embedded timestamps (10+ digit sequences) anywhere in the name
18
- name = name.replace(/-?\d{10,}-?/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
19
- if (/^\d{8,}/.test(name) || /^(cursor|vscode|vim|emacs|windsurf|copilot|cline|codex)[-]?\d*$/i.test(name)) {
20
- return null;
21
- }
22
- if (name.replace(/[-]/g, '').length < 6) return null;
23
- return name;
24
- }
25
-
26
- /**
27
- * Derive a Title Case display name from a kebab-case skill name.
28
- * "retry-with-backoff" -> "Retry With Backoff"
29
- */
30
- function toTitleCase(kebabName) {
31
- return kebabName.split('-').map(function (w) {
32
- if (!w) return '';
33
- return w.charAt(0).toUpperCase() + w.slice(1);
34
- }).join(' ');
35
- }
36
-
37
- /**
38
- * Derive fallback name words from gene signals/summary when id is not usable.
39
- */
40
- function deriveFallbackName(gene) {
41
- var fallbackWords = [];
42
- var STOP = new Set(['the', 'and', 'for', 'with', 'from', 'that', 'this', 'into', 'when', 'are', 'was', 'has', 'had', 'not', 'but', 'its']);
43
- if (Array.isArray(gene.signals_match)) {
44
- gene.signals_match.slice(0, 3).forEach(function (s) {
45
- String(s).toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim().split(/\s+/).forEach(function (w) {
46
- if (w.length >= 3 && !STOP.has(w) && fallbackWords.length < 5) fallbackWords.push(w);
47
- });
48
- });
49
- }
50
- if (fallbackWords.length < 2 && gene.summary) {
51
- String(gene.summary).toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim().split(/\s+/).forEach(function (w) {
52
- if (w.length >= 3 && !STOP.has(w) && fallbackWords.length < 5) fallbackWords.push(w);
53
- });
54
- }
55
- var seen = {};
56
- fallbackWords = fallbackWords.filter(function (w) { if (seen[w]) return false; seen[w] = true; return true; });
57
- return fallbackWords.length >= 2 ? fallbackWords.join('-') : 'auto-distilled-skill';
58
- }
59
-
60
- /**
61
- * Convert a Gene object into SKILL.md format -- marketplace-quality content.
62
- *
63
- * @param {object} gene - Gene asset
64
- * @returns {string} SKILL.md content
65
- */
66
- function geneToSkillMd(gene) {
67
- var rawName = gene.id || 'unnamed-skill';
68
- var name = sanitizeSkillName(rawName) || deriveFallbackName(gene);
69
- var displayName = toTitleCase(name);
70
- var desc = (gene.summary || '').replace(/[\r\n]+/g, ' ').replace(/\s*\d{10,}\s*$/g, '').trim();
71
- if (!desc || desc.length < 10) desc = 'AI agent skill distilled from evolution experience.';
72
-
73
- var lines = [
74
- '---',
75
- 'name: ' + displayName,
76
- 'description: ' + desc,
77
- '---',
78
- '',
79
- '# ' + displayName,
80
- '',
81
- desc,
82
- '',
83
- ];
84
-
85
- // -- When to Use (derived from signals; preconditions go in their own section) --
86
- if (gene.signals_match && gene.signals_match.length > 0) {
87
- lines.push('## When to Use');
88
- lines.push('');
89
- lines.push('- When your project encounters: ' + gene.signals_match.slice(0, 4).map(function (s) {
90
- return '`' + s + '`';
91
- }).join(', '));
92
- lines.push('');
93
- }
94
-
95
- // -- Trigger Signals --
96
- if (gene.signals_match && gene.signals_match.length > 0) {
97
- lines.push('## Trigger Signals');
98
- lines.push('');
99
- gene.signals_match.forEach(function (s) {
100
- lines.push('- `' + s + '`');
101
- });
102
- lines.push('');
103
- }
104
-
105
- // -- Preconditions --
106
- if (gene.preconditions && gene.preconditions.length > 0) {
107
- lines.push('## Preconditions');
108
- lines.push('');
109
- gene.preconditions.forEach(function (p) {
110
- lines.push('- ' + p);
111
- });
112
- lines.push('');
113
- }
114
-
115
- // -- Strategy --
116
- if (gene.strategy && gene.strategy.length > 0) {
117
- lines.push('## Strategy');
118
- lines.push('');
119
- var stepIdx = 0;
120
- gene.strategy.forEach(function (step) {
121
- var text = String(step);
122
- // Defensive: legacy genes may still carry "AVOID: ..." steps from
123
- // pre-2026-04-21 distillations. Skip them from Strategy -- the dedicated
124
- // "## Avoid" section below renders them correctly.
125
- if (/^\s*AVOID\s*[:\-]/i.test(text)) return;
126
- stepIdx += 1;
127
- var verb = extractStepVerb(text);
128
- if (verb) {
129
- lines.push(stepIdx + '. **' + verb + '** -- ' + stripLeadingVerb(text));
130
- } else {
131
- lines.push(stepIdx + '. ' + text);
132
- }
133
- });
134
- lines.push('');
135
- }
136
-
137
- // -- Avoid (anti-patterns, pitfalls, hard "do not" rules) --
138
- // Prefer the top-level `avoid` field (post-2026-04-21 genes). Fall back to
139
- // legacy "AVOID: ..." steps embedded in strategy so pre-existing genes still
140
- // surface their anti-patterns in the right section.
141
- var avoidItems = [];
142
- if (Array.isArray(gene.avoid)) {
143
- gene.avoid.forEach(function (a) {
144
- var s = String(a || '').trim();
145
- if (s) avoidItems.push(s);
146
- });
147
- }
148
- if (avoidItems.length === 0 && Array.isArray(gene.strategy)) {
149
- gene.strategy.forEach(function (step) {
150
- var text = String(step);
151
- var m = text.match(/^\s*AVOID\s*[:\-]\s*(.+)$/i);
152
- if (m) avoidItems.push(m[1].trim());
153
- });
154
- }
155
- if (avoidItems.length > 0) {
156
- lines.push('## Avoid');
157
- lines.push('');
158
- avoidItems.forEach(function (a) {
159
- lines.push('- ' + a);
160
- });
161
- lines.push('');
162
- }
163
-
164
- // -- Constraints --
165
- if (gene.constraints) {
166
- lines.push('## Constraints');
167
- lines.push('');
168
- if (gene.constraints.max_files) {
169
- lines.push('- Max files per invocation: ' + gene.constraints.max_files);
170
- }
171
- if (gene.constraints.forbidden_paths && gene.constraints.forbidden_paths.length > 0) {
172
- lines.push('- Forbidden paths: ' + gene.constraints.forbidden_paths.map(function (p) { return '`' + p + '`'; }).join(', '));
173
- }
174
- lines.push('');
175
- }
176
-
177
- // -- Validation --
178
- if (gene.validation && gene.validation.length > 0) {
179
- lines.push('## Validation');
180
- lines.push('');
181
- gene.validation.forEach(function (cmd) {
182
- lines.push('```bash');
183
- lines.push(cmd);
184
- lines.push('```');
185
- lines.push('');
186
- });
187
- }
188
-
189
- // -- Metadata --
190
- lines.push('## Metadata');
191
- lines.push('');
192
- lines.push('- Category: `' + (gene.category || 'innovate') + '`');
193
- lines.push('- Schema version: `' + (gene.schema_version || '1.6.0') + '`');
194
- if (gene._distilled_meta && gene._distilled_meta.source_capsule_count) {
195
- lines.push('- Distilled from: ' + gene._distilled_meta.source_capsule_count + ' successful capsules');
196
- }
197
- lines.push('');
198
-
199
- lines.push('---');
200
- lines.push('');
201
- lines.push('*This Skill was generated by [Evolver](https://github.com/EvoMap/evolver) and is distributed under the [EvoMap Skill License (ESL-1.0)](https://evomap.ai/terms). Unauthorized redistribution, bulk scraping, or republishing is prohibited. See LICENSE file for full terms.*');
202
- lines.push('');
203
-
204
- return lines.join('\n');
205
- }
206
-
207
- /**
208
- * Extract the leading verb from a strategy step for bolding.
209
- * Only extracts a single verb to avoid splitting compound phrases.
210
- * e.g. "Verify Cursor CLI installation" -> "Verify"
211
- * "Run `npm test` to check" -> "Run"
212
- * "Configure non-interactive mode" -> "Configure"
213
- *
214
- * Excludes anti-pattern markers ("AVOID", "DON'T", "NEVER", ...) so they never
215
- * get bolded as if they were real action verbs. These should be rendered as
216
- * anti-pattern list items in the dedicated "## Avoid" section instead.
217
- */
218
- function extractStepVerb(step) {
219
- var ANTI_PATTERN_MARKERS = /^(AVOID|DO|DON'?T|NEVER|NOT|STOP|SKIP|IGNORE|FORBIDDEN|WARN|WARNING|CAUTION|NOTE)\b/i;
220
- if (ANTI_PATTERN_MARKERS.test(step)) return '';
221
- // Only match a capitalized verb at the very start (no leading backtick/special chars)
222
- var match = step.match(/^([A-Z][a-z]+)/);
223
- if (!match) return '';
224
- // Extra safety: do not treat single-capital-letter + no-lowercase abbreviations
225
- // (already filtered by the [a-z]+ requirement) or common non-verbs like
226
- // "The", "This", "These", "Those" as verbs.
227
- var DETERMINERS = new Set(['The', 'This', 'These', 'Those', 'That', 'A', 'An']);
228
- if (DETERMINERS.has(match[1])) return '';
229
- return match[1];
230
- }
231
-
232
- /**
233
- * Remove the leading verb from a step (already shown in bold).
234
- */
235
- function stripLeadingVerb(step) {
236
- var verb = extractStepVerb(step);
237
- if (verb && step.startsWith(verb)) {
238
- var rest = step.slice(verb.length).replace(/^[\s:.\-]+/, '');
239
- return rest || step;
240
- }
241
- return step;
242
- }
243
-
244
- /**
245
- * Publish a Gene as a Skill to the Hub skill store.
246
- *
247
- * @param {object} gene - Gene asset
248
- * @param {object} [opts] - { category, tags }
249
- * @returns {Promise<{ok: boolean, result?: object, error?: string}>}
250
- */
251
- function publishSkillToHub(gene, opts) {
252
- opts = opts || {};
253
- var hubUrl = getHubUrl();
254
- if (!hubUrl) return Promise.resolve({ ok: false, error: 'no_hub_url' });
255
-
256
- // Shallow-copy gene to avoid mutating the caller's object
257
- var geneCopy = {};
258
- Object.keys(gene).forEach(function (k) { geneCopy[k] = gene[k]; });
259
- if (Array.isArray(geneCopy.signals_match)) {
260
- try {
261
- var distiller = require('./skillDistiller');
262
- geneCopy.signals_match = distiller.sanitizeSignalsMatch(geneCopy.signals_match);
263
- } catch (e) { /* distiller not available, skip */ }
264
- }
265
-
266
- var content = geneToSkillMd(geneCopy);
267
- var nodeId = getNodeId();
268
- var fmName = content.match(/^name:\s*(.+)$/m);
269
- var derivedName = fmName ? fmName[1].trim().toLowerCase().replace(/[^a-z0-9]+/g, '_') : (gene.id || 'unnamed').replace(/^gene_/, '');
270
- // Strip ALL embedded timestamps from skillId
271
- derivedName = derivedName.replace(/_?\d{10,}_?/g, '_').replace(/_+/g, '_').replace(/^_|_$/g, '');
272
- var skillId = 'skill_' + derivedName;
273
-
274
- // Clean tags: use already-sanitized signals from geneCopy
275
- var tags = opts.tags || geneCopy.signals_match || [];
276
- tags = tags.filter(function (t) {
277
- var s = String(t || '').trim();
278
- return s.length >= 3 && !/^\d+$/.test(s) && !/\d{10,}/.test(s);
279
- });
280
-
281
- var body = {
282
- sender_id: nodeId,
283
- skill_id: skillId,
284
- content: content,
285
- category: opts.category || geneCopy.category || null,
286
- tags: tags,
287
- };
288
-
289
- var endpoint = hubUrl.replace(/\/+$/, '') + '/a2a/skill/store/publish';
290
-
291
- return hubFetch(endpoint, {
292
- method: 'POST',
293
- headers: buildSkillStoreHeaders(),
294
- body: JSON.stringify(body),
295
- signal: AbortSignal.timeout(15000),
296
- })
297
- .then(function (res) { return res.json().then(function (data) { return { status: res.status, data: data }; }); })
298
- .then(function (result) {
299
- if (result.status === 201 || result.status === 200) {
300
- return { ok: true, result: result.data };
301
- }
302
- if (result.status === 409) {
303
- return updateSkillOnHub(nodeId, skillId, content, opts, gene);
304
- }
305
- return { ok: false, error: result.data?.error || 'publish_failed', status: result.status };
306
- })
307
- .catch(function (err) {
308
- return { ok: false, error: err.message };
309
- });
310
- }
311
-
312
- /**
313
- * Update an existing Skill on the Hub (new version).
314
- */
315
- function updateSkillOnHub(nodeId, skillId, content, opts, gene) {
316
- var hubUrl = getHubUrl();
317
- if (!hubUrl) return Promise.resolve({ ok: false, error: 'no_hub_url' });
318
-
319
- var tags = opts.tags || gene.signals_match || [];
320
- tags = tags.filter(function (t) {
321
- var s = String(t || '').trim();
322
- return s.length >= 3 && !/^\d+$/.test(s) && !/\d{10,}/.test(s);
323
- });
324
-
325
- var body = {
326
- sender_id: nodeId,
327
- skill_id: skillId,
328
- content: content,
329
- category: opts.category || gene.category || null,
330
- tags: tags,
331
- changelog: 'Iterative evolution update',
332
- };
333
-
334
- var endpoint = hubUrl.replace(/\/+$/, '') + '/a2a/skill/store/update';
335
-
336
- return hubFetch(endpoint, {
337
- method: 'PUT',
338
- headers: buildSkillStoreHeaders(),
339
- body: JSON.stringify(body),
340
- signal: AbortSignal.timeout(15000),
341
- })
342
- .then(function (res) { return res.json().then(function (data) { return { status: res.status, data: data }; }); })
343
- .then(function (result) {
344
- if (result.status >= 200 && result.status < 300) {
345
- return { ok: true, result: result.data };
346
- }
347
- return { ok: false, error: result.data?.error || 'update_failed', status: result.status };
348
- })
349
- .catch(function (err) { return { ok: false, error: err.message }; });
350
- }
351
-
352
- module.exports = {
353
- geneToSkillMd: geneToSkillMd,
354
- publishSkillToHub: publishSkillToHub,
355
- updateSkillOnHub: updateSkillOnHub,
356
- sanitizeSkillName: sanitizeSkillName,
357
- toTitleCase: toTitleCase,
358
- };