From 4a96f875de58483924a83c5c3828160befb8f59a Mon Sep 17 00:00:00 2001 From: rgarcia <72655+rgarcia@users.noreply.github.com> Date: Fri, 12 Jun 2026 15:37:51 +0000 Subject: [PATCH 1/2] Set up npm release workflow for @onkernel/cua-cli --- .github/workflows/release-cua-cli.yml | 124 ++++++++++++++++++++++++++ docs/npm-releases.md | 57 +++++++++++- packages/cli/package.json | 16 ++++ 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/release-cua-cli.yml diff --git a/.github/workflows/release-cua-cli.yml b/.github/workflows/release-cua-cli.yml new file mode 100644 index 00000000..46de0c61 --- /dev/null +++ b/.github/workflows/release-cua-cli.yml @@ -0,0 +1,124 @@ +name: Release CUA CLI + +on: + push: + tags: + - "cua-cli/v*" + +permissions: + contents: read + id-token: write + +concurrency: + group: release-cua-cli-${{ github.ref_name }} + cancel-in-progress: false + +jobs: + publish: + runs-on: ubuntu-latest + timeout-minutes: 30 + env: + PTYWRIGHT_ZIG_VERSION: "0.15.2" + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Verify tag is on main + run: | + git fetch origin main:refs/remotes/origin/main + git merge-base --is-ancestor "$GITHUB_SHA" origin/main + + - uses: actions/setup-node@v5 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + + - name: Ensure npm supports trusted publishing + run: npm install -g npm@^11.5.1 + + - run: npm ci + + - name: Verify package version matches tag + run: | + node --input-type=module <<'EOF' + import { readFileSync } from "node:fs"; + + const tag = process.env.GITHUB_REF_NAME; + const prefix = "cua-cli/v"; + if (!tag?.startsWith(prefix)) { + throw new Error(`Expected tag to start with ${prefix}, got ${tag}`); + } + + const tagVersion = tag.slice(prefix.length); + const pkg = JSON.parse(readFileSync("packages/cli/package.json", "utf8")); + if (pkg.version !== tagVersion) { + throw new Error(`Tag version ${tagVersion} does not match ${pkg.name} package.json version ${pkg.version}`); + } + + console.log(`${pkg.name}@${pkg.version}`); + EOF + + - name: Cache Zig toolchain + uses: actions/cache@v4 + with: + path: .dev/tools/zig-x86_64-linux-${{ env.PTYWRIGHT_ZIG_VERSION }} + key: zig-${{ runner.os }}-${{ env.PTYWRIGHT_ZIG_VERSION }} + + - name: Install Zig ${{ env.PTYWRIGHT_ZIG_VERSION }} + run: | + set -euo pipefail + ZIG_DIR=".dev/tools/zig-x86_64-linux-${PTYWRIGHT_ZIG_VERSION}" + if [ ! -x "${ZIG_DIR}/zig" ]; then + mkdir -p .dev/tools + curl -fsSL "https://ziglang.org/download/${PTYWRIGHT_ZIG_VERSION}/zig-x86_64-linux-${PTYWRIGHT_ZIG_VERSION}.tar.xz" \ + | tar -xJ -C .dev/tools + fi + "${ZIG_DIR}/zig" version + echo "${GITHUB_WORKSPACE}/${ZIG_DIR}" >> "${GITHUB_PATH}" + + - name: Cache ptywright native artifacts + uses: actions/cache@v4 + with: + path: | + packages/ptywright/.cache + packages/ptywright/native/build + key: ptywright-${{ runner.os }}-${{ hashFiles('packages/ptywright/GHOSTTY_UPSTREAM', 'packages/ptywright/native/**', 'packages/ptywright/scripts/**') }} + + - run: npm run build --workspace @onkernel/cua-ai + - run: npm run build --workspace @onkernel/cua-agent + + - name: Build ptywright (native binding) + run: npm run build --workspace @onkernel/ptywright + + - name: Build cua-cli + run: npm run build --workspace @onkernel/cua-cli + + - name: Verify runtime dependencies are published + run: | + node -p 'require("./packages/cli/package.json").dependencies["@onkernel/cua-ai"]' \ + | xargs -I{} npm view @onkernel/cua-ai@{} version + node -p 'require("./packages/cli/package.json").dependencies["@onkernel/cua-agent"]' \ + | xargs -I{} npm view @onkernel/cua-agent@{} version + + - name: CLI unit tests + env: + PTYWRIGHT_REQUIRED: "1" + run: npm test --workspace @onkernel/cua-cli + + - name: Pack tarball + run: npm pack --workspace @onkernel/cua-cli --pack-destination "$RUNNER_TEMP" + + - name: CLI bin smoke test + run: | + SMOKE_DIR=$(mktemp -d) + cd "$SMOKE_DIR" + npm init -y > /dev/null + npm install "$RUNNER_TEMP"/onkernel-cua-cli-*.tgz + OUTPUT=$(./node_modules/.bin/cua --help) + echo "$OUTPUT" + echo "$OUTPUT" | grep -q "Usage:" + echo "$OUTPUT" | grep -q "cua \[options\] \[prompt\.\.\.\]" + + - name: Publish to npm + run: npm publish --workspace @onkernel/cua-cli --access public diff --git a/docs/npm-releases.md b/docs/npm-releases.md index 731d9134..b78880cb 100644 --- a/docs/npm-releases.md +++ b/docs/npm-releases.md @@ -1,9 +1,11 @@ # npm releases -`@onkernel/cua-ai` and `@onkernel/cua-agent` publish from package-specific tags: +`@onkernel/cua-ai`, `@onkernel/cua-agent`, and `@onkernel/cua-cli` publish from +package-specific tags: - `cua-ai/v0.1.0` runs `.github/workflows/release-cua-ai.yml` - `cua-agent/v0.1.0` runs `.github/workflows/release-cua-agent.yml` +- `cua-cli/v0.1.0` runs `.github/workflows/release-cua-cli.yml` The tag version must match the target package's `package.json` version, and the tagged commit must be contained in `main`. @@ -16,6 +18,7 @@ Configure each package on npm with a GitHub Actions trusted publisher: | --- | --- | --- | --- | --- | | `@onkernel/cua-ai` | `kernel` | `cua` | `release-cua-ai.yml` | leave blank | | `@onkernel/cua-agent` | `kernel` | `cua` | `release-cua-agent.yml` | leave blank | +| `@onkernel/cua-cli` | `kernel` | `cua` | `release-cua-cli.yml` | leave blank | The same configuration can be created from the npm CLI: @@ -23,6 +26,7 @@ The same configuration can be created from the npm CLI: npm install -g npm@^11.10.0 npm trust github @onkernel/cua-ai --repo kernel/cua --file release-cua-ai.yml npm trust github @onkernel/cua-agent --repo kernel/cua --file release-cua-agent.yml +npm trust github @onkernel/cua-cli --repo kernel/cua --file release-cua-cli.yml ``` npm requires packages to exist before a trusted publisher can be configured. If @@ -47,3 +51,54 @@ After `@onkernel/cua-ai@0.1.0` is available on npm: git tag cua-agent/v0.1.0 git push origin cua-agent/v0.1.0 ``` + +## Releasing `@onkernel/cua-cli` 0.1.0 + +`@onkernel/cua-cli` has not been published yet. npm requires a package to exist +before a trusted publisher can be configured for it, so the first release is a +manual publish from a local checkout. Subsequent releases come from +`cua-cli/v*` tags via `.github/workflows/release-cua-cli.yml`. + +The CLI's runtime dependencies (`@onkernel/cua-ai`, `@onkernel/cua-agent`, +`@onkernel/sdk`) must already be on npm at the pinned versions before +publishing; verify with `npm view @onkernel/cua-ai@` etc. if unsure. + +First-publish steps (run from a maintainer machine with an npm account in the +`onkernel` org and Zig available on `PATH` for the ptywright dev build): + +```sh +# 1. Fresh checkout of main +git clone https://github.com/kernel/cua.git +cd cua +git checkout main +git pull --ff-only + +# 2. Install and build the workspace (Node >= 22.19) +npm ci +npm run build + +# 3. Run cua-cli unit tests with the native ptywright binding required +PTYWRIGHT_REQUIRED=1 npm test --workspace @onkernel/cua-cli + +# 4. Log in to npm as a user in the onkernel org, then publish +npm login +npm publish --workspace @onkernel/cua-cli --access public +``` + +After `@onkernel/cua-cli@0.1.0` is on the registry, configure the trusted +publisher — either via the package page in the npm web UI (Settings → +Publishing access → Add trusted publisher) using the row from the +[trusted publishing setup](#trusted-publishing-setup) table, or from the CLI: + +```sh +npm install -g npm@^11.10.0 +npm trust github @onkernel/cua-cli --repo kernel/cua --file release-cua-cli.yml +``` + +From `0.1.1` onward, bump `packages/cli/package.json` on `main`, then tag and +push: + +```sh +git tag cua-cli/v0.1.1 +git push origin cua-cli/v0.1.1 +``` diff --git a/packages/cli/package.json b/packages/cli/package.json index dd0be2cb..061eeca4 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -2,9 +2,19 @@ "name": "@onkernel/cua-cli", "version": "0.1.0", "description": "Kernel-cloud-browser computer-use TUI built on @onkernel/cua-agent and pi-tui", + "license": "MIT", "type": "module", "main": "./dist/cli.js", "types": "./dist/cli.d.ts", + "repository": { + "type": "git", + "url": "git+https://github.com/kernel/cua.git", + "directory": "packages/cli" + }, + "bugs": { + "url": "https://github.com/kernel/cua/issues" + }, + "homepage": "https://github.com/kernel/cua/tree/main/packages/cli#readme", "bin": { "cua": "./dist/cli.js" }, @@ -12,6 +22,12 @@ "dist", "README.md" ], + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=22.19.0" + }, "scripts": { "build": "tsc -b && chmod +x dist/cli.js", "clean": "tsc -b --clean", From 62a47ed1127dcb757502558cc532741409bbebdb Mon Sep 17 00:00:00 2001 From: rgarcia <72655+rgarcia@users.noreply.github.com> Date: Fri, 12 Jun 2026 16:07:57 +0000 Subject: [PATCH 2/2] Address review for cua-cli release setup - docs: add pre-publish smoke test step (npm pack + install + cua --help) to the first-publish runbook, so a maintainer following it verbatim does not ship a broken 0.1.0 to npm. - docs: list @earendil-works/pi-coding-agent and @earendil-works/pi-tui alongside the @onkernel runtime deps that must already be published. - package-lock.json: bring the packages/cli entry in line with the packages/ai and packages/agent entries by adding license MIT and engines node >=22.19.0 to match the package.json metadata. --- docs/npm-releases.md | 21 +++++++++++++++++---- package-lock.json | 4 ++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docs/npm-releases.md b/docs/npm-releases.md index b78880cb..c4ae53a5 100644 --- a/docs/npm-releases.md +++ b/docs/npm-releases.md @@ -59,9 +59,11 @@ before a trusted publisher can be configured for it, so the first release is a manual publish from a local checkout. Subsequent releases come from `cua-cli/v*` tags via `.github/workflows/release-cua-cli.yml`. -The CLI's runtime dependencies (`@onkernel/cua-ai`, `@onkernel/cua-agent`, -`@onkernel/sdk`) must already be on npm at the pinned versions before -publishing; verify with `npm view @onkernel/cua-ai@` etc. if unsure. +The CLI's runtime dependencies, including `@onkernel/cua-ai`, +`@onkernel/cua-agent`, `@onkernel/sdk`, `@earendil-works/pi-coding-agent`, +and `@earendil-works/pi-tui`, must already be on npm at the pinned versions +before publishing; verify with `npm view @onkernel/cua-ai@` etc. if +unsure. First-publish steps (run from a maintainer machine with an npm account in the `onkernel` org and Zig available on `PATH` for the ptywright dev build): @@ -80,7 +82,18 @@ npm run build # 3. Run cua-cli unit tests with the native ptywright binding required PTYWRIGHT_REQUIRED=1 npm test --workspace @onkernel/cua-cli -# 4. Log in to npm as a user in the onkernel org, then publish +# 4. Pre-publish smoke test: pack the tarball, install it into a fresh temp +# project, and run the installed `cua` bin. Do NOT proceed to step 5 until +# this passes — published npm versions are immutable, and the tag-driven +# workflow runs this same check on subsequent releases. +PACK_DIR=$(mktemp -d) +npm pack --workspace @onkernel/cua-cli --pack-destination "$PACK_DIR" +SMOKE_DIR=$(mktemp -d) +(cd "$SMOKE_DIR" && npm init -y > /dev/null && \ + npm install "$PACK_DIR"/onkernel-cua-cli-*.tgz && \ + ./node_modules/.bin/cua --help) + +# 5. Log in to npm as a user in the onkernel org, then publish npm login npm publish --workspace @onkernel/cua-cli --access public ``` diff --git a/package-lock.json b/package-lock.json index dde11cad..60001b53 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6514,6 +6514,7 @@ "packages/cli": { "name": "@onkernel/cua-cli", "version": "0.1.0", + "license": "MIT", "dependencies": { "@earendil-works/pi-coding-agent": "0.79.1", "@earendil-works/pi-tui": "0.79.1", @@ -6527,6 +6528,9 @@ "devDependencies": { "@onkernel/ptywright": "0.1.0", "vitest": "^3.2.4" + }, + "engines": { + "node": ">=22.19.0" } }, "packages/ptywright": {