@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.
- package/README.md +27 -564
- package/bin/evolver-llm-proxy.js +3 -0
- package/bin/evolver-mcp.js +2 -0
- package/bin/evolver-proxy.js +3 -0
- package/bin/evolver.js +4 -0
- package/index.js +1 -3586
- package/package.json +32 -62
- package/CONTRIBUTING.md +0 -19
- package/LICENSE +0 -641
- package/README.ja-JP.md +0 -521
- package/README.ko-KR.md +0 -520
- package/README.zh-CN.md +0 -531
- package/SKILL.md +0 -365
- package/assets/cover.png +0 -0
- package/assets/gep/genes.seed.json +0 -496
- package/conformance/savings-core/constants.json +0 -30
- package/conformance/savings-core/golden-vectors.json +0 -333
- package/scripts/a2a_export.js +0 -63
- package/scripts/a2a_ingest.js +0 -79
- package/scripts/a2a_promote.js +0 -118
- package/scripts/analyze_by_skill.js +0 -121
- package/scripts/build_binaries.js +0 -479
- package/scripts/check-changelog.js +0 -166
- package/scripts/extract_log.js +0 -85
- package/scripts/generate_history.js +0 -75
- package/scripts/gep_append_event.js +0 -96
- package/scripts/gep_personality_report.js +0 -234
- package/scripts/human_report.js +0 -147
- package/scripts/recall-verify-report.js +0 -234
- package/scripts/recover_loop.js +0 -61
- package/scripts/refresh_stars_badge.js +0 -168
- package/scripts/seed-merchants.js +0 -91
- package/scripts/skill2recipes.js +0 -118
- package/scripts/suggest_version.js +0 -89
- package/scripts/validate-modules.js +0 -38
- package/scripts/validate-suite.js +0 -78
- package/skills/_meta/SKILL.md +0 -41
- package/skills/index.json +0 -14
- package/src/adapters/claudeCode.js +0 -194
- package/src/adapters/codex.js +0 -216
- package/src/adapters/cursor.js +0 -91
- package/src/adapters/hookAdapter.js +0 -469
- package/src/adapters/kiro.js +0 -195
- package/src/adapters/opencode.js +0 -326
- package/src/adapters/scripts/_lockPaths.js +0 -74
- package/src/adapters/scripts/_memoryFiltering.js +0 -35
- package/src/adapters/scripts/_runtimePaths.js +0 -440
- package/src/adapters/scripts/evolver-session-end.js +0 -321
- package/src/adapters/scripts/evolver-session-start.js +0 -587
- package/src/adapters/scripts/evolver-signal-detect.js +0 -98
- package/src/adapters/scripts/evolver-task-recall.js +0 -173
- package/src/atp/atpExecute.js +0 -283
- package/src/atp/atpTaskPickup.js +0 -233
- package/src/atp/autoBuyer.js +0 -382
- package/src/atp/autoDeliver.js +0 -215
- package/src/atp/cli.js +0 -354
- package/src/atp/cliAutobuyPrompt.js +0 -154
- package/src/atp/consumerAgent.js +0 -157
- package/src/atp/defaultHandler.js +0 -69
- package/src/atp/heartbeatSignalsHandler.js +0 -254
- package/src/atp/hubClient.js +0 -317
- package/src/atp/index.js +0 -38
- package/src/atp/merchantAgent.js +0 -118
- package/src/atp/protocol.js +0 -41
- package/src/atp/questionComposer.js +0 -133
- package/src/atp/serviceHelper.js +0 -92
- package/src/canary.js +0 -13
- package/src/config.js +0 -351
- package/src/evolve/guards.js +0 -1
- package/src/evolve/pipeline/collect.js +0 -1
- package/src/evolve/pipeline/dispatch.js +0 -1
- package/src/evolve/pipeline/enrich.js +0 -1
- package/src/evolve/pipeline/hub.js +0 -1
- package/src/evolve/pipeline/select.js +0 -1
- package/src/evolve/pipeline/signals.js +0 -1
- package/src/evolve/utils.js +0 -1
- package/src/evolve.js +0 -1
- package/src/experiment/agentRunner.js +0 -229
- package/src/experiment/cli.js +0 -159
- package/src/experiment/comparison.js +0 -233
- package/src/experiment/metrics.js +0 -75
- package/src/forceUpdate.js +0 -991
- package/src/gep/a2a.js +0 -173
- package/src/gep/a2aProtocol.js +0 -1
- package/src/gep/analyzer.js +0 -35
- package/src/gep/antiAbuseTelemetry.js +0 -1
- package/src/gep/assetCallLog.js +0 -197
- package/src/gep/assetStore.js +0 -723
- package/src/gep/assets.js +0 -36
- package/src/gep/autoDistillConv.js +0 -1
- package/src/gep/autoDistillLlm.js +0 -1
- package/src/gep/bridge.js +0 -138
- package/src/gep/candidateEval.js +0 -1
- package/src/gep/candidates.js +0 -1
- package/src/gep/claimNudge.js +0 -121
- package/src/gep/cliContracts.js +0 -1190
- package/src/gep/contentHash.js +0 -1
- package/src/gep/conversationDistiller.js +0 -1
- package/src/gep/conversationSniffer.js +0 -1
- package/src/gep/crypto.js +0 -1
- package/src/gep/curriculum.js +0 -1
- package/src/gep/deviceId.js +0 -1
- package/src/gep/directoryClient.js +0 -115
- package/src/gep/envFingerprint.js +0 -1
- package/src/gep/epigenetics.js +0 -1
- package/src/gep/execBridge.js +0 -1
- package/src/gep/executionTrace.js +0 -291
- package/src/gep/explore.js +0 -1
- package/src/gep/featureFlags.js +0 -121
- package/src/gep/gitOps.js +0 -265
- package/src/gep/hash.js +0 -1
- package/src/gep/hostErrorClassifier.js +0 -34
- package/src/gep/hubFetch.js +0 -1
- package/src/gep/hubReview.js +0 -1
- package/src/gep/hubSearch.js +0 -1
- package/src/gep/hubVerify.js +0 -1
- package/src/gep/idleScheduler.js +0 -400
- package/src/gep/issueReporter.js +0 -416
- package/src/gep/learningSignals.js +0 -1
- package/src/gep/llmReview.js +0 -92
- package/src/gep/localStateAwareness.js +0 -243
- package/src/gep/mailboxTransport.js +0 -119
- package/src/gep/memoryGraph.js +0 -1
- package/src/gep/memoryGraphAdapter.js +0 -1
- package/src/gep/mutation.js +0 -1
- package/src/gep/narrativeMemory.js +0 -1
- package/src/gep/oauthLogin.js +0 -181
- package/src/gep/openPRRegistry.js +0 -1
- package/src/gep/paths.js +0 -522
- package/src/gep/personality.js +0 -1
- package/src/gep/policyCheck.js +0 -1
- package/src/gep/portable.js +0 -103
- package/src/gep/privacyClient.js +0 -235
- package/src/gep/prompt.js +0 -1
- package/src/gep/questionGenerator.js +0 -518
- package/src/gep/recallInject.js +0 -1
- package/src/gep/recallVerifier.js +0 -1
- package/src/gep/reflection.js +0 -1
- package/src/gep/sanitize.js +0 -264
- package/src/gep/savingsCore.js +0 -1
- package/src/gep/schemas/capsule.js +0 -170
- package/src/gep/schemas/gene.js +0 -154
- package/src/gep/schemas/index.js +0 -8
- package/src/gep/schemas/protocol.js +0 -51
- package/src/gep/schemas/task.js +0 -74
- package/src/gep/selector.js +0 -1
- package/src/gep/selfPR.js +0 -469
- package/src/gep/signals.js +0 -776
- package/src/gep/skill2gep.js +0 -1056
- package/src/gep/skill2gepAudit.js +0 -303
- package/src/gep/skill2recipes.js +0 -511
- package/src/gep/skillDistiller.js +0 -1
- package/src/gep/skillPublisher.js +0 -358
- package/src/gep/solidify.js +0 -1
- package/src/gep/strategy.js +0 -1
- package/src/gep/taskReceiver.js +0 -575
- package/src/gep/tokenSavings.js +0 -1
- package/src/gep/trajectoryExport.js +0 -1
- package/src/gep/validationReport.js +0 -55
- package/src/gep/validator/index.js +0 -411
- package/src/gep/validator/reporter.js +0 -210
- package/src/gep/validator/sandboxExecutor.js +0 -480
- package/src/gep/validator/stakeBootstrap.js +0 -357
- package/src/gep/workspaceKeychain.js +0 -1
- package/src/ops/cleanup.js +0 -80
- package/src/ops/commentary.js +0 -60
- package/src/ops/health_check.js +0 -104
- package/src/ops/index.js +0 -11
- package/src/ops/innovation.js +0 -67
- package/src/ops/lifecycle.js +0 -798
- package/src/ops/self_repair.js +0 -76
- package/src/ops/skills_monitor.js +0 -147
- package/src/ops/trigger.js +0 -33
- package/src/proxy/clientSettings.js +0 -405
- package/src/proxy/envelope.js +0 -59
- package/src/proxy/extensions/dmHandler.js +0 -45
- package/src/proxy/extensions/sessionHandler.js +0 -141
- package/src/proxy/extensions/skillUpdater.js +0 -64
- package/src/proxy/extensions/traceControl.js +0 -1
- package/src/proxy/index.js +0 -1395
- package/src/proxy/inject.js +0 -1
- package/src/proxy/lifecycle/manager.js +0 -1568
- package/src/proxy/mailbox/state.js +0 -207
- package/src/proxy/mailbox/store.js +0 -590
- package/src/proxy/router/cache_passthrough.js +0 -26
- package/src/proxy/router/features.js +0 -84
- package/src/proxy/router/gemini_route.js +0 -154
- package/src/proxy/router/messages_route.js +0 -535
- package/src/proxy/router/model_router.js +0 -113
- package/src/proxy/router/models_route.js +0 -52
- package/src/proxy/router/ollama_route.js +0 -103
- package/src/proxy/router/responses_route.js +0 -170
- package/src/proxy/router/vertex_route.js +0 -110
- package/src/proxy/server/http.js +0 -363
- package/src/proxy/server/routes.js +0 -558
- package/src/proxy/server/settings.js +0 -115
- package/src/proxy/sync/engine.js +0 -179
- package/src/proxy/sync/inbound.js +0 -211
- package/src/proxy/sync/outbound.js +0 -320
- package/src/proxy/task/monitor.js +0 -131
- package/src/proxy/trace/extractor.js +0 -1
- package/src/proxy/trace/usage.js +0 -1
- package/src/webui/client/clientJs/assets.js +0 -111
- package/src/webui/client/clientJs/bootstrap.js +0 -92
- package/src/webui/client/clientJs/common.js +0 -77
- package/src/webui/client/clientJs/i18n.js +0 -366
- package/src/webui/client/clientJs/index.js +0 -35
- package/src/webui/client/clientJs/interactions.js +0 -351
- package/src/webui/client/clientJs/overview.js +0 -152
- package/src/webui/client/clientJs/personality.js +0 -285
- package/src/webui/client/clientJs/pipelines.js +0 -330
- package/src/webui/client/indexHtml.js +0 -221
- package/src/webui/client/static.js +0 -23
- package/src/webui/client/stylesCss.js +0 -639
- package/src/webui/client/vendor/README.md +0 -15
- package/src/webui/client/vendor/echarts.min.js +0 -45
- package/src/webui/index.js +0 -14
- package/src/webui/observer/assets.js +0 -146
- package/src/webui/observer/index.js +0 -37
- package/src/webui/observer/interactions.js +0 -127
- package/src/webui/observer/jsonl.js +0 -75
- package/src/webui/observer/paths.js +0 -46
- package/src/webui/observer/personality.js +0 -43
- package/src/webui/observer/pipelineEvents.js +0 -58
- package/src/webui/observer/redact.js +0 -63
- package/src/webui/observer/runs.js +0 -356
- package/src/webui/observer/safety.js +0 -57
- package/src/webui/observer/skills.js +0 -70
- package/src/webui/observer/status.js +0 -71
- package/src/webui/server/http.js +0 -138
- 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
|
-
};
|