Skip to main content

release-agent

Release Happy Agent from this repository. Use when asked to "release", "release the agent", "cut a release", or to publish a new version. Covers version selection, building the release notes, dispatching the workflow correctly, and verifying the published result.

Source facts

Repository
slopus/happy-agent
Last source activity
October 27, 2026 at 08:19
Detected SKILL.md language
English
Stars
36
Forks
24

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
release-agent
description
Release Happy Agent from this repository. Use when asked to "release", "release the agent", "cut a release", or to publish a new version. Covers version selection, building the release notes, dispatching the workflow correctly, and verifying the published result.
# Releasing Happy Agent Releases go out through GitHub Actions using trusted publishing. Never publish from local npm credentials, and never create or push a release tag by hand — the workflow creates the tag, and it only does so after the build and publication have succeeded. The [release master plan](../../../master-plans/25-releases.md#coordinating-requested-releases) coordinates Agent, Desktop native, and hosted renderer releases. Preserve the user's authorized scope across handoffs under the runtime's trusted authorization policy. Do not re-ask preemptively for authorized work. If the runtime denies an action, stop it, explain the denial, and follow its rules for fresh approval. Publish and verify changed SDKs before updating consumers, then prepare and dispatch independent products in parallel once their dependencies are ready. Wait only at actual dependency gates, and verify every requested product before reporting completion. ## Which product, which version An unqualified "release" means **a Happy Agent preview**. Production must be explicit. Neither means a library unless that library is named. Before choosing production, check that the user explicitly requested a production or stable release for this product in the current task. A request to "release", "ship", or push is not production authorization; default to preview. An existing explicit request is sufficient: do not ask for redundant confirmation. Use the candidate ourselves in the affected workflows for at least a brief soak before releasing it to production. Passing tests or CI alone does not count as that use. If the candidate has not been used, keep it in preview and explain what still needs to be tried. No fixed soak duration or previously published preview is required. | Request | Product | Version | | -------------------- | ------------ | ------------------------------------ | | "release" | Happy Agent | next patch followed by `-preview.N` | | "release production" | Happy Agent | next stable patch; no preview needed | | "release stable" | Happy Agent | same as production | | a named library | that library | next patch | Read Agent versions from GitHub releases/tags, not its npm package or source manifest. Use npm for libraries. Fetch tags before choosing an unused version: ```bash gh release list --limit 30 gh api repos/slopus/happy-agent/releases/latest --jq .tag_name git tag --list 'v[0-9]*' --sort=-v:refname | head -10 # Happy Agent ``` For stable `X.Y.Z`, use the next patch after the latest stable Agent release. For previews, append the next unused `-preview.N` (start at 1). Example: `0.4.67-preview.1`. No package manifest bump or SDK publication is required just to assign this binary identity. Existing pinned SDK dependencies must still resolve. Never reuse or move a failed tag; advance the preview number or stable patch as appropriate. A push never publishes a preview. ## Before dispatching 1. **Be on current `origin/main`.** The workflow refuses to run unless `HEAD` equals `origin/main` and the ref is `refs/heads/main`. Fetch and rebase first. The release's [update card file](#writing-the-update-card-file) must already be on `main`. 2. **Reinstall after any rebase.** A rebase that moves a published SDK dependency leaves `node_modules` stale, and the failure shows up as unrelated type errors: ```bash CI=true pnpm install --frozen-lockfile ``` 3. **Run the tests on Node 24.** The repo targets Node 24; a newer Node produces failures that are artifacts of the Node version rather than real: ```bash export PATH="/opt/homebrew/opt/node@24/bin:$PATH" pnpm test ``` The gym is a separate suite with its own failure modes. Gym failures do not necessarily block a release, but establish whether they are pre-existing before deciding — build a worktree at the commit before yours and reproduce there. ## Counting what is in the release Count commits against the **product and channel's own last release**, not the last tag of any kind. For the first preview of a stable target, start from the latest stable release; production notes include everything since the previous stable, including previewed changes: ```bash git log --format='%h %s' v0.3.17..origin/main ``` Do not scope this count to the product's package directory. Happy Agent ships the modules and providers packages, so a change in `packages/happy-agent-modules` is in the release even though it never touches `packages/happy-agent`. Reporting the directory-scoped count as the total understates the release — verify the number you quote by running the unscoped command above. Read the commit bodies, not just the subjects. The bodies explain what actually broke and what the user will notice: ```bash git log --format='%h%n%s%n%b%n---' v0.3.17..origin/main ``` ## Writing the notes The notes are user-facing Markdown. Write for someone who uses the product and does not read the repository. - Explain what was wrong and what is different now. Never paste commit subjects or a raw changelog. - Group by what the person experiences, under `##` headings, not by package or commit order. - Say plainly what a bug did to them — "every restart drained forever waiting on an agent you could not see" is worth more than "fixed daemon drain". - Leave out internal mechanics they cannot observe: transaction boundaries, module structure, lifetimes, test scaffolding. Write the notes to a file under `.context/`, which is scratch and gitignored: ```bash .context/release-notes.md ``` ## Writing the update card file Every Agent release, preview and production alike, also gets a very short file at `release-notes/<tag>.md`, for example `release-notes/v0.4.106.md` or `release-notes/v0.4.106-preview.5.md`. Happy Desktop's update card reads it from `main` and lists the bullets of every release between the installed version and the new one, newest first, without rewriting them. It is an extra artifact; keep writing the full notes above for the GitHub Release. ```md ## Features - Sidebar sorts work by topic - New work appears instantly ## Fixes - Reliable task and bot names ``` - Cover the same range as the full notes: a preview covers only what changed since the previous release on its channel, so previews are more detailed; production covers everything since the previous stable. - Write two or three bullets in total for most releases, and never more than three per section. Pick what a person would notice; leave out internal work entirely. - Each bullet is three to six plain words, ideally three, with no Markdown, links, code, or trailing period. - Label experimental or off-by-default features with `(Beta)` in the bullet. The website changelog at `https://happy.engineering/changelog/` contains production releases only, newest first; previews use these files and GitHub Release notes. Coordinate production feature entries and their dedicated share pages with the website owner. - New capabilities go under `## Features`; things that stopped going wrong go under `## Fixes`. The card shows features first and fixes behind a tab. Omit a section with nothing in it. Check it, then commit it on its own and push that commit to `main` as part of the requested release — the workflow only runs from the current `origin/main`, and it fails before building when the file is missing or invalid: ```bash node scripts/release/validateReleaseNotes.ts v0.4.67-preview.1 git add release-notes/v0.4.67-preview.1.md git commit -m "Add release notes for v0.4.67-preview.1" git push origin HEAD:main ``` If `main` moved, rebase and push again without force. ## Dispatching **`gh` needs `@` to read a file into a workflow input.** Without it the literal path string is submitted as the release body, the workflow succeeds, and the published release reads `.context/release-notes-0.3.18.md` instead of the notes. The workflow's blank-notes check does not catch this, because a path is not blank. ```bash # Preview example — use the version you selected, not this literal example gh workflow run release-happy-agent.yml --ref main \ -f version=0.4.67-preview.1 -F prerelease=true \ -F release_notes=@.context/release-notes.md ``` `-f` is a literal string; `-F` reads a file only when the value begins with `@`. For short single-line values `-f` is fine. Immediately before a production dispatch, verify both the explicit user request for this product and our actual use of this candidate. Only then supply the stable version and `-F prerelease=false`. CI builds, tests, signs, and publishes the same artifacts within one workflow run. Do not introduce a separate prepare/publish dispatch or bump commit between those jobs. Source verification and platform builds overlap after release-input validation; publication still waits for all gates. Retries reuse verified unsigned native outputs when all native inputs match; native checks and final binary tests, signing, and notarization still run for each release. ## Verifying Watch the run to completion, then **read back the published body** — this is the step that catches the `@` mistake: ```bash gh run watch <run-id> --exit-status gh release view v0.4.67-preview.1 --json body -q .body ``` The body must be the notes. If it is a file path, repair it in place — the artifacts are fine, only the body is wrong, so there is no need to re-release: ```bash gh release edit v0.4.67-preview.1 --notes-file .context/release-notes.md ``` Confirm the update card can read the short file: ```bash curl -fsS https://raw.githubusercontent.com/slopus/happy-agent/main/release-notes/v0.4.67-preview.1.md ``` Then confirm the rest: ```bash # Happy Agent: four platform archives plus a .sha256 for each; never a draft gh release view v0.4.67-preview.1 --json tagName,isDraft,isPrerelease,assets \ -q '"tag=\(.tagName) draft=\(.isDraft) pre=\(.isPrerelease)", (.assets[] | .name)' ``` Use your actual tag in each command. Verify preview releases have `isPrerelease=true` and leave GitHub's latest stable unchanged; production has `isPrerelease=false` and becomes latest. Download assets with `gh release download <tag> --dir <scratch-directory>` and run `shasum -a 256 -c <archive>.sha256` there for each archive. On a supported host, extract its archive and check the binary's `--version`; do not start the daemon. Nightly accepts supported Agent previews; standard Desktop must not offer them. No app or daemon restart is implied by a release request. ## After the release Report the version, where it was published, and anything you knowingly left unfixed. If tests failed or a suite was skipped, say so with the output rather than reporting a clean release. ## Sandbox notes Several Git operations need to write inside `.git` and are refused by the workspace sandbox — `fetch` writing `FETCH_HEAD`, `checkout` and `rebase` taking `index.lock`. Request reviewed full-access execution for those specific commands. Do not work around a refusal by another route, and be careful pairing a blocked Git command with a destructive one in the same shell line: if the Git command is refused, the second command still runs. On macOS, Git commands print `xcodebuild` and `confstr` noise from the sandbox. It is harmless; filter it when it obscures real output.
View on GitHub