Files
cassady/AGENTS.md
T
2026-06-26 13:59:54 -05:00

16 KiB

AGENTS.md

Release process: build artifacts and create a draft GitHub release

Use this process when preparing a Cassady (cass) release. Always create the GitHub release as a draft first; do not publish the final release unless the user explicitly asks.

1. Review prior releases for consistency

git fetch origin --tags
gh release list --repo owenqwenstarsky/cassady --limit 5
gh release view --repo owenqwenstarsky/cassady --json tagName,body --jq '.tagName + "\n\n" + .body'

Keep release notes consistent with the existing format:

  • Title: ## Cassady vX.Y.Z
  • One short summary paragraph.
  • ### Downloads with four bullets in this order: macOS Apple Silicon, Linux x86_64, Linux ARM64, Windows x86_64.
  • Note that each archive contains both cass and cassady; mention SHA-256 files.
  • ### Highlights with concise user-facing bullets.
  • Optional ### Upgrade notes only when compatibility, config, or migration details matter.
  • ### Install from source with a cargo install --git ... --tag vX.Y.Z command.
  • ### Verification listing the exact test/build commands used.

2. Confirm the version and starting state

git status --short
VERSION=$(awk -F\" '/^version = / { print $2; exit }' Cargo.toml)
TAG="v${VERSION}"
echo "$TAG"
git log --oneline --decorate -20

If the version is wrong, update Cargo.toml and Cargo.lock first, then commit that change before tagging. Release tags should point at the intended release commit on main.

3. Run verification before packaging

cargo +stable test --locked --all-targets

4. Build all release binaries

Prerequisites for cross-builds: stable Rust, cargo-zigbuild, Zig, and the needed Rust targets.

rustup target add aarch64-apple-darwin x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu x86_64-pc-windows-gnu
cargo install cargo-zigbuild --locked

Build the same four targets used by previous releases:

cargo +stable build --release --locked --target aarch64-apple-darwin
cargo +stable zigbuild --release --locked --target x86_64-unknown-linux-gnu
cargo +stable zigbuild --release --locked --target aarch64-unknown-linux-gnu
cargo +stable zigbuild --release --locked --target x86_64-pc-windows-gnu

5. Rebuild the dist/ artifacts

This creates the unpacked artifact directories, compressed archives, and checksum files for the current $TAG. Generate checksums from inside dist/ so the .sha256 files contain archive names without a dist/ prefix.

VERSION=$(awk -F\" '/^version = / { print $2; exit }' Cargo.toml)
TAG="v${VERSION}"

rm -rf \
  "dist/cassady-${TAG}-aarch64-apple-darwin"* \
  "dist/cassady-${TAG}-x86_64-unknown-linux-gnu"* \
  "dist/cassady-${TAG}-aarch64-unknown-linux-gnu"* \
  "dist/cassady-${TAG}-x86_64-pc-windows-gnu"*

mkdir -p dist

for target in aarch64-apple-darwin x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
  name="cassady-${TAG}-${target}"
  mkdir -p "dist/${name}"
  cp "target/${target}/release/cass" "dist/${name}/cass"
  cp "target/${target}/release/cassady" "dist/${name}/cassady"
  cp README.md "dist/${name}/README.md"
  tar -C dist -czf "dist/${name}.tar.gz" "${name}"
done

win_target=x86_64-pc-windows-gnu
win_name="cassady-${TAG}-${win_target}"
mkdir -p "dist/${win_name}"
cp "target/${win_target}/release/cass.exe" "dist/${win_name}/cass.exe"
cp "target/${win_target}/release/cassady.exe" "dist/${win_name}/cassady.exe"
cp README.md "dist/${win_name}/README.md"
(cd dist && zip -qr "${win_name}.zip" "${win_name}")

(cd dist && for artifact in cassady-${TAG}-*.tar.gz cassady-${TAG}-*.zip; do
  shasum -a 256 "$artifact" > "${artifact}.sha256"
done)

Sanity-check the generated artifacts:

ls -lh dist/cassady-${TAG}-*.tar.gz dist/cassady-${TAG}-*.zip dist/cassady-${TAG}-*.sha256
for sum in dist/cassady-${TAG}-*.sha256; do (cd dist && shasum -a 256 -c "$(basename "$sum")"); done
tar -tzf "dist/cassady-${TAG}-aarch64-apple-darwin.tar.gz" | head
unzip -l "dist/cassady-${TAG}-x86_64-pc-windows-gnu.zip" | head

6. Write the release notes

Create dist/RELEASE_NOTES_${TAG}.md using the same structure as prior releases. Use this template and replace the summary/highlights with the actual changes:

## Cassady vX.Y.Z

Cassady vX.Y.Z ...

### Downloads

- macOS Apple Silicon: `cassady-vX.Y.Z-aarch64-apple-darwin.tar.gz`
- Linux x86_64: `cassady-vX.Y.Z-x86_64-unknown-linux-gnu.tar.gz`
- Linux ARM64: `cassady-vX.Y.Z-aarch64-unknown-linux-gnu.tar.gz`
- Windows x86_64: `cassady-vX.Y.Z-x86_64-pc-windows-gnu.zip`

Each archive contains both `cass` and `cassady`. SHA-256 checksum files are included for every archive.

### Highlights

- ...

### Upgrade notes

...

### Install from source

```sh
cargo install --git https://github.com/owenqwenstarsky/cassady --tag vX.Y.Z
```

### Verification

Built and tested with:

```sh
cargo +stable test --locked --all-targets
cargo +stable build --release --locked --target aarch64-apple-darwin
cargo +stable zigbuild --release --locked --target x86_64-unknown-linux-gnu
cargo +stable zigbuild --release --locked --target aarch64-unknown-linux-gnu
cargo +stable zigbuild --release --locked --target x86_64-pc-windows-gnu
```

Check the notes before uploading:

sed -n '1,220p' "dist/RELEASE_NOTES_${TAG}.md"

7. Tag the release commit

Only tag after tests pass, artifacts are built, and release notes are ready.

git fetch origin --tags
git status --short  # should be clean except generated dist/ files
git tag -a "$TAG" -m "Cassady ${TAG}"
git push origin "$TAG"

If the tag already exists, stop and ask before deleting or moving it.

8. Create the GitHub release as a draft

Upload only the current version's archives and checksum files. Keep --draft and --verify-tag in the command.

gh release create "$TAG" \
  "dist/cassady-${TAG}-aarch64-apple-darwin.tar.gz" \
  "dist/cassady-${TAG}-aarch64-apple-darwin.tar.gz.sha256" \
  "dist/cassady-${TAG}-x86_64-unknown-linux-gnu.tar.gz" \
  "dist/cassady-${TAG}-x86_64-unknown-linux-gnu.tar.gz.sha256" \
  "dist/cassady-${TAG}-aarch64-unknown-linux-gnu.tar.gz" \
  "dist/cassady-${TAG}-aarch64-unknown-linux-gnu.tar.gz.sha256" \
  "dist/cassady-${TAG}-x86_64-pc-windows-gnu.zip" \
  "dist/cassady-${TAG}-x86_64-pc-windows-gnu.zip.sha256" \
  --repo owenqwenstarsky/cassady \
  --title "Cassady ${TAG}" \
  --notes-file "dist/RELEASE_NOTES_${TAG}.md" \
  --draft \
  --verify-tag

Verify the draft:

gh release view "$TAG" --repo owenqwenstarsky/cassady --json tagName,name,isDraft,isPrerelease,assets --jq .

Do not publish the draft or mark it as the final/latest release unless the user explicitly asks.

NPM package process: prepare and publish the CLI packages

Use this process when preparing Cassady for npm. The npm distribution is a tiny wrapper package plus platform-specific binary packages. Do not publish to npm unless the user explicitly asks; when they ask for a publish-ready setup, make sure the packages can be published with one command.

Package layout and names

The committed npm tooling generates packages under dist/npm/ from the current Rust version in Cargo.toml:

  • Wrapper package: cassady
    • Exposes both npm binaries: cass and cassady.
    • Depends on the platform packages through optionalDependencies at the exact same version.
  • Platform packages:
    • @cassady/cli-darwin-arm64 for aarch64-apple-darwin
    • @cassady/cli-linux-x64 for x86_64-unknown-linux-gnu
    • @cassady/cli-linux-arm64 for aarch64-unknown-linux-gnu
    • @cassady/cli-win32-x64 for x86_64-pc-windows-gnu

Before the first publish, make sure the npm account owns or has publish access to the cassady package name and the @cassady scope. If the npm package name or scope changes, update npm/scripts/lib/release-config.mjs and regenerate the packages. Scoped packages are published with --access public.

1. Build the release binaries first

The npm packages copy binaries from target/<target>/release/, so run the same verification and target builds used for the GitHub release first:

cargo +stable test --locked --all-targets
cargo +stable build --release --locked --target aarch64-apple-darwin
cargo +stable zigbuild --release --locked --target x86_64-unknown-linux-gnu
cargo +stable zigbuild --release --locked --target aarch64-unknown-linux-gnu
cargo +stable zigbuild --release --locked --target x86_64-pc-windows-gnu

2. Generate and verify the npm package directories

npm run npm:prepare
npm run npm:verify

npm:prepare rebuilds dist/npm/ for the current Cargo.toml version. npm:verify runs npm publish --dry-run for each generated package and does not publish anything.

3. Publish to npm when explicitly requested

The publish command prepares packages, checks npm auth, runs npm login if needed, checks whether each package version already exists, publishes platform packages first, publishes the wrapper last, and verifies that the published versions can be packed from npm. The existence/verification checks intentionally use npm pack --dry-run instead of npm view because npm registry metadata for newly-created scoped packages can briefly return 404 even after publish succeeds.

npm run npm:publish

Optional checks and controls:

npm run npm:publish -- --dry-run   # full publish flow without publishing
NPM_TAG=next npm run npm:publish    # publish under a non-latest dist-tag

If a version already exists, npm cannot overwrite it. Stop and ask before changing versions, deleting packages, or moving dist-tags.

Roadmap process: write a new release entry in ROADMAP.md

Use this process when planning a future Cassady release. Follow the existing newest-first format in ROADMAP.md so new entries look like prior releases.

1. Review the existing roadmap format

sed -n '1,220p' ROADMAP.md
ls plans

Current conventions:

  • Keep the # Cassady (Cass) Roadmap title at the top.
  • Add the newest release immediately below the title, above older releases.
  • Use headings like ## vX.Y.Z — Short Theme for planned releases.
  • Add ✅ Completed to the heading only after the release is actually complete.
  • Start with a short paragraph: This release focuses on ....
  • If there is a detailed plan, reference it with a sentence like: See plans/PLAN_FILE.md.
  • Group work under ### area headings such as Interactive Setup, Agent Control, or Safety and Reviewability.
  • Use checklist items: - [ ] for planned work, - [x] for completed work.
  • Write main tasks as bold, user-facing outcomes: **Add a first-run setup wizard.** ....
  • Use indented bullets for scope details, constraints, and explicit deferrals.

2. Decide the release scope

Before editing ROADMAP.md, identify:

  • Version number: vX.Y.Z.
  • Short theme: a concise release name after the em dash.
  • One-paragraph goal: what the release changes for users.
  • 2-4 major areas to group the work.
  • Concrete checklist tasks under each area.
  • Any intentionally deferred work, especially broad integrations or risky scope.
  • Optional plan file under plans/ if the release needs deeper implementation detail.

Prefer roadmap items that describe outcomes and acceptance criteria, not implementation minutiae. Keep them concise enough to scan.

3. Insert the new entry

Place the new release section directly under the top-level title:

# Cassady (Cass) Roadmap

## vX.Y.Z — Short Release Theme

This release focuses on ... See `plans/VX_Y_Z_SHORT_PLAN.md`.

### Area Name

- [ ] **User-facing task title.** Describe the outcome in one sentence.
  - Add key behavior or acceptance criteria.
  - Note constraints or non-goals.

- [ ] **Second task title.** Describe the next outcome.
  - Include compatibility, docs, tests, or safety requirements when relevant.

### Another Area

- [ ] **Another task title.** Describe the outcome.
  - Keep details specific and checkable.

## vPrevious — Existing Theme ✅ Completed

If there is no detailed plan file yet, omit the See ... sentence rather than linking to a nonexistent file.

4. Keep old entries stable

  • Do not reorder completed releases except to insert the new release at the top.
  • Do not rewrite old completed scopes unless correcting a clear error.
  • Use [x] only for work that has landed.
  • Add ✅ Completed only when the release has shipped or the user explicitly asks to mark it complete.
  • Keep wording consistent with earlier entries: concise headings, bold task names, and nested details.

5. Check the edit

sed -n '1,180p' ROADMAP.md
git diff -- ROADMAP.md

Plan process: write implementation plans in plans/

Use this process when creating or updating an implementation plan. All project plans belong in the plans/ directory; do not put new plan documents at the repository root.

1. Review previous plans first

ls plans
sed -n '1,240p' plans/V0_2_2_ONBOARDING_SETUP_WIZARD_PLAN.md
sed -n '1,220p' plans/V0_2_1_MESSAGE_RENDERING_POLISH_PLAN.md
sed -n '1,220p' plans/V0_2_1_COLLAPSED_TOOL_DENSITY_PLAN.md

Also read any plan that is directly related to the new work. For example, read plans/SECURITY_ACCESS_MODES_PLAN.md before planning access-control work, or plans/PROVIDER_MODEL_CONFIG_PLAN.md before planning provider/config changes.

2. Choose the plan filename

Write new plans under plans/ using uppercase snake-case names:

  • Release-scoped plan: plans/VX_Y_Z_SHORT_THEME_PLAN.md, e.g. plans/V0_2_3_CONTEXT_MANAGEMENT_PLAN.md.
  • Feature/follow-up plan: plans/FEATURE_OR_AREA_PLAN.md, e.g. plans/SECURITY_ACCESS_MODES_PLAN.md.
  • Follow-up to an existing release plan: include the version and specific topic, e.g. plans/V0_2_1_COLLAPSED_TOOL_DENSITY_PLAN.md.

Prefer one focused plan per coherent feature or release theme. Do not edit plans/PLAN.md for new release work; it is the historical MVP plan.

3. Match the existing plan structure

Most plans should use this shape, adapted to the task size:

# vX.Y.Z Short Theme Implementation Plan

## Goal

State the user-facing outcome in a short paragraph. If helpful, add a success statement.

## Scope

### In scope

- Concrete included work.
- Supported behavior and user-visible changes.

### Out of scope

- Explicit non-goals and deferred work.
- Integrations or risky scope that should not be pulled into this plan.

## Context or Current State

Describe the relevant files, modules, existing behavior, and constraints.

## Design Principles

1. Principle that guides tradeoffs.
2. Safety, compatibility, or UX constraint.
3. Simplicity or deferral rule.

## Design

Describe the proposed behavior and architecture. Include tables, examples, CLI output, JSON shapes, or module/type sketches when they make implementation clearer.

## Implementation Steps

1. First concrete code/docs step.
2. Next step.
3. Final integration step.

## Tests

- Specific unit/integration tests to add or update.
- Manual checks when automated tests are not enough.

## Documentation

- README, bundled docs, release notes, or roadmap updates required.

## Acceptance Criteria

- Checkable condition that proves the plan is done.
- `cargo fmt` and `cargo test --locked --all-targets` pass.

For small follow-ups, it is okay to use the shorter style from V0_2_1_COLLAPSED_TOOL_DENSITY_PLAN.md: Context, Goal, Scope, Design, Implementation Steps, and Acceptance Criteria.

4. Writing guidelines

  • Keep plans implementation-oriented but readable by a future agent.
  • Be explicit about in-scope vs out-of-scope work to prevent scope creep.
  • Mention exact files/modules when known, such as src/ui/render.rs or src/config.rs.
  • Include examples of expected CLI output, JSON, or UI text when behavior matters.
  • Add compatibility and migration notes when config, storage, provider behavior, or public commands change.
  • Add docs and tests sections for any user-facing change.
  • Prefer ordered implementation steps over vague tasks.
  • Do not mark roadmap items complete just because a plan was written.

5. Check the plan

sed -n '1,260p' plans/YOUR_PLAN_FILE.md
git diff -- plans/YOUR_PLAN_FILE.md ROADMAP.md

General project notes

  • This is a Rust project. Use cargo test --locked --all-targets before handing off code changes when practical.
  • Keep release notes user-facing and concise; avoid dumping raw commit logs.
  • dist/ contains generated release artifacts. Rebuild current-version files rather than editing archives by hand.