package-workshop-skill.mjs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536
  1. import fs from 'node:fs';
  2. import path from 'node:path';
  3. import crypto from 'node:crypto';
  4. import { fileURLToPath } from 'node:url';
  5. const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
  6. const skill = 'skills/ksf-workshop-runtime';
  7. const sha = bytes => crypto.createHash('sha256').update(bytes).digest('hex');
  8. const [flag, directory, ...extra] = process.argv.slice(2);
  9. if (flag !== '--out' || !directory || !path.isAbsolute(directory) || extra.length || fs.existsSync(directory)) {
  10. throw new Error('Use --out ABSOLUTE_NEW_DIRECTORY');
  11. }
  12. const entries = fs.readFileSync(path.join(root, skill, 'FILES.sha256'), 'utf8').trim().split(/\r?\n/).map(line => {
  13. const match = line.match(/^([a-f0-9]{64}) ([A-Za-z0-9_./-]+)$/);
  14. if (!match || match[2].split('/').includes('..')) throw new Error('Invalid Skill manifest');
  15. if (sha(fs.readFileSync(path.join(root, skill, match[2]))) !== match[1]) throw new Error('Skill hash mismatch');
  16. return skill + '/' + match[2];
  17. });
  18. if (new Set(entries).size !== 10) throw new Error('Expected ten Skill manifest entries');
  19. const files = [...entries, skill + '/FILES.sha256',
  20. 'scripts/install-workshop-skill.mjs', 'scripts/build-workshop-skill.mjs', 'scripts/package-workshop-skill.mjs',
  21. 'docs/workshop-skill-employee-identity-20261103.md', 'docs/workshop-skill-validation-20261103.json',
  22. 'docs/wecom-identity-integration-20261103.md',
  23. ].sort();
  24. for (const file of files) {
  25. const stat = fs.lstatSync(path.join(root, file));
  26. if (!stat.isFile() || stat.isSymbolicLink() || /credential-binding|participants\/|agents\//.test(file)) throw new Error('Unexpected package file');
  27. }
  28. fs.mkdirSync(directory, { recursive: true });
  29. for (const file of files) {
  30. const target = path.join(directory, file);
  31. fs.mkdirSync(path.dirname(target), { recursive: true });
  32. fs.copyFileSync(path.join(root, file), target, fs.constants.COPYFILE_EXCL);
  33. }
  34. fs.writeFileSync(path.join(directory, 'FILES.sha256'), files.map(file => sha(fs.readFileSync(path.join(directory, file))) + ' ' + file).join('\n') + '\n', { flag: 'wx' });
  35. console.log(JSON.stringify({ ok: true, release: 'ksf.workshop-skill.employee.20261103.r1', directory, files: files.length + 1, productionWrites: 0, deployed: false }));