Skip to content
Closed
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
35 changes: 24 additions & 11 deletions .claude/skills/release/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ argument-hint: [version]

# Release txcript

Publishes the `txcript` library to crates.io and the WASM package to npm via
the tag-triggered `publish-crates` and `publish-npm` workflows. Three releases
(v0.1.0–v0.3.0) established this procedure; follow it in order. A crates.io
Publishes the `txcript` library to crates.io, the WASM package to npm, and a
GitHub Release with notes, via the tag-triggered `publish-crates`,
`publish-npm`, and `release` workflows. Three releases (v0.1.0–v0.3.0)
established this procedure; follow it in order. A crates.io
version is **permanent** — it can be yanked but never deleted or reused — so
every gate runs before the tag exists.

Expand Down Expand Up @@ -46,29 +47,41 @@ irreversible decision.
v0.5.0; the npm workflow guards tag-vs-`package.json`, so drift there is a
dispatch-time failure, not a tag-time one. `cargo check` once so
`Cargo.lock` picks up the bump; commit the lockfile with the manifests.
2. Commit the bump, push, and confirm CI is green on that commit before
tagging.
3. Annotated tag matching the manifest exactly:
2. Update `CHANGELOG.md`: rename the `## [Unreleased]` section to
`## [X.Y.Z] - YYYY-MM-DD`, open a fresh empty `## [Unreleased]` above it,
and add the `[X.Y.Z]: …/compare/v<prev>...vX.Y.Z` link at the bottom
(repoint `[Unreleased]` at the new tag). Every user-visible change since
the last tag must be under Added/Changed/Fixed/Removed. The `release`
workflow takes the GitHub Release notes from this section and **fails the
tag** when the section is missing, so check it locally first:
`.github/scripts/release-notes.sh X.Y.Z`.
3. Commit the bump and changelog together, push, and confirm CI is green on
that commit before tagging.
4. Annotated tag matching the manifest exactly:
`git tag -a v<X.Y.Z> -m "v<X.Y.Z>" && git push origin v<X.Y.Z>`.
The workflow's first step compares `${GITHUB_REF_NAME#v}` against the
manifest and hard-fails on mismatch.

## Watch and verify

1. The tag push fires **two** workflows: `publish-crates` (cargo, with
`cargo publish --locked -p txcript` — only the library ships) and
1. The tag push fires **three** workflows: `publish-crates` (cargo, with
`cargo publish --locked -p txcript` — only the library ships),
`publish-npm` (builds the WASM bundle and publishes via OIDC trusted
publishing — no token, npm trusts this repo + workflow filename as of
v0.5.0). Watch both runs (`gh run watch` in the background).
v0.5.0), and `release` (creates the GitHub Release with the changelog
section as notes). Watch all three runs (`gh run watch` in the
background).
2. Verify crates.io: `cargo search txcript` or fetch
`https://crates.io/api/v1/crates/txcript` and check `max_version`.
3. Verify npm: `npm view txcript version`. If the npm run failed on its
version guard, `package.json` missed the bump (step 1 of Bump and tag);
fix the manifest, then re-dispatch on the tag is not possible — the tag
must carry the right `package.json`, so a failed guard means cutting a
patch release with the manifest fixed.
4. Verify the release: `gh release view vX.Y.Z` shows the changelog notes and
the crates.io / npm / docs.rs links.

## Report

State the published version, both workflow run URLs, and the crates.io and
npm verification results.
State the published version, the three workflow run URLs, the GitHub Release
URL, and the crates.io and npm verification results.
26 changes: 26 additions & 0 deletions .github/scripts/release-notes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env sh
# Print the CHANGELOG.md section for one version, followed by links to the
# published packages. Usage: release-notes.sh 0.12.1 > notes.md
# Exits 1 when the version has no section, so a tag without changelog
# coverage fails the release job instead of shipping empty notes.
set -eu
ver="$1"
section="$(awk -v ver="$ver" '
/^## \[/ { inside = ($0 ~ "^## \\[" ver "\\]") ; next }
inside && /^\[/ { next }
inside { print }
' CHANGELOG.md)"
# Trim leading/trailing blank lines.
section="$(printf '%s\n' "$section" | sed -e '/./,$!d' | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}')"
if [ -z "$section" ]; then
echo "::error::CHANGELOG.md has no section for $ver" >&2
exit 1
fi
printf '%s\n\n' "$section"
cat <<NOTES
---

- crates.io: https://crates.io/crates/txcript/$ver
- npm: https://www.npmjs.com/package/txcript/v/$ver
- docs.rs: https://docs.rs/txcript/$ver
NOTES
37 changes: 37 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: release

# Creates the GitHub Release for a version tag, with notes taken from the
# matching CHANGELOG.md section. Runs alongside publish-crates and
# publish-npm on the same tag push. A tag whose version has no changelog
# section fails here, so every release ships with notes.
on:
push:
tags:
- "v*"

permissions:
contents: write

jobs:
github-release:
name: Create GitHub Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Tag matches Cargo.toml version
run: |
tag="${GITHUB_REF_NAME#v}"
ver="$(grep -m1 '^version = ' Cargo.toml | sed -E 's/version = "(.*)"/\1/')"
echo "tag=$tag manifest=$ver"
[ "$tag" = "$ver" ] || { echo "::error::tag $tag != Cargo.toml version $ver"; exit 1; }
- name: Release notes from CHANGELOG.md
run: .github/scripts/release-notes.sh "${GITHUB_REF_NAME#v}" > notes.md
- name: Create release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "$GITHUB_REF_NAME" \
--repo "$GITHUB_REPOSITORY" \
--verify-tag \
--title "$GITHUB_REF_NAME" \
--notes-file notes.md
225 changes: 225 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
# Changelog

All notable changes to txcript are recorded here. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Each release is published to [crates.io](https://crates.io/crates/txcript),
[npm](https://www.npmjs.com/package/txcript), and
[GitHub Releases](https://github.com/skillsynchq/txcript/releases).

## [Unreleased]

### Added

- `txcript resume` as an alias for `txcript continue`.
- Interactive context cropping: trim a session to the part worth carrying
over before handing it to the next harness.

### Fixed

- MCP tool schemas no longer carry non-standard format annotations that some
clients reject.
- Artifact search origin is derived from the message role, so search results
point at the right side of the conversation.

## [0.12.1] - 2026-09-01

### Changed

- Search patterns match literally instead of fuzzily.
- Discovery is cheaper, and the picker's echo stays off the search path.
- Cursor Desktop discovery and loads scale with the session instead of the
whole database.

## [0.12.0] - 2026-08-25

### Added

- ChatGPT as a live, pull-only harness: list and continue ChatGPT
conversations in a local harness.

## [0.11.0] - 2026-08-24

### Added

- fx (Vercel's coding agent) harness.
- `txcript view` draws images inline on kitty-graphics terminals and ships a
built-in pager with controls over what it shows.
- Claude Chat sessions load directly by UUID.

### Changed

- `view` output is tuned for terminals.

### Fixed

- Terminal query helpers are gated to unix.

## [0.10.0] - 2026-08-21

### Added

- Claude Chat as a live, pull-only harness, off by default and reachable only
through an explicit `--from`.
- `txcript export` for moving sessions between machines.
- `txcript init` installs the ctrl+shift+r session picker into your shell.

### Changed

- Launched harnesses receive the real tty.

### Fixed

- The wasm bundle is built from the txcript package.

## [0.9.1] - 2026-08-20

### Added

- The CLI is also a library (`txcript-cli`), exposing its commands as clap
types and a `run_session` entry point.
- A persistent search cache for `query`.

## [0.9.0] - 2026-08-20

### Added

- Cowork, Claude desktop's local agent mode, as a harness.

## [0.8.1] - 2026-08-19

### Fixed

- Foreign `tool_result` blocks are flattened when writing claude_code.

### Changed

- README translations moved under `docs/translations/`.

## [0.8.0] - 2026-08-19

### Added

- Simple, an interchange pseudo-harness for agents without a native store.
- `continue` accepts a Simple document from a file or stdin.

## [0.7.0] - 2026-08-18

### Added

- README translations in twelve languages.

### Changed

- The harness list is a capability matrix.
- opencode import satisfies the stricter session and message schema.
- CLI quality gaps found against replay-cli are closed.

## [0.6.0] - 2026-08-17

### Added

- Cursor desktop harness for the IDE app's `state.vscdb` sessions.
- Documentation of every harness's on-disk transcript format.

### Changed

- Stores and the CLI are hardened against hostile session files.
- The Claude Code summary line is anchored to a real leaf.
- npm publishing uses trusted publishing and is triggered by version tags
again.

## [0.5.0] - 2026-08-08

### Added

- Claude Code local commands are modelled as `Tool::Command`.
- Experimental `--move` for `txcript continue`.

## [0.4.3] - 2026-08-03

### Added

- `Session::updated_at`.

## [0.4.2] - 2026-07-30

### Fixed

- Harness session stores resolve correctly on Windows.

## [0.4.1] - 2026-07-20

### Added

- `txcript view`, and `#range` refs for `view` and `continue`.

### Fixed

- Exported codex rollouts name a real `model_provider`.
- Non-`ses` session ids are re-shaped for opencode export.

## [0.4.0] - 2026-07-17

### Added

- amp and antigravity harnesses.
- An MCP server with a token-conscious text projection.
- `Span` for pointing into sessions with zero-copy fragment resolution.
- `completion` subcommand; harness names are advertised to completers.
- `--cwd` scopes `list` and `query` to a folder.

### Changed

- `query` indexes in parallel and interactive navigation is responsive.

## [0.3.0] - 2026-07-06

### Added

- Grok CLI harness.
- `txcript::search`: fuzzy and substring search with a hot index.
- `txcript::local` and the `query` command with an fzf-style picker.
- `Store::delete` on every harness store.

### Changed

- The CLI is a separate workspace crate on clap.
- Literal occurrences rank above every gapped fuzzy alignment.
- MSRV tracks the latest stable Rust.

## [0.2.0] - 2026-07-01

### Changed

- The public API is hierarchical.

## [0.1.0] - 2026-07-01

### Added

- Canonical session model and core traits.
- claude_code, codex, pi, campfire, opencode, and Cursor harnesses.
- `txcript` CLI with `list` and cross-harness `continue`.
- Composable `TextCodec` layer and WASM bindings.

[Unreleased]: https://github.com/skillsynchq/txcript/compare/v0.12.1...HEAD
[0.12.1]: https://github.com/skillsynchq/txcript/compare/v0.12.0...v0.12.1
[0.12.0]: https://github.com/skillsynchq/txcript/compare/v0.11.0...v0.12.0
[0.11.0]: https://github.com/skillsynchq/txcript/compare/v0.10.0...v0.11.0
[0.10.0]: https://github.com/skillsynchq/txcript/compare/v0.9.1...v0.10.0
[0.9.1]: https://github.com/skillsynchq/txcript/compare/v0.9.0...v0.9.1
[0.9.0]: https://github.com/skillsynchq/txcript/compare/v0.8.1...v0.9.0
[0.8.1]: https://github.com/skillsynchq/txcript/compare/v0.8.0...v0.8.1
[0.8.0]: https://github.com/skillsynchq/txcript/compare/v0.7.0...v0.8.0
[0.7.0]: https://github.com/skillsynchq/txcript/compare/v0.6.0...v0.7.0
[0.6.0]: https://github.com/skillsynchq/txcript/compare/v0.5.0...v0.6.0
[0.5.0]: https://github.com/skillsynchq/txcript/compare/v0.4.3...v0.5.0
[0.4.3]: https://github.com/skillsynchq/txcript/compare/v0.4.2...v0.4.3
[0.4.2]: https://github.com/skillsynchq/txcript/compare/v0.4.1...v0.4.2
[0.4.1]: https://github.com/skillsynchq/txcript/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/skillsynchq/txcript/compare/v0.3.0...v0.4.0
[0.3.0]: https://github.com/skillsynchq/txcript/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/skillsynchq/txcript/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/skillsynchq/txcript/releases/tag/v0.1.0
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ edition = "2024"
rust-version = "1.96"
description = "Convert coding-agent session transcripts between harness formats."
license = "Apache-2.0"
homepage = "https://github.com/skillsynchq/txcript"
repository = "https://github.com/skillsynchq/txcript"
readme = "README.md"
keywords = ["transcript", "claude", "codex", "agent", "wasm"]
Expand Down
11 changes: 11 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@
"name": "txcript",
"version": "0.12.1",
"description": "Convert coding-agent session transcripts between harness formats.",
"keywords": [
"transcript",
"claude",
"codex",
"agent",
"wasm"
],
"license": "Apache-2.0",
"homepage": "https://github.com/skillsynchq/txcript#readme",
"bugs": {
"url": "https://github.com/skillsynchq/txcript/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/skillsynchq/txcript.git"
Expand Down