Skip to content

Releases: it-bens/cc-port

v0.7.0 - Codex Support Alongside Claude Code

Choose a tag to compare

@SpiGAndromeda SpiGAndromeda released this 22 Jul 20:19

Summary

Add OpenAI Codex support alongside Claude Code. Every command now takes a repeatable --tool flag to pick which tools a run touches, moves are crash-safe across both tools, and non-fatal findings surface as warnings instead of silent skips.

Changes

Features

  • Add OpenAI Codex as a second supported tool. move, export, import, push, pull, and stats all operate on Codex projects, and with --tool omitted a command runs against every tool it detects. Pass --tool codex or --tool claude (repeatable) to limit a run. (#55)
  • Make moves crash-safe. A move stages its writes and publishes them by atomic rename; an in-process failure rolls back and restores file modification times, and a move killed mid-apply re-runs to convergence. (#55)
  • Surface non-fatal findings as warnings. move, import, and pull now report a malformed history line, an active writer, or a rules file that references the project instead of silently skipping the entry or refusing the whole run. (#55)

Fixes

  • Stop Claude import from answering the destination machine's security prompts. Import used to copy the .claude.json trust-dialog and external-include approval keys verbatim, pre-accepting the folder-trust checkpoint that gates the archive's allowedTools and mcpServers. Those keys are now destination-owned, so Claude Code asks its own questions the first time an imported project opens. (#62)
  • Raise the Go floor to 1.26.5 so release binaries pick up the stdlib fixes for the crypto/tls and os vulnerabilities. (#54)
  • Render push, pull, and move --apply output after the progress ledger tears down. Plan summaries and result tables were interleaving with the ledger's live region and staircasing across the terminal. Apply runs also print a real command header instead of the [dry-run] prefix. (#64)
  • Reconstruct per-session witnesses on Claude import. An imported project used to land unwitnessed, so its identity check was skipped with a "no witness" warning. import now writes a ~/.claude/sessions/<id>.json witness for each staged session, attributed to the destination and recorded with pid 0 so it never blocks a later move. (#63)
  • Make Codex rollout imports converge. When an import stages a rollout, cc-port re-arms Codex's one-shot session backfill so the next Codex start rebuilds the missing threads rows. The old warning told users to rerun after opening the project, which never worked. (#61)
  • List Codex projects known only through a rollout file in all-projects stats. stats built its project set from thread cwd values and config.toml keys alone, so a project whose cwd appeared only in a rollout was missing entirely. (#58)
  • Close the pull dry-run and push warning parity gaps. Pull's dry-run now refuses every archive --apply would refuse by running the same preflight gates, and push now prints the export warnings it was silently dropping. (#59)

Documentation

  • Refresh the export/import, push/pull, and move demo clips to show both Claude Code and Codex. (#65)

Dependencies

  • Update Go modules and GitHub Actions dependencies. (#52, #53, #56, #57, #60)

Breaking Changes

The --claude-dir flag is gone. Use --claude-home or --codex-home to override a tool's state location, and --tool <name> (repeatable) to limit a run to specific tools.

metadata.xml changed shape. The old root-level <export><categories> block and top-level <placeholders> are replaced by one <tool name="..."> block per exported tool, each carrying its own categories and placeholders. Archives produced by v0.6.0 and earlier don't import.

Upgrade Notes

  • Replace any --claude-dir <path> invocation with --claude-home <path>.
  • Re-export any archives you still need to import. Archives from v0.6.0 and earlier no longer load under the new metadata.xml schema.

v0.6.0 - Project Stats Command

Choose a tag to compare

@SpiGAndromeda SpiGAndromeda released this 29 Jun 07:37
98da2c2

Summary

Adds cc-port stats, a read-only command that reports per-surface path-reference counts and disk footprint for one project or all projects. Also replaces error-string matching with exported sentinels across lock, move, and manifest.

Changes

Features

  • Add cc-port stats <project-path> to show per-surface path-reference counts, per-category disk usage, and history/session-file counts for a project. Run cc-port stats with no argument to rank all projects by disk footprint. Pass --json to either mode for machine-readable output. (#51)

Refactors

  • Replace err.Error() substring checks in lock, move, and manifest with exported sentinels and typed errors (LiveSessionsError, ErrEncodedDirAmbiguous, ErrManifestFileTooLarge, and others), so callers can branch on error identity rather than message wording. (#50)

CI

  • Bump actions/checkout to v7 and actions/setup-go to v6.5.0. (#47, #49)

Dependencies

  • Update charmbracelet/x/exp/teatest/v2 to a newer pre-release commit. (#48)

Upgrade Notes

No breaking changes.

v0.5.1 - Fix Live Ledger Terminal Input

Choose a tag to compare

@github-actions github-actions released this 17 Jun 16:58
d4ac902

Summary

Fixes garbled escape sequences appearing at the shell prompt after any command that uses the live progress ledger. The ledger now owns the controlling terminal's input reader, which lets Ctrl+C cancel a running command rather than being dropped.

Changes

Fixes

  • Fix garbled text at the shell prompt after ledger-mode commands by letting bubbletea own the terminal's input reader, so startup capability queries drain before the ledger exits. (#46)
  • Route Ctrl+C to context cancellation via a new Interruptible interface on the ledger renderer. Non-TTY runs and external signals keep the existing signal.NotifyContext path, so cancellation behavior is uniform at the context level. (#46)

Upgrade Notes

No breaking changes.

v0.5.0 - Live Progress & Portable Paths

Choose a tag to compare

@github-actions github-actions released this 17 Jun 10:56
2a2c3d7

Summary

Add live progress rendering to all long-running commands and extend the move/export/import pipeline to handle the encoded project storage directory. Two bug fixes close an inaccurate dry-run count in move and a temp-file leak in import.

Changes

Features

  • Add live progress rendering to move --apply, export, import, push, and pull. A new internal/progress package provides four renderers: a bubbletea TTY ledger with spinners and per-phase timers, an ANSI-free stream mode for CI (rate-limited to one PhaseAdvance line per phase per 500 ms), newline-delimited JSON under --json, and a null sink under --quiet that keeps warnings. New persistent flags --quiet, --verbose, --debug, and --json are available on every subcommand. (#42)

  • Anonymize and rewrite the encoded project storage directory (~/.claude/projects/<encoded>) across export, import, and move. Export replaces it with {{PROJECT_DIR}}. Import resolves it to the recipient machine's encoded path. Move rewrites it alongside the real project path so references in transcript and memory files stay consistent. (#40)

Fixes

  • Report memory-file replacements in the move dry-run preview. The --apply pass has always rewritten memory files, but the preview counted only transcript replacements. A new Memory: N replacements line now appears in the output. (#44)

  • Reclaim staging temp files orphaned by a failed import write. When a staging write failed after the temp file was created, the temp stayed on disk because the staging record was only built on success. The record is now built as soon as the temp path is known, so cleanupTemps removes it on any error path. (#43)

Dependencies

  • Update charm.land/lipgloss/v2 to v2.0.4, charm.land/bubbles/v2 to v2.1.0, charm.land/bubbletea/v2 to v2.0.7, and several AWS SDK Go v2 modules across 4 Renovate PRs. (#36, #38, #39, #41)

CI

  • Add a Homebrew environment to the release job for Homebrew Cask distribution.
  • Update actions/checkout to v6.0.3. (#37)

Upgrade Notes

No breaking changes.

v0.4.0 - Move Timestamp Preservation & Demo Videos

Choose a tag to compare

@SpiGAndromeda SpiGAndromeda released this 24 May 16:51
e33803c

Summary

move --apply now preserves modification times on relocated session files, keeping Claude Code's /resume picker in order after a move. This release also adds animated GIF demos for all three main commands to the README.

Changes

Features

  • Preserve modification times on session files during move --apply, so Claude Code's /resume picker maintains its order after a relocation. Transcripts and memory files carry their source mtime through CopyDir. Todos, usage data, plugins data, and tasks restore their pre-rewrite mtime via os.Chtimes. Merged globals like history.jsonl get a fresh write-time since they're edited rather than copied verbatim. (#35)

Documentation

  • Add animated GIF demos for move, export/import, and push/pull to the README, embedded at each command's section. The recordings are reproducible from VHS tape sources in docs/videos/. A single-node Garage S3 compose stack in dev/s3/ handles the remote for the push/pull tape, and make videos rebuilds all three GIFs and MP4s. (#31)
  • Update release verification instructions to use the .sigstore.json bundle format. The --bundle flag replaces the earlier --signature/--certificate pair.

Dependencies

  • Bump github.com/aws/aws-sdk-go-v2/credentials to v1.19.17 and patch-bump GitHub Actions (golangci-lint-action, goreleaser-action). (#33, #34)

Upgrade Notes

No breaking changes.

v0.3.0 - Logo Build Variant and Signed Releases

Choose a tag to compare

@SpiGAndromeda SpiGAndromeda released this 10 May 13:17
7ea4cc6

Summary

Ships cc-port-with-logo as a second binary compiled with -tags=logo, rendering the gantry-crane logo on --help, --version, and the interactive category prompt. The default cc-port build is unchanged. Release artifacts are now signed with cosign keyless OIDC, and CI validates the goreleaser config and runs a full snapshot build on every push.

Changes

Features

  • Add cc-port-with-logo, a second Homebrew-installable binary that renders the gantry-crane logo on --help, --version, version, and the interactive category prompt. The default cc-port build shows no logo. logo.Banner becomes the sole exported entry point in internal/logo; all previously exported logo functions are unexported. (#28)

Build / Release

  • Fix goreleaser config to use archives[*].ids instead of the removed archives[*].builds key, bind each Homebrew cask to the correct archive, and add cosign keyless OIDC signing that attaches a checksums.txt.sigstore.json bundle to each release. (#29)
  • Switch cosign signing from separate certificate and signature files to the bundle format (--bundle), producing a single .sigstore.json artifact. Pin cosign to v3.0.6. (#30)

CI

  • Replace the build job with goreleaser-check, which validates .goreleaser.yml schema on every push, and add release-snapshot, which runs the full goreleaser pipeline in snapshot mode (build, archive, checksum, keyless sign) without publishing. (#30)

Chore

  • Add a Claude Code brainstorming hook context that injects cc-port's design-rules overlay, so feature proposals are checked against the correct internal primitives before implementation.

Dependencies

  • Update aws-sdk-go-v2/service/s3 (v1.92.1 to v1.101.0), gjson (v1.18.0 to v1.19.0), and golangci-lint (to v2.12.2). (#27, #26)

Upgrade Notes

No breaking changes.

v0.2.0 - Remote Sync and Encrypted Archives

Choose a tag to compare

@SpiGAndromeda SpiGAndromeda released this 07 May 19:44
20b27b4

Summary

Adds cc-port push and cc-port pull for syncing archives to file:// and s3:// remotes with optional passphrase encryption. Placeholder discovery switches to an anchor-based algorithm that resolves {{HOME}} implicitly, which removes the --resolution flag from import and pull.

Changes

Features

  • Add cc-port push and cc-port pull for syncing project archives to file:// and s3:// remotes via gocloud.dev blob. Push detects prior uploads from a different machine and refuses without --force; pull renders a dry-run plan before applying. (#7)
  • Add passphrase encryption to export, import, and import manifest via --passphrase-env and --passphrase-file. Archives are encrypted with age scrypt; the import side detects and decrypts without extra configuration. (#6)
  • Add --credentials-file and --no-prompt to push and pull for injecting AWS credentials from a .env-style file or environment variables before falling back to an interactive TTY prompt. Files with permissions looser than 0600 are rejected. (#23)
  • Preserve source file modification times on verbatim archive entries through the export/import round-trip. The /resume session picker in Claude Code now sorts imported sessions in their original chronological order rather than by import time. (#25)
  • Switch placeholder discovery to an anchor-based algorithm that accepts only paths under {{PROJECT_PATH}} or {{HOME}}. {{HOME}} now resolves implicitly on import alongside {{PROJECT_PATH}}, so neither anchor requires user interaction. (#19)

Fixes

  • Fix push and pull with S3-compatible remotes that pass a bare-host endpoint parameter. The opener now prepends https:// (or http:// when disable_https=true) so the AWS SDK receives a valid URL. (#24)
  • Stop rejecting archives whose content contains {{UPPER_SNAKE}}-shaped text not listed in the manifest. Session logs, skills, and documentation can hold such patterns; the preflight pass now only checks that declared placeholder keys have a resolution. (#21)
  • Upgrade google.golang.org/grpc to v1.80.0, addressing GO-2026-4762 (authorization bypass via malformed :path header), and update the OpenTelemetry suite to v1.43.0. (#18)

Dependencies

  • Update charm.land/lipgloss to v2.0.3 and bump GitHub Actions runner versions. (#16, #17)

Breaking Changes

--resolution is removed from cc-port import and cc-port pull. Scripts that passed custom placeholder values via --resolution KEY=VALUE must switch to --from-manifest <file.xml>.

Archives exported before this release that contain {{UNRESOLVED_N}} placeholder keys can't be imported without a manifest file providing resolve entries for those keys.

Three symbols are removed from cc-port internals: GroupPathPrefixes and PlaceholderSuggestion.Auto from internal/export, and Placeholder.Resolvable from internal/manifest.

Upgrade Notes

Remove --resolution flags from any import or pull invocations and supply a manifest with --from-manifest instead. Archives that don't contain {{UNRESOLVED_N}} keys need no changes.

v0.1.0 - Move, Export, Import

Choose a tag to compare

@SpiGAndromeda SpiGAndromeda released this 23 Apr 22:28

Summary

First public release of cc-port, the CLI that rewrites Claude Code project state when a project directory is moved, exported, or imported. Path rewriting stays inside word boundaries. Mutating commands take an exclusive flock and abort if a Claude Code session for the project is alive. Writes are atomic with rollback on failure.

Changes

Features

The CLI ships with five subcommands.

  • cc-port move <old> <new> rewrites every reference to the old path under ~/.claude/ to the new path. Default is dry-run. --apply copies, verifies, and deletes the old encoded directory. --refs-only updates references in place, and --rewrite-transcripts extends rewriting into session transcript bodies.
  • cc-port export <project> produces a portable archive of one project. Categories include sessions, memory, history, file-history, config, todos, usage-data, plugins-data, and tasks. Use --all, individual category flags, or omit them all for an interactive picker.
  • cc-port export manifest <project> emits the manifest XML alone for review or hand-editing. Refuses to overwrite an existing output path.
  • cc-port import <archive> <target> applies an archive to a target path. Placeholder values come from --resolution KEY=VALUE flags or from a manifest via --from-manifest. Mixing the two sources is rejected.
  • cc-port import manifest <archive> reads the metadata from an archive and writes a manifest XML with empty resolve attributes for hand-editing.

Beyond the subcommand surface, every mutating operation acquires an exclusive flock on ~/.claude/.cc-port.lock and aborts if any session JSON records a live PID. LocateProject cross-checks session files before rewriting, so two distinct paths that encode to the same directory (my project and my-project both map to my-project) surface as a conflict rather than splicing one project's data into another. Project paths resolve through symlinks before encoding, imports write sensitive files at 0o600, and --resolution accepts placeholder values from the command line for non-interactive runs. Interactive prompts run a TTY preflight. Piped invocations surface a clear error instead of hanging on stdin. Help output, version output, and the interactive picker render the project logo when stdout is a TTY.

Fixes

  • Prefix-sharing paths no longer corrupt each other during rewrite. A project at /work/foo is left alone when porting /work/foobar.
  • Embedded paths inside ~/.claude.json project blocks, session transcripts, session-memory files, and text file-history snapshots are all rewritten on move.
  • Encoded-directory collisions abort a move before any data is touched.
  • A sentence-ending period no longer suppresses path rewrites in prose.
  • Free-text history entries that reference the project path are included in the rewrite scope.
  • ~/.claude.json keeps its existing formatting through targeted sjson edits rather than a full re-marshal.
  • Malformed history.jsonl lines surface with the offending line number.
  • Imports validate placeholders before any write and roll back on failure, so a broken archive can no longer leave partial state on disk.
  • Close errors from streaming pipelines and rollback paths are aggregated via errors.Join instead of being dropped.
  • Importer staging lands on the resolved filesystem parent so a target on a different mount does not trigger EXDEV.

Build / Release

  • Homebrew cask published to the it-bens/tap tap. macOS users can brew install it-bens/tap/cc-port.
  • goreleaser produces tarballs, checksums, and the cask artifact.
  • A top-level Makefile exposes build, test, lint, and vuln targets.

CI

  • ci.yml runs test, lint, govulncheck, and a build matrix on push.
  • release.yml drives the goreleaser flow on tag push.

Documentation

  • README covers install, every subcommand, the experimental warning, and known limitations.
  • docs/architecture.md and the per-module README.md and AGENTS.md files document the cross-cutting policies, session-keyed registry, lock contract, import cap guards, and path-rewrite boundary rules.

Upgrade Notes

No breaking changes. This is the first public release.