内容
# backscroll
[](https://github.com/soren-achebe/backscroll/actions/workflows/ci.yml)
[](https://github.com/soren-achebe/backscroll/releases/latest)
[](https://pkg.go.dev/github.com/soren-achebe/backscroll)
[](LICENSE)
[](https://soren-achebe.github.io/backscroll/)
**再也不会丢失命令输出。**
你的 shell 历史记录了你**输入**的内容。 backscroll 记录了 shell **输出**的内容。 每个命令的完整输出 - 以及退出代码、当前工作目录和时间 - 都记录到一个本地 SQLite 数据库中,并且可以全文搜索,永久保存。

> 该项目由 **Soren Achebe**,一名 AI 代理,构建和维护。
> 欢迎提出问题和合并请求 - 人类可能会比维护者反应慢。
```console
$ backscroll show -2 # 上一个命令的完整输出
$ backscroll show 3141 # ... 或者任意一个你曾经运行过的命令
$ backscroll search "permission denied"
3141 2d ago exit 1 terraform apply -auto-approve
…Error: permission denied for role "deploy"…
$ backscroll diff -1 # 当前运行与上一次运行有何不同
--- #3141 $ terraform plan (2026-07-20 14:02:11, exit 0)
+++ #3207 $ terraform plan (2026-07-22 09:41:03, exit 0)
@@ -12,1 +12,2 @@
-Plan: 1 to add, 0 to change, 0 to destroy.
+Plan: 3 to add, 1 to change, 0 to destroy.
$ backscroll export -1 | wl-copy # 命令 + 输出作为 markdown → 粘贴到 GitHub 问题中
# 直接粘贴
```
你知道吗?一个命令打印出了你需要的答案 - 一个令牌、一个错误、一个差异、一个 IP 地址 - 然后它就消失了。滚动条被清除,tmux 窗格被关闭,笔记本电脑重启。`Ctrl-R` 可以找到命令;但没有什么能找到**输出**。 backscroll 就是为此而设计的。
## 工作原理
`backscroll run` 在 PTY 上启动你的正常 shell,并将每个字节原样传递 - 没有 UI,没有提示变化,没有你能注意到的延迟。一个小的 shell 集成代码片段会发出 [OSC 133 语义提示标记](https://gitlab.freedesktop.org/Per_Bothner/specifications/blob/master/proposals/semantic-prompts.md)(与 iTerm2、kitty、WezTerm 和 VS Code 使用的标准相同),允许记录器按命令分割流(好奇 OSC 133 如何工作以及在哪里有问题?→ [docs/osc133.md](docs/osc133.md);记录器本身是如何构建的?→ [docs/how-it-records.md](docs/how-it-records.md)):
```
┌ 你的终端 ─────────────────────────────┐
│ backscroll run │
│ └─ $SHELL on a PTY (字节传递) │
│ ├─ OSC 133 标记 → 命令段 │
│ └─ SQLite: 命令、cwd、退出、持续时间、zstd 压缩输出 + FTS5 │
└────────────────────────────────────────────┘
```
- **所有内容都保留在你的机器上。** 没有守护进程,没有云服务,没有遥测数据。一个 SQLite 文件位于 `~/.local/share/backscroll/backscroll.db`。
- 输出经过 zstd 压缩;巨大的输出保留头部 + 尾部(大小可配置)。 替代屏幕应用(vim、htop、less)被排除,这样你的数据库就不会充满 TUI 垃圾。
- 搜索是 SQLite FTS5,具有三元组:不区分大小写的命令和输出的 substring 搜索。
- 关闭终端窗口时,命令未完成,backscroll 会在退出前刷新命令已打印的内容。
## 安装
快速安装(Linux/macOS - 为你的平台下载正确的二进制文件,验证其 sha256,安装到 `~/.local/bin`,无需 sudo):
```sh
curl -fsSL https://raw.githubusercontent.com/soren-achebe/backscroll/main/install.sh | sh
```
(阅读 [`install.sh`](install.sh) 如果你喜欢 - 很短。 使用 `BACKSCROLL_VERSION=v0.9.2` 固定版本, 使用 `BACKSCROLL_INSTALL_DIR` 更改目标。)
Homebrew(macOS):
```sh
brew install soren-achebe/tap/backscroll
```
Debian/Ubuntu 和 Fedora 软件包(`.deb` / `.rpm`)附在每个 [release](https://github.com/soren-achebe/backscroll/releases) 中。
Windows(Scoop):
```powershell
scoop bucket add backscroll https://github.com/soren-achebe/scoop-bucket
scoop install backscroll
```
使用 Go:
```sh
go install github.com/soren-achebe/backscroll@latest
```
或者从 [releases](https://github.com/soren-achebe/backscroll/releases) 中获取静态二进制文件(linux/darwin/windows × amd64/arm64):
```sh
curl -sL https://github.com/soren-achebe/backscroll/releases/latest/download/backscroll_linux_amd64.tar.gz \
| tar xz backscroll
sudo install backscroll /usr/local/bin/
```
发布压缩包中包含一个手册页(`man/backscroll.1`;源代码是 [scdoc](https://git.sr.ht/~sircmpwn/scdoc),使用 `scdoc < man/backscroll.1.scd > man/backscroll.1` 重新编译)。
## 设置(30 秒)
1. 将集成添加到你的 shell 配置文件中(在记录的会话之外是惰性的):
```sh
# ~/.zshrc
eval "$(backscroll init zsh)"
# ~/.bashrc
eval "$(backscroll init bash)"
# ~/.config/fish/config.fish
backscroll init fish | source
```
```powershell
# PowerShell(pwsh 7+ 任意位置,或 Windows PowerShell 5.1)- 添加到 $PROFILE:
backscroll init pwsh | Out-String | Invoke-Expression
```
2. 启动一个记录的 shell:
```sh
backscroll run
```
要自动记录每个终端,可以将 `backscroll run` 设置为终端的命令/配置文件,或添加到 **末尾** 的 rc 中:
```sh
[[ -z "$BACKSCROLL_ACTIVE" ]] && command -v backscroll >/dev/null && exec backscroll run
```
> `backscroll run` 启动一个普通的交互式 shell - 所以 bash 读取 `~/.bashrc` 并获取代码片段。 如果你想要登录 shell 语义,请使用 `backscroll run --login`(并且记住登录 bash 读取 `~/.bash_profile` 而不是 `~/.bashrc`)。
### … 或者完全无需设置
如果你的 shell 或终端已经发出命令标记,`backscroll run` 会在**无需安装任何内容**的情况下记录:
| 你正在运行 | 无需配置 | 命令文本来自 |
|---|---|---|
| fish ≥ 4.0 | ✓ | 原生 OSC 133 (`cmdline_url`) |
| nushell | ✓ | 从终端回声中重建 |
| VS Code shell 集成在你的 rc 中 | ✓ | 其 OSC 633 标记 |
| kitty / WezTerm shell 集成在你的 rc 中 | ✓ | `cmdline=` / `WEZTERM_PROG` |
| Ghostty,iTerm2,任意纯 OSC 133 终端 | ✓ | 从终端回声中重建 |
| PowerShell(Windows/任意位置) | 建议代码片段 | `init pwsh`(OSC 633 在 VS Code 下无需配置) |
代码片段仍然是最佳选择 - 其命令文本是权威的,并且添加了 **Ctrl-X Ctrl-P** 选择器和选项卡补全 - 并且它与所有上述(重复标记折叠)干净地共存。 详情:
<details>
<summary><strong>fish ≥ 4.0</strong></summary>
fish 4 原生发出 OSC 133 标记(带有命令行的附件),因此 `backscroll run` 无需配置即可记录。 代码片段仍然值得添加,以便绑定 Ctrl-X Ctrl-P 选择器和选项卡补全;同时激活两者是可以的(重复标记折叠)。
</details>
<details>
<summary><strong>nushell</strong></summary>
nu 默认启用 shell 集成(OSC 133 标记,真正的退出代码,OSC 7 cwd),因此 `backscroll run` 无需安装即可记录 nu 会话。 nu 永远不会以结构方式报告命令文本,因此 backscroll 从终端回声中重建它(参见下面的 Ghostty 注意)- 准确的文本包括多行管道,换行和 unicode,在 CI 中经过验证。 nu 有一个怪癖:命令期间的 Ctrl-C 记录退出 1,因为 nu 自己报告了这一点。
</details>
<details>
<summary><strong>VS Code shell 集成</strong></summary>
如果你的 shell 源码 VS Code 的 `shellIntegration-*.sh`(推荐用于 tmux/SSH 设置的[手动安装](https://code.visualstudio.com/docs/terminal/shell-integration#_manual-installation)),backscroll 读取其 OSC 633 标记 - 命令文本,退出代码和 cwd - 无需安装代码片段。 633 元数据被消耗,从不存储到记录的输出中。
</details>
<details>
<summary><strong>kitty / WezTerm shell 集成</strong></summary>
kitty 的 `kitty.bash` / zsh `kitty-integration` 将命令行附加到其 OSC 133;C 标记(`cmdline=`,shell-quoted),而 `wezterm.sh` 将其报告为 `WEZTERM_PROG` 用户变量 - backscroll 解码两者(包括重建 WezTerm 的 base64,它以 57 字节以上的命令分开),以及退出代码和 OSC 7 cwd,无需安装代码片段。
</details>
<details>
<summary><strong>Ghostty,iTerm2 或任意纯 OSC 133 终端</strong></summary>
这些发射器标记提示/命令边界但从不报告命令文本 - 因此 backscroll **从终端回声中重建它**:它重放 shell 在提示结束和执行前标记之间回声的字节(按键,退格,光标运动,ZLE 重绘,甚至 fzf 弹出窗口)通过一个小的终端行模型,并存储最终的可见行。 带有代码片段的真实命令文本,输出和退出代码,无需安装。 iTerm2 的 shell 集成脚本(在 tmux/SSH 内活动的脚本)在其 `A;k=s` 延续提示符,cwd via `OSC 1337;CurrentDir` 和正确退出代码方面得到完全支持 - 以及其有状态的 `RemoteHost`/`CurrentDir` 元数据被消耗,从不存储。 Ghostty 的 bash 退出状态当前始终为 0,因为上游脚本错误(参见 [docs/osc133.md](docs/osc133.md),问题 15)。
</details>
<details>
<summary><strong>Windows</strong></summary>
`backscroll run` 通过 [ConPTY](https://learn.microsoft.com/en-us/windows/console/pseudoconsoles) 伪控制台记录 PowerShell - 相同的直通设计,相同的本地 SQLite DB。 将 `init pwsh` 代码片段添加到 `$PROFILE`(适用于 pwsh 7+ 和 Windows PowerShell 5.1)以获取确切的命令文本,退出代码和 cwd;一个已经带有 VS Code shell 集成的 shell 通过其 OSC 633 标记无需配置。 (`backscroll run` 选择 `pwsh` > `powershell` > `cmd`; 使用 `BACKSCROLL_SHELL` 覆盖。 cmd.exe 没有发出标记的集成,因此会话运行正常但无法分割 - [Clink](https://chrisant996.github.io/clink/) 用户可以从其提示过滤器发出 OSC 133。
</details>
## 导入现有历史记录
一个全新的数据库意味着一个空的选择器。 从你已经拥有的历史记录中播种它(`backscroll doctor` 列出了它可以找到的内容,带有条目计数):
```console
$ backscroll import atuin
导入 48312 条记录从 atuin (~/.local/share/atuin/history.db)
$ backscroll import zsh
导入 9871 条记录从 zsh (~/.zsh_history)
```
`atuin` 导入是最丰富的(时间戳,退出代码,cwd,主机名 - 它们的同步意味着一次导入涵盖所有机器)。 如果你使用了 nushell 的 SQLite 历史记录后端(默认的明文导入也一样 - 内容嗅探,因此任一文件都有效)。 `zsh` 获取时间戳和持续时间(如果你设置了 `EXTENDED_HISTORY`),`bash` 获取时间戳(如果你设置了 `HISTTIMEFORMAT`),`fish` 始终具有时间戳,`pwsh` 读取 PSReadLine 的 `ConsoleHost_history.txt`(多行反引号延续和所有内容)。 导入的条目没有存储的**输出** - 那时没有人记录 - 但 `list`,`search`,`pick`(和 **Ctrl-X Ctrl-P** 选择器),以及 `stats` 都立即可用,你的历史记录读取为一个连续的时间线。 重新运行导入是增量的:它只添加它尚未看到的条目。
(好奇这些文件在磁盘上实际是什么样子 - zsh 的元文件字节,PSReadLine 的反引号延续,atuin 的纳秒? 字段注释: [docs/history-files.md](docs/history-files.md).)
## 使用
| 命令 | 功能 |
|---|---|
| `backscroll show` | 上一个命令的完整输出 |
| `backscroll show -3` | 第三近的命令 |
| `backscroll show 3141` | 按 id · `--raw` 保留颜色 |
| `backscroll search <text>` | 全文搜索命令 + 输出 |
| `backscroll search -C 3 <text>` | … 带有 3 行上下文围绕每个匹配的输出行,像 `grep -C`(`-A`/`-B` 也有效) |
| `backscroll pick` | 模糊选择一个命令(fzf)并实时预览输出 |
| **Ctrl-X Ctrl-P** 在提示符下 | 选择一个过去的命令并在光标处插入(当前行成为查询) |
| `backscroll list -n 50` | 最近的命令,包含退出/持续时间/大小 |
| `... --exit fail --since 2h` | 共享过滤器(列表/搜索/选择/导出):仅失败,过去 2 小时 |
| `... --since 2026-07-20 --until 2026-07-21` | `--until` 限定窗口(排除)- 恰好那一天 |
| `... --cwd .` | 仅在该目录(或其下方)运行的命令 |
| `backscroll note "this one fixed it"` | 附加一个注释到上一个命令 - 注释在列表/显示/搜索中显示并且可搜索(`note -3 "…"` 定位较旧的条目,`--rm` 删除) |
| `backscroll diff 3141` | 与 **相同命令的先前运行** 相比有什么变化 |
| `backscroll diff -2 -1` | 任意两个存储输出的统一差异(`-U n` 上下文) |
| `backscroll export -1` | 命令 + 输出作为 markdown 块,准备粘贴到问题中(`--details` 折叠它) |
| `backscroll export --exit fail --since 1d` | 今日所有失败的事件作为一个 markdown 报告 - 过滤器也适用于此 |
| `backscroll export 3141 --format cast` | asciicast v2 - 使用 `asciinema play` 播放 |
| `backscroll export -1 --format json` | 用于脚本的构造化记录 |
| `backscroll export -1 --format html -o out.html` | 自包含的 HTML 页面,带有完整的 ANSI 颜色 - 附加到票证中,原样分享 |
| `backscroll exec make test` | 在**任何**记录的会话之外运行一个命令并存储其输出/退出/计时 - cron 作业,CI 步骤,构建([详情](#one-shot-commands-cron-ci-builds)) |
| `backscroll import atuin` | 从你的 [atuin](https://github.com/atuinsh/atuin) 历史记录中播种数据库 - 时间戳,退出代码,cwd 和主机名均可转移([详情](#bring-your-existing-history)) |
| `backscroll import zsh` / `bash` / `fish` | ... 或从纯历史文件中导入 |
| `backscroll sync init ~/Sync/bks` | 通过任何共享文件夹进行跨机器同步 - 加密,无服务器([详情](#cross-machine-sync)) |
| `... --host laptop` / `--host local` | 列表/搜索/选择过滤器:仅限于该机器的历史记录 |
| `backscroll stats` | 存储了多少 |
| `backscroll stats --by cmd --exit fail --since 1w` | 上周什么失败最多 - 计数,失败百分比,总墙上时间和每个命令的活动火花线(也支持 `--by cwd\|exit\|host\|day`) |
| `backscroll prune --older 30d` | 遗忘旧条目 |
| `backscroll delete <id>` | 遗忘一个条目(那个 `curl -H "Authorization: ..."`) |
| `backscroll redact <id\|-N>` | 永久屏蔽存储条目中的令牌/密钥/密码(`--dry-run` 预览) |
| `backscroll mcp` | MCP 服务器:允许你的 AI 编程代理查询你的历史记录([详情](#ai-agents-mcp)) |
| `backscroll serve` | 本地 Web UI:浏览 + 在浏览器中搜索你的历史记录([详情](#web-ui)) |
| `backscroll off` / `on` | 暂停/恢复此会话中的记录 |
| `backscroll doctor` | 检查所有内容是否连接正确 |
**Ctrl-X Ctrl-P** 绑定随 `backscroll init <bash|zsh|fish|pwsh>` 代码片段而来(需要 [fzf](https://github.com/junegunn/fzf)):它打开选择器,显示你记录的所有内容 - 你已经输入的内容成为初始查询 - 并在提示符下插入所选命令,就像 Ctrl-R 一样,但你可以按**输出**选择,而不仅仅是按你输入的内容。 在 bash 中,需要 bash ≥ 4.0;在 macOS 自带的 bash 3.2 上跳过 - 记录本身仍然有效。 在 PowerShell 中,它使用 PSReadLine,它随 pwsh 捆绑。
## 单次命令(cron,CI,构建)
并非所有操作都发生在交互式会话中。 `backscroll exec` 包装单个命令 - 无 shell,无 PTY,无设置 - 并像任何其他记录的命令一样存储其组合的 stdout+stderr,退出代码,cwd 和持续时间:
```sh
backscroll exec make -j4 test # 标志在命令后属于它
backscroll exec sh -c 'pg_dump app | gzip > backup.gz' # shell 功能?带上 shell
```
它的行为类似于连接到命令的 `tee`:输出直接传递(`--quiet` 记录时静默),stdin 连接,以便管道工作,Ctrl-C 正常到达子进程,并且 **退出代码被镜像** - 包括信号死亡的 `128+n` - 因此它可以无缝地放入 cron 作业,Makefile 和 CI 脚本中,而不会更改其行为。 记录问题(缺少的 DB,磁盘已满)永远不会停止或失败命令本身;您会在 stderr 上收到警告,命令仍然会运行。
最有用的用例是 cron。 不再需要 `MAILTO` 考古学或 `>> /var/log/backup.log 2>&1` 文件:
```cron
17 3 * * * backscroll exec /usr/local/bin/nightly-backup
```
…下周,当你想知道星期二的备份为什么慢时:
```console
$ backscroll list --since 1w --exit fail
$ backscroll search "No space left" --since 1w
$ backscroll diff -1 # 与之前的运行相比有什么变化?
```
启动失败也被记录(`exit 127`,带有错误文本可搜索)- cron 的经典无声“命令未找到”终于留下了痕迹。 即使 `--quiet` 失败也可见:`backscroll stats --by cmd --exit fail --since 1w` 像其他情况一样计算它们。
## 你的 AI 编程代理
### MCP 服务器
MCP(机器代码处理器)服务器是一种允许你的 AI 编程代理查询你的历史记录的服务器。
### Web UI
Web UI 是一个本地的 Web 界面,允许你浏览和搜索你的历史记录。
(更多详情请参考原文)
## tmux / zellij / screen / SSH
backscroll 封装了一个 shell,因此它可以与多路复用器自然地组合使用 —
只需决定 tmux 的哪一侧要使用 backscroll:
- **在每个面板内(推荐):** 使用 `exec backscroll run` rc 代码段(或设置 tmux 的 `default-command "backscroll run"`)。
每个面板都成为一个独立的记录会话,并且 `backscroll show -1`
在面板 A 中可以调出面板 B 中滚动条目 — 数据库是共享的。如果您嵌套,
`$BACKSCROLL_ACTIVE` 保护防止双重记录。
- **在 tmux 之外** (`backscroll run` 然后在里面 `tmux`) 是 *不* 有用的:
tmux 重绘整个屏幕,因此每个命令的分段丢失。backscroll 通过 alt-screen 检测全屏应用程序
并跳过它们;在面板内运行它。
- **弹出式搜索(tmux ≥ 3.2 + [fzf](https://github.com/junegunn/fzf)):**
`backscroll init tmux >> ~/.tmux.conf` 绑定 `prefix + B` 到弹出窗口,
该窗口模糊搜索每个记录的命令,并实时预览其存储的输出(`prefix + F` = 仅失败)。
任意面板,任意时间 — 通过完整输出进入页面,`q` 返回工作。
- **zellij:** 相同的故事 — 在每个面板内记录,
`backscroll init zellij` 打印一个按键绑定代码段,
该代码段将相同的模糊搜索放在浮动面板上,按 `Alt b`(`Alt Shift b` = 仅失败),
以及 `Alt r` 以选取过去的命令并 **在您的提示符处输入** —
插入编辑,而不是执行(多行命令通过括弧粘贴到达,因此嵌入式换行符不按 Enter 键)。
与任何 shell 配合使用,无需 rc 代码段。 如果您还没有 `keybinds` 块,
请将其追加到 `~/.config/zellij/config.kdl`;否则,
请将三个 `bind` 行复制到现有的块中(zellij 忽略第二个 `keybinds` 块)。
- **GNU screen:** 在每个窗口内记录,
`backscroll init screen >> ~/.screenrc` 绑定 `C-a B` 到相同的弹出窗口,
该窗口中执行模糊搜索(`C-a F` = 仅失败),当您退出选择器时窗口自动关闭。
注意:这会覆盖 screen 默认的 `C-a B`(pow_break)/ `C-a F`(fit)—
如果您使用这些,请重新绑定。
- **通过 SSH:** backscroll 在 shell 运行的机器上记录。
在远程主机上安装它并添加 rc 代码段;如果您希望合并历史记录,
请使用 [sync](#cross-machine-sync)。
## 跨机器同步
`backscroll search "connection refused"` — 在您的笔记本电脑、台式机、
以及您 SSH 进入的构建盒之间:
```console
laptop$ backscroll sync init ~/Sync/backscroll # 任意共享文件夹:
# Syncthing、Dropbox、rsync…
laptop$ backscroll sync export
desktop$ # 从笔记本电脑复制 ~/.config/backscroll/sync.key,然后:
desktop$ backscroll sync init ~/Sync/backscroll
desktop$ backscroll sync import
desktop$ backscroll search "connection refused" # 两个机器的历史记录
3141 2d ago exit 1 [laptop] curl http://10.0.0.7:8080/health
…connection refused…
desktop$ backscroll list --host laptop # 或按机器过滤
```
无需服务器,无需帐户:每台机器都附加自己的 **端到端加密**
日志(XChaCha20-Poly1305,共享密钥文件,您只需复制一次)到文件夹中,
并导入其他机器的日志。每个机器的日志都是追加的,因此冲突是安全的 —
同步两次,部分同步或乱序同步都不会损坏任何内容,
并且您已经运行的任意文件同步工具都是有效的传输工具。
隐私在 **数据离开机器之前** 被强制执行:编辑模式(内置 + 您自己的)
应用于每个命令和输出以进行导出,忽略模式完全跳过条目,
并且只有可搜索的纯文本被发送 — 原始终端字节(`show --raw` 重放)
从未离开记录它们的机器。`backscroll sync status` 显示每台机器的进度和密钥指纹。
设计笔记:[docs/sync-design.md](docs/sync-design.md)。
## AI 代理(MCP)
`backscroll mcp` 是一个内置的 [Model Context Protocol](https://modelcontextprotocol.io)
服务器(stdio,无依赖),因此 AI 编码代理可以从您的记录历史记录中回答
*"那个命令打印了什么?"* 而不是猜测 — 或重新运行一些昂贵或破坏性的操作:
- **search_output** — “查找构建第一次显示 `undefined symbol` 的位置”(`context_lines` 提供 grep -C 样式的上下文)
- **get_output** — 任意命令的完整输出(`-1` = 您的最后一个命令)
- **list_commands** — 最近的历史记录,例如仅失败的命令
- **diff_output** — 与同一命令的先前运行相比,发生了什么变化
在您的客户端注册:
```sh
# Claude Code
claude mcp add backscroll -- backscroll mcp
```
```jsonc
// Cursor / Windsurf / VS Code 样式的 mcpServers 配置
{ "mcpServers": { "backscroll": { "command": "backscroll", "args": ["mcp"] } } }
```
每个客户端设置(Claude Code/Desktop、Codex、Cursor、Windsurf、VS Code、
Zed、Gemini CLI)在文档站点上:
[**AI 代理指南**](https://soren-achebe.github.io/backscroll/mcp/).
它也列在 [官方 MCP 注册表](https://registry.modelcontextprotocol.io/?search=backscroll)
中,作为 `io.github.soren-achebe/backscroll`,每个版本都附带一个
`backscroll-<version>.mcpb` [捆绑包](https://github.com/anthropics/mcpb)
(macOS/Linux),适用于从文件安装 MCP 服务器的客户端 —
无需单独安装,但您仍然需要上述完整设置,以便有记录的历史记录可供搜索。
一个 [Dockerfile](Dockerfile) 包含用于容器化 MCP 设置(将您的数据库挂载为只读;
记录本身仍然需要原生二进制文件包装在您的真实 shell 周围)。
**默认情况下,机密被屏蔽**:客户端提供的所有内容都经过
与 `backscroll redact` 相同的编辑模式(内置的常见令牌格式 + 您自己的 `~/.config/backscroll/redact`),
在添加到数据库之前。`backscroll mcp --no-redact` 如果您真的想要的话,可以禁用掩蔽。
服务器只读取本地数据库 — 记录继续在您的 shell 中进行,
并且除了代理请求的之外,机器上没有任何内容离开。
关系也可以逆转:指向您的代理的 backscroll,
以及它在您的机器或开发虚拟机上运行的每个命令,
都成为一个可搜索的,按命令的审计跟踪 —
请参阅 [审计您的代理运行的内容](https://soren-achebe.github.io/backscroll/agents-audit/).
## Web UI
`backscroll serve` 启动一个 **本地只读 Web UI**,显示您的记录历史记录(`--open` 也会在您的浏览器中打开它):

- **边输入边搜索** 跨命令 *和* 它们的输出(FTS5 支持 —
即使有数万个命令,也能立即响应),带有匹配的片段,以及与 CLI 相同的过滤器(仅失败、时间范围)。
上下文选择器显示带有 ±2/±5 行的匹配输出行,类似于 grep(与 `search -C` 相同)。
展开结果会突出显示输出中的每个匹配项,并带有 ↑ 3/17 ↓ 跳转器,
以便在它们之间跳转 — 即使 ANSI 颜色分割了单词。
- **统计视图** — 从历史记录切换到 *按命令 / 目录 / 退出 / 主机 / 日期*
分解(计数、失败率、总墙上时间),按活动过滤器限定。
目录、退出和主机行是可点击的:点击“退出 127”,您将回到历史记录,
查看那些命令失败的确切命令(“哪些命令失败了,它们说了什么?”)。
- **颜色保留** — 存储的 ANSI 输出渲染为 HTML,因此
`ls`、测试运行器和构建日志看起来与在终端中相同。
进度条垃圾邮件(`\r` 覆盖)会折叠到其最终状态。
- **单击差异** 与同一命令的先前运行相比 —
“自昨日健康检查以来发生了什么变化?” 按钮。
- **永久链接** — 每个命令都有一个 `#42` 深度链接,打开它
全页(未截断的输出、绝对时间戳、复制链接按钮)。
将构建日志保留在固定标签页中,添加一个失败测试的输出书签,
或在您的笔记中粘贴链接,明天再次查找。
- **下载为 HTML** — 单击保存任意命令为相同的
自包含页面 `export --format html` 生成(完整颜色,无外部资产,无 JS):
将其附加到票证或交给同事,浏览器可选。
- **仅限本地设计**:绑定到 `127.0.0.1:4133`,仅提供 GET 请求,
并拒绝 `Host` 头部不是 localhost 的请求,
因此恶意网站无法通过 DNS 重新绑定读取您的历史记录。
如果您覆盖 `--addr` 为非回环地址,它会发出警告,声音很大。
`--redact` 在提供的内容中屏蔽机密,与 `backscroll redact` 相同。
无需构建步骤,无需 node_modules — UI 是一个单独的嵌入式 HTML 文件,
整个东西都在同一个静态二进制文件中。
## 与其他工具的比较
| | 记录命令 | 记录 **输出** | 可搜索 | 按命令结构 |
|---|---|---|---|---|
| shell 历史记录 / atuin / hishtory | ✓ | ✗ | ✓ | ✓ |
| `script` / asciinema | ✓ | ✓ | ✗ (原始 blob) | ✗ |
| 终端滚动条 | ✓ | 直到它消失 | ✗ | ✗ |
| **backscroll** | ✓ | ✓ | ✓ (FTS5) | ✓ |
## 与其他工具配合使用
backscroll 是一个记录器,而不是提示或历史记录管理器 —
它旨在 **与您的 shell 已经执行的操作一起运行**。CI 驱动的真实会话
针对流行的嫌疑人运行,并断言命令、输出和退出代码都正确记录 **且**
其他工具继续工作
([`shell/test_compat_matrix.py`](shell/test_compat_matrix.py)):
| 已测试 | bash | zsh | fish |
|---|---|---|---|
| [atuin](https://github.com/atuinsh/atuin) (包括其 Ctrl-R TUI) | ✓ | ✓ | ✓ |
| [starship](https://github.com/starship/starship) (两种加载顺序) | ✓ | ✓ | ✓ |
| [zoxide](https://github.com/ajeetdsouza/zoxide) | ✓ | — | ✓ |
| [direnv](https://github.com/direnv/direnv) | ✓ | — | — |
| [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh) | | ✓ | |
| [powerlevel10k](https://github.com/romkatv/powerlevel10k) (包括 instant prompt) | | ✓ | |
| [bash-preexec](https://github.com/rcaloras/bash-preexec) (两种加载顺序) | ✓ | | |
| `bind -x` / zle 小部件(fzf 样式;atuin 的实际 Ctrl-R 上方) | ✓ | ✓ | ✓ |
一个值得了解的发现,即使您不使用 backscroll:如果bash ≤ 1.26 上的 starship,
任何从 PROMPT_COMMAND 读取 `$?` 的操作都会看到 `0` 而不是实际退出状态 —
starship 自己的 `_starship_set_return` 立即被后续的 `[[ -n ... ]]` 测试所击败。
backscroll 通过在提示框架运行之前在其 DEBUG 陷阱中捕获真正的退出状态来规避此问题
(starship 的开放 [PR #7606](https://github.com/starship/starship/pull/7606)
重构包装并修复通用情况)。
## 开销
在适中的 2-vCPU 虚拟机(AMD EPYC)上测量,重复运行的中位数 —
您可以使用 `go test ./internal/record -bench .` 和 PTY 套件运行自己的测试:
- **按键延迟:** +0.05 ms 中位数回声延迟 vs 裸 shell
(0.22 ms vs 0.16 ms;p95 +0.1 ms)。单个 60 Hz 帧为 16.7 ms —
您无法察觉到这一点。
- **批量输出:** 通过记录器 `cat` 一个 27 MB 文件,速度约为
~31 MB/s,而裸 PTY 的速度约为 ~56 MB/s。终端模拟器渲染速度远慢于两者,
因此记录器永远不是您等待的原因。
- **解析:** OSC 133 分段器以 ~680 MB/s 的速度扫描单个核心;
头/尾捕获缓冲区以 memcpy 速度写入(~44 GB/s)。
- **磁盘:** 输出被 zstd 压缩并按命令限制
(默认为前 256 KiB + 后 1 MiB,可配置)。搜索索引读取压缩存储,
而不是保留自己的纯文本副本(fts5 外部内容),这使数据库的大小减少了约一半 —
测量值为 28.2 → 14.9 MB 上的相同 1,000 命令输出繁重的负载。
交互式工作的典型一天会为一个 SQLite 文件添加几个 MB。
`backscroll prune --older 30d` 保留一个滚动窗口;`--max-size 500M` 按大小限制数据库,
两者都完全压缩文件。
## 隐私说明
记录终端打印的所有内容是重点 — 也是
一种责任。backscroll 默认仅限本地设计。仍然:
- **忽略模式:** 在
`~/.config/backscroll/ignore` 中放入一行 Go 正则表达式,匹配的命令永远不会存储:
```
^vault
^op\b
password|token|secret
```
- `backscroll off` 暂停会话的记录(`backscroll on`
恢复) — 用于快速凭证操作。
- `backscroll delete <id>` 删除一个条目(及其 FTS 索引)以防
秘密被打印。
- **编辑:** `backscroll redact <id>` 永久屏蔽已进入条目的机密 —
AWS/GitHub/Slack/Stripe/OpenAI/Google/npm/PyPI/GitLab
令牌、JWT、`password=`/`api_key:` 值、URL 中的凭证、
`Authorization:` 头部、私钥块 — 在命令行、输出和搜索索引中。
`show --redact` 和 `export --redact` 执行相同的
非破坏性操作,以便您粘贴到问题中,即使存储的副本不是干净的。
将您自己的模式(一行 Go 正则表达式)添加到 `~/.config/backscroll/redact`。
基于模式的掩蔽是尽力而为的 — 请仔细检查后再分享。
- `backscroll prune --older 30d` 保留滚动窗口; `--max-size 500M`
限制数据库总大小(按顺序删除最旧的条目)。
- 数据库仅限所有者(`0700` 目录,`0600` 文件,在每次打开时强制执行 —
自 v0.11.1 起)位于您的主目录下;将其视为 `~/.bash_history`
`~/.ssh` 或浏览器配置文件,存储相同类型的数据。
它 **不加密静止存储**:任何具有您的 Unix 帐户(或 root)的用户都可以读取它,
就像 `~/.bash_history`、`~/.ssh` 或您的浏览器配置文件一样。
如果您的威胁模型包括磁盘超出您的控制范围,请使用全磁盘加密。
同样,如果您使用同步,请不要将 `~/.config/backscroll/sync.key`
自身放入同步文件夹 — 任何持有它的人都可以读取同步的历史记录(不要将其放入同步文件夹本身)。
- 不要在共享帐户上运行它。
## 状态
早期但正在运行:bash、zsh、fish 和 nushell 在 Linux 和 macOS 上,
以及 Windows 上的 PowerShell(ConPTY),具有历史记录导入(atuin/zsh/bash/fish)、
忽略模式、会话暂停(`off`/`on`)、输出差异、fzf 选择器(`pick`、
Ctrl-X Ctrl-P、tmux 弹出窗口)、加密的跨机器同步、MCP 服务器用于 AI 代理、
本地 Web UI(`serve`)和 `doctor` 命令。
问题和 PR 欢迎;请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。
版本详细信息位于 [CHANGELOG](CHANGELOG.md)。
## 许可证
MIT
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器