文件预览

skillUpdater.js

查看 Evolver 技能包中的文件内容。

文件内容

src/proxy/extensions/skillUpdater.js

'use strict';

const fs = require('fs');
const path = require('path');

class SkillUpdater {
  constructor({ store, skillPath, logger } = {}) {
    this.store = store;
    this.skillPath = skillPath || null;
    this.logger = logger || console;
  }

  setSkillPath(filePath) {
    this.skillPath = filePath;
  }

  processSkillUpdate(message) {
    if (!this.skillPath) {
      this.logger.warn('[skill-updater] No skill path configured, skipping update');
      return false;
    }

    const payload = message.payload || message;
    const content = payload.content || payload.skill_content;

    if (!content || typeof content !== 'string') {
      this.logger.warn('[skill-updater] No content in skill_update message');
      return false;
    }

    try {
      const dir = path.dirname(this.skillPath);
      if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });

      if (fs.existsSync(this.skillPath)) {
        const backupPath = this.skillPath + '.bak';
        fs.copyFileSync(this.skillPath, backupPath);
      }

      fs.writeFileSync(this.skillPath, content, 'utf8');
      this.store.setState('last_skill_update', new Date().toISOString());
      this.store.setState('skill_version', payload.version || 'unknown');
      this.logger.log(`[skill-updater] Updated skill.md (version: ${payload.version || 'unknown'})`);
      return true;
    } catch (err) {
      this.logger.error(`[skill-updater] Failed to update: ${err.message}`);
      return false;
    }
  }

  pollAndApply() {
    const updates = this.store.poll({ type: 'skill_update' });
    let applied = 0;
    for (const msg of updates) {
      if (this.processSkillUpdate(msg)) {
        this.store.ack(msg.id);
        applied++;
      }
    }
    return applied;
  }
}

module.exports = { SkillUpdater };