From 2c350e9db3cd0946f7c8884d67fd9839924598ab Mon Sep 17 00:00:00 2001 From: Jonathan Yang <14588641+Joilence@users.noreply.github.com> Date: Fri, 14 Aug 2026 21:47:00 +0200 Subject: [PATCH 1/3] build: run the build when installed from git `dist/` is gitignored and `main` points at `./dist/index.js`, so installing this package from a git URL produced a package whose entry point did not exist. npm installs devDependencies and runs `prepare` for git dependencies, and typescript is already a devDependency, so the build just needs to be wired to that lifecycle hook. Installing from the npm registry is unaffected: the published tarball already ships `dist/`, and `prepare` does not run for registry installs of a packed tarball. --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index eee8626..f9ae3bc 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "scripts": { "build": "tsc && npm run copy-assets", "copy-assets": "mkdir -p dist/transitions/shaders && cp src/transitions/shaders/*.glsl dist/transitions/shaders/", + "prepare": "npm run build", "test": "vitest run", "test:watch": "vitest" }, From d6119e01501fb8262a62ffa023ca0826c26f12ee Mon Sep 17 00:00:00 2001 From: Shreyas Karnik Date: Sat, 29 Aug 2026 21:12:19 -0700 Subject: [PATCH 2/3] build: make copy-assets cross-platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `prepare` runs `build`, and `build` chained a POSIX-only `copy-assets`: mkdir -p dist/transitions/shaders && cp src/transitions/shaders/*.glsl ... npm runs lifecycle scripts through cmd.exe on Windows, where `cp` does not exist and `mkdir -p` creates a directory literally named `-p`. Before this PR that only broke an explicit `npm run build`; with `prepare` it breaks plain `npm install` too — including the very command this PR exists to fix, `npm i git+https://github.com/shreyaskarnik/argo`, which would now fail during prepare rather than at runtime. The README documents Windows (choco install ffmpeg) and every CI job is ubuntu-latest, so nothing here would have caught it. A script file rather than an inline `node -e`, because quoting is the same hazard one level down: cmd.exe and sh disagree about nested quotes, which is what made the original break. It copies only *.glsl. A recursive directory copy — the obvious one-liner — also drags index.ts and a README into dist/, which the old glob did not. Verified: build emits 5 shaders, `npm pack` carries all 5, `npm run prepare` reproduces them from a clean dist/, 774 tests pass. --- package.json | 2 +- scripts/copy-assets.mjs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 scripts/copy-assets.mjs diff --git a/package.json b/package.json index f9ae3bc..d483893 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "scripts": { "build": "tsc && npm run copy-assets", - "copy-assets": "mkdir -p dist/transitions/shaders && cp src/transitions/shaders/*.glsl dist/transitions/shaders/", + "copy-assets": "node scripts/copy-assets.mjs", "prepare": "npm run build", "test": "vitest run", "test:watch": "vitest" diff --git a/scripts/copy-assets.mjs b/scripts/copy-assets.mjs new file mode 100644 index 0000000..bd251b0 --- /dev/null +++ b/scripts/copy-assets.mjs @@ -0,0 +1,30 @@ +#!/usr/bin/env node +/** + * Copy the GLSL shader sources into dist/. + * + * `tsc` only emits what it compiles, so the .glsl files shader-render reads at + * runtime have to be copied separately. + * + * This is a script rather than an inline npm command because `prepare` runs it + * on every install, including on Windows, where npm invokes lifecycle scripts + * through cmd.exe. The previous `mkdir -p ... && cp src/**\/*.glsl` is + * POSIX-only: cmd.exe has no `cp`, and `mkdir -p` there creates a directory + * literally named `-p`. An inline `node -e` would work but reintroduces the + * same hazard one level down, since quoting differs between cmd.exe and sh. + */ +import { mkdirSync, readdirSync, copyFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; + +const root = dirname(dirname(fileURLToPath(import.meta.url))); +const from = join(root, 'src', 'transitions', 'shaders'); +const to = join(root, 'dist', 'transitions', 'shaders'); + +mkdirSync(to, { recursive: true }); + +// Only .glsl — the directory also holds index.ts and a README, which tsc +// handles or which do not belong in dist at all. +const shaders = readdirSync(from).filter(name => name.endsWith('.glsl')); +for (const name of shaders) copyFileSync(join(from, name), join(to, name)); + +console.log(`copy-assets: ${shaders.length} shaders -> dist/transitions/shaders`); From 5d4532047b099089a561998ad48d728a19fb4067 Mon Sep 17 00:00:00 2001 From: Shreyas Karnik Date: Sat, 29 Aug 2026 21:17:07 -0700 Subject: [PATCH 3/3] build: keep copy-assets output off stdout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `prepare` makes copy-assets run inside `npm pack`, and the pack-smoke job captures that command's stdout as the tarball filename: echo "TARBALL=$(pwd)/$(npm pack --silent)" >> "$GITHUB_ENV" The progress line landed on stdout, so the capture became two lines and the step failed with: ##[error]Invalid format 'argo-video-cli-0.39.1.tgz' stderr keeps the build feedback without contaminating a stream something else parses. `--silent` suppresses npm's own output, not a lifecycle script's, so any future addition to this path has the same constraint. Worth noting the pack-smoke job caught this on its first real outing — the failure only exists once `prepare` is wired, which is what that job is for. --- scripts/copy-assets.mjs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/copy-assets.mjs b/scripts/copy-assets.mjs index bd251b0..93bf7e2 100644 --- a/scripts/copy-assets.mjs +++ b/scripts/copy-assets.mjs @@ -27,4 +27,7 @@ mkdirSync(to, { recursive: true }); const shaders = readdirSync(from).filter(name => name.endsWith('.glsl')); for (const name of shaders) copyFileSync(join(from, name), join(to, name)); -console.log(`copy-assets: ${shaders.length} shaders -> dist/transitions/shaders`); +// stderr, not stdout: `prepare` makes this run inside `npm pack --silent`, +// whose stdout is captured as the tarball filename (see the pack-smoke job's +// TARBALL=$(npm pack --silent)). A line on stdout here corrupts that capture. +console.error(`copy-assets: ${shaders.length} shaders -> dist/transitions/shaders`);