112 lines
4.8 KiB
JavaScript
112 lines
4.8 KiB
JavaScript
// Build-time generator for the code-mode engine manifest.
|
|
//
|
|
// Code mode provisions each agent's native engine on demand by downloading the
|
|
// per-platform npm package AT THE EXACT VERSION OUR ACP ADAPTER DEPENDS ON, so the
|
|
// adapter <-> engine handshake is always in lockstep. This script reads those pinned
|
|
// versions from the installed adapter package.json files, queries the npm registry for
|
|
// each platform package's tarball URL + integrity, and writes them to
|
|
// `src/code-mode/acp/engine-manifest.ts` (committed; regenerate on a version bump).
|
|
//
|
|
// Usage: node scripts/gen-engine-manifest.mjs (run from packages/core)
|
|
//
|
|
// Why a committed .ts (not a fetched-at-build .json): it needs no network at app build
|
|
// time, works offline in dev, is reviewable in PRs, and esbuild inlines it into the
|
|
// packaged main bundle.
|
|
|
|
import { createRequire } from 'module';
|
|
import { writeFileSync } from 'fs';
|
|
import { fileURLToPath } from 'url';
|
|
import * as path from 'path';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const REGISTRY = 'https://registry.npmjs.org';
|
|
|
|
// Platform keys we publish for each agent. These mirror the optionalDependencies of the
|
|
// engine packages. claude ships musl variants; codex does not.
|
|
const CLAUDE_PLATFORMS = [
|
|
'darwin-arm64', 'darwin-x64',
|
|
'linux-x64', 'linux-arm64', 'linux-x64-musl', 'linux-arm64-musl',
|
|
'win32-x64', 'win32-arm64',
|
|
];
|
|
const CODEX_PLATFORMS = [
|
|
'darwin-arm64', 'darwin-x64',
|
|
'linux-x64', 'linux-arm64',
|
|
'win32-x64', 'win32-arm64',
|
|
];
|
|
|
|
// Read a pinned dependency version from an adapter's package.json, stripping any range
|
|
// prefix (^, ~). createRequire resolves the adapter from the installed node_modules.
|
|
function pinnedDep(adapterPkg, depName) {
|
|
const pj = require(`${adapterPkg}/package.json`);
|
|
const spec = (pj.dependencies || {})[depName] || (pj.optionalDependencies || {})[depName];
|
|
if (!spec) throw new Error(`${adapterPkg} has no dependency on ${depName}`);
|
|
return spec.replace(/^[\^~]/, '');
|
|
}
|
|
|
|
// Fetch a single version's manifest from the registry and return its dist coordinates.
|
|
async function distFor(pkg, version) {
|
|
const url = `${REGISTRY}/${pkg}/${version}`;
|
|
const res = await fetch(url);
|
|
if (!res.ok) {
|
|
if (res.status === 404) return null; // platform not published for this version
|
|
throw new Error(`registry ${res.status} for ${pkg}@${version}`);
|
|
}
|
|
const doc = await res.json();
|
|
return { tarball: doc.dist.tarball, integrity: doc.dist.integrity };
|
|
}
|
|
|
|
// Build one agent's manifest entry: { version, platforms: { <key>: {tarball, integrity} } }.
|
|
// pkgFor(platform) -> { pkg, version } gives the registry coordinates for each platform.
|
|
async function buildAgent(version, platforms, pkgFor) {
|
|
const out = { version, platforms: {} };
|
|
for (const key of platforms) {
|
|
const { pkg, version: pv } = pkgFor(key);
|
|
const dist = await distFor(pkg, pv);
|
|
if (!dist) {
|
|
console.warn(` ! ${pkg}@${pv} not found on registry — skipping ${key}`);
|
|
continue;
|
|
}
|
|
out.platforms[key] = { pkg, pkgVersion: pv, ...dist };
|
|
console.log(` ✓ ${key}: ${pkg}@${pv}`);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
async function main() {
|
|
// Pinned engine versions, read straight from the adapters we ship.
|
|
const claudeVersion = pinnedDep('@agentclientprotocol/claude-agent-acp', '@anthropic-ai/claude-agent-sdk');
|
|
const codexVersion = pinnedDep('@agentclientprotocol/codex-acp', '@openai/codex');
|
|
console.log(`claude engine: @anthropic-ai/claude-agent-sdk@${claudeVersion}`);
|
|
console.log(`codex engine: @openai/codex@${codexVersion}`);
|
|
|
|
const manifest = {
|
|
claude: await buildAgent(claudeVersion, CLAUDE_PLATFORMS, (key) => ({
|
|
pkg: `@anthropic-ai/claude-agent-sdk-${key}`,
|
|
version: claudeVersion,
|
|
})),
|
|
codex: await buildAgent(codexVersion, CODEX_PLATFORMS, (key) => ({
|
|
// codex publishes platform binaries as VERSIONS of @openai/codex
|
|
// (e.g. 0.128.0-darwin-arm64), not as separate package names.
|
|
pkg: '@openai/codex',
|
|
version: `${codexVersion}-${key}`,
|
|
})),
|
|
};
|
|
|
|
const outPath = path.join(
|
|
path.dirname(fileURLToPath(import.meta.url)),
|
|
'..', 'src', 'code-mode', 'acp', 'engine-manifest.ts',
|
|
);
|
|
const banner =
|
|
'// AUTO-GENERATED by packages/core/scripts/gen-engine-manifest.mjs — do not edit by hand.\n' +
|
|
'// Regenerate after bumping the @agentclientprotocol/*-acp adapter (engine) versions.\n' +
|
|
'// Maps each agent + platform to the npm tarball + integrity of its native engine.\n\n';
|
|
const body = `export const ENGINE_MANIFEST = ${JSON.stringify(manifest, null, 4)} as const;\n`;
|
|
writeFileSync(outPath, banner + body);
|
|
console.log(`\nWrote ${outPath}`);
|
|
}
|
|
|
|
main().catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
});
|