Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 206 additions & 0 deletions .agents/skills/release/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
---
name: release
description: Prepare and publish @onkernel/cua-ai and @onkernel/cua-agent npm releases from kernel/cua. Use when checking release readiness, choosing package versions, writing package changelogs, committing release metadata to main, pushing package-prefixed tags, or monitoring release workflows.
---

# Release

Use this workflow to release `@onkernel/cua-ai` and `@onkernel/cua-agent`. The
packages do not need to release in lockstep.

If a release run hits an unexpected bump, unclear decision, missing command, or
avoidable manual step, update this skill as part of the release cleanup. Keep
the note concise and operational so the next release is faster and less
error-prone.

## Package Map

| package | directory | tag prefix | workflow |
| --- | --- | --- | --- |
| `@onkernel/cua-ai` | `packages/ai` | `cua-ai/v` | `release-cua-ai.yml` |
| `@onkernel/cua-agent` | `packages/agent` | `cua-agent/v` | `release-cua-agent.yml` |

Release `@onkernel/cua-ai` before `@onkernel/cua-agent` when both are changing
or when the agent package depends on the new AI package version.

## Quick Start

1. Sync `main` and tags:

```bash
git switch main
git pull --ff-only origin main
git fetch --tags origin
```

2. Check release readiness:

```bash
git status --short
npm view @onkernel/cua-ai versions --json
npm view @onkernel/cua-agent versions --json
test -f .github/workflows/release-cua-ai.yml
test -f .github/workflows/release-cua-agent.yml
```

3. For each package, find the previous release tag:

```bash
git tag --list "cua-ai/v*" --sort=-v:refname | head -1
git tag --list "cua-agent/v*" --sort=-v:refname | head -1
```

If no tag exists, treat the next release as the package's current
`package.json` version unless npm already has that version.

4. Inspect package-specific changes since the last tag:

```bash
git log --oneline <last-tag>..HEAD -- packages/ai package.json package-lock.json tsconfig.base.json
git diff --name-status <last-tag>..HEAD -- packages/ai package.json package-lock.json tsconfig.base.json

git log --oneline <last-tag>..HEAD -- packages/agent packages/ai package.json package-lock.json tsconfig.base.json
git diff --name-status <last-tag>..HEAD -- packages/agent packages/ai package.json package-lock.json tsconfig.base.json
```

For `@onkernel/cua-agent`, include `packages/ai` changes only when they affect
the published agent dependency or runtime behavior.

## Version Choice

Choose a version per package from source changes, existing npm versions, and the
previous tag:

- No package-relevant changes: do not release that package.
- Bug fixes, docs that affect package consumers, dependency metadata, or small
behavior fixes: patch.
- New exported APIs, new model/provider support, new examples intended for
consumers, or materially expanded behavior: minor.
- Breaking API or behavior changes: major. While packages are `0.x`, use a
minor bump for breaking changes unless the package is intentionally moving to
`1.0.0`.

The candidate version must be greater than both the last tag for that package
and every version returned by `npm view <package> versions --json`.

## Changelog

Update only the changelog for packages being released:

- `packages/ai/CHANGELOG.md`
- `packages/agent/CHANGELOG.md`

Add a new top entry:

```markdown
## <version> - YYYY-MM-DD

- ...
```

Write customer-facing changes. Do not dump commit subjects, internal issue
names, Slack context, or vague entries like "misc improvements." Group details
only when it improves readability. If the release is only metadata or docs,
say that plainly.

## Edit Release Metadata

Set versions explicitly:

```bash
npm pkg set version=<version> --workspace @onkernel/cua-ai
npm pkg set version=<version> --workspace @onkernel/cua-agent
```

When releasing `@onkernel/cua-agent`, ensure its `@onkernel/cua-ai` dependency
points at the intended published AI package version. Edit
`packages/agent/package.json` directly if `npm pkg set` is awkward for the
scoped dependency key.

Refresh the lockfile:

```bash
npm install --package-lock-only
```

## Validate

Run the checks for each package being released:

```bash
npm ci
npm run build --workspace @onkernel/cua-ai
npm test --workspace @onkernel/cua-ai -- test/api-keys.test.ts test/models.test.ts test/providers.test.ts test/runtime-spec.test.ts test/tools.test.ts test/yutori-payload.test.ts
npm pack --workspace @onkernel/cua-ai --dry-run
```

For `@onkernel/cua-agent`:

```bash
npm run build --workspace @onkernel/cua-ai
npm run build --workspace @onkernel/cua-agent
npm test --workspace @onkernel/cua-agent -- test/agent.test.ts test/tool-exhaustiveness.test.ts
npm pack --workspace @onkernel/cua-agent --dry-run
```

Do not push release tags if build, tests, or pack dry-runs fail.

## Commit To Main

Direct commits to `main` are acceptable for release metadata. Keep the commit
limited to package versions, changelogs, and `package-lock.json`.

```bash
git status --short
git add package-lock.json packages/ai/package.json packages/ai/CHANGELOG.md packages/agent/package.json packages/agent/CHANGELOG.md
git commit -m "Release CUA packages"
git push origin main
```

Use a package-specific commit message if releasing only one package, for
example `Release CUA AI v0.2.0`.

## Tag And Push

After the release commit is on `main`, create annotated package tags at that
commit:

```bash
git tag -a cua-ai/v<version> -m "@onkernel/cua-ai v<version>"
git push origin cua-ai/v<version>
```

For the agent package:

```bash
git tag -a cua-agent/v<version> -m "@onkernel/cua-agent v<version>"
git push origin cua-agent/v<version>
```

Push the AI tag first and wait for it to publish before pushing the agent tag
when the agent depends on that AI version.

## Monitor

Find and watch the workflow run triggered by each tag:

```bash
gh run list --workflow release-cua-ai.yml --json databaseId,status,conclusion,headBranch,displayTitle,url --limit 10
gh run watch <run-id> --exit-status

gh run list --workflow release-cua-agent.yml --json databaseId,status,conclusion,headBranch,displayTitle,url --limit 10
gh run watch <run-id> --exit-status
```

After a workflow succeeds, verify npm:

```bash
npm view @onkernel/cua-ai@<version> version
npm dist-tag ls @onkernel/cua-ai
npm view @onkernel/cua-agent@<version> version
npm dist-tag ls @onkernel/cua-agent
```

If a workflow fails after a tag is pushed, do not reuse the same package
version unless npm did not publish it. Fix forward with a new commit and a new
patch version when a package version has reached npm.
73 changes: 73 additions & 0 deletions .github/workflows/release-cua-agent.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Release CUA Agent

on:
push:
tags:
- "cua-agent/v*"

permissions:
contents: read
id-token: write

concurrency:
group: release-cua-agent-${{ github.ref_name }}
cancel-in-progress: false

jobs:
publish:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
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@v4
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-agent/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/agent/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

- run: npm run build --workspace @onkernel/cua-ai
- run: npm run build --workspace @onkernel/cua-agent

- name: Unit tests
run: npm test --workspace @onkernel/cua-agent -- test/agent.test.ts test/tool-exhaustiveness.test.ts

- name: Verify dependency package is published
run: npm view @onkernel/cua-ai@$(node -p 'require("./packages/agent/package.json").dependencies["@onkernel/cua-ai"]') version

- name: Pack dry run
run: npm pack --workspace @onkernel/cua-agent --dry-run

- name: Publish to npm
run: npm publish --workspace @onkernel/cua-agent --access public
76 changes: 76 additions & 0 deletions .github/workflows/release-cua-ai.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Release CUA AI

on:
push:
tags:
- "cua-ai/v*"

permissions:
contents: read
id-token: write

concurrency:
group: release-cua-ai-${{ github.ref_name }}
cancel-in-progress: false

jobs:
publish:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
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@v4
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-ai/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/ai/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

- run: npm run build --workspace @onkernel/cua-ai

- name: Unit tests
run: >
npm test --workspace @onkernel/cua-ai --
test/api-keys.test.ts
test/models.test.ts
test/providers.test.ts
test/runtime-spec.test.ts
test/tools.test.ts
test/yutori-payload.test.ts

- name: Pack dry run
run: npm pack --workspace @onkernel/cua-ai --dry-run

- name: Publish to npm
run: npm publish --workspace @onkernel/cua-ai --access public
Loading
Loading