build-sdk.mjs 4.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/env node
  2. // 构建业务平台使用的 SDK 包(docs/integration.md):@agent-server/shared、@agent-server/client、@agent-server/chat-ui,
  3. // 以及技能推送工具 agent-skills(docs/design/19-skill-cli.md)。
  4. // 输出 dist-sdk/<包名>-<版本>.tgz,部署到 app/sdk(保留旧版本),由服务的 npm 仓库 /npm/ 公开提供(不含任何密钥)。
  5. // 包之间是对等依赖;业务平台用 @agent-server:registry=<服务器>/npm/ 安装,其余依赖仍从 npm 官方仓库安装。
  6. import { execFileSync } from 'node:child_process'
  7. import fs from 'node:fs'
  8. import path from 'node:path'
  9. import { fileURLToPath } from 'node:url'
  10. const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
  11. const out = path.join(root, 'dist-sdk')
  12. const stage = path.join(out, 'stage')
  13. const run = (cmd, args, cwd) => execFileSync(cmd, args, { cwd, stdio: ['ignore', 'inherit', 'inherit'] })
  14. const pkgDir = name => path.join(root, 'packages', name)
  15. const readPkg = name => JSON.parse(fs.readFileSync(path.join(pkgDir(name), 'package.json'), 'utf8'))
  16. fs.rmSync(out, { recursive: true, force: true })
  17. fs.mkdirSync(stage, { recursive: true })
  18. run('npx', ['tsup', '--silent'], pkgDir('shared'))
  19. run('npx', ['tsup', '--silent'], pkgDir('client'))
  20. run('npx', ['vite', 'build', '--logLevel', 'warn'], pkgDir('chat-ui'))
  21. run('npx', ['vue-tsc', '-p', 'tsconfig.build.json'], pkgDir('chat-ui'))
  22. run('npx', ['tsup', '--silent'], pkgDir('skills-cli'))
  23. const version = readPkg('client').version
  24. const peer = { '@agent-server/shared': version }
  25. const packages = [
  26. {
  27. dir: 'shared', files: { 'dist/index.js': 'index.js', 'dist/index.d.ts': 'index.d.ts' },
  28. manifest: { exports: { '.': { types: './index.d.ts', import: './index.js' } }, types: './index.d.ts' },
  29. },
  30. {
  31. dir: 'client', files: { 'dist/index.js': 'index.js', 'dist/index.d.ts': 'index.d.ts' },
  32. manifest: { exports: { '.': { types: './index.d.ts', import: './index.js' } }, types: './index.d.ts', peerDependencies: peer },
  33. },
  34. {
  35. dir: 'chat-ui', files: { 'dist/index.js': 'index.js', 'dist/style.css': 'style.css', 'dist/types': 'types' },
  36. manifest: {
  37. exports: { '.': { types: './types/index.d.ts', import: './index.js' }, './style.css': './style.css' },
  38. types: './types/index.d.ts',
  39. sideEffects: ['*.css'],
  40. dependencies: { 'markdown-it': readPkg('chat-ui').dependencies['markdown-it'] },
  41. peerDependencies: { ...peer, '@agent-server/client': version, vue: readPkg('chat-ui').peerDependencies.vue },
  42. },
  43. },
  44. ]
  45. const index = []
  46. for (const p of packages) {
  47. const src = readPkg(p.dir)
  48. const dir = path.join(stage, p.dir)
  49. for (const [from, to] of Object.entries(p.files)) fs.cpSync(path.join(pkgDir(p.dir), from), path.join(dir, to), { recursive: true })
  50. const manifest = { name: src.name, version, type: 'module', description: `AgentServer SDK:${p.dir}`, ...p.manifest }
  51. fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify(manifest, null, 2))
  52. const file = execFileSync('npm', ['pack', '--silent', '--pack-destination', out], { cwd: dir, encoding: 'utf8' }).trim().split('\n').pop()
  53. index.push({ name: src.name, version, file })
  54. }
  55. // 推送工具:单文件、不带依赖,版本独立
  56. {
  57. const src = readPkg('skills-cli')
  58. const dir = path.join(stage, 'skills-cli')
  59. fs.mkdirSync(dir, { recursive: true })
  60. fs.copyFileSync(path.join(pkgDir('skills-cli'), 'dist/agent-skills.mjs'), path.join(dir, 'agent-skills.mjs'))
  61. fs.chmodSync(path.join(dir, 'agent-skills.mjs'), 0o755)
  62. const manifest = { name: src.name, version: src.version, type: 'module', description: src.description, bin: { 'agent-skills': './agent-skills.mjs' }, engines: { node: '>=18' } }
  63. fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify(manifest, null, 2))
  64. const file = execFileSync('npm', ['pack', '--silent', '--pack-destination', out], { cwd: dir, encoding: 'utf8' }).trim().split('\n').pop()
  65. index.push({ name: src.name, version: src.version, file })
  66. }
  67. fs.rmSync(stage, { recursive: true, force: true })
  68. console.log(`SDK ${version}:${index.map(p => p.file).join('、')}`)