singularity-forge/scripts/copy-resources.cjs
Mikael Hugo d447095bd7 build: switch full build pipeline to TypeScript 7 native (tsgo)
Replace tsc with tsgo in all build scripts — 5.6x faster emit.
tsgo has full emit parity for this codebase (NodeNext, ES2022, strict).

- build:core: tsc → tsgo (root tsconfig.json)
- copy-resources.cjs: typescript/bin/tsc → @typescript/native-preview/bin/tsgo.js
- All workspace packages (agent-core, ai, coding-agent, daemon,
  google-gemini-cli-provider, native, rpc-client, tui): tsc → tsgo

Benchmarks (root project):
  tsc --project tsconfig.json: 7.7s
  tsgo --project tsconfig.json: 1.4s  (5.6x faster)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-10 11:58:58 +02:00

119 lines
3.2 KiB
JavaScript

#!/usr/bin/env node
const { spawnSync } = require("node:child_process");
const {
copyFileSync,
mkdirSync,
readFileSync,
readdirSync,
rmSync,
writeFileSync,
} = require("node:fs");
const { dirname, join, resolve } = require("node:path");
const root = resolve(__dirname, "..");
const srcResources = join(root, "src", "resources");
const distResources = join(root, "dist", "resources");
const resourcesTsconfig = join(root, "tsconfig.resources.json");
function copyNonTsFiles(srcDir, destDir) {
for (const entry of readdirSync(srcDir, { withFileTypes: true })) {
const srcPath = join(srcDir, entry.name);
const destPath = join(destDir, entry.name);
if (entry.isDirectory()) {
copyNonTsFiles(srcPath, destPath);
continue;
}
if (
entry.name.endsWith(".ts") ||
entry.name.endsWith(".tsx") ||
entry.name.endsWith(".js") ||
entry.name.endsWith(".jsx")
) {
continue;
}
mkdirSync(dirname(destPath), { recursive: true });
// Rewrite pi.extensions paths from .ts to .js in package.json files
// so they match the compiled output (tsc compiles index.ts → index.js
// but package.json is copied as-is).
if (entry.name === "package.json") {
try {
const pkg = JSON.parse(readFileSync(srcPath, "utf-8"));
if (Array.isArray(pkg?.pi?.extensions)) {
pkg.pi.extensions = pkg.pi.extensions.map((ext) =>
ext.replace(/\.ts$/, ".js").replace(/\.tsx$/, ".js"),
);
writeFileSync(destPath, JSON.stringify(pkg, null, 2) + "\n");
continue;
}
} catch {
/* fall through to plain copy */
}
}
copyFileSync(srcPath, destPath);
}
}
rmSync(distResources, { recursive: true, force: true });
// Check if there are any .ts files to compile
function hasTsFilesRecursive(dir) {
for (const entry of readdirSync(dir, { withFileTypes: true })) {
const fullPath = join(dir, entry.name);
if (entry.isDirectory()) {
if (hasTsFilesRecursive(fullPath)) return true;
} else if (entry.name.endsWith(".ts") && !entry.name.endsWith(".d.ts")) {
return true;
}
}
return false;
}
const hasTsFiles = hasTsFilesRecursive(srcResources);
if (hasTsFiles) {
const tsgoBin = require.resolve("@typescript/native-preview/bin/tsgo.js");
const compile = spawnSync(
process.execPath,
[tsgoBin, "--project", resourcesTsconfig],
{
cwd: root,
stdio: "inherit",
},
);
if (compile.status !== 0) {
process.exit(compile.status ?? 1);
}
} else {
// No .ts files — just create the dist/resources directory and copy .js files
mkdirSync(distResources, { recursive: true });
}
copyNonTsFiles(srcResources, distResources);
// Also copy .js files since they're not compiled from .ts
function copyJsFiles(srcDir, destDir) {
for (const entry of readdirSync(srcDir, { withFileTypes: true })) {
const srcPath = join(srcDir, entry.name);
const destPath = join(destDir, entry.name);
if (entry.isDirectory()) {
copyJsFiles(srcPath, destPath);
continue;
}
if (entry.name.endsWith(".js")) {
mkdirSync(dirname(destPath), { recursive: true });
copyFileSync(srcPath, destPath);
}
}
}
copyJsFiles(srcResources, distResources);
writeFileSync(
join(distResources, ".sf-resource-build-stamp"),
`${new Date().toISOString()}\n`,
);