import { createHash } from 'node:crypto'; import { mkdirSync, writeFileSync, readFileSync } from 'node:fs'; import { execFileSync } from 'node:child_process'; import { createRequire } from 'node:module'; import { patchClient } from './patch-chat-manager.mjs'; const root = '/usr/local/lib/dsh-mgr'; const version = '1.5.12'; const patchedVersion = '1.5.12-dsh-mgr.1'; const hostManifest = '/usr/local/lib/node_modules/@deepseek-ai/dsh/package.json'; const destination = '/usr/local/lib/node_modules/@deepseek-ai/dsh/node_modules/dsh-chat-manager'; const packages = [ ['dsh-chat-manager', version, 'https://registry.npmjs.org/dsh-chat-manager/-/dsh-chat-manager-1.5.12.tgz', 'UpecIKftHTKZMAdZg0w/GFtYGN2A/fB7NVQ/OrrBOKsq1frN5nm4CDBH8KZggwfT9GSx+MjwLlwYgxDfDWLm4g=='], ['clsx', '2.1.1', 'https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz', 'eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=='], ]; mkdirSync(root, { recursive: true }); for (const [name, release, url, integrity] of packages) { const response = await fetch(url, { signal: AbortSignal.timeout(120000) }); if (!response.ok) throw new Error('download failed: ' + name); const data = Buffer.from(await response.arrayBuffer()); if (createHash('sha512').update(data).digest('base64') !== integrity) throw new Error('integrity mismatch: ' + name); writeFileSync(`${root}/${name}-${release}.tgz`, data, { mode: 0o644 }); } mkdirSync(destination, { recursive: true }); execFileSync('tar', ['-xzf', `${root}/dsh-chat-manager-${version}.tgz`, '--strip-components=1', '--no-same-owner', '-C', destination]); const pkg = JSON.parse(readFileSync(destination + '/package.json')); if (pkg.name !== 'dsh-chat-manager' || pkg.version !== version || pkg.license !== 'MIT' || JSON.stringify(pkg.dependencies) !== JSON.stringify({ clsx: '^2.0.0' })) throw new Error('unexpected chat-manager metadata'); if (!readFileSync(destination + '/LICENSE', 'utf8').includes('MIT License')) throw new Error('missing chat-manager MIT license'); const require = createRequire(hostManifest); const host = JSON.parse(readFileSync(hostManifest)); const semver = createRequire('/usr/local/lib/node_modules/npm/package.json')('semver'); for (const [name, range] of Object.entries(pkg.peerDependencies || {})) { if (name === 'react') { if (host.version !== '0.2.0-rc.2') throw new Error('unverified browser React host: ' + host.version); continue; } const peer = require(name + '/package.json'); if (!semver.satisfies(peer.version, range)) throw new Error('incompatible chat-manager host dependency: ' + name + '@' + peer.version); } const client = destination + '/lib/client.js'; writeFileSync(client, patchClient(readFileSync(client, 'utf8'), version)); pkg.version = patchedVersion; writeFileSync(destination + '/package.json', JSON.stringify(pkg, null, 2)); execFileSync('chmod', ['-R', 'a+rX', destination]); execFileSync('tar', ['-czf', `${root}/dsh-chat-manager-${patchedVersion}.tgz`, '--transform=s,^dsh-chat-manager,package,', '-C', destination + '/..', 'dsh-chat-manager']); execFileSync('chmod', ['644', `${root}/dsh-chat-manager-${patchedVersion}.tgz`]); const clsx = destination + '/node_modules/clsx'; mkdirSync(clsx, { recursive: true }); execFileSync('tar', ['-xzf', `${root}/clsx-2.1.1.tgz`, '--strip-components=1', '--no-same-owner', '-C', clsx]); execFileSync('chmod', ['-R', 'a+rX', clsx]); host.dependencies = { ...host.dependencies, 'dsh-chat-manager': patchedVersion }; writeFileSync(hostManifest, JSON.stringify(host, null, 2)); console.log('Installed dsh-chat-manager@' + patchedVersion + ' and clsx@2.1.1 (SHA-512 verified; no lifecycle scripts; MIT retained)');