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
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ Don't accidentally pursue these:
See `spec.md` "Key Risks" for known unknowns. Key open questions:

1. ~~Windows ConPTY library choice~~ — **Resolved:** `github.com/UserExistsError/conpty` (the earlier-referenced `iamacarpet/go-conpty` does not exist). Proven by the Phase 1 spike (PR #3). Windows is folded back into Phase 1.
2. ~~Whether to bundle `agg` or require it~~ — **Resolved:** require it; pin the sixel-capable fork `tig/agg v1.9.0-sixel` (see `spec.md` Decisions). Release archives bundle it; source builds auto-download or use `--agg-path`.
2. ~~Whether to bundle `agg` or require it~~ — **Resolved:** require it; pin the sixel-capable fork `tig/agg v1.10.1-sixel` (see `spec.md` Decisions). Release archives bundle it; source builds auto-download or use `--agg-path`.
3. Mouse event encoding format (currently `click:col:row` from prototype)

If a task touches one of these, surface the decision rather than picking unilaterally.
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ $gobin = "$(go env GOPATH)\bin"

Verify: `tuirec --version`

Or download a binary from [GitHub Releases](https://github.com/gui-cs/tuirec/releases). Release archives include a pinned, sixel-capable `agg` binary (`tig/agg v1.9.0-sixel`) next to `tuirec`, and the CLI auto-detects that sibling binary before falling back to `PATH`.
Or download a binary from [GitHub Releases](https://github.com/gui-cs/tuirec/releases). Release archives include a pinned, sixel-capable `agg` binary (`tig/agg v1.10.1-sixel`) next to `tuirec`, and the CLI auto-detects that sibling binary before falling back to `PATH`.
Homebrew and Scoop manifests are planned after the first release automation pass.

**Prerequisite for source builds:** [agg](https://github.com/tig/agg) `v1.9.0-sixel` — a sixel-capable fork of asciinema/agg — renders casts to GIFs. tuirec **auto-downloads `agg`** on first use if it's not found on PATH or in the local cache (`~/.cache/tuirec/agg-v1.9.0-sixel/` on Unix, `%LOCALAPPDATA%\tuirec\agg-v1.9.0-sixel\` on Windows). You can also pass `--agg-path` explicitly.
**Prerequisite for source builds:** [agg](https://github.com/tig/agg) `v1.10.1-sixel` — a sixel-capable fork of asciinema/agg — renders casts to GIFs. tuirec **auto-downloads `agg`** on first use if it's not found on PATH or in the local cache (`~/.cache/tuirec/agg-v1.10.1-sixel/` on Unix, `%LOCALAPPDATA%\tuirec\agg-v1.10.1-sixel\` on Windows). You can also pass `--agg-path` explicitly.

**Sixel graphics:** tuirec answers the queries a sixel-capable app needs — DA1 (advertises sixel) and the `CSI 14/16/18 t` window/cell-size reports, so the app detects sixel, sizes its raster to match `agg`'s cells, and lays out its UI — and preserves the sixel DCS in the `.cast`. With a sixel-aware `agg` the images render in the GIF. Caveats: sixel capture works on **Linux/macOS only** (Windows ConPTY strips sixel DCS from the output stream), and full-screen / alternate-screen apps need `--trim=false` (otherwise trim can discard the recording).

Expand Down Expand Up @@ -64,12 +64,12 @@ To install the pinned `agg` binary locally for demos on Windows:
```powershell
New-Item -ItemType Directory -Force .\tools | Out-Null
Invoke-WebRequest `
https://github.com/tig/agg/releases/download/v1.9.0-sixel/agg-x86_64-pc-windows-msvc.exe `
https://github.com/tig/agg/releases/download/v1.10.1-sixel/agg-x86_64-pc-windows-msvc.exe `
-OutFile .\tools\agg.exe
.\tools\agg.exe --version
```

On Windows ARM64, the `agg v1.9.0-sixel` release does not publish a native ARM64 Windows binary. The Windows ARM64 tuirec release archive includes the x64 Windows `agg` binary for Windows x64 emulation (validated on Windows ARM64). You can also build `agg` from source and pass that binary with `--agg-path`. The demo commands automatically prefer `.\tools\agg.exe` when it exists.
On Windows ARM64, the `agg v1.10.1-sixel` release does not publish a native ARM64 Windows binary. The Windows ARM64 tuirec release archive includes the x64 Windows `agg` binary for Windows x64 emulation (validated on Windows ARM64). You can also build `agg` from source and pass that binary with `--agg-path`. The demo commands automatically prefer `.\tools\agg.exe` when it exists.

To create and open a visible demo GIF from the bundled cast fixture:

Expand Down
2 changes: 1 addition & 1 deletion agent/RECORDING-AGENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ can use this as context to drive `tuirec record` (GIF) or `tuirec snapshot`
```

> **Note:** `tuirec record` auto-downloads `agg` if not found on PATH or in the
> cache (`~/.cache/tuirec/agg-v1.9.0-sixel/`). No separate setup needed.
> cache (`~/.cache/tuirec/agg-v1.10.1-sixel/`). No separate setup needed.
>
> **Sixel graphics:** tuirec answers the terminal queries a sixel-capable app
> needs — DA1 (advertises sixel) plus the window/cell-size reports
Expand Down
2 changes: 1 addition & 1 deletion cmd/tuirec/agent-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ can use this as context to drive `tuirec record` (GIF) or `tuirec snapshot`
```

> **Note:** `tuirec record` auto-downloads `agg` if not found on PATH or in the
> cache (`~/.cache/tuirec/agg-v1.9.0-sixel/`). No separate setup needed.
> cache (`~/.cache/tuirec/agg-v1.10.1-sixel/`). No separate setup needed.
>
> **Sixel graphics:** tuirec answers the terminal queries a sixel-capable app
> needs — DA1 (advertises sixel) plus the window/cell-size reports
Expand Down
2 changes: 1 addition & 1 deletion internal/release/downloadagg/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type asset struct {
}

func main() {
version := flag.String("version", "v1.9.0-sixel", "agg release version")
version := flag.String("version", "v1.10.1-sixel", "agg release version")
outputDir := flag.String("output", filepath.Join("build", "agg"), "output directory")
flag.Parse()

Expand Down
2 changes: 1 addition & 1 deletion pkg/gif/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const (
// DefaultAggVersion is the agg release version downloaded when auto-fetching.
// The fork (see aggReleaseRepo) ships sixel rendering; pinned here until that
// support lands in an upstream asciinema/agg release.
DefaultAggVersion = "v1.9.0-sixel"
DefaultAggVersion = "v1.10.1-sixel"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Pin a release that publishes agg binaries

With this version, fresh installs and release packaging try to fetch URLs such as https://github.com/tig/agg/releases/download/v1.10.1-sixel/agg-x86_64-unknown-linux-musl, but the v1.10.1-sixel release page currently only has the two source-code assets and that binary URL 404s. This means tuirec record auto-download fails for users without an existing agg, and GoReleaser's go run ./internal/release/downloadagg hook will fail before producing archives; either attach the expected platform binaries to this tag or keep the pin on a release that has them.

Useful? React with 👍 / 👎.


// aggReleaseRepo is the GitHub owner/name the agg binary is fetched from.
aggReleaseRepo = "tig/agg"
Expand Down
14 changes: 7 additions & 7 deletions spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Rewrite tuirec as a **cross-platform Go CLI** that records any terminal app and
| Windows ConPTY library | `github.com/UserExistsError/conpty` | Resolves CLAUDE.md open decision #1. The previously-referenced `iamacarpet/go-conpty` **does not exist** as a module. `UserExistsError/conpty` builds and passes on Windows — proven by the Phase 1 spike (PR #3) |
| Windows in v1 | **In scope — folded back into Phase 1** (not a deferred spike) | PR #3 is the spike evidence: ConPTY works. Cross-platform PTY is a Phase 1 deliverable again. The only Windows item still deferred is agg-on-Windows in CI for full-GIF integration |
| Module path | `github.com/gui-cs/tuirec` (exact case) | Go import paths are case-sensitive; must match `go.mod`, README, and `.goreleaser.yaml` |
| agg distribution | Bundle pinned `agg v1.9.0-sixel` in release archives and support source-build prerequisites | Release archives include a sibling `agg` binary that tuirec auto-detects before PATH. `go install`/local builds still require `agg` on PATH or `--agg-path`. Upstream does not publish a native Windows ARM64 asset for `v1.9.0-sixel`; Windows ARM64 archives include the x64 Windows binary for OS emulation, or users can build `agg` from source and pass `--agg-path` |
| agg distribution | Bundle pinned `agg v1.10.1-sixel` in release archives and support source-build prerequisites | Release archives include a sibling `agg` binary that tuirec auto-detects before PATH. `go install`/local builds still require `agg` on PATH or `--agg-path`. Upstream does not publish a native Windows ARM64 asset for `v1.10.1-sixel`; Windows ARM64 archives include the x64 Windows binary for OS emulation, or users can build `agg` from source and pass `--agg-path` |
| Recording clock | Support a deterministic (scripted) clock in addition to wall-clock | Wall-clock timing makes GIFs non-reproducible and CI flaky; scripted timing enables golden-GIF regression |

---
Expand Down Expand Up @@ -66,7 +66,7 @@ Rewrite tuirec as a **cross-platform Go CLI** that records any terminal app and
`.cast` is byte-stable; store it in `testdata/` and diff.

4. **FR-4: Render the cast file to an animated GIF**
- Invoke pinned `agg v1.9.0-sixel` (prerequisite; see Decisions + CI).
- Invoke pinned `agg v1.10.1-sixel` (prerequisite; see Decisions + CI).
- Flag mapping (apply only the flags whose CLI value is set):

| CLI flag | agg flag | Notes |
Expand Down Expand Up @@ -349,7 +349,7 @@ row and no Unix-only fallback.
| 5 | `pkg/record` orchestration + teardown | `go test -race ./pkg/record`: deadline, drain window, single-owner close, no data race | `go run ./examples/record-pipeline -output ./pipeline-demo.gif -cast-output ./pipeline-demo.cast`, then open `pipeline-demo.gif`. The demo auto-detects `./tools/agg.exe`/`./tools/agg` before PATH. |
| 6 | CLI wiring (cobra), all flags + exit codes | `go test ./cmd/tuirec`: flag parsing + exit-code table; `--help` snapshot | `go run ./cmd/tuirec record --binary go --args run,./internal/testapp --keystrokes "wait:1000,Ctrl+Q" --output ./cli-demo.gif --cast-output ./cli-demo.cast`, then open `cli-demo.gif`. |
| 7 | End-to-end GIF integration | `go test -tags integration ./...` green on ubuntu + macOS: real `tuirec record` command + `internal/testapp` -> validated GIF. Windows PTY is already covered by Phase 1; Windows full-GIF integration follows in Phase 8. | Same CLI command as Phase 6, documented as the canonical README quickstart using `internal/testapp`. |
| 8 | Windows full-GIF integration | `go test -tags integration ./...` green on ubuntu + macOS + windows: CI installs pinned `agg v1.9.0-sixel` on Windows and runs the real CLI `internal/testapp` -> validated GIF path there too. | Same canonical CLI demo on Windows, using repo-local `tools\agg.exe` or `agg` on PATH. |
| 8 | Windows full-GIF integration | `go test -tags integration ./...` green on ubuntu + macOS + windows: CI installs pinned `agg v1.10.1-sixel` on Windows and runs the real CLI `internal/testapp` -> validated GIF path there too. | Same canonical CLI demo on Windows, using repo-local `tools\agg.exe` or `agg` on PATH. |

---

Expand All @@ -367,7 +367,7 @@ row and no Unix-only fallback.
### Release Process

1. Tag a commit: `git tag v0.1.0 && git push --tags`
2. GoReleaser (via `.github/workflows/release.yml`) downloads pinned `agg v1.9.0-sixel`, then builds for linux/darwin/windows × amd64/arm64
2. GoReleaser (via `.github/workflows/release.yml`) downloads pinned `agg v1.10.1-sixel`, then builds for linux/darwin/windows × amd64/arm64
3. Creates GitHub Release with tarballs/zips containing `tuirec`, matching `agg`, README, LICENSE, and checksums
4. Homebrew tap and Scoop bucket publishing are enabled after the target repos
and tokens exist.
Expand All @@ -376,7 +376,7 @@ row and no Unix-only fallback.

- `.github/workflows/ci.yml` — already present. Pins **Go 1.22**, runs
build + unit tests + `go vet` on ubuntu/macOS/windows, `golangci-lint`
on ubuntu, and an integration job that installs **pinned `agg v1.9.0-sixel`**
on ubuntu, and an integration job that installs **pinned `agg v1.10.1-sixel`**
per-OS (Linux `x86_64-unknown-linux-musl`, macOS `aarch64-apple-darwin`,
Windows `x86_64-pc-windows-msvc.exe`) then runs
`go test -tags integration ./...`. The Windows integration job exercises
Expand Down Expand Up @@ -431,7 +431,7 @@ Encode these so they are **not** rediscovered:
| Risk | Mitigation |
|------|-----------|
| Windows ConPTY quirks | **Resolved:** spike (PR #3) proved `github.com/UserExistsError/conpty` builds + passes on Windows; folded into Phase 1. Full Windows cast→GIF integration is covered by the CI integration job. |
| agg not available on all platforms | Pinned `agg v1.9.0-sixel`, installed per-OS in CI and bundled into release archives; source-build prerequisite behavior is documented |
| agg not available on all platforms | Pinned `agg v1.10.1-sixel`, installed per-OS in CI and bundled into release archives; source-build prerequisite behavior is documented |
| Key map incompleteness | Full normative table in-spec (incl. the F11/F12/`Alt` gaps the prototype had); R6 unit test per row; the `Ctrl+Q` bug is the testapp's exit path |
| Weak success signal | GIF validation decodes frames + asserts pixel variance + golden compare, not just magic bytes |
| Non-reproducible recordings | `--clock scripted` makes `.cast`/GIF byte-stable for golden regression |
Expand All @@ -451,7 +451,7 @@ v1 is done when:
and `go test -tags integration ./...` green
3. PTY recording and the full cast→GIF pipeline work on Linux, macOS,
**and Windows** (ConPTY)
4. Release archives include `tuirec` plus pinned `agg v1.9.0-sixel`; source builds require `agg` separately
4. Release archives include `tuirec` plus pinned `agg v1.10.1-sixel`; source builds require `agg` separately
5. README with install instructions and usage examples
6. CI green on the matrix (untagged tests and `integration` job on Linux,
macOS, and Windows)
Loading