Changelog

Qué ha ido pasando

El registro de commits del CLI, del más reciente al más antiguo, directo de GitLab. Cada versión queda marcada donde apunta su etiqueta, con sus notas de CHANGELOG.md debajo.

actual: 0.16.1 · 100 commits · la historia completa en GitLab

  1. 0.16.1

    Added

    • Diff a snapshot against now. In the snapshot view, d (or ops → diff) opens a tree of the folders and files that changed versus the current worktree. Enter a file to see its patch; Esc returns to the tree. Folders start folded. torii snapshot diff <id> lists the files first, then the patches.
    • Custom auto-snapshot intervals in the TUI. The snapshot view's picker still has off / 5 / 15 / 30 min / 1 hour, plus a custom… row. Type 30m, 2h, 45, the same durations torii snapshot config --interval already takes. The value is stored as minutes in .torii/config.toml, so a CLI 2h no longer snaps to 1 hour when the TUI loads it.
    • The issues view names the forge. Heading, each row and the detail pane show gitlab / github / … and the owner/repo the list came from. p switches between remotes, the way the PR view already does. torii issue list prints the same host line.
    • Built-in keys are claimed per view. A letter may live in many views; it may not live twice in one, or collide with a global (e, Tab, W). The files tree is dispatched from that table, so adding the event-log key there fails before the handler can hide it.
    • t in the files view shows the tree of HEAD. Status columns hide for a nested tree of folders and files in the current commit, with icons and the usual connectors. Folders lead, then files. t or Esc brings the status layout back. Folders start folded. Enter, space, h/l, arrows or -/+ open and fold; a click selects a row, a second click opens or folds it. An unborn HEAD is an empty tree, not an error. (e stays the event log, which is global.)

    Fixed

    • torii sync <branch> --merge no longer destroys uncommitted work on a fast-forward. The checkout is safe: a dirty file the incoming tree does not touch stays, and a dirty file it would overwrite refuses the merge instead of being clobbered. torii sync --pull uses the same path. (#1)
    • torii snapshot config writes the same store torii config reads. It used to dump a per-repo JSON with different key names that nothing else looked at, so torii config get snapshot.auto_enabled stayed false after a successful --enable. --interval now parses the documented 30m / 1h forms (and bare minutes) and errors on garbage instead of silently becoming 30. (#3)
    • Auto-snapshot actually fires. With snapshot.auto_enabled, a dirty fast-forward takes a snapshot first. The TUI interval picker reads and writes the same toml. (#2)
    • torii snapshot restore no longer deletes the repository. Snapshots live under .git/torii/snapshots/, and restore used to remove_dir_all(.git) — which erased the snapshot it was reading and left an empty .git. It now rewrites .git while keeping torii/, and a snapshot also stores dirty / untracked files so uncommitted work comes back. The TUI snapshot view talks to the same store instead of writing empty .meta files.
  2. 28247910 chore 0.16.1
  3. 0.16.0

    Added

    • A clone view in the TUI. The sidebar's new clone entry leads the list: getting a repository is how you start, not a property of the one already open. Opening the TUI still lands on files, because you launch it inside a repository. It lists the repositories of whichever account you have a token for, filters them as you type, and clones the one you pick — with a progress bar, because a clone is the one operation in torii that can take a minute and say nothing.
    • The destination is on screen before the clone starts, and is editable. It is <clone.base_dir>/<repo>, re-derived every time the caret moves or the URL box changes, and left alone the moment you edit it: a field that overwrites what you typed is not an editable field. An existing path is refused up front rather than by libgit2 halfway in.
    • [u] takes a URL or a local path, for everything a listing cannot name — someone else's repository, a host torii has no listing for, a bare repo on this disk. It wins over the selection when it has anything in it, and the destination follows it, so the path shown is always the path used.
    • [p] switches host and says which ones have a token here. A host is still selectable without one; the error it gives names the command that sets it, which is more use than a row that cannot be clicked.
    • [t] picks ssh or https, seeded the way torii clone seeds it — mirror.default_protocol, or the presence of an SSH key.
    • When it finishes, the repository is open. It is also registered in the active workspace, if there is one, so the repo switcher and the multi-repo commands see it without being told twice. Cloning a repository in order to then go and find it is two steps too many.
    • The listing is a background worker, like every other network call in the TUI; the view stays usable while it runs, and a host with no token is never asked, because the answer is already known.
    • Esc over a running clone stops it. The progress sink returns false, which is what libgit2 already asked for, and libgit2 removes the half-fetched tree. A Radicle clone kills the rad process instead; seed state in ~/.radicle may remain.
    • clone.base_dir — where a clone lands when no destination is given. Default is ., which is what git clone does, so nothing moves for anyone who does not set it. ~ is expanded. torii config set clone.base_dir ~/repos.
    • list_repos for Gitea, Forgejo and Codeberg. All three answer the same API and all three returned "not yet wired", which left the new view with three empty hosts. One paged implementation now serves them, stopping on the first short page and at a ceiling, so a host that ignores limit cannot spin.
    • list_repos for Bitbucket, sourcehut and Azure. The clone view can now browse those three the way it already browses GitHub / GitLab / Gitea. Bitbucket follows next with the same 20-page ceiling; sourcehut pages git.sr.ht/api/repos and names the owner from meta.sr.ht when a row does not carry one; Azure lists every git repo in the organisations the PAT can see (AZURE_DEVOPS_ORG / AZDO_ORG pin it to one).
    • Gitea / Forgejo / Codeberg PlatformClient. create / delete / get / update / configure_features share one helper, the way list_repos and set_visibility already did. torii remote create codeberg … no longer sends you to the web UI.
    • torii clone <plat> user/repo covers sourcehut and Azure. Sourcehut is ~user/repo (the tilde is added if you omit it). Azure is org/project/repo, because that is how the URLs are shaped (git@ssh.dev.azure.com:v3/… / https://dev.azure.com/…/_git/…). Forgejo and Gitea shorthand now read FORGEJO_URL / GITEA_URL the same way the API client does, instead of always pointing Forgejo at codeberg.org.
    • Radicle clone via rad, not libgit2. list_repos is rad ls --all (falls back to rad ls); get_repo is rad inspect --payload. torii clone radicle rad:z… and a rad: / rad:// URL both run rad clone. The TUI lists Radicle without a token — the local node is the auth — and Esc kills the rad process. A stop during fetch can leave seed state in ~/.radicle; the working copy is not promised. rad still has to be on PATH.
    • OAuth for self-hosted Forgejo and Gitea. They share an API, not an OAuth grant. Forgejo has RFC 8628 (Codeberg already did): torii auth oauth forgejo talks to FORGEJO_URL (default codeberg.org, and then the bundled Codeberg client_id is reused). Any other host needs a public OAuth app and TORII_FORGEJO_APP_ID. Gitea still only speaks authorization-code: torii auth oauth gitea opens a PKCE loopback on 127.0.0.1:8888/callback, host from GITEA_URL, client_id from TORII_GITEA_APP_ID. The TUI runs Forgejo's device flow in-place; Gitea (and Bitbucket) name the CLI command instead of pretending device flow works.
    • GitRepo::clone_repo_with_progress — the clone, with libgit2's progress handed to a caller-supplied sink instead of to stdout. clone_repo is now that function plus the printing sink the CLI wants, so credentials, TORII_CLONE_DEPTH and the empty-remote HEAD fixup have one implementation rather than two that drift.
    • Filter the log by author. A opens a dropdown of the identities in the loaded log — most commits first, with a count each — over an "all authors" row that lifts the filter. The cursor starts on whoever is filtered in already, or failing that on the author of the commit under the caret, so the usual ask is A then Enter. The search box (/) reaches the same filter as an author:<who> qualifier, which narrows to one identity instead of matching the message as well.
    • The term is matched against the whole Name <email>, so a bare name, a bare address and a pasted identity all reach the same commits; the menu writes the identity in full, because a name alone folds together two people who share one, and one person's two addresses.
    • "all authors" is a row rather than a second keybind: with the filter on there is no commit of anyone else's left in the list, so the menu has to carry its own undo.
    • It pairs with the picking that landed alongside it: filter to the identity you mean to replace, then space down the list, and every commit the pick lock would have refused is already gone from the view.
    • The heading says of those loaded — ↓ for more while the log is still paginated. The filter only ever sees the commits already fetched, and a count that looks like the whole answer has to admit it is not one.
    • A filtered list pages like an unfiltered one. j past the last match pulls the next slice of history and re-runs the filter over it; it used to stop dead at the bottom of the loaded page, which made an author whose commits were further back look like an author with none.
    • The plain log search reaches the author's email. It matched the message, the name and the hash — never the address — so searching for the identity you were trying to get rid of came back empty.
    • Pick commits in the log, then act on the picks. space marks the commit under the caret and the ops dropdown becomes a short menu that takes the marked set as its subject — reauthor picked and clear picks. Esc drops the selection.
    • The first pick locks the set to that author identity, and commits by anyone else are greyed and refused, with the reason in the event log. That is not a UI nicety: reauthor replaces *one* --old, so a set spanning two identities has nothing coherent to run with.
    • Because the set already agrees on an identity, reauthor picked never asks for the old one — it is the half that has to match exactly, and the selection already has it right. Only the replacement is typed.
    • torii history reauthor --only <rev>... — restrict the identity change to named commits (repeatable or comma-separated), which is what the picked menu runs. Note what it does *not* promise: commits after a rewritten one are recreated regardless, because their parent moved, so their hashes change either way. A rev the walk never reaches is an error rather than a silent no-op.
    • reauthor in the log's ops menu. Replacing an author identity across history was CLI-only — the menu went straight from "rewrite dates" to "scan history". It now prompts for the old identity and then the new one, and rewrites the committer alongside the author: a menu has no room for the CLI's --committer flag, and an identity fixed on one field and left stale on the other is the half-rewrite that sends people back to the terminal.
    • Both prompts want Name <email> in full, including the old one — the CLI's looser --old (a bare name or a bare email) is bounded by --since and --dry-run, and the menu has neither. A long history keeps the same person under several identities, and half a pair matches all of them.
    • A malformed identity is refused on the prompt line, with the parser's own reason next to the cursor, instead of Enter doing nothing.
    • The two prompts accept shifted characters. Every older prompt matches KeyModifiers::NONE alone, which is harmless for a path or a ref and quietly eats the capitals and <> an identity is made of.
    • Refusals arrive verbatim, so the dirty-tree guard now reads as "working tree has uncommitted changes" instead of "reauthor failed".

    Changed

    • stats sits with the admin views. It is a look at the repo from a distance, not a daily action, and it was occupying the row under files. It drops to just above bisect, so save and sync sit next to the entry views.

    Fixed

    • torii clone ends its progress line. The last 📥 … was written with a carriage return and no newline, so ✅ Cloned repository to: … landed on top of its tail.
    • Event-log messages wrap instead of being cut off. Each entry was one ratatui Line, and a Line in a List is clipped, not wrapped — in a panel 55 columns wide at most, that left the timestamp and the first few words of every message. Entries now flow over as many lines as they need, with a hanging indent under the status symbol, and a word too wide for the panel (a hash, a path, an identity) is broken rather than lost.
  4. 7513d5e3 feat clone from every git forge, and stop one that is running
  5. 677b1eba chore 0.16.0
  6. 9aacd90e feat clone a repository without leaving the TUI
  7. 601920ca feat a clone that reports progress instead of printing it
  8. 99f0c34f feat a dropdown of authors in the log
  9. d63e1cad feat filter the log by author
  10. 16ec889b feat pick commits in the log and reauthor just those
  11. 19565933 feat torii variable — CI variables and secrets
  12. 40c36884 style rustfmt the tiny-window test's panic closure
  13. 153d5232 docs pin the GitLab runner protocol and commit to an agent
  14. f7fe2c2e feat publish both AUR packages from the repository
  15. dd617f58 fix a window too small for a modal no longer kills the TUI
  16. 3c2b2709 chore 0.15.0
  17. efe1b7c0 style take the redundant borrows out of format! and rewrap submodule
  18. afa10e46 fix stop the config view from forking the test binary
  19. 7c9ad869 chore record the llm-qa baseline for this repo
  20. 85105574 feat register list rows for the mouse across the remaining views
  21. db10dcfc style cargo fmt over core vcs and platform contents
  22. a23cd4f2 feat mouse support, with a hit map and a switch to turn it off
  23. 7b7a7049 feat configure the scanner from the safety view
  24. 915252f0 fix apply the user's own secret rules everywhere, not only on save
  25. a7f45b50 chore lockfile follows the 0.14.0 bump
  26. 367069ff feat fold the ignore rules and the scanner into one safety view
  27. b389cabe feat stats sits second in the sidebar, where an overview belongs
  28. 1879b561 feat a people section in stats — addresses, aliases and signing
  29. 16fc5f93 feat a stats view for the repo and the workspace
  30. 536b192a feat the selected row is the accent, washed down
  31. c219450c fix drop the ellipsis from action labels
  32. d80daac1 fix wrap the keys rows instead of cutting the action id
  33. 32937c38 feat switch branch or workspace repo from any screen
  34. bde88d50 feat user-defined keys, with a config section and an action palette
  35. 44612f0f feat move ignore up the sidebar, next to snapshot
  36. dc745dac feat an ignore view for the .toriignore pair
  37. e7e4aad7 feat the secret scanner reports its findings into the event log
  38. 3cfd5757 feat put the events popup in the window chrome
  39. 93691834 fix tell behind, ahead and diverged apart in --verify
  40. 92583d53 chore 0.14.0
  41. 21e9dbc5 style cargo fmt over the restyled views
  42. 41873adf feat torii restore — put a tracked file back the way it was
  43. e565a692 fix keep core's CLI output off the alternate screen
  44. f7e13b57 fix re-derive the log view's state when the commit list is reloaded
  45. aa9df06e feat square nodes, and lanes in the rule's grey
  46. 7a4dc473 refactor move the hint strip and overlays onto the theme palette
  47. 5632b13c refactor move the log view's last colours onto the theme
  48. 5ed9bbee feat convert the platform view to the window chrome
  49. 94cfdec7 feat convert the pull request view to the window chrome
  50. 48bb45b4 feat convert the config and issue views to the window chrome
  51. 4c9ea75a fix let the bisect detail pane wrap its own paragraph
  52. 906e31e0 feat convert the auth and bisect views to the window chrome
  53. 35076328 feat convert the worktree and submodule views to the window chrome
  54. 88ac21c9 feat convert the remote and workspace views to the window chrome
  55. 309a1495 feat convert the snapshot and tag views to the window chrome
  56. 42438af7 feat convert the sync view to the window chrome
  57. b6bb8186 feat convert the commit view to the window chrome
  58. 08da391f feat convert the branch view, and let columns meet the rule below
  59. 78d78854 feat convert the log view to the window chrome
  60. bc25d21a fix tie a view's column rules into the rule above them
  61. 69b09a7a feat give the chrome the shape drawn on gitorii.com
  62. 48922f82 docs release artifacts stopped at v0.7.15, and the AUR plan behind it
  63. e3a44390 fix close missing DB-scheme aliases, stop excluding guessable passwords
  64. 01fd4420 chore bump version to 0.13.0
  65. d769da62 feat add --stage to prepare files without committing
  66. 836398a8 fix status and diff --staged no longer crash on unborn HEAD
  67. dfa77deb fix close secret-scanner detection gaps and false positives
  68. 8174a368 build vendor libgit2 (git2 vendored-libgit2 feature)
  69. 81629c16 feat GitLab support for remote contents
  70. 08885794 feat remote repo contents (tree + file) without cloning
  71. 2252a07b fix record MERGE_HEAD parents when committing a merge resolution
  72. 4b8a9a84 fix resolve remote-tracking branches when integrating
  73. f011daf1 fix use the GitHub REST API instead of gh for repo settings
  74. b8e50103 feat filter-branch/filter-repo suite; bump 0.12.0
  75. 9b9aae27 feat history reword + date-preserving save/amend; bump 0.11.0
  76. c584a9c7 style clear all 325 clippy warnings across the workspace
  77. 58b9c889 chore regenerate Cargo.lock for 0.10.0
  78. dcb53048 chore bump to 0.10.0 — torii-lib split, precise errors, fixes
  79. cd1aba4f refactor package torii-lib (import torii_lib) — nombre registrable
  80. 9149d88c style cargo fmt over the workspace
  81. 37f75dfb fix fail fast on findings without a TTY; add --yes
  82. 236888da fix reindex tracked entries when renaming a directory
  83. c0546586 chore drop stale TSAL header — relicensed MIT/Apache in 0.9.0
  84. f703c939 refactor workspace lib+bin — crates/torii-core + crates/torii
  85. 78e0e28c refactor WorkspaceManager devuelve datos, el CLI imprime
  86. 301e713b refactor sellar fugas git2 de la API pública + vcs/sign.rs
  87. 0e1e827f refactor status() devuelve RepoStatus en vez de imprimir
  88. 422a4529 chore regenerate Cargo.lock for 0.9.2
  89. 764e62b8 chore bump to 0.9.2 — refresh README badges (license, rust)
  90. b1c335d3 chore bump MSRV to rustc 1.95 (Cargo.toml + README badge)
  91. c83d6f56 chore regenerate Cargo.lock for 0.9.1
  92. bf56dac9 chore unpin russh, drop rust-toolchain.toml
  93. db4693b9 chore regenerate Cargo.lock for 0.9.0
  94. 5058b53d chore relicense to MIT OR Apache-2.0
  95. 712e61b8 feat Log ops dropdown gains history ops
  96. d7463efe docs refresh crates.io / README presence
  97. c6bec5c0 chore bump Cargo.lock for 0.8.1
  98. 78b23b73 feat split online/local runners in Platform Runners sub-tab
  99. 53af6e76 feat platforms.toml registry + GitLab self-hosted
  100. 122acbd0 feat submodule ops dropdown
  101. ed6a7c31 fix+feat workspace path bug + OAuth auto-refresh + worktree TUI ops
  102. 1ed0aad4 feat exec local job — gitlab-runner exec / gitlab-ci-local / act