From ea22df0b3802823f103d69e0404304e8eeaa766e Mon Sep 17 00:00:00 2001 From: David Wu Date: Sat, 16 May 2026 15:15:08 +0900 Subject: [PATCH] fix publish scope rewrite for dist output --- .changeset/fix-publish-dist-scope.md | 17 +++ scripts/publish.mjs | 150 +++++++++++++++++++-------- 2 files changed, 123 insertions(+), 44 deletions(-) create mode 100644 .changeset/fix-publish-dist-scope.md diff --git a/.changeset/fix-publish-dist-scope.md b/.changeset/fix-publish-dist-scope.md new file mode 100644 index 0000000..e853796 --- /dev/null +++ b/.changeset/fix-publish-dist-scope.md @@ -0,0 +1,17 @@ +--- +'@agentscript/agentfabric-dialect': patch +'@agentscript/agentforce': patch +'@agentscript/agentforce-dialect': patch +'@agentscript/agentscript-dialect': patch +'@agentscript/compiler': patch +'@agentscript/language': patch +'@agentscript/lsp': patch +'@agentscript/lsp-browser': patch +'@agentscript/lsp-server': patch +'@agentscript/monaco': patch +'@agentscript/parser': patch +'@agentscript/parser-javascript': patch +'@agentscript/parser-tree-sitter': patch +--- + +Rewrite built dist imports to the published `@sf-agentscript/*` scope during release. diff --git a/scripts/publish.mjs b/scripts/publish.mjs index 52292e9..19ee21e 100644 --- a/scripts/publish.mjs +++ b/scripts/publish.mjs @@ -1,62 +1,124 @@ /** * Publish script for CI: rewrites @agentscript/* → @sf-agentscript/* in all - * package.json files at publish time, then runs changeset publish. + * package.json files and built dist files at publish time, then runs + * changeset publish. * * This allows the codebase to use @agentscript/* internally while publishing * under the @sf-agentscript npm scope. */ import { execFileSync } from 'node:child_process'; -import { readFileSync, writeFileSync } from 'node:fs'; +import { existsSync, readFileSync, readdirSync, writeFileSync } from 'node:fs'; import { join } from 'node:path'; +import { fileURLToPath, pathToFileURL } from 'node:url'; -const ROOT = new URL('..', import.meta.url).pathname; +const ROOT = fileURLToPath(new URL('..', import.meta.url)); const INTERNAL_SCOPE = '@agentscript/'; const PUBLISH_SCOPE = '@sf-agentscript/'; +const DIST_FILE_SUFFIXES = [ + '.js', + '.mjs', + '.cjs', + '.d.ts', + '.d.mts', + '.d.cts', + '.map', +]; -// Step 1: Discover all workspace packages -const output = execFileSync('pnpm', ['-r', 'list', '--json', '--depth', '-1'], { - cwd: ROOT, - encoding: 'utf8', -}); -const packages = JSON.parse(output); - -// Step 2: Rewrite package.json files to publish scope -let count = 0; -for (const pkg of packages) { - const pkgJsonPath = join(pkg.path, 'package.json'); - const raw = readFileSync(pkgJsonPath, 'utf8'); +export function shouldRewriteDistFile(fileName) { + return DIST_FILE_SUFFIXES.some(suffix => fileName.endsWith(suffix)); +} + +function rewriteScopeInFile(filePath) { + const raw = readFileSync(filePath, 'utf8'); const rewritten = raw.replaceAll(INTERNAL_SCOPE, PUBLISH_SCOPE); - if (rewritten !== raw) { - writeFileSync(pkgJsonPath, rewritten); - count++; - console.log( - ` ✓ ${pkg.name} → ${pkg.name.replace(INTERNAL_SCOPE, PUBLISH_SCOPE)}` - ); + if (rewritten === raw) { + return false; + } + + writeFileSync(filePath, rewritten); + return true; +} + +export function rewriteDistFiles(directory) { + if (!existsSync(directory)) { + return 0; + } + + let count = 0; + for (const entry of readdirSync(directory, { withFileTypes: true })) { + const entryPath = join(directory, entry.name); + + if (entry.isDirectory()) { + count += rewriteDistFiles(entryPath); + } else if (entry.isFile() && shouldRewriteDistFile(entry.name)) { + count += rewriteScopeInFile(entryPath) ? 1 : 0; + } + } + + return count; +} + +function main() { + // Step 1: Discover all workspace packages + const output = execFileSync( + 'pnpm', + ['-r', 'list', '--json', '--depth', '-1'], + { + cwd: ROOT, + encoding: 'utf8', + } + ); + const packages = JSON.parse(output); + + // Step 2: Rewrite package.json files to publish scope + let packageJsonCount = 0; + for (const pkg of packages) { + const pkgJsonPath = join(pkg.path, 'package.json'); + + if (rewriteScopeInFile(pkgJsonPath)) { + packageJsonCount++; + console.log( + ` ✓ ${pkg.name} → ${pkg.name.replace(INTERNAL_SCOPE, PUBLISH_SCOPE)}` + ); + } } + + // Step 3: Rewrite changeset config so it recognizes the new package names + const changesetConfigPath = join(ROOT, '.changeset', 'config.json'); + const changesetRaw = readFileSync(changesetConfigPath, 'utf8'); + writeFileSync( + changesetConfigPath, + changesetRaw.replaceAll(INTERNAL_SCOPE, PUBLISH_SCOPE) + ); + + // Step 4: Rewrite built package outputs to publish scope + let distFileCount = 0; + for (const pkg of packages) { + distFileCount += rewriteDistFiles(join(pkg.path, 'dist')); + } + + console.log( + `\nRewrote ${packageJsonCount} package.json files and ${distFileCount} dist files to ${PUBLISH_SCOPE}* scope\n` + ); + + // Step 5: Re-install so pnpm resolves workspace: references with new names + execFileSync('pnpm', ['install', '--no-frozen-lockfile'], { + cwd: ROOT, + stdio: 'inherit', + }); + + // Step 6: Publish via changeset + execFileSync('pnpm', ['changeset', 'publish'], { + cwd: ROOT, + stdio: 'inherit', + }); } -// Step 3: Rewrite changeset config so it recognizes the new package names -const changesetConfigPath = join(ROOT, '.changeset', 'config.json'); -const changesetRaw = readFileSync(changesetConfigPath, 'utf8'); -writeFileSync( - changesetConfigPath, - changesetRaw.replaceAll(INTERNAL_SCOPE, PUBLISH_SCOPE) -); - -console.log( - `\nRewrote ${count} package.json files to ${PUBLISH_SCOPE}* scope\n` -); - -// Step 4: Re-install so pnpm resolves workspace: references with new names -execFileSync('pnpm', ['install', '--no-frozen-lockfile'], { - cwd: ROOT, - stdio: 'inherit', -}); - -// Step 5: Publish via changeset -execFileSync('pnpm', ['changeset', 'publish'], { - cwd: ROOT, - stdio: 'inherit', -}); +if ( + process.argv[1] && + import.meta.url === pathToFileURL(process.argv[1]).href +) { + main(); +}