MCPcopy Create free account
hub / github.com/EvoMap/evolver / publishSkillToHub

Function publishSkillToHub

src/gep/skillPublisher.js:251–310  ·  view source on GitHub ↗

* Publish a Gene as a Skill to the Hub skill store. * * @param {object} gene - Gene asset * @param {object} [opts] - { category, tags } * @returns {Promise<{ok: boolean, result?: object, error?: string}>}

(gene, opts)

Source from the content-addressed store, hash-verified

249 * @returns {Promise<{ok: boolean, result?: object, error?: string}>}
250 */
251function 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 };

Callers

nothing calls this directly

Calls 4

getHubUrlFunction · 0.85
geneToSkillMdFunction · 0.85
buildSkillStoreHeadersFunction · 0.85
updateSkillOnHubFunction · 0.85

Tested by

no test coverage detected