installer-acceptance.mjs 2.2 KB

123456789101112131415161718192021222324252627
  1. import fs from 'node:fs';
  2. import os from 'node:os';
  3. import path from 'node:path';
  4. import { spawnSync } from 'node:child_process';
  5. import manifest from '../skill-package-manifest.json' with { type: 'json' };
  6. const packageRoot = path.resolve(import.meta.dirname, '..');
  7. const workspace = fs.mkdtempSync(path.join(os.tmpdir(), 'fmode-image-set-installer-'));
  8. fs.writeFileSync(path.join(workspace, '.mcp.json'), JSON.stringify({ mcpServers: { existing: { command: 'keep-me' } } }, null, 2));
  9. try {
  10. const result = spawnSync(process.execPath, [path.join(packageRoot, 'bin', 'fmode-image-set.js'), 'workspace', '--skip-install', '--force'], { cwd: workspace, encoding: 'utf8' });
  11. if (result.status !== 0) throw new Error(result.error?.message || result.stderr || result.stdout || `workspace install failed (status=${result.status}, signal=${result.signal})`);
  12. const installed = path.join(workspace, '.claude', 'plugins', 'fmode-image-set');
  13. if (!fs.existsSync(path.join(installed, 'mcp', 'src', 'server.mjs'))) throw new Error('MCP server not installed');
  14. for (const skill of manifest.skills) if (!fs.existsSync(path.join(workspace, '.claude', 'skills', skill, 'SKILL.md'))) throw new Error(`Skill not exposed: ${skill}`);
  15. const mcp = JSON.parse(fs.readFileSync(path.join(workspace, '.mcp.json'), 'utf8'));
  16. if (!mcp.mcpServers.existing || !mcp.mcpServers['fmode-image-set']) throw new Error('.mcp.json merge failed');
  17. if (!path.isAbsolute(mcp.mcpServers['fmode-image-set'].cwd) || !fs.existsSync(mcp.mcpServers['fmode-image-set'].args[0])) throw new Error('MCP paths are invalid');
  18. if (mcp.mcpServers['fmode-image-set'].env?.FMODE_WORKSPACE_ROOT !== workspace) throw new Error('Workspace root env was not injected');
  19. for (const forbidden of ['node_modules', '.env', 'outputs', '输出']) if (fs.existsSync(path.join(installed, forbidden))) throw new Error(`Forbidden copy: ${forbidden}`);
  20. for (const legacy of ['qwen-vision.mjs', 'jimeng.mjs']) {
  21. if (fs.existsSync(path.join(installed, 'mcp', 'src', 'providers', legacy))) throw new Error(`Legacy provider remained installed: ${legacy}`);
  22. }
  23. console.log(JSON.stringify({ status: 'ok', installed, skills: manifest.skills.length }, null, 2));
  24. } finally {
  25. fs.rmSync(workspace, { recursive: true, force: true });
  26. }