consortium
Version:
Remote control and session sharing CLI for AI coding agents
76 lines (68 loc) • 3.25 kB
JavaScript
/**
* Runs pkgroll with build-identity values frozen into the bundle.
*
* Exists so `dist/` can answer "which source is this?" — see src/buildInfo.ts
* for why the package.json version cannot. Kept as a node script rather than
* inline `$(git ...)` in package.json because the Windows build path runs
* these scripts through PowerShell, where command substitution differs.
*
* Values resolve in this order:
* 1. An already-exported CONSORTIUM_BUILD_* env var. This is the path that
* matters for publishing: publish-canary.sh builds inside a temp copy
* that is NOT a git repo, so it captures the SHA from the real checkout
* and exports it before the build runs.
* 2. git, when we are in a working checkout.
* 3. 'unknown' — a built artifact that genuinely cannot name its source.
* Distinct from src/buildInfo.ts's 'dev' fallback, which means "not
* built at all, running from source via tsx".
*
* Any extra argv is forwarded to pkgroll untouched.
*/
const { execFileSync, spawnSync } = require('child_process');
function git(args) {
try {
return execFileSync('git', args, {
cwd: __dirname,
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'ignore'],
}).trim();
} catch {
return '';
}
}
const sha = process.env.CONSORTIUM_BUILD_SHA || git(['rev-parse', '--short', 'HEAD']) || 'unknown';
const branch = process.env.CONSORTIUM_BUILD_BRANCH || git(['rev-parse', '--abbrev-ref', 'HEAD']) || 'unknown';
const time = process.env.CONSORTIUM_BUILD_TIME || new Date().toISOString();
// `git status --porcelain` is empty exactly when the tree is clean. An empty
// result from a FAILED git call is indistinguishable, so only trust it when
// git resolved a SHA — otherwise leave dirty unset rather than claiming clean.
const dirty = process.env.CONSORTIUM_BUILD_DIRTY
|| (git(['rev-parse', 'HEAD']) && git(['status', '--porcelain']) ? '1' : '0');
const args = [
`--env.CONSORTIUM_BUILD_SHA=${sha}`,
`--env.CONSORTIUM_BUILD_BRANCH=${branch}`,
`--env.CONSORTIUM_BUILD_TIME=${time}`,
`--env.CONSORTIUM_BUILD_DIRTY=${dirty}`,
...process.argv.slice(2),
];
console.log(`[build-stamp] ${sha}${dirty === '1' ? '+dirty' : ''} on ${branch} @ ${time}`);
const result = spawnSync('npx', ['pkgroll', ...args], { stdio: 'inherit', shell: process.platform === 'win32' });
if (result.status !== 0) process.exit(result.status ?? 1);
// Also drop the identity beside the bundle, as data.
//
// The values above are inlined into the bundle as separate string literals, so
// nothing can reliably recover "which build is this?" by grepping dist/ -- and
// asking the binary means paying ~20s of CLI startup just to read four fields.
// `dist` is in package.json#files, so this file travels inside `npm pack`
// output too: an installed CLI on a cloud agent can be identified without
// running it.
const path = require('path');
const fs = require('fs');
const distDir = path.join(__dirname, '..', 'dist');
if (fs.existsSync(distDir)) {
fs.writeFileSync(
path.join(distDir, 'build-info.json'),
JSON.stringify({ sha, branch, builtAt: time, dirty: dirty === '1' }, null, 2) + '\n',
);
}