personal fork of atuin without AI stuff, sync stuff, script management stuff
0

Configure Feed

Select the types of activity you want to include in your feed.

remove several files

don't really need agents, .claude .depot etc.

Signed-off-by: oppiliappan <me@oppi.li>

author
oppiliappan
date (Jul 18, 2026, 10:02 AM +0100) commit 592dadca parent 1b1aad41 change-id ztxomvkw
-13548
-357
.atuin/skills/release/SKILL.md
··· 1 - --- 2 - name: release 3 - description: > 4 - Orchestrate a multi-step Atuin CLI release — version bumping, changelog 5 - generation, PR creation, tagging, and crates.io publishing. Invoke with 6 - /release or /release <version>. 7 - disable-model-invocation: true 8 - argument-hint: [version] 9 - --- 10 - 11 - # Atuin CLI Release 12 - 13 - You are orchestrating a release of the Atuin CLI. Follow the steps below 14 - **in order**, pausing at each checkpoint for user confirmation. Do not skip 15 - steps or combine them. 16 - 17 - ## Current State 18 - 19 - - Workspace version: !`sed -n '/^\[workspace\.package\]/,/^\[/s/^version = "\(.*\)"/\1/p' Cargo.toml` 20 - - Latest tag: !`git describe --tags --abbrev=0 2>/dev/null || echo "none"` 21 - - Suggested next version: !`git-cliff --bumped-version 2>/dev/null | sed 's/^v//' || echo "(unknown)"` 22 - 23 - --- 24 - 25 - ## Step 1 — Check Dependencies 26 - 27 - Verify these tools are installed: `git`, `cargo`, `gh`, `git-cliff`. 28 - 29 - On macOS, also verify `gsed`. On Linux, `sed` is already GNU sed. 30 - 31 - Use `command -v` for each. If any are missing, report which ones and stop. 32 - 33 - Set the `SED` variable for later use: if on macOS, `SED=gsed`; on Linux, `SED=sed`. 34 - 35 - --- 36 - 37 - ## Step 2 — Determine Version 38 - 39 - The target version may be provided as `$ARGUMENTS`. If it's empty, use 40 - AskUserQuestion to ask for the new version (show the current state above 41 - for reference). 42 - 43 - After determining the version: 44 - - If it contains a `-` (e.g. `18.15.0-beta.1`), it is a **prerelease**. 45 - Note this — it affects changelog and publish behavior later. 46 - - Show the user: `current → new` and whether it's a prerelease. 47 - - **Checkpoint:** Ask the user to confirm before proceeding. 48 - 49 - --- 50 - 51 - ## Step 2.5 — Survey Release-Labeled PRs 52 - 53 - Two labels mark PRs whose merge has to be timed around the release. They are 54 - typically PRs touching `docs/` or `install.sh` — changes that deploy on merge to 55 - `main` rather than shipping inside the release artifact. 56 - 57 - | Label | Merged at | In the tag & artifact? | 58 - |-------|-----------|------------------------| 59 - | `merge-immediately-before-release` | Step 7.5 — after the prep PR merges, before the tag | Yes | 60 - | `merge-immediately-after-release` | Step 8.5 — after the release workflow uploads assets | No | 61 - 62 - Check both: 63 - 64 - ```bash 65 - gh pr list --repo atuinsh/atuin --state open \ 66 - --label merge-immediately-before-release \ 67 - --json number,title,url 68 - gh pr list --repo atuinsh/atuin --state open \ 69 - --label merge-immediately-after-release \ 70 - --json number,title,url 71 - ``` 72 - 73 - If both come back empty, say so and continue to Step 3. No checkpoint needed. 74 - 75 - The two labels are mutually exclusive: they name opposite sides of the tag. If a 76 - PR number comes back in **both** lists, that is a labelling mistake — the two 77 - queries are independent, so it would otherwise be approved twice, merged at Step 78 - 7.5, then merged again at Step 8.5 against an already-closed PR. **Stop** and ask 79 - the user which single timing applies, then treat it as carrying only that label 80 - for the rest of the release. Do not guess, and do not carry it into both steps. 81 - 82 - If either is non-empty: 83 - 84 - 1. Show the user every PR found, grouped by label, with its number, title, and 85 - the merge point from the table above. 86 - 2. **Checkpoint:** Use AskUserQuestion (multiSelect) to ask which of these PRs 87 - should in fact be merged at their labeled time. 88 - 3. Record the approved set — it carries to Step 7.5 and Step 8.5. A PR the user 89 - declines is left alone for the remainder of the release: don't merge it, 90 - don't raise it again. 91 - 92 - Take each label at face value. It records the PR author's decision about timing; 93 - it is not a suggestion for you to re-evaluate: 94 - 95 - - An `after-release` PR is **not** in the tag and **not** in the release 96 - artifact. That is the intended outcome, not a problem to solve. The label is 97 - for changes that deploy the moment they merge, so artifact inclusion is 98 - irrelevant to them. An author who needed the change in the artifact would have 99 - labeled it `merge-immediately-before-release`. 100 - - Never merge an `after-release` PR early to get it into the release, and never 101 - reclassify a PR from one label to the other. 102 - 103 - --- 104 - 105 - ## Step 3 — Set Up Working Directory 106 - 107 - Clone a fresh copy into a temp directory: 108 - 109 - ```bash 110 - WORKDIR=$(mktemp -d) 111 - git clone git@github.com:atuinsh/atuin.git "$WORKDIR" 112 - ``` 113 - 114 - Print the working directory path so the user can find it if needed. 115 - 116 - NOTE: 117 - ALL subsequent Bash commands run from `$WORKDIR`. 118 - 119 - --- 120 - 121 - ## Step 4 — Create Branch & Update Versions 122 - 123 - 1. Create a release branch named after the version (no `v` prefix): 124 - `git checkout -b <VERSION>` 125 - 126 - 2. Replace the old version with the new one in all `Cargo.toml` files. 127 - **Escape dots** in the old version so sed treats them literally: 128 - 129 - ```bash 130 - VERSION_PATTERN="${OLD_VERSION//./\\.}" 131 - find . -type f -name 'Cargo.toml' -not -path './.git/*' \ 132 - -exec $SED -i "s/$VERSION_PATTERN/$NEW_VERSION/g" {} \; 133 - ``` 134 - 135 - 3. Run `cargo check` to update `Cargo.lock`. 136 - 137 - 4. Show `git diff --stat` and the version-related lines from the diff: 138 - ```bash 139 - git diff --unified=0 -- '*.toml' | grep '^\+.*version' | grep -vF '+++' 140 - ``` 141 - Remember to use macOS grep arguments on macOS systems. 142 - 143 - 5. Verify the workspace version was actually updated by re-reading it 144 - from `Cargo.toml`. 145 - 146 - 6. **Checkpoint:** Show the diff summary and ask the user to confirm the 147 - version changes look correct. 148 - 149 - --- 150 - 151 - ## Step 5 — Update Changelog 152 - 153 - The changelog strategy differs for prereleases vs stable releases: 154 - 155 - - **Prerelease:** Maintain a running `## [unreleased]` section containing 156 - all changes since the last stable release. Use: 157 - `git-cliff --unreleased --strip all` 158 - (cliff.toml's `ignore_tags` already ignores beta/alpha tags, so 159 - `--unreleased` spans back to the last stable release automatically.) 160 - 161 - - **Stable release:** Generate a versioned entry that replaces the 162 - `[unreleased]` section. Use: 163 - `git-cliff --unreleased --tag "v<VERSION>" --strip all` 164 - 165 - Then update `CHANGELOG.md`: 166 - 167 - 1. If an existing `## [unreleased]` or `## [Unreleased]` section exists, 168 - **remove it entirely** (the heading and all content up to the next 169 - `## ` heading). 170 - 171 - 2. Insert the new entry before the first existing `## ` version heading. 172 - 173 - 3. **Checkpoint:** Read and display the new changelog entry to the user. 174 - Ask if they want any edits. If so, make the requested changes using 175 - the Edit tool. Repeat until they're satisfied. 176 - 177 - --- 178 - 179 - ## Step 6 — Commit & Push 180 - 181 - Stage all changes and commit: 182 - 183 - ``` 184 - chore(release): prepare for release <VERSION> 185 - ``` 186 - 187 - Push the branch with `--set-upstream origin`. 188 - 189 - --- 190 - 191 - ## Step 7 — Create PR & Wait for Merge 192 - 193 - ### Create the PR 194 - 195 - Extract the changelog entry body (everything between the new `## ` heading 196 - and the next one) for the PR description. 197 - 198 - For prereleases, the heading to match is `## [unreleased]`. 199 - For stable releases, it's `## <VERSION>` (escape dots in the awk pattern). 200 - 201 - Create the PR: 202 - ```bash 203 - gh pr create \ 204 - --title "chore(release): prepare for release <VERSION>" \ 205 - --body "<body with changelog>" \ 206 - --repo atuinsh/atuin \ 207 - --draft 208 - ``` 209 - 210 - Show the PR URL to the user. Tell the user to go review and merge the PR. 211 - 212 - When the user reports the PR is merged, proceed to the next step. 213 - 214 - --- 215 - 216 - ## Step 7.5 — Merge `merge-immediately-before-release` PRs 217 - 218 - Skip to Step 8 unless Step 2.5 recorded approved PRs with this label. 219 - 220 - The prep PR has merged and the tag does not exist yet. This is the only window 221 - in which these PRs land in `v<VERSION>` and its artifacts. 222 - 223 - For each approved PR: 224 - 225 - 1. Check it is still mergeable and its checks are green: 226 - ```bash 227 - gh pr view <N> --repo atuinsh/atuin \ 228 - --json mergeable,mergeStateStatus,statusCheckRollup 229 - ``` 230 - If it is not mergeable, or checks are red, report that and ask the user how 231 - to proceed. Do not force it through. 232 - 233 - 2. **Checkpoint:** Show the PR number and title and ask the user to confirm this 234 - specific merge. Step 2.5 approved the *timing*; this confirms merging *now*. 235 - 236 - 3. Merge: 237 - ```bash 238 - gh pr merge <N> --repo atuinsh/atuin --squash 239 - ``` 240 - 241 - These commits land in the tag but are absent from the changelog generated in 242 - Step 5, which was cut before they merged. That is expected — do not regenerate 243 - the changelog to include them. 244 - 245 - --- 246 - 247 - ## Step 8 — Tag Release 248 - 249 - Back in the working directory: 250 - 251 - ```bash 252 - git checkout main 253 - git pull 254 - git tag "v<VERSION>" 255 - git push --tags 256 - ``` 257 - 258 - Tell the user the tag was pushed and the release CI workflow has been 259 - triggered. 260 - 261 - --- 262 - 263 - ## Step 8.5 — Merge `merge-immediately-after-release` PRs 264 - 265 - Skip to Step 9 unless Step 2.5 recorded approved PRs with this label. 266 - 267 - "After the release" means **after the release workflow has finished and the 268 - assets exist** — not merely after the tag was pushed. These PRs deploy the 269 - instant they merge, so a docs change announcing the new version must not go 270 - live while the release it points at is still building. 271 - 272 - 1. Wait for the release workflow the tag just triggered: 273 - ```bash 274 - gh run list --repo atuinsh/atuin --workflow release.yml \ 275 - --branch "v<VERSION>" --limit 1 276 - gh run watch <run-id> --repo atuinsh/atuin --exit-status 277 - ``` 278 - `--exit-status` is what makes a failed run exit non-zero. Without it 279 - `gh run watch` prints the failure but still exits `0`, and a broken release 280 - sails through into the merges below. If it exits non-zero, **stop** here — 281 - do not go on to the release lookup. 282 - 283 - 2. Confirm the release exists and has assets attached: 284 - ```bash 285 - gh release view "v<VERSION>" --repo atuinsh/atuin --json assets,isDraft 286 - ``` 287 - If the release is missing, is still a draft, or has no assets, **stop**. 288 - Report it and merge nothing — these PRs keep until the release is actually 289 - out. A release object alone is not evidence: it may predate this run or have 290 - been left half-built by a failed workflow. What clears this gate is a 291 - non-draft release with assets attached. 292 - 293 - 3. Re-check that each approved PR is still mergeable and its checks are green: 294 - ```bash 295 - gh pr view <N> --repo atuinsh/atuin \ 296 - --json mergeable,mergeStateStatus,statusCheckRollup 297 - ``` 298 - Step 2.5 surveyed these PRs before the release was even built, so its 299 - findings are now many minutes stale — long enough for a PR to pick up a 300 - conflict or a red check. If it is not mergeable, or checks are red, report 301 - that and ask the user how to proceed. Do not force it through. These PRs 302 - deploy the instant they merge, so there is no CI gate downstream to catch a 303 - bad one. 304 - 305 - 4. **Checkpoint:** For each approved PR, show its number and title and ask the 306 - user to confirm this specific merge. Step 2.5 approved the *timing*; this 307 - confirms merging *now*. 308 - 309 - 5. Merge each PR the user confirms: 310 - ```bash 311 - gh pr merge <N> --repo atuinsh/atuin --squash 312 - ``` 313 - 314 - Merging a `docs/` change here fires `trigger-docs-deploy.yml` and the docs go 315 - out immediately. That is the whole point of the label. 316 - 317 - --- 318 - 319 - ## Step 9 — Publish to crates.io 320 - 321 - **If this is a prerelease**, skip this step entirely and tell the user. 322 - 323 - **If this is a stable release**, ask the user whether to publish. 324 - 325 - If yes, publish each crate **in dependency order** using `--no-verify` 326 - (the code already passed CI, and verification fails when crates.io 327 - hasn't indexed a freshly-published dependency yet): 328 - 329 - ``` 330 - atuin-common, atuin-client, atuin-ai, atuin-dotfiles, atuin-history, 331 - atuin-nucleo/matcher, atuin-nucleo, atuin-daemon, atuin-kv, 332 - atuin-scripts, atuin-server-database, atuin-server-postgres, 333 - atuin-server-sqlite, atuin-server, atuin-pty-proxy, atuin 334 - ``` 335 - 336 - For each crate, run from `crates/<name>`: 337 - ```bash 338 - cargo publish --no-verify 2>&1 339 - ``` 340 - 341 - If it fails with "already uploaded", report it as a skip (not an error) — 342 - some crates like `atuin-nucleo` are versioned independently and may 343 - already be published at their current version. 344 - 345 - If it fails for any other reason, stop and report the error. 346 - 347 - --- 348 - 349 - ## Completion 350 - 351 - Summarize what was done: 352 - - Version released 353 - - PR URL 354 - - Tag name 355 - - Which label-timed PRs were merged, and which the user declined (if any) 356 - - Which crates were published (if any) 357 - - Working directory path and how to clean it up (`rm -rf`)
-154
.claude/skills/hunk/SKILL.md
··· 1 - --- 2 - name: hunk-review 3 - description: Interacts with live Hunk diff review sessions via CLI. Inspects review focus, navigates files and hunks, reloads session contents, and adds inline review comments. Use when the user has a Hunk session running or wants to review diffs interactively. 4 - --- 5 - 6 - # Hunk Review 7 - 8 - Hunk is an interactive terminal diff viewer. The TUI is for the user -- do NOT run `hunk diff`, `hunk show`, or other interactive commands directly. Use `hunk session *` CLI commands to inspect and control live sessions through the local daemon. 9 - 10 - If no session exists, ask the user to launch Hunk in their terminal first. 11 - 12 - ## Workflow 13 - 14 - ```text 15 - 1. hunk session list # find live sessions 16 - 2. hunk session get --repo . # inspect path / repo / source 17 - 3. hunk session review --repo . --json # inspect file/hunk structure first 18 - 4. hunk session review --repo . --include-patch --json # opt into raw diff text only when needed 19 - 5. hunk session context --repo . # check current focus when needed 20 - 6. hunk session navigate ... # move to the right place 21 - 7. hunk session reload -- <command> # swap contents if needed 22 - 8. hunk session comment add ... # leave one review note 23 - 9. hunk session comment apply ... # apply many agent notes in one stdin batch 24 - ``` 25 - 26 - ## Session selection 27 - 28 - Most session commands accept: 29 - 30 - - `--repo <path>` -- match the live session by its current loaded repo root (most common) 31 - - `<session-id>` -- match by exact ID (use when multiple sessions share a repo) 32 - - If only one session exists, it auto-resolves 33 - 34 - `reload` also supports: 35 - 36 - - `--session-path <path>` -- match the live Hunk window by its current working directory 37 - - `--source <path>` -- load the replacement `diff` / `show` command from a different directory 38 - 39 - Use `--source` only for advanced reloads where the live session you want to control is not already associated with the checkout you want to load next. For a normal worktree session, prefer selecting it directly with `--repo /path/to/worktree`. 40 - 41 - ## Commands 42 - 43 - ### Inspect 44 - 45 - ```bash 46 - hunk session list [--json] 47 - hunk session get (--repo . | <id>) [--json] 48 - hunk session context (--repo . | <id>) [--json] 49 - hunk session review (--repo . | <id>) [--json] [--include-patch] 50 - ``` 51 - 52 - - `get` shows the session `Path`, `Repo`, and `Source`, which helps when choosing between `--repo` and `--session-path` 53 - - `Repo` is what `--repo` matches; `Path` is what `--session-path` matches 54 - - `review --json` returns file and hunk structure by default; add `--include-patch` only when a caller truly needs raw unified diff text 55 - 56 - ### Navigate 57 - 58 - Absolute navigation requires `--file` and exactly one of `--hunk`, `--new-line`, or `--old-line`: 59 - 60 - ```bash 61 - hunk session navigate --repo . --file src/App.tsx --hunk 2 62 - hunk session navigate --repo . --file src/App.tsx --new-line 372 63 - hunk session navigate --repo . --file src/App.tsx --old-line 355 64 - ``` 65 - 66 - Relative comment navigation jumps between annotated hunks and does not require `--file`: 67 - 68 - ```bash 69 - hunk session navigate --repo . --next-comment 70 - hunk session navigate --repo . --prev-comment 71 - ``` 72 - 73 - - `--hunk <n>` is 1-based 74 - - `--new-line` / `--old-line` are 1-based line numbers on that diff side 75 - - Use either `--next-comment` or `--prev-comment`, not both 76 - 77 - ### Reload 78 - 79 - Swaps the live session's contents. Pass a Hunk review command after `--`: 80 - 81 - ```bash 82 - hunk session reload --repo . -- diff 83 - hunk session reload --repo . -- diff main...feature -- src/ui 84 - hunk session reload --repo . -- show HEAD~1 85 - hunk session reload --repo . -- show HEAD~1 -- README.md 86 - hunk session reload --repo /path/to/worktree -- diff 87 - hunk session reload --session-path /path/to/live-window --source /path/to/other-checkout -- diff 88 - ``` 89 - 90 - - Always include `--` before the nested Hunk command 91 - - `--repo` or `<session-id>` usually selects the session you want 92 - - `--source` is advanced: it does not select the session; it only changes where the replacement review command runs 93 - - If the live session is already showing the target worktree, prefer `hunk session reload --repo /path/to/worktree -- diff` 94 - - `--session-path` targets the live window when you need to keep session selection separate from reload source 95 - 96 - ### Comments 97 - 98 - ```bash 99 - hunk session comment add --repo . --file README.md --new-line 103 --summary "Tighten this wording" [--rationale "..."] [--author "agent"] [--focus] 100 - printf '%s\n' '{"comments":[{"filePath":"README.md","newLine":103,"summary":"Tighten this wording"}]}' | hunk session comment apply --repo . --stdin [--focus] 101 - hunk session comment list --repo . [--file README.md] 102 - hunk session comment rm --repo . <comment-id> 103 - hunk session comment clear --repo . --yes [--file README.md] 104 - ``` 105 - 106 - - `comment add` is best for one note; `comment apply` is best when an agent already has several notes ready 107 - - `comment add` requires `--file`, `--summary`, and exactly one of `--old-line` or `--new-line` 108 - - `comment apply` payload items require `filePath`, `summary`, and exactly one target such as `hunk`, `hunkNumber`, `oldLine`, or `newLine` 109 - - `comment apply` reads a JSON batch from stdin and validates the full batch before mutating the live session 110 - - Pass `--focus` when you want to jump to the new note or the first note in a batch 111 - - `comment list` and `comment clear` accept optional `--file` 112 - - Quote `--summary` and `--rationale` defensively in the shell 113 - 114 - ## New files in working-tree reviews 115 - 116 - `hunk diff` includes untracked files by default. If the user wants tracked changes only, reload with `--exclude-untracked`: 117 - 118 - ```bash 119 - hunk session reload --repo . -- diff --exclude-untracked 120 - ``` 121 - 122 - ## Guiding a review 123 - 124 - The user may ask you to walk them through a changeset or review code using Hunk. Start with `hunk session review --json` to understand the file/hunk structure without inflating agent context, then use `--include-patch` only for the files you truly need to read in raw diff form. Use `context` and `navigate` to line up the user's current view before adding comments. 125 - 126 - Your role is to narrate: steer the user's view to what matters and leave comments that explain what they're looking at. 127 - 128 - Typical flow: 129 - 130 - 1. Load the right content (`reload` if needed) 131 - 2. Navigate to the first interesting file / hunk 132 - 3. Add a comment explaining what's happening and why 133 - 4. If you already have several notes ready, prefer one `comment apply` batch over many separate shell invocations 134 - 5. Summarize when done 135 - 136 - Guidelines: 137 - 138 - - Work in the order that tells the clearest story, not necessarily file order 139 - - Navigate before commenting so the user sees the code you're discussing 140 - - Use `comment apply` for agent-generated batches and `comment add` for one-off notes 141 - - Use `--focus` sparingly when the note itself should actively steer the review 142 - - Keep comments focused: intent, structure, risks, or follow-ups 143 - - Don't comment on every hunk -- highlight what the user wouldn't spot themselves 144 - 145 - ## Common errors 146 - 147 - - **"No visible diff file matches ..."** -- the file is not in the loaded review. Check `context`, then `reload` if needed. 148 - - **"No active Hunk sessions"** -- ask the user to open Hunk in their terminal. 149 - - **"Multiple active sessions match"** -- pass `<session-id>` explicitly. 150 - - **"No active Hunk session matches session path ..."** -- for advanced split-path reloads, verify the live window `Path` via `hunk session get` or `list`, then use `--session-path`. 151 - - **"Pass the replacement Hunk command after `--`"** -- include `--` before the nested `diff` / `show` command. 152 - - **"Pass --stdin to read batch comments from stdin JSON."** -- `comment apply` only reads its batch payload from stdin. 153 - - **"Specify exactly one navigation target"** -- pick one of `--hunk`, `--old-line`, or `--new-line`. 154 - - **"Specify either --next-comment or --prev-comment, not both."** -- choose one comment-navigation direction.
-7
.codespellrc
··· 1 - [codespell] 2 - # Ref: https://github.com/codespell-project/codespell#using-a-config-file 3 - skip = .git*,*.lock,.codespellrc,CODE_OF_CONDUCT.md,CONTRIBUTORS 4 - check-hidden = true 5 - # ignore-regex = 6 - ignore-words-list = crate,ratatui,inbetween,iterm,fo,brunch 7 -
-28
.depot/workflows/codespell.yml
··· 1 - # Depot CI Migration 2 - # Source: .github/workflows/codespell.yml 3 - # 4 - # No changes were necessary. 5 - 6 - # Codespell configuration is within .codespellrc 7 - name: Codespell 8 - on: 9 - push: 10 - branches: [main] 11 - pull_request: 12 - branches: [main] 13 - permissions: 14 - contents: read 15 - jobs: 16 - codespell: 17 - name: Check for spelling errors 18 - runs-on: depot-ubuntu-24.04 19 - steps: 20 - - name: Checkout 21 - uses: actions/checkout@v6 22 - - name: Codespell 23 - uses: codespell-project/actions-codespell@v2 24 - with: 25 - # This is regenerated from commit history 26 - # we cannot rewrite commit history, and I'd rather not correct it 27 - # every time 28 - exclude_file: CHANGELOG.md
-36
.depot/workflows/installer.yml
··· 1 - # Depot CI Migration 2 - # Source: .github/workflows/installer.yml 3 - # 4 - # No changes were necessary. 5 - 6 - name: Install 7 - on: 8 - push: 9 - branches: [main] 10 - pull_request: 11 - paths: .github/workflows/installer.yml 12 - env: 13 - CARGO_TERM_COLOR: always 14 - jobs: 15 - install: 16 - strategy: 17 - matrix: 18 - os: [depot-ubuntu-24.04, macos-14] 19 - runs-on: ${{ matrix.os }} 20 - steps: 21 - - uses: actions/checkout@v6 22 - - name: Install zsh for ubuntu 23 - if: matrix.os == 'depot-ubuntu-24.04' 24 - run: | 25 - sudo apt install zsh 26 - - name: Test install script on bash 27 - run: | 28 - /bin/bash -c "$(curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh)" 29 - [ -d "$HOME/.atuin" ] && source $HOME/.atuin/bin/env 30 - atuin --help 31 - - name: Test install script on zsh 32 - shell: zsh {0} 33 - run: | 34 - /bin/bash -c "$(curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh)" 35 - [ -d "$HOME/.atuin" ] && source $HOME/.atuin/bin/env 36 - atuin --help
-33
.depot/workflows/nix.yml
··· 1 - # Depot CI Migration 2 - # Source: .github/workflows/nix.yml 3 - # 4 - # No changes were necessary. 5 - 6 - # Verify the Nix build is working 7 - # Failures will usually occur due to an out of date Rust version 8 - # That can be updated to the latest version in nixpkgs-unstable with `nix flake update` 9 - name: Nix 10 - on: 11 - push: 12 - branches: [main] 13 - paths-ignore: 14 - - 'ui/**' 15 - pull_request: 16 - branches: [main] 17 - paths-ignore: 18 - - 'ui/**' 19 - jobs: 20 - check: 21 - runs-on: depot-ubuntu-24.04 22 - steps: 23 - - uses: actions/checkout@v6 24 - - uses: cachix/install-nix-action@v31 25 - - name: Run nix flake check 26 - run: nix flake check --print-build-logs 27 - build-test: 28 - runs-on: depot-ubuntu-24.04 29 - steps: 30 - - uses: actions/checkout@v6 31 - - uses: cachix/install-nix-action@v31 32 - - name: Run nix build 33 - run: nix build --print-build-logs
-187
.depot/workflows/rust.yml
··· 1 - # Depot CI Migration 2 - # Source: .github/workflows/rust.yml 3 - # 4 - # No changes were necessary. 5 - 6 - name: Rust 7 - on: 8 - push: 9 - branches: [main] 10 - paths-ignore: 11 - - "ui/**" 12 - pull_request: 13 - branches: [main] 14 - paths-ignore: 15 - - "ui/**" 16 - env: 17 - CARGO_TERM_COLOR: always 18 - jobs: 19 - build: 20 - strategy: 21 - matrix: 22 - os: [depot-ubuntu-24.04, macos-14, windows-latest] 23 - runs-on: ${{ matrix.os }} 24 - steps: 25 - - uses: actions/checkout@v6 26 - - name: Install rust 27 - uses: dtolnay/rust-toolchain@master 28 - with: 29 - toolchain: 1.94.0 30 - - uses: actions/cache@v5 31 - with: 32 - path: | 33 - ~/.cargo/registry 34 - ~/.cargo/git 35 - target 36 - key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }} 37 - - name: Run cargo build common 38 - run: cargo build -p atuin-common --locked --release 39 - - name: Run cargo build client 40 - run: cargo build -p atuin-client --locked --release 41 - - name: Run cargo build server 42 - run: cargo build -p atuin-server --locked --release 43 - - name: Run cargo build main 44 - run: cargo build --all --locked --release 45 - cross-compile: 46 - strategy: 47 - matrix: 48 - # There was an attempt to make cross-compiles also work on FreeBSD, but that failed with: 49 - # 50 - # warning: libelf.so.2, needed by <...>/libkvm.so, not found (try using -rpath or -rpath-link) 51 - target: [x86_64-unknown-illumos] 52 - runs-on: depot-ubuntu-24.04 53 - steps: 54 - - uses: actions/checkout@v6 55 - - name: Install cross 56 - uses: taiki-e/install-action@v2 57 - with: 58 - tool: cross 59 - - uses: actions/cache@v5 60 - with: 61 - path: | 62 - ~/.cargo/registry 63 - ~/.cargo/git 64 - target 65 - key: ${{ matrix.target }}-cross-compile-${{ hashFiles('**/Cargo.lock') }} 66 - - name: Run cross build common 67 - run: cross build -p atuin-common --locked --target ${{ matrix.target }} 68 - - name: Run cross build client 69 - run: cross build -p atuin-client --locked --target ${{ matrix.target }} 70 - - name: Run cross build server 71 - run: cross build -p atuin-server --locked --target ${{ matrix.target }} 72 - - name: Run cross build main 73 - run: | 74 - cross build --all --locked --target ${{ matrix.target }} 75 - unit-test: 76 - strategy: 77 - matrix: 78 - os: [depot-ubuntu-24.04, macos-14, windows-latest] 79 - runs-on: ${{ matrix.os }} 80 - steps: 81 - - uses: actions/checkout@v6 82 - - name: Install rust 83 - uses: dtolnay/rust-toolchain@master 84 - with: 85 - toolchain: 1.94.0 86 - - uses: taiki-e/install-action@v2 87 - name: Install nextest 88 - with: 89 - tool: cargo-nextest 90 - - uses: actions/cache@v5 91 - with: 92 - path: | 93 - ~/.cargo/registry 94 - ~/.cargo/git 95 - target 96 - key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }} 97 - - name: Run cargo test 98 - run: cargo nextest run --lib --bins 99 - check: 100 - strategy: 101 - matrix: 102 - os: [depot-ubuntu-24.04, macos-14, windows-latest] 103 - runs-on: ${{ matrix.os }} 104 - steps: 105 - - uses: actions/checkout@v6 106 - - name: Install rust 107 - uses: dtolnay/rust-toolchain@master 108 - with: 109 - toolchain: 1.94.0 110 - - uses: actions/cache@v5 111 - with: 112 - path: | 113 - ~/.cargo/registry 114 - ~/.cargo/git 115 - target 116 - key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }} 117 - - name: Run cargo check (all features) 118 - run: cargo check --all-features --workspace 119 - - name: Run cargo check (no features) 120 - run: cargo check --no-default-features --workspace 121 - - name: Run cargo check (sync) 122 - run: cargo check --no-default-features --features sync --workspace 123 - - name: Run cargo check (server) 124 - run: cargo check -p atuin-server 125 - - name: Run cargo check (client only) 126 - run: cargo check --no-default-features --features client --workspace 127 - integration-test: 128 - runs-on: depot-ubuntu-24.04 129 - services: 130 - postgres: 131 - image: postgres 132 - env: 133 - POSTGRES_USER: atuin 134 - POSTGRES_PASSWORD: pass 135 - POSTGRES_DB: atuin 136 - ports: 137 - - 5432:5432 138 - steps: 139 - - uses: actions/checkout@v6 140 - - name: Install rust 141 - uses: dtolnay/rust-toolchain@master 142 - with: 143 - toolchain: 1.94.0 144 - - uses: taiki-e/install-action@v2 145 - name: Install nextest 146 - with: 147 - tool: cargo-nextest 148 - - uses: actions/cache@v5 149 - with: 150 - path: | 151 - ~/.cargo/registry 152 - ~/.cargo/git 153 - target 154 - key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }} 155 - - name: Run cargo test 156 - run: cargo nextest run --test '*' 157 - env: 158 - ATUIN_DB_URI: postgres://atuin:pass@localhost:5432/atuin 159 - clippy: 160 - runs-on: depot-ubuntu-24.04 161 - steps: 162 - - uses: actions/checkout@v6 163 - - name: Install latest rust 164 - uses: dtolnay/rust-toolchain@master 165 - with: 166 - toolchain: 1.94.0 167 - components: clippy 168 - - uses: actions/cache@v5 169 - with: 170 - path: | 171 - ~/.cargo/registry 172 - ~/.cargo/git 173 - target 174 - key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }} 175 - - name: Run clippy 176 - run: cargo clippy -- -D warnings -D clippy::redundant_clone 177 - format: 178 - runs-on: depot-ubuntu-24.04 179 - steps: 180 - - uses: actions/checkout@v6 181 - - name: Install latest rust 182 - uses: dtolnay/rust-toolchain@master 183 - with: 184 - toolchain: 1.94.0 185 - components: rustfmt 186 - - name: Format 187 - run: cargo fmt -- --check
-20
.depot/workflows/shellcheck.yml
··· 1 - # Depot CI Migration 2 - # Source: .github/workflows/shellcheck.yml 3 - # 4 - # No changes were necessary. 5 - 6 - name: Shellcheck 7 - on: 8 - push: 9 - branches: [main] 10 - pull_request: 11 - branches: [main] 12 - jobs: 13 - shellcheck: 14 - runs-on: depot-ubuntu-24.04 15 - steps: 16 - - uses: actions/checkout@v6 17 - - name: Run shellcheck 18 - uses: ludeeus/action-shellcheck@master 19 - env: 20 - SHELLCHECK_OPTS: "-e SC2148"
-25
.depot/workflows/update-nix-deps.yml
··· 1 - # Depot CI Migration 2 - # Source: .github/workflows/update-nix-deps.yml 3 - # 4 - # No changes were necessary. 5 - 6 - name: Update Nix Deps 7 - on: 8 - workflow_dispatch: # allows manual triggering 9 - schedule: 10 - - cron: '0 0 1 * *' # runs monthly on the first day of the month at 00:00 11 - jobs: 12 - lockfile: 13 - runs-on: depot-ubuntu-24.04 14 - if: github.repository == 'atuinsh/atuin' 15 - steps: 16 - - name: Checkout repository 17 - uses: actions/checkout@v6 18 - - name: Install Nix 19 - uses: DeterminateSystems/nix-installer-action@main 20 - - name: Update flake.lock 21 - uses: DeterminateSystems/update-flake-lock@main 22 - with: 23 - pr-title: "chore(deps): update flake.lock" 24 - pr-labels: | 25 - dependencies
-2
.dockerignore
··· 1 - ./target 2 - Dockerfile
-8
.editorconfig
··· 1 - root = true 2 - 3 - [*.rs] 4 - indent_style = space 5 - indent_size = 4 6 - max_line_length = 100 7 - insert_final_newline = true 8 - trim_trailing_whitespace = true
.fossier.db

This is a binary file and will not be displayed.

-84
.github/DISCUSSION_TEMPLATE/support.yml
··· 1 - body: 2 - - type: input 3 - attributes: 4 - label: Operating System 5 - description: What operating system are you using? 6 - placeholder: "Example: macOS Big Sur" 7 - validations: 8 - required: true 9 - 10 - - type: input 11 - attributes: 12 - label: Shell 13 - description: What shell are you using? 14 - placeholder: "Example: zsh 5.8.1" 15 - validations: 16 - required: true 17 - 18 - - type: dropdown 19 - attributes: 20 - label: Version 21 - description: What version of atuin are you running? 22 - multiple: false 23 - options: # how often will I forget to update this? a lot. 24 - - v17.0.0 (Default) 25 - - v16.0.0 26 - - v15.0.0 27 - - v14.0.1 28 - - v14.0.0 29 - - v13.0.1 30 - - v13.0.0 31 - - v12.0.0 32 - - v11.0.0 33 - - v0.10.0 34 - - v0.9.1 35 - - v0.9.0 36 - - v0.8.1 37 - - v0.8.0 38 - - v0.7.2 39 - - v0.7.1 40 - - v0.7.0 41 - - v0.6.4 42 - - v0.6.3 43 - default: 0 44 - validations: 45 - required: true 46 - 47 - - type: checkboxes 48 - attributes: 49 - label: Self hosted 50 - description: Are you self hosting atuin server? 51 - options: 52 - - label: I am self hosting atuin server 53 - 54 - - type: checkboxes 55 - attributes: 56 - label: Search the issues 57 - description: Did you search the issues and discussions for your problem? 58 - options: 59 - - label: I checked that someone hasn't already asked about the same issue 60 - required: true 61 - 62 - - type: textarea 63 - attributes: 64 - label: Behaviour 65 - description: "Please describe the issue - what you expected to happen, what actually happened" 66 - 67 - - type: textarea 68 - attributes: 69 - label: Logs 70 - description: "If possible, please include logs from atuin, especially if you self host the server - ATUIN_LOG=debug" 71 - 72 - - type: textarea 73 - attributes: 74 - label: Extra information 75 - description: "Anything else you'd like to add?" 76 - 77 - - type: checkboxes 78 - attributes: 79 - label: Code of Conduct 80 - description: The Code of Conduct helps create a safe space for everyone. We require 81 - that everyone agrees to it. 82 - options: 83 - - label: I agree to follow this project's [Code of Conduct](https://github.com/atuinsh/atuin/blob/main/CODE_OF_CONDUCT.md) 84 - required: true
-13
.github/FUNDING.yml
··· 1 - # These are supported funding model platforms 2 - 3 - github: [atuinsh] 4 - patreon: # Replace with a single Patreon username 5 - open_collective: # Replace with a single Open Collective username 6 - ko_fi: # Replace with a single Ko-fi username 7 - tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 - community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 - liberapay: # Replace with a single Liberapay username 10 - issuehunt: # Replace with a single IssueHunt username 11 - otechie: # Replace with a single Otechie username 12 - lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 - custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
-39
.github/ISSUE_TEMPLATE/bug.yaml
··· 1 - name: Bug Report 2 - description: File a bug report 3 - title: "[Bug]: " 4 - labels: ["bug", "triage"] 5 - body: 6 - - type: markdown 7 - attributes: 8 - value: | 9 - Thanks for taking the time to fill out this bug report! 10 - - type: textarea 11 - id: what-expected 12 - attributes: 13 - label: What did you expect to happen? 14 - placeholder: Tell us what you expected to see! 15 - validations: 16 - required: true 17 - - type: textarea 18 - id: what-happened 19 - attributes: 20 - label: What happened? 21 - placeholder: Tell us what you see! 22 - validations: 23 - required: true 24 - - type: textarea 25 - id: doctor 26 - validations: 27 - required: true 28 - attributes: 29 - label: Atuin doctor output 30 - description: Please run 'atuin doctor' and share the output. If it fails to run, share any errors. This requires Atuin >=v18.1.0 31 - render: yaml 32 - - type: checkboxes 33 - id: terms 34 - attributes: 35 - label: Code of Conduct 36 - description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/atuinsh/atuin/blob/main/CODE_OF_CONDUCT.md) 37 - options: 38 - - label: I agree to follow this project's Code of Conduct 39 - required: true
-19
.github/dependabot.yml
··· 1 - # To get started with Dependabot version updates, you'll need to specify which 2 - # package ecosystems to update and where the package manifests are located. 3 - # Please see the documentation for all configuration options: 4 - # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 - 6 - version: 2 7 - updates: 8 - - package-ecosystem: "cargo" # See documentation for possible values 9 - directory: "/" # Location of package manifests 10 - schedule: 11 - interval: "weekly" 12 - - package-ecosystem: "docker" # See documentation for possible values 13 - directory: "/" # Location of package manifests 14 - schedule: 15 - interval: "weekly" 16 - - package-ecosystem: "github-actions" 17 - directory: "/" 18 - schedule: 19 - interval: "weekly"
-5
.github/pull_request_template.md
··· 1 - <!-- Thank you for making a PR! Bug fixes are always welcome, but if you're adding a new feature or changing an existing one, we'd really appreciate if you open an issue, post on the forum, or drop in on Discord --> 2 - 3 - ## Checks 4 - - [ ] I am happy for maintainers to push small adjustments to this PR, to speed up the review cycle 5 - - [ ] I have checked that there are no existing pull requests for the same thing
-28
.github/workflows/codespell.yml
··· 1 - # Codespell configuration is within .codespellrc 2 - --- 3 - name: Codespell 4 - 5 - on: 6 - push: 7 - branches: [main] 8 - pull_request: 9 - branches: [main] 10 - 11 - permissions: 12 - contents: read 13 - 14 - jobs: 15 - codespell: 16 - name: Check for spelling errors 17 - runs-on: depot-ubuntu-24.04 18 - 19 - steps: 20 - - name: Checkout 21 - uses: actions/checkout@v6 22 - - name: Codespell 23 - uses: codespell-project/actions-codespell@v2 24 - with: 25 - # This is regenerated from commit history 26 - # we cannot rewrite commit history, and I'd rather not correct it 27 - # every time 28 - exclude_file: CHANGELOG.md
-61
.github/workflows/docker.yaml
··· 1 - name: build-docker 2 - 3 - on: 4 - push: 5 - branches: [main] 6 - tags: 7 - - 'v*' 8 - 9 - jobs: 10 - publish: 11 - concurrency: 12 - group: ${{ github.ref }}-docker 13 - cancel-in-progress: true 14 - permissions: 15 - packages: write 16 - contents: read 17 - id-token: write 18 - 19 - runs-on: depot-ubuntu-24.04 20 - steps: 21 - - uses: actions/checkout@v6 22 - 23 - - name: Get Repo Owner 24 - id: get_repo_owner 25 - run: echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" > $GITHUB_ENV 26 - 27 - - uses: depot/setup-action@v1 28 - 29 - - name: Login to container Registry 30 - uses: docker/login-action@v3 31 - with: 32 - username: ${{ github.repository_owner }} 33 - password: ${{ secrets.GITHUB_TOKEN }} 34 - registry: ghcr.io 35 - 36 - - name: Docker meta 37 - id: meta 38 - uses: docker/metadata-action@v5 39 - with: 40 - images: ghcr.io/${{ env.REPO_OWNER }}/atuin 41 - flavor: | 42 - latest=false 43 - tags: | 44 - type=ref,event=branch 45 - type=sha,prefix= 46 - type=semver,pattern={{version}} 47 - type=semver,pattern={{major}}.{{minor}} 48 - 49 - - name: Build and push 50 - uses: depot/build-push-action@v1 51 - with: 52 - push: true 53 - platforms: linux/amd64,linux/arm64 54 - file: ./Dockerfile 55 - context: . 56 - provenance: false 57 - build-args: | 58 - Version=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] || 'dev' }} 59 - GitCommit=${{ github.sha }} 60 - tags: ${{ steps.meta.outputs.tags }} 61 - labels: ${{ steps.meta.outputs.labels }}
-38
.github/workflows/installer.yml
··· 1 - name: Install 2 - 3 - on: 4 - push: 5 - branches: [main] 6 - pull_request: 7 - paths: .github/workflows/installer.yml 8 - 9 - env: 10 - CARGO_TERM_COLOR: always 11 - 12 - jobs: 13 - install: 14 - strategy: 15 - matrix: 16 - os: [depot-ubuntu-24.04, macos-14] 17 - runs-on: ${{ matrix.os }} 18 - 19 - steps: 20 - - uses: actions/checkout@v6 21 - 22 - - name: Install zsh for ubuntu 23 - if: matrix.os == 'depot-ubuntu-24.04' 24 - run: | 25 - sudo apt install zsh 26 - 27 - - name: Test install script on bash 28 - run: | 29 - /bin/bash -c "$(curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh)" 30 - [ -d "$HOME/.atuin" ] && source $HOME/.atuin/bin/env 31 - atuin --help 32 - 33 - - name: Test install script on zsh 34 - shell: zsh {0} 35 - run: | 36 - /bin/bash -c "$(curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh)" 37 - [ -d "$HOME/.atuin" ] && source $HOME/.atuin/bin/env 38 - atuin --help
-34
.github/workflows/nix.yml
··· 1 - # Verify the Nix build is working 2 - # Failures will usually occur due to an out of date Rust version 3 - # That can be updated to the latest version in nixpkgs-unstable with `nix flake update` 4 - name: Nix 5 - on: 6 - push: 7 - branches: [ main ] 8 - paths-ignore: 9 - - 'ui/**' 10 - pull_request: 11 - branches: [ main ] 12 - paths-ignore: 13 - - 'ui/**' 14 - 15 - jobs: 16 - check: 17 - runs-on: depot-ubuntu-24.04 18 - 19 - steps: 20 - - uses: actions/checkout@v6 21 - - uses: cachix/install-nix-action@v31 22 - 23 - - name: Run nix flake check 24 - run: nix flake check --print-build-logs 25 - 26 - build-test: 27 - runs-on: depot-ubuntu-24.04 28 - 29 - steps: 30 - - uses: actions/checkout@v6 31 - - uses: cachix/install-nix-action@v31 32 - 33 - - name: Run nix build 34 - run: nix build --print-build-logs
-304
.github/workflows/release.yml
··· 1 - # This file was autogenerated by dist: https://axodotdev.github.io/cargo-dist 2 - # 3 - # Copyright 2022-2024, axodotdev 4 - # SPDX-License-Identifier: MIT or Apache-2.0 5 - # 6 - # CI that: 7 - # 8 - # * checks for a Git Tag that looks like a release 9 - # * builds artifacts with dist (archives, installers, hashes) 10 - # * uploads those artifacts to temporary workflow zip 11 - # * on success, uploads the artifacts to a GitHub Release 12 - # 13 - # Note that the GitHub Release will be created with a generated 14 - # title/body based on your changelogs. 15 - 16 - name: Release 17 - permissions: 18 - "contents": "write" 19 - 20 - # This task will run whenever you push a git tag that looks like a version 21 - # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. 22 - # Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where 23 - # PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION 24 - # must be a Cargo-style SemVer Version (must have at least major.minor.patch). 25 - # 26 - # If PACKAGE_NAME is specified, then the announcement will be for that 27 - # package (erroring out if it doesn't have the given version or isn't dist-able). 28 - # 29 - # If PACKAGE_NAME isn't specified, then the announcement will be for all 30 - # (dist-able) packages in the workspace with that version (this mode is 31 - # intended for workspaces with only one dist-able package, or with all dist-able 32 - # packages versioned/released in lockstep). 33 - # 34 - # If you push multiple tags at once, separate instances of this workflow will 35 - # spin up, creating an independent announcement for each one. However, GitHub 36 - # will hard limit this to 3 tags per commit, as it will assume more tags is a 37 - # mistake. 38 - # 39 - # If there's a prerelease-style suffix to the version, then the release(s) 40 - # will be marked as a prerelease. 41 - on: 42 - pull_request: 43 - push: 44 - tags: 45 - - '**[0-9]+.[0-9]+.[0-9]+*' 46 - 47 - jobs: 48 - # Run 'dist plan' (or host) to determine what tasks we need to do 49 - plan: 50 - runs-on: "ubuntu-22.04" 51 - outputs: 52 - val: ${{ steps.plan.outputs.manifest }} 53 - tag: ${{ !github.event.pull_request && github.ref_name || '' }} 54 - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} 55 - publishing: ${{ !github.event.pull_request }} 56 - env: 57 - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 58 - steps: 59 - - uses: actions/checkout@v6 60 - with: 61 - persist-credentials: false 62 - submodules: recursive 63 - - name: Install dist 64 - # we specify bash to get pipefail; it guards against the `curl` command 65 - # failing. otherwise `sh` won't catch that `curl` returned non-0 66 - shell: bash 67 - run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.31.0/cargo-dist-installer.sh | sh" 68 - - name: Cache dist 69 - uses: actions/upload-artifact@v6 70 - with: 71 - name: cargo-dist-cache 72 - path: ~/.cargo/bin/dist 73 - # sure would be cool if github gave us proper conditionals... 74 - # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible 75 - # functionality based on whether this is a pull_request, and whether it's from a fork. 76 - # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* 77 - # but also really annoying to build CI around when it needs secrets to work right.) 78 - - id: plan 79 - run: | 80 - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json 81 - echo "dist ran successfully" 82 - cat plan-dist-manifest.json 83 - echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" 84 - - name: "Upload dist-manifest.json" 85 - uses: actions/upload-artifact@v6 86 - with: 87 - name: artifacts-plan-dist-manifest 88 - path: plan-dist-manifest.json 89 - 90 - # Build and packages all the platform-specific things 91 - build-local-artifacts: 92 - name: build-local-artifacts (${{ join(matrix.targets, ', ') }}) 93 - # Let the initial task tell us to not run (currently very blunt) 94 - needs: 95 - - plan 96 - if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }} 97 - strategy: 98 - fail-fast: false 99 - # Target platforms/runners are computed by dist in create-release. 100 - # Each member of the matrix has the following arguments: 101 - # 102 - # - runner: the github runner 103 - # - dist-args: cli flags to pass to dist 104 - # - install-dist: expression to run to install dist on the runner 105 - # 106 - # Typically there will be: 107 - # - 1 "global" task that builds universal installers 108 - # - N "local" tasks that build each platform's binaries and platform-specific installers 109 - matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }} 110 - runs-on: ${{ matrix.runner }} 111 - container: ${{ matrix.container && matrix.container.image || null }} 112 - env: 113 - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 114 - BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json 115 - permissions: 116 - "attestations": "write" 117 - "contents": "read" 118 - "id-token": "write" 119 - steps: 120 - - name: enable windows longpaths 121 - run: | 122 - git config --global core.longpaths true 123 - - uses: actions/checkout@v6 124 - with: 125 - persist-credentials: false 126 - submodules: recursive 127 - - name: Install Rust non-interactively if not already installed 128 - if: ${{ matrix.container }} 129 - run: | 130 - if ! command -v cargo > /dev/null 2>&1; then 131 - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 132 - echo "$HOME/.cargo/bin" >> $GITHUB_PATH 133 - fi 134 - - name: Install dist 135 - run: ${{ matrix.install_dist.run }} 136 - # Get the dist-manifest 137 - - name: Fetch local artifacts 138 - uses: actions/download-artifact@v7 139 - with: 140 - pattern: artifacts-* 141 - path: target/distrib/ 142 - merge-multiple: true 143 - - name: Install dependencies 144 - run: | 145 - ${{ matrix.packages_install }} 146 - - name: Build artifacts 147 - run: | 148 - # Actually do builds and make zips and whatnot 149 - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json 150 - echo "dist ran successfully" 151 - - name: Attest 152 - uses: actions/attest-build-provenance@v3 153 - with: 154 - subject-path: "target/distrib/*${{ join(matrix.targets, ', ') }}*" 155 - - id: cargo-dist 156 - name: Post-build 157 - # We force bash here just because github makes it really hard to get values up 158 - # to "real" actions without writing to env-vars, and writing to env-vars has 159 - # inconsistent syntax between shell and powershell. 160 - shell: bash 161 - run: | 162 - # Parse out what we just built and upload it to scratch storage 163 - echo "paths<<EOF" >> "$GITHUB_OUTPUT" 164 - dist print-upload-files-from-manifest --manifest dist-manifest.json >> "$GITHUB_OUTPUT" 165 - echo "EOF" >> "$GITHUB_OUTPUT" 166 - 167 - cp dist-manifest.json "$BUILD_MANIFEST_NAME" 168 - - name: "Upload artifacts" 169 - uses: actions/upload-artifact@v6 170 - with: 171 - name: artifacts-build-local-${{ join(matrix.targets, '_') }} 172 - path: | 173 - ${{ steps.cargo-dist.outputs.paths }} 174 - ${{ env.BUILD_MANIFEST_NAME }} 175 - 176 - # Build and package all the platform-agnostic(ish) things 177 - build-global-artifacts: 178 - needs: 179 - - plan 180 - - build-local-artifacts 181 - runs-on: "ubuntu-22.04" 182 - env: 183 - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 184 - BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json 185 - steps: 186 - - uses: actions/checkout@v6 187 - with: 188 - persist-credentials: false 189 - submodules: recursive 190 - - name: Install cached dist 191 - uses: actions/download-artifact@v7 192 - with: 193 - name: cargo-dist-cache 194 - path: ~/.cargo/bin/ 195 - - run: chmod +x ~/.cargo/bin/dist 196 - # Get all the local artifacts for the global tasks to use (for e.g. checksums) 197 - - name: Fetch local artifacts 198 - uses: actions/download-artifact@v7 199 - with: 200 - pattern: artifacts-* 201 - path: target/distrib/ 202 - merge-multiple: true 203 - - id: cargo-dist 204 - shell: bash 205 - run: | 206 - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json 207 - echo "dist ran successfully" 208 - 209 - # Parse out what we just built and upload it to scratch storage 210 - echo "paths<<EOF" >> "$GITHUB_OUTPUT" 211 - jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT" 212 - echo "EOF" >> "$GITHUB_OUTPUT" 213 - 214 - cp dist-manifest.json "$BUILD_MANIFEST_NAME" 215 - - name: "Upload artifacts" 216 - uses: actions/upload-artifact@v6 217 - with: 218 - name: artifacts-build-global 219 - path: | 220 - ${{ steps.cargo-dist.outputs.paths }} 221 - ${{ env.BUILD_MANIFEST_NAME }} 222 - # Determines if we should publish/announce 223 - host: 224 - needs: 225 - - plan 226 - - build-local-artifacts 227 - - build-global-artifacts 228 - # Only run if we're "publishing", and only if plan, local and global didn't fail (skipped is fine) 229 - if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} 230 - env: 231 - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 232 - runs-on: "ubuntu-22.04" 233 - outputs: 234 - val: ${{ steps.host.outputs.manifest }} 235 - steps: 236 - - uses: actions/checkout@v6 237 - with: 238 - persist-credentials: false 239 - submodules: recursive 240 - - name: Install cached dist 241 - uses: actions/download-artifact@v7 242 - with: 243 - name: cargo-dist-cache 244 - path: ~/.cargo/bin/ 245 - - run: chmod +x ~/.cargo/bin/dist 246 - # Fetch artifacts from scratch-storage 247 - - name: Fetch artifacts 248 - uses: actions/download-artifact@v7 249 - with: 250 - pattern: artifacts-* 251 - path: target/distrib/ 252 - merge-multiple: true 253 - - id: host 254 - shell: bash 255 - run: | 256 - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json 257 - echo "artifacts uploaded and released successfully" 258 - cat dist-manifest.json 259 - echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" 260 - - name: "Upload dist-manifest.json" 261 - uses: actions/upload-artifact@v6 262 - with: 263 - # Overwrite the previous copy 264 - name: artifacts-dist-manifest 265 - path: dist-manifest.json 266 - # Create a GitHub Release while uploading all files to it 267 - - name: "Download GitHub Artifacts" 268 - uses: actions/download-artifact@v7 269 - with: 270 - pattern: artifacts-* 271 - path: artifacts 272 - merge-multiple: true 273 - - name: Cleanup 274 - run: | 275 - # Remove the granular manifests 276 - rm -f artifacts/*-dist-manifest.json 277 - - name: Create GitHub Release 278 - env: 279 - PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}" 280 - ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" 281 - ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" 282 - RELEASE_COMMIT: "${{ github.sha }}" 283 - run: | 284 - # Write and read notes from a file to avoid quoting breaking things 285 - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt 286 - 287 - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* 288 - 289 - announce: 290 - needs: 291 - - plan 292 - - host 293 - # use "always() && ..." to allow us to wait for all publish jobs while 294 - # still allowing individual publish jobs to skip themselves (for prereleases). 295 - # "host" however must run to completion, no skipping allowed! 296 - if: ${{ always() && needs.host.result == 'success' }} 297 - runs-on: "ubuntu-22.04" 298 - env: 299 - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 300 - steps: 301 - - uses: actions/checkout@v6 302 - with: 303 - persist-credentials: false 304 - submodules: recursive
-230
.github/workflows/rust.yml
··· 1 - name: Rust 2 - 3 - on: 4 - push: 5 - branches: [main] 6 - paths-ignore: 7 - - "ui/**" 8 - pull_request: 9 - branches: [main] 10 - paths-ignore: 11 - - "ui/**" 12 - 13 - env: 14 - CARGO_TERM_COLOR: always 15 - 16 - jobs: 17 - build: 18 - strategy: 19 - matrix: 20 - os: [depot-ubuntu-24.04, macos-14, windows-latest] 21 - runs-on: ${{ matrix.os }} 22 - 23 - steps: 24 - - uses: actions/checkout@v6 25 - 26 - - name: Install rust 27 - uses: dtolnay/rust-toolchain@master 28 - with: 29 - toolchain: 1.97.0 30 - 31 - - uses: actions/cache@v5 32 - with: 33 - path: | 34 - ~/.cargo/registry 35 - ~/.cargo/git 36 - target 37 - key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }} 38 - 39 - - name: Run cargo build common 40 - run: cargo build -p atuin-common --locked --release 41 - 42 - - name: Run cargo build client 43 - run: cargo build -p atuin-client --locked --release 44 - 45 - - name: Run cargo build server 46 - run: cargo build -p atuin-server --locked --release 47 - 48 - - name: Run cargo build main 49 - run: cargo build --all --locked --release 50 - 51 - cross-compile: 52 - strategy: 53 - matrix: 54 - # There was an attempt to make cross-compiles also work on FreeBSD, but that failed with: 55 - # 56 - # warning: libelf.so.2, needed by <...>/libkvm.so, not found (try using -rpath or -rpath-link) 57 - target: [x86_64-unknown-illumos] 58 - runs-on: depot-ubuntu-24.04 59 - steps: 60 - - uses: actions/checkout@v6 61 - 62 - - name: Install cross 63 - uses: taiki-e/install-action@v2 64 - with: 65 - tool: cross 66 - 67 - - uses: actions/cache@v5 68 - with: 69 - path: | 70 - ~/.cargo/registry 71 - ~/.cargo/git 72 - target 73 - key: ${{ matrix.target }}-cross-compile-${{ hashFiles('**/Cargo.lock') }} 74 - 75 - - name: Run cross build common 76 - run: cross build -p atuin-common --locked --target ${{ matrix.target }} 77 - 78 - - name: Run cross build client 79 - run: cross build -p atuin-client --locked --target ${{ matrix.target }} 80 - 81 - - name: Run cross build server 82 - run: cross build -p atuin-server --locked --target ${{ matrix.target }} 83 - 84 - - name: Run cross build main 85 - run: | 86 - cross build --all --locked --target ${{ matrix.target }} 87 - 88 - unit-test: 89 - strategy: 90 - matrix: 91 - os: [depot-ubuntu-24.04, macos-14, windows-latest] 92 - runs-on: ${{ matrix.os }} 93 - 94 - steps: 95 - - uses: actions/checkout@v6 96 - 97 - - name: Install rust 98 - uses: dtolnay/rust-toolchain@master 99 - with: 100 - toolchain: 1.97.0 101 - 102 - - uses: taiki-e/install-action@v2 103 - name: Install nextest 104 - with: 105 - tool: cargo-nextest 106 - 107 - - uses: actions/cache@v5 108 - with: 109 - path: | 110 - ~/.cargo/registry 111 - ~/.cargo/git 112 - target 113 - key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }} 114 - 115 - - name: Run cargo test 116 - run: cargo nextest run --lib --bins 117 - 118 - check: 119 - strategy: 120 - matrix: 121 - os: [depot-ubuntu-24.04, macos-14, windows-latest] 122 - runs-on: ${{ matrix.os }} 123 - 124 - steps: 125 - - uses: actions/checkout@v6 126 - 127 - - name: Install rust 128 - uses: dtolnay/rust-toolchain@master 129 - with: 130 - toolchain: 1.97.0 131 - 132 - - uses: actions/cache@v5 133 - with: 134 - path: | 135 - ~/.cargo/registry 136 - ~/.cargo/git 137 - target 138 - key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }} 139 - 140 - - name: Run cargo check (all features) 141 - run: cargo check --all-features --workspace 142 - 143 - - name: Run cargo check (no features) 144 - run: cargo check --no-default-features --workspace 145 - 146 - - name: Run cargo check (sync) 147 - run: cargo check --no-default-features --features sync --workspace 148 - 149 - - name: Run cargo check (server) 150 - run: cargo check -p atuin-server 151 - 152 - - name: Run cargo check (client only) 153 - run: cargo check --no-default-features --features client --workspace 154 - 155 - integration-test: 156 - runs-on: depot-ubuntu-24.04 157 - 158 - services: 159 - postgres: 160 - image: postgres 161 - env: 162 - POSTGRES_USER: atuin 163 - POSTGRES_PASSWORD: pass 164 - POSTGRES_DB: atuin 165 - ports: 166 - - 5432:5432 167 - 168 - steps: 169 - - uses: actions/checkout@v6 170 - 171 - - name: Install rust 172 - uses: dtolnay/rust-toolchain@master 173 - with: 174 - toolchain: 1.97.0 175 - 176 - - uses: taiki-e/install-action@v2 177 - name: Install nextest 178 - with: 179 - tool: cargo-nextest 180 - 181 - - uses: actions/cache@v5 182 - with: 183 - path: | 184 - ~/.cargo/registry 185 - ~/.cargo/git 186 - target 187 - key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }} 188 - 189 - - name: Run cargo test 190 - run: cargo nextest run --test '*' 191 - env: 192 - ATUIN_DB_URI: postgres://atuin:pass@localhost:5432/atuin 193 - 194 - clippy: 195 - runs-on: depot-ubuntu-24.04 196 - 197 - steps: 198 - - uses: actions/checkout@v6 199 - 200 - - name: Install latest rust 201 - uses: dtolnay/rust-toolchain@master 202 - with: 203 - toolchain: 1.97.0 204 - components: clippy 205 - 206 - - uses: actions/cache@v5 207 - with: 208 - path: | 209 - ~/.cargo/registry 210 - ~/.cargo/git 211 - target 212 - key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }} 213 - 214 - - name: Run clippy 215 - run: cargo clippy -- -D warnings -D clippy::redundant_clone 216 - 217 - format: 218 - runs-on: depot-ubuntu-24.04 219 - 220 - steps: 221 - - uses: actions/checkout@v6 222 - 223 - - name: Install latest rust 224 - uses: dtolnay/rust-toolchain@master 225 - with: 226 - toolchain: 1.97.0 227 - components: rustfmt 228 - 229 - - name: Format 230 - run: cargo fmt -- --check
-18
.github/workflows/shellcheck.yml
··· 1 - name: Shellcheck 2 - 3 - on: 4 - push: 5 - branches: [ main ] 6 - pull_request: 7 - branches: [ main ] 8 - 9 - jobs: 10 - shellcheck: 11 - runs-on: depot-ubuntu-24.04 12 - 13 - steps: 14 - - uses: actions/checkout@v6 15 - - name: Run shellcheck 16 - uses: ludeeus/action-shellcheck@master 17 - env: 18 - SHELLCHECK_OPTS: "-e SC2148"
-16
.github/workflows/trigger-docs-deploy.yml
··· 1 - name: Trigger docs deploy 2 - 3 - on: 4 - push: 5 - branches: [main] 6 - paths: 7 - - "docs/**" 8 - 9 - jobs: 10 - trigger: 11 - runs-on: ubuntu-latest 12 - steps: 13 - - name: Dispatch to atuinsh/docs 14 - run: gh api repos/atuinsh/docs/dispatches -f event_type=docs-updated 15 - env: 16 - GH_TOKEN: ${{ secrets.DOCS_DEPLOY_TOKEN }}
-21
.github/workflows/update-nix-deps.yml
··· 1 - name: Update Nix Deps 2 - on: 3 - workflow_dispatch: # allows manual triggering 4 - schedule: 5 - - cron: '0 0 1 * *' # runs monthly on the first day of the month at 00:00 6 - 7 - jobs: 8 - lockfile: 9 - runs-on: depot-ubuntu-24.04 10 - if: github.repository == 'atuinsh/atuin' 11 - steps: 12 - - name: Checkout repository 13 - uses: actions/checkout@v6 14 - - name: Install Nix 15 - uses: DeterminateSystems/nix-installer-action@main 16 - - name: Update flake.lock 17 - uses: DeterminateSystems/update-flake-lock@main 18 - with: 19 - pr-title: "chore(deps): update flake.lock" 20 - pr-labels: | 21 - dependencies
-14
.mailmap
··· 1 - networkException <git@nwex.de> <github@nwex.de> 2 - Violet Shreve <github@shreve.io> <jacob@shreve.io> 3 - Chris Rose <offline@offby1.net> <offbyone@github.com> 4 - Conrad Ludgate <conradludgate@gmail.com> <conrad.ludgate@truelayer.com> 5 - Cristian Le <github@lecris.me> <cristian.le@mpsd.mpg.de> 6 - Dennis Trautwein <git@dtrautwein.eu> <dennis.trautwein@posteo.de> 7 - Ellie Huxtable <ellie@atuin.sh> <e@elm.sh> 8 - Ellie Huxtable <ellie@atuin.sh> <ellie@elliehuxtable.com> 9 - Frank Hamand <frankhamand@gmail.com> <frank.hamand@coinbase.com> 10 - Jakob Schrettenbrunner <dev@schrej.net> <jakob.schrettenbrunner@telekom.de> 11 - Nemo157 <git@nemo157.com> <github@nemo157.com> 12 - Richard de Boer <git@tubul.net> <github@tubul.net> 13 - Sandro <sandro.jaeckel@gmail.com> <sandro.jaeckel@sap.com> 14 - TymanWasTaken <tbeckman530@gmail.com> <ty@blahaj.land>
-109
.nvim.lua
··· 1 - -- Project-local Neovim configuration for Atuin. 2 - -- 3 - -- Opt out entirely: vim.g.atuin_nvim = false 4 - -- Or per-feature: vim.g.atuin_nvim = { format_on_save = false } 5 - -- 6 - -- Set either in your own init.lua; it loads before this file. 7 - 8 - local user = vim.g.atuin_nvim 9 - if user == false then return end 10 - 11 - -- vim.fs.relpath and Client:supports_method() (colon-form) both require 0.11. 12 - if vim.fn.has("nvim-0.11") == 0 then return end 13 - 14 - local opts = vim.tbl_deep_extend("force", { 15 - colorcolumn = true, 16 - format_on_save = true, 17 - }, type(user) == "table" and user or {}) 18 - 19 - -- ~2x a warm rust-analyzer format; generous enough for a cold server. 20 - local FORMAT_TIMEOUT_MS = 2000 21 - 22 - -- 'exrc' also searches parent directories, so cwd is not reliably the repo 23 - -- root. Resolve our own location instead. See :h lua-script-location 24 - local root = vim.fs.dirname(debug.getinfo(1, "S").source:gsub("^@", "")) 25 - 26 - -- Scope every action to this repo. relpath() returns nil for paths outside 27 - -- root, and unlike a string prefix match it rejects sibling dirs such as 28 - -- "/tmp/atuin-evil" for a root of "/tmp/atuin". 29 - local function in_project(buf) 30 - local name = vim.api.nvim_buf_get_name(buf) 31 - return name ~= "" and vim.fs.relpath(root, vim.fs.normalize(name)) ~= nil 32 - end 33 - 34 - local function is_project_rust_buf(buf) 35 - return vim.bo[buf].filetype == "rust" and in_project(buf) 36 - end 37 - 38 - local group = vim.api.nvim_create_augroup("atuin_nvim", { clear = true }) 39 - 40 - local function apply(buf) 41 - if not is_project_rust_buf(buf) or not opts.colorcolumn then 42 - return 43 - end 44 - 45 - -- "+1" is relative to 'textwidth', which .editorconfig sets from rustfmt's 46 - -- max_width -- so the ruler marks the first column rustfmt will not use, and 47 - -- the two cannot drift. Bail if 'textwidth' is unset (someone disabled 48 - -- editorconfig), or "+1" would resolve to column 1. 49 - if vim.bo[buf].textwidth == 0 then 50 - return 51 - end 52 - 53 - -- 'colorcolumn' is window-local, so set it on every window showing this buffer. 54 - for _, win in ipairs(vim.fn.win_findbuf(buf)) do 55 - vim.api.nvim_set_option_value("colorcolumn", "+1", { scope = "local", win = win }) 56 - end 57 - end 58 - 59 - vim.api.nvim_create_autocmd("FileType", { 60 - group = group, 61 - pattern = "rust", 62 - callback = function(ev) apply(ev.buf) end, 63 - }) 64 - 65 - -- FileType alone can fire before the buffer has a window (background loads), 66 - -- which would skip the window-local colorcolumn. apply() is idempotent. 67 - vim.api.nvim_create_autocmd("BufWinEnter", { 68 - group = group, 69 - pattern = "*.rs", 70 - callback = function(ev) apply(ev.buf) end, 71 - }) 72 - 73 - -- Format on save via whichever Rust LSP the user already configured. This 74 - -- never defines or starts a server -- if no Rust LSP is set up, LspAttach 75 - -- simply never fires for these buffers and nothing happens. 76 - vim.api.nvim_create_autocmd("LspAttach", { 77 - group = group, 78 - callback = function(ev) 79 - if not opts.format_on_save then return end 80 - if not is_project_rust_buf(ev.buf) then return end 81 - 82 - local client = vim.lsp.get_client_by_id(ev.data.client_id) 83 - if not client or not client:supports_method("textDocument/formatting") then return end 84 - -- Servers that support willSaveWaitUntil format on save themselves. 85 - if client:supports_method("textDocument/willSaveWaitUntil") then return end 86 - 87 - -- Register exactly one handler per buffer. LspAttach fires again on server 88 - -- restart and for every other client attaching to this buffer. Querying the 89 - -- autocmd list rather than a vim.b flag means the guard cannot outlive the 90 - -- handler it guards (augroup clear=true resets both). 91 - if #vim.api.nvim_get_autocmds({ group = group, event = "BufWritePre", buffer = ev.buf }) > 0 then 92 - return 93 - end 94 - 95 - vim.api.nvim_create_autocmd("BufWritePre", { 96 - group = group, 97 - buffer = ev.buf, 98 - callback = function() 99 - -- Resolve a live client at save time. Capturing client.id here would go 100 - -- stale the moment the server restarts. 101 - local c = vim.iter(vim.lsp.get_clients({ bufnr = ev.buf, method = "textDocument/formatting" })) 102 - :find(function(c) return not c:supports_method("textDocument/willSaveWaitUntil") end) 103 - if c then 104 - vim.lsp.buf.format({ bufnr = ev.buf, id = c.id, timeout_ms = FORMAT_TIMEOUT_MS }) 105 - end 106 - end, 107 - }) 108 - end, 109 - })
-72
AGENTS.md
··· 1 - # Atuin 2 - 3 - Shell history tool. Replaces your shell's built-in history with a SQLite database, adds context (cwd, exit code, duration, hostname), and optionally syncs across machines with end-to-end encryption. 4 - 5 - ## Workspace crates 6 - 7 - ``` 8 - atuin CLI binary + TUI (clap, ratatui, crossterm) 9 - atuin-client Client library: local DB, encryption, sync, settings 10 - atuin-common Shared types, API models, utils 11 - atuin-daemon Background gRPC daemon (tonic) for shell hooks 12 - atuin-dotfiles Alias/var sync via record store 13 - atuin-history Sorting algorithms, stats 14 - atuin-kv Key-value store (synced) 15 - atuin-scripts Script management (minijinja) 16 - atuin-server HTTP sync server (axum) - lib + standalone binary 17 - atuin-server-database Database trait for server 18 - atuin-server-postgres Postgres implementation (sqlx) 19 - atuin-server-sqlite SQLite implementation (sqlx) 20 - ``` 21 - 22 - ## Two sync protocols 23 - 24 - - **V1 (legacy)**: Syncs history entries directly. Being phased out. Toggleable via `sync_v1_enabled`. 25 - - **V2 (current)**: Record store abstraction. All data types (history, KV, aliases, vars, scripts) share the same sync infrastructure using tagged records. Envelope-encrypted with PASETO V4 and per-record CEKs. 26 - 27 - ## Encryption 28 - 29 - - **V1**: XSalsa20Poly1305 (secretbox). Key at `~/.local/share/atuin/key`. 30 - - **V2**: PASETO V4 Local (XChaCha20-Poly1305 + Blake2b). Envelope encryption: each record gets a random CEK wrapped with the master key. Record metadata (id, idx, version, tag, host) is authenticated as implicit assertions. 31 - 32 - ## Databases 33 - 34 - - **Client**: SQLite everywhere. Separate DBs for history, record store, KV, scripts. All use sqlx + WAL mode. 35 - - **Server**: Postgres (primary) or SQLite. Auto-detected from URI prefix. 36 - - Migrations live alongside each crate. Never modify existing migrations, only add new ones. 37 - 38 - ## Hot paths 39 - 40 - `history start`, `history end`, and `init` skip database initialization for latency. Don't add DB calls to these without good reason. 41 - 42 - ## Conventions 43 - 44 - - Rust 2024 edition, toolchain 1.97.0. 45 - - Errors: `eyre::Result` in binaries, `thiserror` for typed errors in libraries. 46 - - Derive boilerplate: `derive_more` (workspace dep) for `Display`, `From`, `Into`, `AsRef`, `Deref`, `Debug` on newtypes and simple enums. Prefer `derive_more` over manual `impl` when the formatting/conversion is a straight delegation. Use `thiserror` (not `derive_more`) for error types. Use `#[as_ref(str)]` on string newtypes for `AsRef<str>`. 47 - - Async: tokio. Client uses `current_thread`; server uses `multi_thread`. 48 - - `#![deny(unsafe_code)]` on client/common, `#![forbid(unsafe_code)]` on server. 49 - - Clippy: `pedantic` + `nursery` on main crate. CI enforces `-D warnings -D clippy::redundant_clone`. 50 - - Format: `cargo fmt`. Only non-default: `reorder_imports = true`. 51 - - IDs: UUIDv7 (time-ordered), newtype wrappers (`HistoryId`, `RecordId`, `HostId`). 52 - - Serialization: MessagePack for encrypted payloads, JSON for API, TOML for config. 53 - - Storage traits: `Database` (client), `Store` (record store), `Database` (server) -- all `async_trait`. 54 - - History builders: `HistoryImported`, `HistoryCaptured`, `HistoryFromDb` with compile-time field validation. 55 - - Feature flags: `client`, `sync`, `daemon`, `clipboard`, `check-update`. 56 - 57 - ## Testing 58 - 59 - - Unit tests inline with `#[cfg(test)]`, async via `#[tokio::test]`. 60 - - Integration tests in `crates/atuin/tests/` need Postgres (`ATUIN_DB_URI` env var). 61 - - Use `":memory:"` SQLite for unit tests needing a database. 62 - - Runner: `cargo nextest`. 63 - - Benchmarks: `divan` in `atuin-history`. 64 - 65 - ## Build and check 66 - 67 - ```sh 68 - cargo build 69 - cargo test 70 - cargo clippy -- -D warnings 71 - cargo fmt --check 72 - ```
-1677
CHANGELOG.md
··· 1 - # Changelog 2 - 3 - All notable changes to this project will be documented in this file. 4 - 5 - ## 18.17.1 6 - 7 - ### Bug Fixes 8 - 9 - - *(ai)* Default to non-Hub mode for custom AI endpoints ([#3620](https://github.com/atuinsh/atuin/issues/3620)) 10 - - *(import)* Fix order of entries imported from zsh history ([#3597](https://github.com/atuinsh/atuin/issues/3597)) 11 - - *(import)* Fix import order of nushell history entries ([#3598](https://github.com/atuinsh/atuin/issues/3598)) 12 - - Various prefix mode bugs ([#3616](https://github.com/atuinsh/atuin/issues/3616)) 13 - 14 - 15 - ### Documentation 16 - 17 - - Document output capture and mcp ([#3595](https://github.com/atuinsh/atuin/issues/3595)) 18 - 19 - 20 - ### Features 21 - 22 - - *(tui)* Truncate long commands from middle to show start...end ([#3602](https://github.com/atuinsh/atuin/issues/3602)) 23 - 24 - 25 - ### Miscellaneous Tasks 26 - 27 - - *(logging)* Remove the `log` crate in favor of `tracing` ([#3608](https://github.com/atuinsh/atuin/issues/3608)) 28 - - Update to rust 1.97 ([#3617](https://github.com/atuinsh/atuin/issues/3617)) 29 - 30 - ## 18.17.0 31 - 32 - ### Bug Fixes 33 - 34 - - *(ai)* Dispatch skills registered in the slash command registry ([#3593](https://github.com/atuinsh/atuin/issues/3593)) 35 - - *(ci)* Fossier install in scan workflow ([#3485](https://github.com/atuinsh/atuin/issues/3485)) 36 - - *(i18n)* Fix typos in Russian localization ([#3575](https://github.com/atuinsh/atuin/issues/3575)) 37 - - *(nu)* Use `char -u 1b` for ESC in OSC 133 sequences ([#3530](https://github.com/atuinsh/atuin/issues/3530)) 38 - - *(nu)* Suppress error when `ATUIN_HISTORY_ID` is missing in `pre_prompt` hook ([#3587](https://github.com/atuinsh/atuin/issues/3587)) 39 - - *(pi)* Observe tool events instead of registering a bash tool ([#3557](https://github.com/atuinsh/atuin/issues/3557)) 40 - - *(pty-proxy)* Set `$SHELL` to the spawned shell ([#3548](https://github.com/atuinsh/atuin/issues/3548)) 41 - - *(search)* Fix terminal clearing with latest Ratatui ([#3578](https://github.com/atuinsh/atuin/issues/3578)) 42 - - *(sync)* Skip records that fail to decrypt or decode instead of failing the whole store ([#3569](https://github.com/atuinsh/atuin/issues/3569)) 43 - - Atuin hangs when attempting to spawn daemon from Ctrl+R invocation ([#3502](https://github.com/atuinsh/atuin/issues/3502)) 44 - - Capture session ID from stream headers rather than final event ([#3531](https://github.com/atuinsh/atuin/issues/3531)) 45 - - Doctor resiliency fo runknown platforms + openbsd warning ([#3551](https://github.com/atuinsh/atuin/issues/3551)) 46 - - Double input on arrow keys in AI setup prompt on Windows ([#3552](https://github.com/atuinsh/atuin/issues/3552)) 47 - - Exclude AI agent commands from zsh-autosuggestions ([#3567](https://github.com/atuinsh/atuin/issues/3567)) 48 - - Silence shellcheck SC2016 on literal `$all-user` author filter 49 - - Respect `store_failed` when using daemon ([#3571](https://github.com/atuinsh/atuin/issues/3571)) 50 - 51 - 52 - ### Documentation 53 - 54 - - Highlight `Ctrl-r` keybinding on docs page ([#3489](https://github.com/atuinsh/atuin/issues/3489)) 55 - - Document store purge workflow ([#3544](https://github.com/atuinsh/atuin/issues/3544)) 56 - - Fix command example typo in documentation ([#3536](https://github.com/atuinsh/atuin/issues/3536)) 57 - - Make commented-out lines in `config.toml` match real defaults ([#3583](https://github.com/atuinsh/atuin/issues/3583)) 58 - - Add fish shell cleanup step to uninstall instructions ([#3582](https://github.com/atuinsh/atuin/issues/3582)) 59 - 60 - 61 - ### Features 62 - 63 - - *(doctor)* Add whether daemon is enabled to `doctor` output ([#3572](https://github.com/atuinsh/atuin/issues/3572)) 64 - - *(pty-proxy)* Add `--shell` flag to override the spawned shell ([#3327](https://github.com/atuinsh/atuin/issues/3327)) 65 - - Setup fossier to stop bot slop prs ([#3482](https://github.com/atuinsh/atuin/issues/3482)) 66 - - Capture command output + expose to new `atuin_output` tool ([#3510](https://github.com/atuinsh/atuin/issues/3510)) 67 - - Cache user contexts on load until `/reload` ([#3525](https://github.com/atuinsh/atuin/issues/3525)) 68 - - Create database integration tests for atuin-server ([#3514](https://github.com/atuinsh/atuin/issues/3514)) 69 - - Add `/model` slash command for changing models ([#3576](https://github.com/atuinsh/atuin/issues/3576)) 70 - - Add mcp server for history tools and expand search filters ([#3581](https://github.com/atuinsh/atuin/issues/3581)) 71 - - Add status bar with model and usage information ([#3591](https://github.com/atuinsh/atuin/issues/3591)) 72 - 73 - 74 - ### Miscellaneous Tasks 75 - 76 - - *(rustdoc)* Fix Rustdoc warnings ([#3585](https://github.com/atuinsh/atuin/issues/3585)) 77 - - *(warnings)* Fix compile warnings with latest dependencies ([#3586](https://github.com/atuinsh/atuin/issues/3586)) 78 - - Vouch for all existing contributors ([#3486](https://github.com/atuinsh/atuin/issues/3486)) 79 - - Update GitHub app token format 80 - - Update to Rust 1.96.1 ([#3568](https://github.com/atuinsh/atuin/issues/3568)) 81 - - Adopt `derive_more` to reduce boilerplate across the codebase ([#3573](https://github.com/atuinsh/atuin/pull/3573)) 82 - 83 - 84 - ### Performance 85 - 86 - - *(search)* Scan history by recency until N unique ([#3553](https://github.com/atuinsh/atuin/issues/3553)) 87 - - Add `synchronous(Normal)` + `optimize_on_close` to record store SQLite ([#3577](https://github.com/atuinsh/atuin/issues/3577)) 88 - - Remove unnecessary clones in a hot path ([#3580](https://github.com/atuinsh/atuin/issues/3580)) 89 - 90 - 91 - ### Refactor 92 - 93 - - Implement `From<sqlx::Error>` and clean up `fix_error` ([#3484](https://github.com/atuinsh/atuin/issues/3484)) 94 - - Pull `fn into_utc` into `atuin-server-database` crate ([#3487](https://github.com/atuinsh/atuin/issues/3487)) 95 - 96 - ## 18.16.1 97 - 98 - ### Bug Fixes 99 - 100 - - *(shell/xonsh)* Use os.devnull instead of hard-coded /dev/null ([#3464](https://github.com/atuinsh/atuin/issues/3464)) 101 - - Atuin update on windows ([#3453](https://github.com/atuinsh/atuin/issues/3453)) 102 - - Ensure local key matches remote data before syncing ([#3474](https://github.com/atuinsh/atuin/issues/3474)) 103 - 104 - 105 - ### Documentation 106 - 107 - - Add related projects section to README 108 - 109 - 110 - ### Features 111 - 112 - - *(ui)* Prominent banner for wrong-key errors at login/sync ([#3475](https://github.com/atuinsh/atuin/issues/3475)) 113 - 114 - 115 - ### Miscellaneous Tasks 116 - 117 - - Generate LLM-optimized docs ([#3468](https://github.com/atuinsh/atuin/issues/3468)) 118 - - Rename 'atuin hex' to 'atuin pty-proxy' ([#3473](https://github.com/atuinsh/atuin/issues/3473)) 119 - 120 - ## 18.16.0 121 - 122 - ### Features 123 - 124 - This release brings full agentic workflows to Atuin AI with file read+write tools, shell command execution, skills, and more. Check out [the docs for Atuin AI](https://docs.atuin.sh/cli/ai/introduction/) for more information. 125 - 126 - - AI tool rendering overhaul + edit_file tool ([#3423](https://github.com/atuinsh/atuin/issues/3423)) 127 - - Implement write_file tool with overwrite safety ([#3432](https://github.com/atuinsh/atuin/issues/3432)) 128 - - Shell tool execution timeouts ([#3437](https://github.com/atuinsh/atuin/issues/3437)) 129 - - Send user-defined context with `TERMINAL.md` ([#3443](https://github.com/atuinsh/atuin/issues/3443)) 130 - - Add skill discovery, loading, and invocation ([#3444](https://github.com/atuinsh/atuin/issues/3444)) 131 - 132 - 133 - ### Bug Fixes 134 - 135 - - Shell tool preview stuck as Running after completion ([#3436](https://github.com/atuinsh/atuin/issues/3436)) 136 - - Require all subcommands covered for shell allow rules ([#3440](https://github.com/atuinsh/atuin/issues/3440)) 137 - - Minor issues with fish's vim mode(s) ([#3362](https://github.com/atuinsh/atuin/issues/3362)) 138 - 139 - 140 - ### Documentation 141 - 142 - - Document show_numeric_shortcuts ([#3433](https://github.com/atuinsh/atuin/issues/3433)) 143 - - Update for new server binary ([#3439](https://github.com/atuinsh/atuin/issues/3439)) 144 - 145 - 146 - ### Miscellaneous Tasks 147 - 148 - - Update to rust 1.95 ([#3426](https://github.com/atuinsh/atuin/issues/3426)) 149 - - Clarified note about regular expressions matching in path. ([#3427](https://github.com/atuinsh/atuin/issues/3427)) 150 - - Use cat -n format for read_file tool ([#3435](https://github.com/atuinsh/atuin/issues/3435)) 151 - - Update to eye_declare 0.5.1 ([#3449](https://github.com/atuinsh/atuin/issues/3449)) 152 - 153 - 154 - ### Performance 155 - 156 - - Reduce AI TUI rendering overhead for long conversations ([#3447](https://github.com/atuinsh/atuin/issues/3447)) 157 - 158 - 159 - ### Refactor 160 - 161 - - Replace ad-hoc dispatch with FSM + driver architecture ([#3434](https://github.com/atuinsh/atuin/issues/3434)) 162 - 163 - ## 18.15.2 164 - 165 - ### Bug Fixes 166 - 167 - - Tab doesn't insert suggested command ([#3420](https://github.com/atuinsh/atuin/issues/3420)) 168 - 169 - ## 18.15.1 170 - 171 - ### Bug Fixes 172 - 173 - - Enter runs suggested command when selecting permissions ([#3418](https://github.com/atuinsh/atuin/issues/3418)) 174 - 175 - ## 18.15.0 176 - 177 - ### Bug Fixes 178 - 179 - - Install script incorrectly tries to install opencode hooks ([#3410](https://github.com/atuinsh/atuin/issues/3410)) 180 - - Dependency fix ([#3414](https://github.com/atuinsh/atuin/issues/3414)) 181 - - Loss of loading spinners + tokio panic on exit ([#3415](https://github.com/atuinsh/atuin/issues/3415)) 182 - 183 - 184 - ### Features 185 - 186 - - Add OCI standard labels to Dockerfile ([#3412](https://github.com/atuinsh/atuin/issues/3412)) 187 - - Enable atuin hex for illumos ([#3413](https://github.com/atuinsh/atuin/issues/3413)) 188 - - Allow resuming previous AI sessions ([#3407](https://github.com/atuinsh/atuin/issues/3407)) 189 - 190 - 191 - ### Miscellaneous Tasks 192 - 193 - - Add release script ([#3411](https://github.com/atuinsh/atuin/issues/3411)) 194 - 195 - ## 18.14.1 196 - 197 - ### Bug Fixes 198 - 199 - - Ensure we can publish to crates ([#3403](https://github.com/atuinsh/atuin/issues/3403)) 200 - - Thread remote and content_length through system for server tool calls ([#3404](https://github.com/atuinsh/atuin/issues/3404)) 201 - 202 - 203 - ### Documentation 204 - 205 - - Add Tools & Permissions doc section ([#3402](https://github.com/atuinsh/atuin/issues/3402)) 206 - 207 - 208 - ## 18.14.0 209 - 210 - ### Bug Fixes 211 - 212 - - *(ui)* Make preview line breaking algorithm aware of CJK double-width characters ([#3360](https://github.com/atuinsh/atuin/issues/3360)) 213 - - *(ui)* When inverted, invert scroll events handling ([#3373](https://github.com/atuinsh/atuin/issues/3373)) 214 - - Replace `e>|` with `|` in nushell integration to restore history recording ([#3358](https://github.com/atuinsh/atuin/issues/3358)) 215 - - Resolve git worktrees to main repo in workspace filter ([#3366](https://github.com/atuinsh/atuin/issues/3366)) 216 - - Ensure daemon is running ([#3384](https://github.com/atuinsh/atuin/issues/3384)) 217 - 218 - 219 - ### Documentation 220 - 221 - - Remove docker-compose duplication ([#3376](https://github.com/atuinsh/atuin/issues/3376)) 222 - - Cover prefix mode properly ([#3383](https://github.com/atuinsh/atuin/issues/3383)) 223 - - Minor readability improvement to README ([#3381](https://github.com/atuinsh/atuin/issues/3381)) 224 - 225 - 226 - ### Features 227 - 228 - - Opt-in to sharing last command with ai ([#3367](https://github.com/atuinsh/atuin/issues/3367)) 229 - - Add 'atuin config' subcommand for reading and setting config values ([#3368](https://github.com/atuinsh/atuin/issues/3368)) 230 - - Option to disable mouse support ([#3372](https://github.com/atuinsh/atuin/issues/3372)) 231 - - Add support for deleting all matching commands via keybindings ([#3375](https://github.com/atuinsh/atuin/issues/3375)) 232 - - Add strip_trailing_whitespace, on by default ([#3390](https://github.com/atuinsh/atuin/issues/3390)) 233 - - Client-tool execution + permission system ([#3370](https://github.com/atuinsh/atuin/issues/3370)) 234 - - Add history tail for live monitoring view ([#3389](https://github.com/atuinsh/atuin/issues/3389)) 235 - - Track coding agent shell usage ([#3388](https://github.com/atuinsh/atuin/issues/3388)) 236 - - Remove agent search from tui ([#3397](https://github.com/atuinsh/atuin/issues/3397)) 237 - - Add pi hook installer ([#3398](https://github.com/atuinsh/atuin/issues/3398)) 238 - - Autoinstall ai shell history hooks ([#3399](https://github.com/atuinsh/atuin/issues/3399)) 239 - 240 - 241 - ### Miscellaneous Tasks 242 - 243 - - Update to eye-declare 0.3.0 ([#3365](https://github.com/atuinsh/atuin/issues/3365)) 244 - - Prepare 18.14.0-beta.1 release ([#3393](https://github.com/atuinsh/atuin/issues/3393)) 245 - 246 - 247 - ### Refactor 248 - 249 - - Rename examples -> contrib ([#3400](https://github.com/atuinsh/atuin/issues/3400)) 250 - 251 - 252 - ## 18.13.6 253 - 254 - ### Bug Fixes 255 - 256 - - *(powershell)* Handle non-FileSystem drives ([#3353](https://github.com/atuinsh/atuin/issues/3353)) 257 - - Remove unnecessary arboard/image-data default feature ([#3345](https://github.com/atuinsh/atuin/issues/3345)) 258 - - Use printf to append fish shell init block ([#3346](https://github.com/atuinsh/atuin/issues/3346)) 259 - - Set WorkingDirectory in PowerShell Invoke-AtuinSearch ([#3351](https://github.com/atuinsh/atuin/issues/3351)) 260 - 261 - 262 - ### Features 263 - 264 - - Use eye-declare for more performant and flexible AI TUI ([#3343](https://github.com/atuinsh/atuin/issues/3343)) 265 - 266 - 267 - ### Miscellaneous Tasks 268 - 269 - - *(ci)* Switch most workflows to depot ci ([#3352](https://github.com/atuinsh/atuin/issues/3352)) 270 - - Prepare 18.13.6 release ([#3356](https://github.com/atuinsh/atuin/issues/3356)) 271 - 272 - 273 - ## 18.13.5 274 - 275 - ### Bug Fixes 276 - 277 - - Atuin Hex fails to init on bash and zsh ([#3341](https://github.com/atuinsh/atuin/issues/3341)) 278 - 279 - 280 - ### Documentation 281 - 282 - - Fix duplicated word in Kubernetes guide ([#3338](https://github.com/atuinsh/atuin/issues/3338)) 283 - 284 - 285 - ### Miscellaneous Tasks 286 - 287 - - Prepare 18.13.5 ([#3342](https://github.com/atuinsh/atuin/issues/3342)) 288 - 289 - 290 - ## 18.13.4 291 - 292 - ### Bug Fixes 293 - 294 - - *(ai)* Restore url-quote-magic for ? in zsh ([#3304](https://github.com/atuinsh/atuin/issues/3304)) 295 - - Redirect tty0 when running setup 296 - - Redirect tty0 when running setup ([#3302](https://github.com/atuinsh/atuin/issues/3302)) 297 - - Call ensure_hub_session even if primary sync endpoint is self-hosted 298 - - Call ensure_hub_session even if primary sync endpoint is self-hosted ([#3301](https://github.com/atuinsh/atuin/issues/3301)) 299 - - Remove per-event mouse capture toggling that leaked ANSI to stdout ([#3299](https://github.com/atuinsh/atuin/issues/3299)) 300 - - Clarify what data is sent when using Atuin AI during setup (only OS and shell) ([#3290](https://github.com/atuinsh/atuin/issues/3290)) 301 - - Better tty check ([#3313](https://github.com/atuinsh/atuin/issues/3313)) 302 - - Disable features in init when that feature is explicitly disabled ([#3328](https://github.com/atuinsh/atuin/issues/3328)) 303 - - Don't run 'atuin init' in 'atuin hex init' — each must be initialized separately ([#3334](https://github.com/atuinsh/atuin/issues/3334)) 304 - 305 - 306 - ### Documentation 307 - 308 - - Fix typo in FAQ alternatives section ([#3292](https://github.com/atuinsh/atuin/issues/3292)) 309 - - Remove 'experimental' status from Atuin Daemon 310 - - Remove 'experimental' status from Atuin Daemon ([#3295](https://github.com/atuinsh/atuin/issues/3295)) 311 - - Add inline_height_shell_up_key_binding ([#3270](https://github.com/atuinsh/atuin/issues/3270)) 312 - 313 - 314 - ### Features 315 - 316 - - Report distro name with OS for distro-specific commands ([#3289](https://github.com/atuinsh/atuin/issues/3289)) 317 - - Allow setting kv values from stdin 318 - - Error if value not provided and no stdin 319 - - Add a small atuin label to the ai box ([#3309](https://github.com/atuinsh/atuin/issues/3309)) 320 - - Allow running `atuin search -i` as subcommand on Windows ([#3250](https://github.com/atuinsh/atuin/issues/3250)) 321 - - Hex init nu ([#3330](https://github.com/atuinsh/atuin/issues/3330)) 322 - 323 - 324 - ### Miscellaneous Tasks 325 - 326 - - *(ci)* Tag docker images with semantic versions on tag creation ([#3316](https://github.com/atuinsh/atuin/issues/3316)) 327 - - Replace atuin-ai rendering with component-oriented system ([#3288](https://github.com/atuinsh/atuin/issues/3288)) 328 - - Refactor CLI auth flows and token storage ([#3317](https://github.com/atuinsh/atuin/issues/3317)) 329 - 330 - 331 - ## 18.13.3 332 - 333 - ### Bug Fixes 334 - 335 - - Nushell 0.111; future Nushell 0.112 support ([#3266](https://github.com/atuinsh/atuin/issues/3266)) 336 - 337 - 338 - ### Features 339 - 340 - - Call atuin setup from install script ([#3265](https://github.com/atuinsh/atuin/issues/3265)) 341 - - Allow headless account ops against Hub server ([#3280](https://github.com/atuinsh/atuin/issues/3280)) 342 - - Add custom filtering and scoring mechanisms 343 - 344 - 345 - ### Miscellaneous Tasks 346 - 347 - - *(ci)* Migrate to depot runners ([#3279](https://github.com/atuinsh/atuin/issues/3279)) 348 - - *(ci)* Use depot to build docker images too ([#3281](https://github.com/atuinsh/atuin/issues/3281)) 349 - - *(ci)* Use github for macos 350 - - Update changelog 351 - - Update permissions in Docker workflow ([#3283](https://github.com/atuinsh/atuin/issues/3283)) 352 - - Change CHANGELOG format to be easier to parse 353 - - Symlink changelog so dist can pick it up 354 - - Vendor nucleo-ext + fork, so we can depend on our changes properly ([#3284](https://github.com/atuinsh/atuin/issues/3284)) 355 - - Update changelog 356 - 357 - 358 - ## 18.13.2 359 - 360 - ### Miscellaneous Tasks 361 - 362 - - *(release)* Building windows aarch64 was overly optimistic 363 - - Update changelog 364 - 365 - 366 - ## 18.13.1 367 - 368 - ### Miscellaneous Tasks 369 - 370 - - *(release)* Update dist, remove custom runners 371 - - Update changelog 372 - 373 - 374 - ## 18.13.0 375 - 376 - ### Bug Fixes 377 - 378 - - *(deps)* Add use-dev-tty to crossterm in atuin-ai ([#3185](https://github.com/atuinsh/atuin/issues/3185)) 379 - - *(docs)* Update Postgres volume path in Docker as required by pg18 ([#3174](https://github.com/atuinsh/atuin/issues/3174)) 380 - - Systemd Exec for separate server binary ([#3176](https://github.com/atuinsh/atuin/issues/3176)) 381 - - Multiline commands with fish ([#3179](https://github.com/atuinsh/atuin/issues/3179)) 382 - - Silent DB failures e.g. when disk is full ([#3183](https://github.com/atuinsh/atuin/issues/3183)) 383 - - Forward $PATH to tmux popup in zsh ([#3198](https://github.com/atuinsh/atuin/issues/3198)) 384 - - Dramatically decrease daemon memory usage ([#3211](https://github.com/atuinsh/atuin/issues/3211)) 385 - - Regen cargo dist 386 - - Clear script database before rebuild to prevent unique constraint violation ([#3232](https://github.com/atuinsh/atuin/issues/3232)) 387 - - Support Nushell 0.111 ([#3249](https://github.com/atuinsh/atuin/issues/3249)) 388 - - Ctrl-c not exiting ai ([#3256](https://github.com/atuinsh/atuin/issues/3256)) 389 - 390 - 391 - ### Documentation 392 - 393 - - Update config.md to remove NuShell support note ([#3190](https://github.com/atuinsh/atuin/issues/3190)) 394 - - Document `search.filters` ([#3195](https://github.com/atuinsh/atuin/issues/3195)) 395 - - Clean up doc references for sqlite-based self-hosting ([#3216](https://github.com/atuinsh/atuin/issues/3216)) 396 - - Document daemon-fuzzy search mode ([#3254](https://github.com/atuinsh/atuin/issues/3254)) 397 - 398 - 399 - ### Features 400 - 401 - - *(docs)* Add Shell Integration and Interoperability docs ([#3163](https://github.com/atuinsh/atuin/issues/3163)) 402 - - `switch-context` ([#3149](https://github.com/atuinsh/atuin/issues/3149)) 403 - - Add Hub authentication for future sync + extra features ([#3010](https://github.com/atuinsh/atuin/issues/3010)) 404 - - Add Atuin AI inline CLI MVP ([#3178](https://github.com/atuinsh/atuin/issues/3178)) 405 - - Add autostart and pid management to daemon ([#3180](https://github.com/atuinsh/atuin/issues/3180)) 406 - - Generate commands or ask questions with `atuin ai` ([#3199](https://github.com/atuinsh/atuin/issues/3199)) 407 - - Add history author/intent metadata and v1 record version ([#3205](https://github.com/atuinsh/atuin/issues/3205)) 408 - - In-memory search index with atuin daemon ([#3201](https://github.com/atuinsh/atuin/issues/3201)) 409 - - Update script for smoother setup ([#3230](https://github.com/atuinsh/atuin/issues/3230)) 410 - - Initial draft of atuin-shell ([#3206](https://github.com/atuinsh/atuin/issues/3206)) 411 - - Allow setting multipliers for frequency, recency, and frecency scores ([#3235](https://github.com/atuinsh/atuin/issues/3235)) 412 - - Allow running `atuin search -i` as subcommand ([#3208](https://github.com/atuinsh/atuin/issues/3208)) 413 - - Use pty proxy for rendering tui popups without clearing the terminal ([#3234](https://github.com/atuinsh/atuin/issues/3234)) 414 - - Allow authenticating with Atuin Hub ([#3237](https://github.com/atuinsh/atuin/issues/3237)) 415 - - Initialize Atuin AI by default with `atuin init` ([#3255](https://github.com/atuinsh/atuin/issues/3255)) 416 - - Add `atuin setup` ([#3257](https://github.com/atuinsh/atuin/issues/3257)) 417 - 418 - 419 - ### Miscellaneous Tasks 420 - 421 - - Update changelog 422 - - Update changelog 423 - - Update changelog 424 - - Use workspace versions ([#3210](https://github.com/atuinsh/atuin/issues/3210)) 425 - - Move atuin ai subcommand into core binary ([#3212](https://github.com/atuinsh/atuin/issues/3212)) 426 - - Update changelog 427 - - Update to Rust 1.94 ([#3247](https://github.com/atuinsh/atuin/issues/3247)) 428 - - Strip symbols in dist profile to reduce binary size 429 - - Upgrade thiserror 1.x to 2.x to deduplicate dependency 430 - - Upgrade axum 0.7 to 0.8 to deduplicate with tonic's axum 431 - - Update changelog 432 - - Update changelog 433 - - Update changelog 434 - - Update changelog 435 - 436 - 437 - ## 18.12.1 438 - 439 - ### Bug Fixes 440 - 441 - - *(shell)* Fix ATUIN_SESSION errors in tmux popup ([#3170](https://github.com/atuinsh/atuin/issues/3170)) 442 - - *(tui)* Enter in vim normal mode, shift-tab keybind ([#3158](https://github.com/atuinsh/atuin/issues/3158)) 443 - - Server start commands for Docker. ([#3160](https://github.com/atuinsh/atuin/issues/3160)) 444 - 445 - 446 - ### Features 447 - 448 - - Expand keybinding system with vim motions, media keys, and inspector improvements ([#3161](https://github.com/atuinsh/atuin/issues/3161)) 449 - - Add original-input-empty keybind condition ([#3171](https://github.com/atuinsh/atuin/issues/3171)) 450 - 451 - 452 - ### Miscellaneous Tasks 453 - 454 - - Update changelog 455 - 456 - 457 - ## 18.12.0 458 - 459 - ### Bug Fixes 460 - 461 - - *(powershell)* Preserve `$LASTEXITCODE` ([#3120](https://github.com/atuinsh/atuin/issues/3120)) 462 - - *(powershell)* Display search stderr ([#3146](https://github.com/atuinsh/atuin/issues/3146)) 463 - - *(search)* Allow hyphen-prefixed query args like `---` ([#3129](https://github.com/atuinsh/atuin/issues/3129)) 464 - - *(tui)* Space and F1-F24 keys not handled properly by new keybind system ([#3138](https://github.com/atuinsh/atuin/issues/3138)) 465 - - *(ui)* Don't draw a leading space for command 466 - - *(ui)* Time column can take up to 9 cells 467 - - *(ui)* Align cursor with the expand column (usually the command) 468 - - *(ui)* Align cursor when expand column is in the middle ([#3103](https://github.com/atuinsh/atuin/issues/3103)) 469 - - Zsh import multiline issue ([#2799](https://github.com/atuinsh/atuin/issues/2799)) 470 - - Do not hit sync v1 endpoints for status 471 - - Do not hit sync v1 endpoints for status ([#3102](https://github.com/atuinsh/atuin/issues/3102)) 472 - - Do not set ATUIN_SESSION if it is already set ([#3107](https://github.com/atuinsh/atuin/issues/3107)) 473 - - Custom data dir test on windows ([#3109](https://github.com/atuinsh/atuin/issues/3109)) 474 - - New session on shlvl change ([#3111](https://github.com/atuinsh/atuin/issues/3111)) 475 - - Larger exit column width on Windows ([#3119](https://github.com/atuinsh/atuin/issues/3119)) 476 - - Halt sync loop if server returns an empty page ([#3122](https://github.com/atuinsh/atuin/issues/3122)) 477 - - Use directories crate for home dir resolution ([#3125](https://github.com/atuinsh/atuin/issues/3125)) 478 - - Tab behaving like enter, eprintln ([#3135](https://github.com/atuinsh/atuin/issues/3135)) 479 - - Issue with shift and modifier keys ([#3143](https://github.com/atuinsh/atuin/issues/3143)) 480 - - Remove invalid IF EXISTS from sqlite drop column migration ([#3145](https://github.com/atuinsh/atuin/issues/3145)) 481 - 482 - 483 - ### Documentation 484 - 485 - - *(CONTRIBUTING)* Update links ([#3117](https://github.com/atuinsh/atuin/issues/3117)) 486 - - *(README)* Update links ([#3116](https://github.com/atuinsh/atuin/issues/3116)) 487 - - *(config)* Clarify scope of directory filter_mode ([#3082](https://github.com/atuinsh/atuin/issues/3082)) 488 - - *(configuration)* Describe new utility "atuin-bind" for Bash ([#3064](https://github.com/atuinsh/atuin/issues/3064)) 489 - - *(installation)* Add mise alternative installation method ([#3066](https://github.com/atuinsh/atuin/issues/3066)) 490 - - Various improvements to the `atuin import` docs ([#3062](https://github.com/atuinsh/atuin/issues/3062)) 491 - - Disambiguate 'setup' (noun) vs. 'set up' (verb) ([#3061](https://github.com/atuinsh/atuin/issues/3061)) 492 - - Fix punctuation and grammar in basic usage guide ([#3063](https://github.com/atuinsh/atuin/issues/3063)) 493 - - Expand and clarify usage of the history prune command ([#3084](https://github.com/atuinsh/atuin/issues/3084)) 494 - - Small edit to themes website file ([#3069](https://github.com/atuinsh/atuin/issues/3069)) 495 - - Config/ with initial uid:gid 496 - - Add PowerShell install instructions 497 - - Add PowerShell and Windows install instructions ([#3096](https://github.com/atuinsh/atuin/issues/3096)) 498 - - Update the `[keys]` docs ([#3114](https://github.com/atuinsh/atuin/issues/3114)) 499 - - Add history deletion guide ([#3130](https://github.com/atuinsh/atuin/issues/3130)) 500 - - Update how to use Docker to self-host ([#3148](https://github.com/atuinsh/atuin/issues/3148)) 501 - - Add IRC contact information to README 502 - 503 - 504 - ### Features 505 - 506 - - *(dotfiles)* Add sort and filter options to alias/var list ([#3131](https://github.com/atuinsh/atuin/issues/3131)) 507 - - *(theme)* Note new default theme name and syntax ([#3080](https://github.com/atuinsh/atuin/issues/3080)) 508 - - *(tui)* Add clear-to-start/end actions ([#3141](https://github.com/atuinsh/atuin/issues/3141)) 509 - - *(ui)* Highlight fulltext search as fulltext search instead of fuzzy search 510 - - *(ui)* Highlight fulltext search as fulltext search instead of fuzzy search ([#3098](https://github.com/atuinsh/atuin/issues/3098)) 511 - - *(ultracompact)* Adds setting for ultracompact mode ([#3079](https://github.com/atuinsh/atuin/issues/3079)) 512 - - Add custom column support ([#3089](https://github.com/atuinsh/atuin/issues/3089)) 513 - - Left arrow/backspace on empty to start edit ([#3090](https://github.com/atuinsh/atuin/issues/3090)) 514 - - Add more vim movement bindings for navigation ([#3041](https://github.com/atuinsh/atuin/issues/3041)) 515 - - Support setting a custom data dir in config ([#3105](https://github.com/atuinsh/atuin/issues/3105)) 516 - - Remove user verification functionality ([#3108](https://github.com/atuinsh/atuin/issues/3108)) 517 - - Add option to use tmux display-popup ([#3058](https://github.com/atuinsh/atuin/issues/3058)) 518 - - Move atuin-server to its own binary ([#3112](https://github.com/atuinsh/atuin/issues/3112)) 519 - - Add a parameter to the sync to specify the download/upload page ([#2408](https://github.com/atuinsh/atuin/issues/2408)) 520 - - Replace several files with a sqlite db ([#3128](https://github.com/atuinsh/atuin/issues/3128)) 521 - - Add new custom keybinding system for search TUI ([#3127](https://github.com/atuinsh/atuin/issues/3127)) 522 - 523 - 524 - ### Miscellaneous Tasks 525 - 526 - - Remove total_history from api index response ([#3094](https://github.com/atuinsh/atuin/issues/3094)) 527 - - **BREAKING**: remove total_history from api index response ([#3094](https://github.com/atuinsh/atuin/issues/3094)) 528 - - Update to rust 1.93 529 - - Update to rust 1.93 ([#3101](https://github.com/atuinsh/atuin/issues/3101)) 530 - - Update changelog 531 - - Update agents.md ([#3126](https://github.com/atuinsh/atuin/issues/3126)) 532 - - Update changelog 533 - - Update changelog 534 - - Update changelog 535 - 536 - 537 - ### Theming 538 - 539 - - Explain how to set ANSI codes directly ([#3065](https://github.com/atuinsh/atuin/issues/3065)) 540 - 541 - 542 - ### Faq 543 - 544 - - Add alternative projects ([#3076](https://github.com/atuinsh/atuin/issues/3076)) 545 - 546 - 547 - ## 18.11.0 548 - 549 - ### Bug Fixes 550 - 551 - - *(bash)* Fix issues with intermediate key sequences in the vi editing mode ([#2977](https://github.com/atuinsh/atuin/issues/2977)) 552 - - *(bash)* Work around a keybinding bug of Bash 5.1 ([#2975](https://github.com/atuinsh/atuin/issues/2975)) 553 - - *(bash/blesh)* Suppress error message for auto-complete source ([#2976](https://github.com/atuinsh/atuin/issues/2976)) 554 - - *(powershell)* Run `atuin history end` in the background ([#3034](https://github.com/atuinsh/atuin/issues/3034)) 555 - - *(powershell)* Add error safety and cleanup ([#3040](https://github.com/atuinsh/atuin/issues/3040)) 556 - - Highlight the correct place when multibyte characters are involved ([#2965](https://github.com/atuinsh/atuin/issues/2965)) 557 - - Prevent interactive search crash when update check fails ([#3016](https://github.com/atuinsh/atuin/issues/3016)) 558 - - Move thorough search through search.filters w/ workspaces ([#2703](https://github.com/atuinsh/atuin/issues/2703)) 559 - 560 - 561 - ### Documentation 562 - 563 - - Migrate docs from separate repo to `docs` subfolder ([#3018](https://github.com/atuinsh/atuin/issues/3018)) 564 - 565 - 566 - ### Features 567 - 568 - - Support additional history filenames in replxx importer ([#3005](https://github.com/atuinsh/atuin/issues/3005)) 569 - - Add colors to --help/-h ([#3000](https://github.com/atuinsh/atuin/issues/3000)) 570 - - Add support for read replicas to postgres ([#3029](https://github.com/atuinsh/atuin/issues/3029)) 571 - - Allow disabling sync v1 ([#3030](https://github.com/atuinsh/atuin/issues/3030)) 572 - - Consider atuin dotfile aliases when calculating atuin wrapped ([#3048](https://github.com/atuinsh/atuin/issues/3048)) 573 - - Add session and uuid column support to history list ([#3049](https://github.com/atuinsh/atuin/issues/3049)) 574 - 575 - 576 - ### Miscellaneous Tasks 577 - 578 - - *(nix)* Prevent deprecation warning on evaluation ([#3006](https://github.com/atuinsh/atuin/issues/3006)) 579 - - Update changelog 580 - - Adjust update wording ([#2974](https://github.com/atuinsh/atuin/issues/2974)) 581 - - Add Windows builds, second try ([#2966](https://github.com/atuinsh/atuin/issues/2966)) 582 - - Update to rust 1.91 ([#2981](https://github.com/atuinsh/atuin/issues/2981)) 583 - - Add Atuin Desktop information to install script 584 - - Remove trailing whitespace ([#2985](https://github.com/atuinsh/atuin/issues/2985)) 585 - - Fix typo ([#2994](https://github.com/atuinsh/atuin/issues/2994)) 586 - - Clarify docstring of the enter_accept config key ([#3003](https://github.com/atuinsh/atuin/issues/3003)) 587 - - Fix github action syntax for variables ([#2998](https://github.com/atuinsh/atuin/issues/2998)) 588 - - Add AGENTS.md 589 - - Update changelog 590 - - Remove x86_64 mac from build targets ([#3052](https://github.com/atuinsh/atuin/issues/3052)) 591 - 592 - 593 - ### Build 594 - 595 - - *(nix)* Update rust toolchain hash ([#2990](https://github.com/atuinsh/atuin/issues/2990)) 596 - 597 - 598 - ## 18.10.0 599 - 600 - ### Bug Fixes 601 - 602 - - Stats ngram window size cli parsing ([#2946](https://github.com/atuinsh/atuin/issues/2946)) 603 - 604 - 605 - ### Features 606 - 607 - - *(bash)* Use Readline's accept-line for enter_accept ([#2953](https://github.com/atuinsh/atuin/issues/2953)) 608 - - Add commit to displayed version info ([#2922](https://github.com/atuinsh/atuin/issues/2922)) 609 - - Add import from PowerShell history ([#2864](https://github.com/atuinsh/atuin/issues/2864)) 610 - - Interactive Inspector ([#2319](https://github.com/atuinsh/atuin/issues/2319)) 611 - - Nu ≥ 0.106.0 support commandline accept ([#2957](https://github.com/atuinsh/atuin/issues/2957)) 612 - 613 - 614 - ### Miscellaneous Tasks 615 - 616 - - Update rusty_paseto and rusty_paserk ([#2942](https://github.com/atuinsh/atuin/issues/2942)) 617 - - Update changelog 618 - 619 - 620 - ## 18.9.0 621 - 622 - ### Bug Fixes 623 - 624 - - *(dotfiles)* Properly escape spaces/quotes in vars 625 - - Clippy issues on Windows ([#2856](https://github.com/atuinsh/atuin/issues/2856)) 626 - - Honor timezone in inspector stats ([#2853](https://github.com/atuinsh/atuin/issues/2853)) 627 - - Make status exit 1 if not logged in ([#2843](https://github.com/atuinsh/atuin/issues/2843)) 628 - - Match logic of theme directory with settings directory, so ATUIN_CONFIG_DIR is respected ([#2707](https://github.com/atuinsh/atuin/issues/2707)) 629 - - Expand path for daemon.socket_path ([#2870](https://github.com/atuinsh/atuin/issues/2870)) 630 - - Use fullscreen if `inline_height` is too large ([#2888](https://github.com/atuinsh/atuin/issues/2888)) 631 - - Clean up new rustc and clippy warnings on Rust 1.89 632 - - `cargo update` and changes needed to accomodate it 633 - - Run `cargo fmt` 634 - - Clippy warnings I don't have on my version of clippy 635 - - Add forgotten `rust-toolchain.toml` to match changes (oops) 636 - - Update version in Cargo.toml + github workflows 637 - - Clippy warnings 638 - - Dissociate command_chaining from enter_accept 639 - - Remove __atuin_chain_command__ prefix 640 - - Docker compose link ([#2914](https://github.com/atuinsh/atuin/issues/2914)) 641 - - Fish up binding ([#2902](https://github.com/atuinsh/atuin/issues/2902)) 642 - 643 - 644 - ### Features 645 - 646 - - *(stats)* Add dotnet to default common subcommands 647 - - *(tui)* Select entries using number in vim-normal mode. closes #2368 ([#2893](https://github.com/atuinsh/atuin/issues/2893)) 648 - - *(tui)* Add show_numeric_shortcuts config to hide 1-9 shortcuts ([#2766](https://github.com/atuinsh/atuin/issues/2766)) 649 - - Highlight matches in interactive search ([#2653](https://github.com/atuinsh/atuin/issues/2653)) 650 - - Add session-preload filter mode to include global history from before session start 651 - - Add various acceptance keys ([#2928](https://github.com/atuinsh/atuin/issues/2928)) 652 - - More accurately filter secret tokens ([#2932](https://github.com/atuinsh/atuin/issues/2932)) 653 - - Add shell pipelines to command chaining ([#2938](https://github.com/atuinsh/atuin/issues/2938)) 654 - 655 - 656 - ### Miscellaneous Tasks 657 - 658 - - Update changelog 659 - - Remove legacy Apple SDK frameworks ([#2885](https://github.com/atuinsh/atuin/issues/2885)) 660 - - Update dist workflows 661 - - Update to Rust 1.90 ([#2916](https://github.com/atuinsh/atuin/issues/2916)) 662 - 663 - 664 - ### Refactor 665 - 666 - - Shell environment variables 667 - 668 - 669 - ### Build 670 - 671 - - Update flake.nix with new sha256 672 - 673 - 674 - ## 18.8.0 675 - 676 - ### Bug Fixes 677 - 678 - - *(build)* Enable sqlite feature for sqlite server ([#2848](https://github.com/atuinsh/atuin/issues/2848)) 679 - - Make login exit 1 if already logged in ([#2832](https://github.com/atuinsh/atuin/issues/2832)) 680 - - Use transaction for idx consistency checking ([#2840](https://github.com/atuinsh/atuin/issues/2840)) 681 - - Ensure the idx cache is cleaned on deletion, only insert if records are inserted ([#2841](https://github.com/atuinsh/atuin/issues/2841)) 682 - 683 - 684 - ### Features 685 - 686 - - Command chaining ([#2834](https://github.com/atuinsh/atuin/issues/2834)) 687 - - Add info for 'official' plugins ([#2835](https://github.com/atuinsh/atuin/issues/2835)) 688 - - Support multi part commands ([#2836](https://github.com/atuinsh/atuin/issues/2836)) ([#2837](https://github.com/atuinsh/atuin/issues/2837)) 689 - - Add inline_height_shell_up_key_binding option ([#2817](https://github.com/atuinsh/atuin/issues/2817)) 690 - - Add IDX_CACHE_ROLLOUT ([#2850](https://github.com/atuinsh/atuin/issues/2850)) 691 - 692 - 693 - ### Miscellaneous Tasks 694 - 695 - - Update to rust 1.88 ([#2815](https://github.com/atuinsh/atuin/issues/2815)) 696 - 697 - 698 - ### Nushell 699 - 700 - - Fix `get -i` deprecation ([#2829](https://github.com/atuinsh/atuin/issues/2829)) 701 - 702 - 703 - ## 18.7.1 704 - 705 - ### Bug Fixes 706 - 707 - - Add check for postgresql prefix ([#2825](https://github.com/atuinsh/atuin/issues/2825)) 708 - 709 - 710 - ### Miscellaneous Tasks 711 - 712 - - Update changelog 713 - 714 - 715 - ## 18.7.0 716 - 717 - ### Bug Fixes 718 - 719 - - *(api)* Allow trailing slashes in sync_address ([#2760](https://github.com/atuinsh/atuin/issues/2760)) 720 - - *(doctor)* Mention the required ble.sh version ([#2774](https://github.com/atuinsh/atuin/issues/2774)) 721 - - *(search)* Prevent panic on malformed format strings ([#2776](https://github.com/atuinsh/atuin/issues/2776)) ([#2777](https://github.com/atuinsh/atuin/issues/2777)) 722 - - Clarify that HISTFILE, if used, must be exported ([#2758](https://github.com/atuinsh/atuin/issues/2758)) 723 - - Don't print errors in `zsh_autosuggest` helper ([#2780](https://github.com/atuinsh/atuin/issues/2780)) 724 - - `atuin.nu` enchancements ([#2778](https://github.com/atuinsh/atuin/issues/2778)) 725 - - Refuse "--dupkeep 0" ([#2807](https://github.com/atuinsh/atuin/issues/2807)) 726 - 727 - 728 - ### Features 729 - 730 - - Add sqlite server support for self-hosting ([#2770](https://github.com/atuinsh/atuin/issues/2770)) 731 - 732 - 733 - ### Miscellaneous Tasks 734 - 735 - - *(ci)* Install toolchain that matches rust-toolchain.toml ([#2759](https://github.com/atuinsh/atuin/issues/2759)) 736 - - Allow setting script DB path ([#2750](https://github.com/atuinsh/atuin/issues/2750)) 737 - 738 - 739 - ## 18.6.1 740 - 741 - ### Bug Fixes 742 - 743 - - Selection vs render issue ([#2706](https://github.com/atuinsh/atuin/issues/2706)) 744 - 745 - 746 - ### Features 747 - 748 - - *(stats)* Add jj to default common subcommands ([#2708](https://github.com/atuinsh/atuin/issues/2708)) 749 - - Delete duplicate history ([#2697](https://github.com/atuinsh/atuin/issues/2697)) 750 - - Sort `atuin store status` output ([#2719](https://github.com/atuinsh/atuin/issues/2719)) 751 - - Implement KV as a write-through cache ([#2732](https://github.com/atuinsh/atuin/issues/2732)) 752 - 753 - 754 - ### Miscellaneous Tasks 755 - 756 - - Use native github arm64 runner ([#2690](https://github.com/atuinsh/atuin/issues/2690)) 757 - - Fix typos ([#2668](https://github.com/atuinsh/atuin/issues/2668)) 758 - 759 - 760 - ## 18.5.0 761 - 762 - ### Bug Fixes 763 - 764 - - *(1289)* Clear terminal area if inline ([#2600](https://github.com/atuinsh/atuin/issues/2600)) 765 - - *(bash)* Fix preexec of child Bash session started by enter_accept ([#2558](https://github.com/atuinsh/atuin/issues/2558)) 766 - - *(build)* Change atuin-daemon build script .proto paths ([#2638](https://github.com/atuinsh/atuin/issues/2638)) 767 - - *(kv)* Filter deleted keys from `kv list` ([#2665](https://github.com/atuinsh/atuin/issues/2665)) 768 - - *(stats)* Ignore leading environment variables when calculating stats ([#2659](https://github.com/atuinsh/atuin/issues/2659)) 769 - - *(wrapped)* Fix crash when history is empty ([#2508](https://github.com/atuinsh/atuin/issues/2508)) 770 - - *(zsh)* Fix an error introduced earilier with support for bracketed paste mode ([#2651](https://github.com/atuinsh/atuin/issues/2651)) 771 - - *(zsh)* Avoid calling user-defined widgets when searching for history position ([#2670](https://github.com/atuinsh/atuin/issues/2670)) 772 - - Add .histfile as file to look for when doing atuin import zsh ([#2588](https://github.com/atuinsh/atuin/issues/2588)) 773 - - Panic when invoking delete on empty tui ([#2584](https://github.com/atuinsh/atuin/issues/2584)) 774 - - Sql files checksums ([#2601](https://github.com/atuinsh/atuin/issues/2601)) 775 - - Up binding with fish 4.0 ([#2613](https://github.com/atuinsh/atuin/issues/2613)) ([#2616](https://github.com/atuinsh/atuin/issues/2616)) 776 - - Don't save empty commands ([#2605](https://github.com/atuinsh/atuin/issues/2605)) 777 - - Improve broken symlink error handling ([#2589](https://github.com/atuinsh/atuin/issues/2589)) 778 - - Multiline command does not honour max_preview_height ([#2624](https://github.com/atuinsh/atuin/issues/2624)) 779 - - Typeerror in client sync code ([#2647](https://github.com/atuinsh/atuin/issues/2647)) 780 - - Add redundant clones to clippy and cleanup instances of it ([#2654](https://github.com/atuinsh/atuin/issues/2654)) 781 - - Allow -ve values for timezone ([#2609](https://github.com/atuinsh/atuin/issues/2609)) 782 - - Fish up binding bug ([#2677](https://github.com/atuinsh/atuin/issues/2677)) 783 - - Switch to astral cargo-dist ([#2687](https://github.com/atuinsh/atuin/issues/2687)) 784 - 785 - 786 - ### Documentation 787 - 788 - - Update logo and badges in README for zh-CN ([#2392](https://github.com/atuinsh/atuin/issues/2392)) 789 - 790 - 791 - ### Features 792 - 793 - - *(client)* Update AWS secrets env var handling checks ([#2501](https://github.com/atuinsh/atuin/issues/2501)) 794 - - *(health)* Add health check endpoint at `/healthz` ([#2549](https://github.com/atuinsh/atuin/issues/2549)) 795 - - *(kv)* Add support for 'atuin kv delete' ([#2660](https://github.com/atuinsh/atuin/issues/2660)) 796 - - *(wrapped)* Add more pkg managers ([#2503](https://github.com/atuinsh/atuin/issues/2503)) 797 - - *(zsh)* Try to go to the position in zsh's history ([#1469](https://github.com/atuinsh/atuin/issues/1469)) 798 - - *(zsh)* Re-enable bracketed paste ([#2646](https://github.com/atuinsh/atuin/issues/2646)) 799 - - Add the --print0 option to search ([#2562](https://github.com/atuinsh/atuin/issues/2562)) 800 - - Make new arrow key behavior configurable ([#2606](https://github.com/atuinsh/atuin/issues/2606)) 801 - - Use readline binding for ctrl-a when it is not the prefix ([#2626](https://github.com/atuinsh/atuin/issues/2626)) 802 - - Option to include duplicate commands when printing history commands ([#2407](https://github.com/atuinsh/atuin/issues/2407)) 803 - - Binaries as subcommands ([#2661](https://github.com/atuinsh/atuin/issues/2661)) 804 - - Support storing, syncing and executing scripts ([#2644](https://github.com/atuinsh/atuin/issues/2644)) 805 - - Add 'atuin scripts rm' and 'atuin scripts ls' aliases; allow reading from stdin ([#2680](https://github.com/atuinsh/atuin/issues/2680)) 806 - 807 - 808 - ### Miscellaneous Tasks 809 - 810 - - Remove unneeded dependencies ([#2523](https://github.com/atuinsh/atuin/issues/2523)) 811 - - Update rust toolchain to 1.85 ([#2618](https://github.com/atuinsh/atuin/issues/2618)) 812 - - Align daemon and client sync freq ([#2628](https://github.com/atuinsh/atuin/issues/2628)) 813 - - Migrate to rust 2024 ([#2635](https://github.com/atuinsh/atuin/issues/2635)) 814 - - Show host and user in inspector ([#2634](https://github.com/atuinsh/atuin/issues/2634)) 815 - - Update to rust 1.85.1 ([#2642](https://github.com/atuinsh/atuin/issues/2642)) 816 - - Update to rust 1.86 ([#2666](https://github.com/atuinsh/atuin/issues/2666)) 817 - 818 - 819 - ### Performance 820 - 821 - - Cache `SECRET_PATTERNS`'s `RegexSet` ([#2570](https://github.com/atuinsh/atuin/issues/2570)) 822 - 823 - 824 - ### Styling 825 - 826 - - Avoid calling `unwrap()` when we don't have to ([#2519](https://github.com/atuinsh/atuin/issues/2519)) 827 - 828 - 829 - ### Build 830 - 831 - - *(nix)* Bump `flake.lock` ([#2637](https://github.com/atuinsh/atuin/issues/2637)) 832 - 833 - 834 - ### Flake.lock 835 - 836 - - Update ([#2463](https://github.com/atuinsh/atuin/issues/2463)) 837 - 838 - 839 - ## 18.4.0 840 - 841 - ### Bug Fixes 842 - 843 - - *(crate)* Add missing description ([#2106](https://github.com/atuinsh/atuin/issues/2106)) 844 - - *(crate)* Add description to daemon crate ([#2107](https://github.com/atuinsh/atuin/issues/2107)) 845 - - *(daemon)* Add context to error when unable to connect ([#2394](https://github.com/atuinsh/atuin/issues/2394)) 846 - - *(deps)* Pin tiny_bip to 1.0.0 until breaking change resolved ([#2412](https://github.com/atuinsh/atuin/issues/2412)) 847 - - *(docker)* Update Dockerfile ([#2369](https://github.com/atuinsh/atuin/issues/2369)) 848 - - *(gui)* Update deps ([#2116](https://github.com/atuinsh/atuin/issues/2116)) 849 - - *(gui)* Add support for checking if the cli is installed on windows ([#2162](https://github.com/atuinsh/atuin/issues/2162)) 850 - - *(gui)* WeekInfo call on Edge ([#2252](https://github.com/atuinsh/atuin/issues/2252)) 851 - - *(gui)* Add \r for windows (shouldn't effect unix bc they should ignore it) ([#2253](https://github.com/atuinsh/atuin/issues/2253)) 852 - - *(gui)* Terminal resize overflow ([#2285](https://github.com/atuinsh/atuin/issues/2285)) 853 - - *(gui)* Kill child on block stop ([#2288](https://github.com/atuinsh/atuin/issues/2288)) 854 - - *(gui)* Do not hardcode db path ([#2309](https://github.com/atuinsh/atuin/issues/2309)) 855 - - *(gui)* Double return on mac/linux ([#2311](https://github.com/atuinsh/atuin/issues/2311)) 856 - - *(gui)* Cursor positioning on new doc creation ([#2310](https://github.com/atuinsh/atuin/issues/2310)) 857 - - *(gui)* Random ts errors ([#2316](https://github.com/atuinsh/atuin/issues/2316)) 858 - - *(history)* Logic for store_failed=false ([#2284](https://github.com/atuinsh/atuin/issues/2284)) 859 - - *(mail)* Incorrect alias and error logs ([#2346](https://github.com/atuinsh/atuin/issues/2346)) 860 - - *(mail)* Enable correct tls features for postmark client ([#2347](https://github.com/atuinsh/atuin/issues/2347)) 861 - - *(theme)* Restore original colours ([#2339](https://github.com/atuinsh/atuin/issues/2339)) 862 - - *(themes)* Restore default theme, refactor ([#2294](https://github.com/atuinsh/atuin/issues/2294)) 863 - - *(tui)* Press ctrl-a twice should jump to beginning of line ([#2246](https://github.com/atuinsh/atuin/issues/2246)) 864 - - *(tui)* Don't panic when search result is empty and up is pressed ([#2395](https://github.com/atuinsh/atuin/issues/2395)) 865 - - Cargo binstall config ([#2112](https://github.com/atuinsh/atuin/issues/2112)) 866 - - Unitless sync_frequence = 0 not parsed by humantime ([#2154](https://github.com/atuinsh/atuin/issues/2154)) 867 - - Some --help comments didn't show properly ([#2176](https://github.com/atuinsh/atuin/issues/2176)) 868 - - Ensure we cleanup all tables when deleting ([#2191](https://github.com/atuinsh/atuin/issues/2191)) 869 - - Add idx cache unique index ([#2226](https://github.com/atuinsh/atuin/issues/2226)) 870 - - Idx cache inconsistency ([#2231](https://github.com/atuinsh/atuin/issues/2231)) 871 - - Ambiguous column name ([#2232](https://github.com/atuinsh/atuin/issues/2232)) 872 - - Atuin-daemon optional dependency ([#2306](https://github.com/atuinsh/atuin/issues/2306)) 873 - - Windows build error ([#2321](https://github.com/atuinsh/atuin/issues/2321)) 874 - - Codespell config still references the ui ([#2330](https://github.com/atuinsh/atuin/issues/2330)) 875 - - Remove dbg! macro ([#2355](https://github.com/atuinsh/atuin/issues/2355)) 876 - - Disable mail by default, resolve #2404 ([#2405](https://github.com/atuinsh/atuin/issues/2405)) 877 - - Time offset display in `atuin status` ([#2433](https://github.com/atuinsh/atuin/issues/2433)) 878 - - Disable the actuated mirror on the x86 docker builder ([#2443](https://github.com/atuinsh/atuin/issues/2443)) 879 - 880 - 881 - ### Documentation 882 - 883 - - *(README)* Fix broken link ([#2206](https://github.com/atuinsh/atuin/issues/2206)) 884 - - *(gui)* Update README ([#2283](https://github.com/atuinsh/atuin/issues/2283)) 885 - - Streamline readme ([#2203](https://github.com/atuinsh/atuin/issues/2203)) 886 - - Update quickstart install command ([#2205](https://github.com/atuinsh/atuin/issues/2205)) 887 - 888 - 889 - ### Features 890 - 891 - - *(bash/blesh)* Hook into BLE_ONLOAD to resolve loading order issue ([#2234](https://github.com/atuinsh/atuin/issues/2234)) 892 - - *(client)* Add filter mode enablement and ordering configuration ([#2430](https://github.com/atuinsh/atuin/issues/2430)) 893 - - *(daemon)* Follow XDG_RUNTIME_DIR if set ([#2171](https://github.com/atuinsh/atuin/issues/2171)) 894 - - *(gui)* Automatically install and setup the cli/shell ([#2139](https://github.com/atuinsh/atuin/issues/2139)) 895 - - *(gui)* Add activity calendar to the homepage ([#2160](https://github.com/atuinsh/atuin/issues/2160)) 896 - - *(gui)* Cache zustand store in localstorage ([#2168](https://github.com/atuinsh/atuin/issues/2168)) 897 - - *(gui)* Toast with prompt for cli install, rather than auto ([#2173](https://github.com/atuinsh/atuin/issues/2173)) 898 - - *(gui)* Runbooks that run ([#2233](https://github.com/atuinsh/atuin/issues/2233)) 899 - - *(gui)* Use fancy new side nav ([#2243](https://github.com/atuinsh/atuin/issues/2243)) 900 - - *(gui)* Add runbook list, ability to create and delete, sql storage ([#2282](https://github.com/atuinsh/atuin/issues/2282)) 901 - - *(gui)* Background terminals and more ([#2303](https://github.com/atuinsh/atuin/issues/2303)) 902 - - *(gui)* Clean up home page, fix a few bugs ([#2304](https://github.com/atuinsh/atuin/issues/2304)) 903 - - *(gui)* Allow interacting with the embedded terminal ([#2312](https://github.com/atuinsh/atuin/issues/2312)) 904 - - *(gui)* Directory block, re-org of some code ([#2314](https://github.com/atuinsh/atuin/issues/2314)) 905 - - *(gui)* Folder select dialogue for directory block ([#2315](https://github.com/atuinsh/atuin/issues/2315)) 906 - - *(history)* Filter out various environment variables containing potential secrets ([#2174](https://github.com/atuinsh/atuin/issues/2174)) 907 - - *(tui)* Configurable prefix character ([#2157](https://github.com/atuinsh/atuin/issues/2157)) 908 - - *(tui)* Customizable Themes ([#2236](https://github.com/atuinsh/atuin/issues/2236)) 909 - - *(tui)* Fixed preview height option ([#2286](https://github.com/atuinsh/atuin/issues/2286)) 910 - - Use cargo-dist installer from our install script ([#2108](https://github.com/atuinsh/atuin/issues/2108)) 911 - - Add user account verification ([#2190](https://github.com/atuinsh/atuin/issues/2190)) 912 - - Add GitLab PAT to secret patterns ([#2196](https://github.com/atuinsh/atuin/issues/2196)) 913 - - Add several other GitHub access token patterns ([#2200](https://github.com/atuinsh/atuin/issues/2200)) 914 - - Add npm, Netlify and Pulumi tokens to secret patterns ([#2210](https://github.com/atuinsh/atuin/issues/2210)) 915 - - Allow advertising a fake version to clients ([#2228](https://github.com/atuinsh/atuin/issues/2228)) 916 - - Monitor idx cache consistency before switching ([#2229](https://github.com/atuinsh/atuin/issues/2229)) 917 - - Ultracompact Mode (search-only) ([#2357](https://github.com/atuinsh/atuin/issues/2357)) 918 - - Right Arrow to modify selected command ([#2453](https://github.com/atuinsh/atuin/issues/2453)) 919 - - Provide additional clarity around key management ([#2467](https://github.com/atuinsh/atuin/issues/2467)) 920 - - Add `atuin wrapped` ([#2493](https://github.com/atuinsh/atuin/issues/2493)) 921 - 922 - 923 - ### Miscellaneous Tasks 924 - 925 - - *(build)* Compile protobufs with protox ([#2122](https://github.com/atuinsh/atuin/issues/2122)) 926 - - *(ci)* Do not run current ci for ui ([#2189](https://github.com/atuinsh/atuin/issues/2189)) 927 - - *(ci)* Codespell again ([#2332](https://github.com/atuinsh/atuin/issues/2332)) 928 - - *(deps-dev)* Bump @tauri-apps/cli in /ui ([#2135](https://github.com/atuinsh/atuin/issues/2135)) 929 - - *(deps-dev)* Bump vite from 5.2.13 to 5.3.1 in /ui ([#2150](https://github.com/atuinsh/atuin/issues/2150)) 930 - - *(deps-dev)* Bump @tauri-apps/cli in /ui ([#2277](https://github.com/atuinsh/atuin/issues/2277)) 931 - - *(deps-dev)* Bump tailwindcss from 3.4.4 to 3.4.6 in /ui ([#2301](https://github.com/atuinsh/atuin/issues/2301)) 932 - - *(install)* Use posix sh, not bash ([#2204](https://github.com/atuinsh/atuin/issues/2204)) 933 - - *(nix)* De-couple atuin nix build from nixpkgs rustc version ([#2123](https://github.com/atuinsh/atuin/issues/2123)) 934 - - Add installer e2e tests ([#2110](https://github.com/atuinsh/atuin/issues/2110)) 935 - - Remove unnecessary proto import ([#2120](https://github.com/atuinsh/atuin/issues/2120)) 936 - - Update to rust 1.78 937 - - Add audit config, ignore RUSTSEC-2023-0071 ([#2126](https://github.com/atuinsh/atuin/issues/2126)) 938 - - Setup dependabot for the ui ([#2128](https://github.com/atuinsh/atuin/issues/2128)) 939 - - Cargo and pnpm update ([#2127](https://github.com/atuinsh/atuin/issues/2127)) 940 - - Update to rust 1.79 ([#2138](https://github.com/atuinsh/atuin/issues/2138)) 941 - - Update to cargo-dist 0.16, enable attestations ([#2156](https://github.com/atuinsh/atuin/issues/2156)) 942 - - Do not use package managers in installer ([#2201](https://github.com/atuinsh/atuin/issues/2201)) 943 - - Enable record sync by default ([#2255](https://github.com/atuinsh/atuin/issues/2255)) 944 - - Remove ui directory ([#2329](https://github.com/atuinsh/atuin/issues/2329)) 945 - - Update to rust 1.80 ([#2344](https://github.com/atuinsh/atuin/issues/2344)) 946 - - Update rust to `1.80.1` ([#2362](https://github.com/atuinsh/atuin/issues/2362)) 947 - - Enable inline height and compact by default ([#2249](https://github.com/atuinsh/atuin/issues/2249)) 948 - - Update to rust 1.82 ([#2432](https://github.com/atuinsh/atuin/issues/2432)) 949 - - Update cargo-dist ([#2471](https://github.com/atuinsh/atuin/issues/2471)) 950 - 951 - 952 - ### Performance 953 - 954 - - *(search)* Benchmark smart sort ([#2202](https://github.com/atuinsh/atuin/issues/2202)) 955 - - Create idx cache table ([#2140](https://github.com/atuinsh/atuin/issues/2140)) 956 - - Write to the idx cache ([#2225](https://github.com/atuinsh/atuin/issues/2225)) 957 - 958 - 959 - ### Testing 960 - 961 - - Add env ATUIN_TEST_LOCAL_TIMEOUT to control test timeout of SQLite ([#2337](https://github.com/atuinsh/atuin/issues/2337)) 962 - 963 - 964 - ### Flake.lock 965 - 966 - - Update ([#2213](https://github.com/atuinsh/atuin/issues/2213)) 967 - - Update ([#2378](https://github.com/atuinsh/atuin/issues/2378)) 968 - - Update ([#2402](https://github.com/atuinsh/atuin/issues/2402)) 969 - 970 - 971 - ## 18.3.0 972 - 973 - ### Bug Fixes 974 - 975 - - *(bash)* Fix a workaround for bash-5.2 keybindings ([#2060](https://github.com/atuinsh/atuin/issues/2060)) 976 - - *(ci)* Release workflow ([#1978](https://github.com/atuinsh/atuin/issues/1978)) 977 - - *(client)* Better error reporting on login/registration ([#2076](https://github.com/atuinsh/atuin/issues/2076)) 978 - - *(config)* Add quotes for strategy value in comment ([#1993](https://github.com/atuinsh/atuin/issues/1993)) 979 - - *(daemon)* Do not try to sync if logged out ([#2037](https://github.com/atuinsh/atuin/issues/2037)) 980 - - *(deps)* Replace parse_duration with humantime ([#2074](https://github.com/atuinsh/atuin/issues/2074)) 981 - - *(dotfiles)* Alias import with init output ([#1970](https://github.com/atuinsh/atuin/issues/1970)) 982 - - *(dotfiles)* Fish alias import ([#1972](https://github.com/atuinsh/atuin/issues/1972)) 983 - - *(dotfiles)* More fish alias import ([#1974](https://github.com/atuinsh/atuin/issues/1974)) 984 - - *(dotfiles)* Unquote aliases before quoting ([#1976](https://github.com/atuinsh/atuin/issues/1976)) 985 - - *(dotfiles)* Allow clearing aliases, disable import ([#1995](https://github.com/atuinsh/atuin/issues/1995)) 986 - - *(stats)* Generation for commands starting with a pipe ([#2058](https://github.com/atuinsh/atuin/issues/2058)) 987 - - *(ui)* Handle being logged out gracefully ([#2052](https://github.com/atuinsh/atuin/issues/2052)) 988 - - *(ui)* Fix mistake in last pr ([#2053](https://github.com/atuinsh/atuin/issues/2053)) 989 - - Support not-mac for default shell ([#1960](https://github.com/atuinsh/atuin/issues/1960)) 990 - - Adapt help to `enter_accept` config ([#2001](https://github.com/atuinsh/atuin/issues/2001)) 991 - - Add protobuf compiler to docker image ([#2009](https://github.com/atuinsh/atuin/issues/2009)) 992 - - Add incremental rebuild to daemon loop ([#2010](https://github.com/atuinsh/atuin/issues/2010)) 993 - - Alias enable/enabled in settings ([#2021](https://github.com/atuinsh/atuin/issues/2021)) 994 - - Bogus error message wording ([#1283](https://github.com/atuinsh/atuin/issues/1283)) 995 - - Save sync time in daemon ([#2029](https://github.com/atuinsh/atuin/issues/2029)) 996 - - Redact password in database URI when logging ([#2032](https://github.com/atuinsh/atuin/issues/2032)) 997 - - Save sync time in daemon ([#2051](https://github.com/atuinsh/atuin/issues/2051)) 998 - - Replace serde_yaml::to_string with serde_json::to_string_yaml ([#2087](https://github.com/atuinsh/atuin/issues/2087)) 999 - 1000 - 1001 - ### Documentation 1002 - 1003 - - Fix "From source" `cd` command ([#1973](https://github.com/atuinsh/atuin/issues/1973)) 1004 - - Add docs for store subcommand ([#2097](https://github.com/atuinsh/atuin/issues/2097)) 1005 - 1006 - 1007 - ### Features 1008 - 1009 - - *(daemon)* Add support for daemon on windows ([#2014](https://github.com/atuinsh/atuin/issues/2014)) 1010 - - *(doctor)* Detect active preexec framework ([#1955](https://github.com/atuinsh/atuin/issues/1955)) 1011 - - *(doctor)* Report sqlite version ([#2075](https://github.com/atuinsh/atuin/issues/2075)) 1012 - - *(dotfiles)* Support syncing shell/env vars ([#1977](https://github.com/atuinsh/atuin/issues/1977)) 1013 - - *(gui)* Work on home page, sort state ([#1956](https://github.com/atuinsh/atuin/issues/1956)) 1014 - - *(history)* Create atuin-history, add stats to it ([#1990](https://github.com/atuinsh/atuin/issues/1990)) 1015 - - *(install)* Add Tuxedo OS ([#2018](https://github.com/atuinsh/atuin/issues/2018)) 1016 - - *(server)* Add me endpoint ([#1954](https://github.com/atuinsh/atuin/issues/1954)) 1017 - - *(ui)* Scroll history infinitely ([#1999](https://github.com/atuinsh/atuin/issues/1999)) 1018 - - *(ui)* Add history explore ([#2022](https://github.com/atuinsh/atuin/issues/2022)) 1019 - - *(ui)* Use correct username on welcome screen ([#2050](https://github.com/atuinsh/atuin/issues/2050)) 1020 - - *(ui)* Add login/register dialog ([#2056](https://github.com/atuinsh/atuin/issues/2056)) 1021 - - *(ui)* Setup single-instance ([#2093](https://github.com/atuinsh/atuin/issues/2093)) 1022 - - *(ui/dotfiles)* Add vars ([#1989](https://github.com/atuinsh/atuin/issues/1989)) 1023 - - Allow ignoring failed commands ([#1957](https://github.com/atuinsh/atuin/issues/1957)) 1024 - - Show preview auto ([#1804](https://github.com/atuinsh/atuin/issues/1804)) 1025 - - Add background daemon ([#2006](https://github.com/atuinsh/atuin/issues/2006)) 1026 - - Support importing from replxx history files ([#2024](https://github.com/atuinsh/atuin/issues/2024)) 1027 - - Support systemd socket activation for daemon ([#2039](https://github.com/atuinsh/atuin/issues/2039)) 1028 - 1029 - 1030 - ### Miscellaneous Tasks 1031 - 1032 - - *(ci)* Don't run "Update Nix Deps" CI on forks ([#2070](https://github.com/atuinsh/atuin/issues/2070)) 1033 - - *(codespell)* Ignore CODE_OF_CONDUCT ([#2044](https://github.com/atuinsh/atuin/issues/2044)) 1034 - - *(install)* Log cargo and rustc version ([#2068](https://github.com/atuinsh/atuin/issues/2068)) 1035 - - *(release)* V18.3.0-prerelease.1 ([#2090](https://github.com/atuinsh/atuin/issues/2090)) 1036 - - Move crates into crates/ dir ([#1958](https://github.com/atuinsh/atuin/issues/1958)) 1037 - - Fix atuin crate readme ([#1959](https://github.com/atuinsh/atuin/issues/1959)) 1038 - - Add some more logging to handlers ([#1971](https://github.com/atuinsh/atuin/issues/1971)) 1039 - - Add some more debug logs ([#1979](https://github.com/atuinsh/atuin/issues/1979)) 1040 - - Clarify default config file ([#2026](https://github.com/atuinsh/atuin/issues/2026)) 1041 - - Handle rate limited responses ([#2057](https://github.com/atuinsh/atuin/issues/2057)) 1042 - - Add Systemd config for self-hosted server ([#1879](https://github.com/atuinsh/atuin/issues/1879)) 1043 - - Switch to cargo dist for releases ([#2085](https://github.com/atuinsh/atuin/issues/2085)) 1044 - - Update email, gitignore, tweak ui ([#2094](https://github.com/atuinsh/atuin/issues/2094)) 1045 - - Show scope in changelog ([#2102](https://github.com/atuinsh/atuin/issues/2102)) 1046 - 1047 - 1048 - ### Performance 1049 - 1050 - - *(nushell)* Use version.(major|minor|patch) if available ([#1963](https://github.com/atuinsh/atuin/issues/1963)) 1051 - - Only open the database for commands if strictly required ([#2043](https://github.com/atuinsh/atuin/issues/2043)) 1052 - 1053 - 1054 - ### Refactor 1055 - 1056 - - Preview_auto to use enum and different option ([#1991](https://github.com/atuinsh/atuin/issues/1991)) 1057 - 1058 - 1059 - ## 18.2.0 1060 - 1061 - ### Bug Fixes 1062 - 1063 - - *(bash)* Do not use "return" to cancel initialization ([#1928](https://github.com/atuinsh/atuin/issues/1928)) 1064 - - *(crate)* Add missing description ([#1861](https://github.com/atuinsh/atuin/issues/1861)) 1065 - - *(doctor)* Detect preexec plugin using env ATUIN_PREEXEC_BACKEND ([#1856](https://github.com/atuinsh/atuin/issues/1856)) 1066 - - *(install)* Install script echo ([#1899](https://github.com/atuinsh/atuin/issues/1899)) 1067 - - *(nu)* Update atuin.nu to resolve 0.92 deprecation ([#1913](https://github.com/atuinsh/atuin/issues/1913)) 1068 - - *(search)* Allow empty search ([#1866](https://github.com/atuinsh/atuin/issues/1866)) 1069 - - *(search)* Case insensitive hostname filtering ([#1883](https://github.com/atuinsh/atuin/issues/1883)) 1070 - - Pass search query in via env ([#1865](https://github.com/atuinsh/atuin/issues/1865)) 1071 - - Pass search query in via env for *Nushell* ([#1874](https://github.com/atuinsh/atuin/issues/1874)) 1072 - - Report non-decodable errors correctly ([#1915](https://github.com/atuinsh/atuin/issues/1915)) 1073 - - Use spawn_blocking for file access during async context ([#1936](https://github.com/atuinsh/atuin/issues/1936)) 1074 - 1075 - 1076 - ### Documentation 1077 - 1078 - - *(bash-preexec)* Describe the limitation of missing commands ([#1937](https://github.com/atuinsh/atuin/issues/1937)) 1079 - - Add security contact ([#1867](https://github.com/atuinsh/atuin/issues/1867)) 1080 - - Add install instructions for cave/exherbo linux in README.md ([#1927](https://github.com/atuinsh/atuin/issues/1927)) 1081 - - Add missing cli help text ([#1945](https://github.com/atuinsh/atuin/issues/1945)) 1082 - 1083 - 1084 - ### Features 1085 - 1086 - - *(bash/blesh)* Use _ble_exec_time_ata for duration even in bash < 5 ([#1940](https://github.com/atuinsh/atuin/issues/1940)) 1087 - - *(dotfiles)* Add alias import ([#1938](https://github.com/atuinsh/atuin/issues/1938)) 1088 - - *(gui)* Add base structure ([#1935](https://github.com/atuinsh/atuin/issues/1935)) 1089 - - *(install)* Update install.sh to support KDE Neon ([#1908](https://github.com/atuinsh/atuin/issues/1908)) 1090 - - *(search)* Process [C-h] and [C-?] as representations of backspace ([#1857](https://github.com/atuinsh/atuin/issues/1857)) 1091 - - *(search)* Allow specifying search query as an env var ([#1863](https://github.com/atuinsh/atuin/issues/1863)) 1092 - - *(search)* Add better search scoring ([#1885](https://github.com/atuinsh/atuin/issues/1885)) 1093 - - *(server)* Check PG version before running migrations ([#1868](https://github.com/atuinsh/atuin/issues/1868)) 1094 - - Add atuin prefix binding ([#1875](https://github.com/atuinsh/atuin/issues/1875)) 1095 - - Sync v2 default for new installs ([#1914](https://github.com/atuinsh/atuin/issues/1914)) 1096 - - Add 'ctrl-a a' to jump to beginning of line ([#1917](https://github.com/atuinsh/atuin/issues/1917)) 1097 - - Prevents stderr from going to the screen ([#1933](https://github.com/atuinsh/atuin/issues/1933)) 1098 - 1099 - 1100 - ### Miscellaneous Tasks 1101 - 1102 - - *(ci)* Add codespell support (config, workflow) and make it fix some typos ([#1916](https://github.com/atuinsh/atuin/issues/1916)) 1103 - - *(gui)* Cargo update ([#1943](https://github.com/atuinsh/atuin/issues/1943)) 1104 - - Add issue form ([#1871](https://github.com/atuinsh/atuin/issues/1871)) 1105 - - Require atuin doctor in issue form ([#1872](https://github.com/atuinsh/atuin/issues/1872)) 1106 - - Add section to issue form ([#1873](https://github.com/atuinsh/atuin/issues/1873)) 1107 - 1108 - 1109 - ### Performance 1110 - 1111 - - *(dotfiles)* Cache aliases and read straight from file ([#1918](https://github.com/atuinsh/atuin/issues/1918)) 1112 - 1113 - 1114 - ## 18.1.0 1115 - 1116 - ### Bug Fixes 1117 - 1118 - - *(bash)* Rework #1509 to recover from the preexec failure ([#1729](https://github.com/atuinsh/atuin/issues/1729)) 1119 - - *(build)* Make atuin compile on non-win/mac/linux platforms ([#1825](https://github.com/atuinsh/atuin/issues/1825)) 1120 - - *(client)* No panic on empty inspector ([#1768](https://github.com/atuinsh/atuin/issues/1768)) 1121 - - *(doctor)* Use a different method to detect env vars ([#1819](https://github.com/atuinsh/atuin/issues/1819)) 1122 - - *(dotfiles)* Use latest client ([#1859](https://github.com/atuinsh/atuin/issues/1859)) 1123 - - *(import/zsh-histdb)* Missing or wrong fields ([#1740](https://github.com/atuinsh/atuin/issues/1740)) 1124 - - *(nix)* Set meta.mainProgram in the package ([#1823](https://github.com/atuinsh/atuin/issues/1823)) 1125 - - *(nushell)* Readd up-arrow keybinding, now with menu handling ([#1770](https://github.com/atuinsh/atuin/issues/1770)) 1126 - - *(regex)* Disable regex error logs ([#1806](https://github.com/atuinsh/atuin/issues/1806)) 1127 - - *(stats)* Enable multiple command stats to be shown using unicode_segmentation ([#1739](https://github.com/atuinsh/atuin/issues/1739)) 1128 - - *(store-init)* Re-sync after running auto store init ([#1834](https://github.com/atuinsh/atuin/issues/1834)) 1129 - - *(sync)* Check store length after sync, not before ([#1805](https://github.com/atuinsh/atuin/issues/1805)) 1130 - - *(sync)* Record size limiter ([#1827](https://github.com/atuinsh/atuin/issues/1827)) 1131 - - *(tz)* Attempt to fix timezone reading ([#1810](https://github.com/atuinsh/atuin/issues/1810)) 1132 - - *(ui)* Don't preserve for empty space ([#1712](https://github.com/atuinsh/atuin/issues/1712)) 1133 - - *(xonsh)* Add xonsh to auto import, respect $HISTFILE in xonsh import, and fix issue with up-arrow keybinding in xonsh ([#1711](https://github.com/atuinsh/atuin/issues/1711)) 1134 - - Fish init ([#1725](https://github.com/atuinsh/atuin/issues/1725)) 1135 - - Typo ([#1741](https://github.com/atuinsh/atuin/issues/1741)) 1136 - - Check session file exists for status command ([#1756](https://github.com/atuinsh/atuin/issues/1756)) 1137 - - Ensure sync time is saved for sync v2 ([#1758](https://github.com/atuinsh/atuin/issues/1758)) 1138 - - Missing characters in preview ([#1803](https://github.com/atuinsh/atuin/issues/1803)) 1139 - - Doctor shell wording ([#1858](https://github.com/atuinsh/atuin/issues/1858)) 1140 - 1141 - 1142 - ### Documentation 1143 - 1144 - - Minor formatting updates to the default config.toml ([#1689](https://github.com/atuinsh/atuin/issues/1689)) 1145 - - Update docker compose ([#1818](https://github.com/atuinsh/atuin/issues/1818)) 1146 - - Use db name env variable also in uri ([#1840](https://github.com/atuinsh/atuin/issues/1840)) 1147 - 1148 - 1149 - ### Features 1150 - 1151 - - *(client)* Add config option keys.scroll_exits ([#1744](https://github.com/atuinsh/atuin/issues/1744)) 1152 - - *(dotfiles)* Add enable setting to dotfiles, disable by default ([#1829](https://github.com/atuinsh/atuin/issues/1829)) 1153 - - *(nix)* Add update action ([#1779](https://github.com/atuinsh/atuin/issues/1779)) 1154 - - *(nu)* Return early if history is disabled ([#1807](https://github.com/atuinsh/atuin/issues/1807)) 1155 - - *(nushell)* Add nushell completion generation ([#1791](https://github.com/atuinsh/atuin/issues/1791)) 1156 - - *(search)* Process Ctrl+m for kitty keyboard protocol ([#1720](https://github.com/atuinsh/atuin/issues/1720)) 1157 - - *(stats)* Normalize formatting of default config, suggest nix ([#1764](https://github.com/atuinsh/atuin/issues/1764)) 1158 - - *(stats)* Add linux sysadmin commands to common_subcommands ([#1784](https://github.com/atuinsh/atuin/issues/1784)) 1159 - - *(ui)* Add config setting for showing tabs ([#1755](https://github.com/atuinsh/atuin/issues/1755)) 1160 - - Use ATUIN_TEST_SQLITE_STORE_TIMEOUT to specify test timeout of SQLite store ([#1703](https://github.com/atuinsh/atuin/issues/1703)) 1161 - - Add 'a', 'A', 'h', and 'l' bindings to vim-normal mode ([#1697](https://github.com/atuinsh/atuin/issues/1697)) 1162 - - Add xonsh history import ([#1678](https://github.com/atuinsh/atuin/issues/1678)) 1163 - - Add 'ignored_commands' option to stats ([#1722](https://github.com/atuinsh/atuin/issues/1722)) 1164 - - Support syncing aliases ([#1721](https://github.com/atuinsh/atuin/issues/1721)) 1165 - - Change fulltext to do multi substring match ([#1660](https://github.com/atuinsh/atuin/issues/1660)) 1166 - - Add history prune subcommand ([#1743](https://github.com/atuinsh/atuin/issues/1743)) 1167 - - Add alias feedback and list command ([#1747](https://github.com/atuinsh/atuin/issues/1747)) 1168 - - Add PHP package manager "composer" to list of default common subcommands ([#1757](https://github.com/atuinsh/atuin/issues/1757)) 1169 - - Add '/', '?', and 'I' bindings to vim-normal mode ([#1760](https://github.com/atuinsh/atuin/issues/1760)) 1170 - - Add `CTRL+[` binding as `<Esc>` alias ([#1787](https://github.com/atuinsh/atuin/issues/1787)) 1171 - - Add atuin doctor ([#1796](https://github.com/atuinsh/atuin/issues/1796)) 1172 - - Add checks for common setup issues ([#1799](https://github.com/atuinsh/atuin/issues/1799)) 1173 - - Support regex with r/.../ syntax ([#1745](https://github.com/atuinsh/atuin/issues/1745)) 1174 - - Guard against ancient versions of bash where this does not work. ([#1794](https://github.com/atuinsh/atuin/issues/1794)) 1175 - - Add automatic history store init ([#1831](https://github.com/atuinsh/atuin/issues/1831)) 1176 - - Adds info command to show env vars and config files ([#1841](https://github.com/atuinsh/atuin/issues/1841)) 1177 - 1178 - 1179 - ### Miscellaneous Tasks 1180 - 1181 - - *(ci)* Add cross-compile job for illumos ([#1830](https://github.com/atuinsh/atuin/issues/1830)) 1182 - - *(ci)* Setup nextest ([#1848](https://github.com/atuinsh/atuin/issues/1848)) 1183 - - Do not show history table stats when using records ([#1835](https://github.com/atuinsh/atuin/issues/1835)) 1184 - 1185 - 1186 - ### Performance 1187 - 1188 - - Optimize history init-store ([#1691](https://github.com/atuinsh/atuin/issues/1691)) 1189 - 1190 - 1191 - ### Refactor 1192 - 1193 - - *(alias)* Clarify operation result for working with aliases ([#1748](https://github.com/atuinsh/atuin/issues/1748)) 1194 - - *(nushell)* Update `commandline` syntax, closes #1733 ([#1735](https://github.com/atuinsh/atuin/issues/1735)) 1195 - - Rename atuin-config to atuin-dotfiles ([#1817](https://github.com/atuinsh/atuin/issues/1817)) 1196 - 1197 - 1198 - ## 18.0.1 1199 - 1200 - ### Bug Fixes 1201 - 1202 - - Reorder the exit of enhanced keyboard mode ([#1694](https://github.com/atuinsh/atuin/issues/1694)) 1203 - 1204 - 1205 - ## 18.0.0 1206 - 1207 - ### Bug Fixes 1208 - 1209 - - *(bash)* Avoid unexpected `atuin history start` for keybindings ([#1509](https://github.com/atuinsh/atuin/issues/1509)) 1210 - - *(bash)* Prevent input to be interpreted as options for blesh auto-complete ([#1511](https://github.com/atuinsh/atuin/issues/1511)) 1211 - - *(bash)* Work around custom IFS ([#1514](https://github.com/atuinsh/atuin/issues/1514)) 1212 - - *(bash)* Fix and improve the keybinding to `up` ([#1515](https://github.com/atuinsh/atuin/issues/1515)) 1213 - - *(bash)* Work around bash < 4 and introduce initialization guards ([#1533](https://github.com/atuinsh/atuin/issues/1533)) 1214 - - *(bash)* Strip control chars generated by `\[\]` in PS1 with bash-preexec ([#1620](https://github.com/atuinsh/atuin/issues/1620)) 1215 - - *(bash/preexec)* Erase the prompt last line before Bash renders it 1216 - - *(bash/preexec)* Erase the previous prompt before overwriting 1217 - - *(bash/preexec)* Support termcap names for tput ([#1670](https://github.com/atuinsh/atuin/issues/1670)) 1218 - - *(docs)* Update repo url in CONTRIBUTING.md ([#1594](https://github.com/atuinsh/atuin/issues/1594)) 1219 - - *(fish)* Integration on older fishes ([#1563](https://github.com/atuinsh/atuin/issues/1563)) 1220 - - *(perm)* Set umask 077 ([#1554](https://github.com/atuinsh/atuin/issues/1554)) 1221 - - *(search)* Fix invisible tab title ([#1560](https://github.com/atuinsh/atuin/issues/1560)) 1222 - - *(shell)* Fix incorrect timing of child shells ([#1510](https://github.com/atuinsh/atuin/issues/1510)) 1223 - - *(sync)* Save sync time when it starts, not ends ([#1573](https://github.com/atuinsh/atuin/issues/1573)) 1224 - - *(tests)* Add Settings::utc() for utc settings ([#1677](https://github.com/atuinsh/atuin/issues/1677)) 1225 - - *(tui)* Dedupe was removing history ([#1610](https://github.com/atuinsh/atuin/issues/1610)) 1226 - - *(windows)* Disables unix specific stuff for windows ([#1557](https://github.com/atuinsh/atuin/issues/1557)) 1227 - - Prevent input to be interpreted as options for zsh autosuggestions ([#1506](https://github.com/atuinsh/atuin/issues/1506)) 1228 - - Disable musl deb building ([#1525](https://github.com/atuinsh/atuin/issues/1525)) 1229 - - Shorten text, use ctrl-o for inspector ([#1561](https://github.com/atuinsh/atuin/issues/1561)) 1230 - - Print literal control characters to non terminals ([#1586](https://github.com/atuinsh/atuin/issues/1586)) 1231 - - Escape control characters in command preview ([#1588](https://github.com/atuinsh/atuin/issues/1588)) 1232 - - Use existing db querying for history list ([#1589](https://github.com/atuinsh/atuin/issues/1589)) 1233 - - Add acquire timeout to sqlite database connection ([#1590](https://github.com/atuinsh/atuin/issues/1590)) 1234 - - Only escape control characters when writing to terminal ([#1593](https://github.com/atuinsh/atuin/issues/1593)) 1235 - - Check for format errors when printing history ([#1623](https://github.com/atuinsh/atuin/issues/1623)) 1236 - - Skip padding time if it will overflow the allowed prefix length ([#1630](https://github.com/atuinsh/atuin/issues/1630)) 1237 - - Never overwrite the key ([#1657](https://github.com/atuinsh/atuin/issues/1657)) 1238 - - Set durability for sqlite to recommended settings ([#1667](https://github.com/atuinsh/atuin/issues/1667)) 1239 - - Correct download list for incremental builds ([#1672](https://github.com/atuinsh/atuin/issues/1672)) 1240 - 1241 - 1242 - ### Documentation 1243 - 1244 - - *(README)* Clarify prerequisites for Bash ([#1686](https://github.com/atuinsh/atuin/issues/1686)) 1245 - - *(readme)* Add repology badge ([#1494](https://github.com/atuinsh/atuin/issues/1494)) 1246 - - Add forum link to contributing ([#1498](https://github.com/atuinsh/atuin/issues/1498)) 1247 - - Refer to image with multi-arch support ([#1513](https://github.com/atuinsh/atuin/issues/1513)) 1248 - - Remove activity graph 1249 - - Fix `Destination file already exists` in Nushell ([#1530](https://github.com/atuinsh/atuin/issues/1530)) 1250 - - Clarify enter/tab usage ([#1538](https://github.com/atuinsh/atuin/issues/1538)) 1251 - - Improve style ([#1537](https://github.com/atuinsh/atuin/issues/1537)) 1252 - - Remove old docusaurus ([#1581](https://github.com/atuinsh/atuin/issues/1581)) 1253 - - Mention environment variables for custom paths ([#1614](https://github.com/atuinsh/atuin/issues/1614)) 1254 - - Create pull_request_template.md ([#1632](https://github.com/atuinsh/atuin/issues/1632)) 1255 - - Update CONTRIBUTING.md ([#1633](https://github.com/atuinsh/atuin/issues/1633)) 1256 - 1257 - 1258 - ### Features 1259 - 1260 - - *(bash)* Support high-resolution timing even without ble.sh ([#1534](https://github.com/atuinsh/atuin/issues/1534)) 1261 - - *(search)* Introduce keymap-dependent vim-mode ([#1570](https://github.com/atuinsh/atuin/issues/1570)) 1262 - - *(search)* Make cursor style configurable ([#1595](https://github.com/atuinsh/atuin/issues/1595)) 1263 - - *(shell)* Bind the Atuin search to "/" in vi-normal mode ([#1629](https://github.com/atuinsh/atuin/issues/1629)) 1264 - - **BREAKING**: bind the Atuin search to "/" in vi-normal mode ([#1629](https://github.com/atuinsh/atuin/issues/1629)) 1265 - - *(ui)* Add redraw ([#1519](https://github.com/atuinsh/atuin/issues/1519)) 1266 - - *(ui)* Vim mode ([#1553](https://github.com/atuinsh/atuin/issues/1553)) 1267 - - *(ui)* When in vim-normal mode apply an alternative highlighting to the selected line ([#1574](https://github.com/atuinsh/atuin/issues/1574)) 1268 - - *(zsh)* Update widget names ([#1631](https://github.com/atuinsh/atuin/issues/1631)) 1269 - - Enable enhanced keyboard mode ([#1505](https://github.com/atuinsh/atuin/issues/1505)) 1270 - - Rework record sync for improved reliability ([#1478](https://github.com/atuinsh/atuin/issues/1478)) 1271 - - Include atuin login in secret patterns ([#1518](https://github.com/atuinsh/atuin/issues/1518)) 1272 - - Make it clear what you are registering for ([#1523](https://github.com/atuinsh/atuin/issues/1523)) 1273 - - Add extended help ([#1540](https://github.com/atuinsh/atuin/issues/1540)) 1274 - - Add interactive command inspector ([#1296](https://github.com/atuinsh/atuin/issues/1296)) 1275 - - Add better error handling for sync ([#1572](https://github.com/atuinsh/atuin/issues/1572)) 1276 - - Add history rebuild ([#1575](https://github.com/atuinsh/atuin/issues/1575)) 1277 - - Make deleting from the UI work with record store sync ([#1580](https://github.com/atuinsh/atuin/issues/1580)) 1278 - - Add metrics counter for records downloaded ([#1584](https://github.com/atuinsh/atuin/issues/1584)) 1279 - - Make store init idempotent ([#1609](https://github.com/atuinsh/atuin/issues/1609)) 1280 - - Don't stop with invalid key ([#1612](https://github.com/atuinsh/atuin/issues/1612)) 1281 - - Add registered and deleted metrics ([#1622](https://github.com/atuinsh/atuin/issues/1622)) 1282 - - Make history list format configurable ([#1638](https://github.com/atuinsh/atuin/issues/1638)) 1283 - - Add change-password command & support on server ([#1615](https://github.com/atuinsh/atuin/issues/1615)) 1284 - - Automatically init history store when record sync is enabled ([#1634](https://github.com/atuinsh/atuin/issues/1634)) 1285 - - Add store push ([#1649](https://github.com/atuinsh/atuin/issues/1649)) 1286 - - Reencrypt/rekey local store ([#1662](https://github.com/atuinsh/atuin/issues/1662)) 1287 - - Add prefers_reduced_motion flag ([#1645](https://github.com/atuinsh/atuin/issues/1645)) 1288 - - Add verify command to local store 1289 - - Add store purge command 1290 - - Failure to decrypt history = failure to sync 1291 - - Add `store push --force` 1292 - - Add `store pull` 1293 - - Disable auto record store init ([#1671](https://github.com/atuinsh/atuin/issues/1671)) 1294 - - Add progress bars to sync and store init ([#1684](https://github.com/atuinsh/atuin/issues/1684)) 1295 - 1296 - 1297 - ### Miscellaneous Tasks 1298 - 1299 - - *(ci)* Use github m1 for release builds ([#1658](https://github.com/atuinsh/atuin/issues/1658)) 1300 - - *(ci)* Re-enable test cache, add separate check step ([#1663](https://github.com/atuinsh/atuin/issues/1663)) 1301 - - *(ci)* Run rust build/test/check on 3 platforms ([#1675](https://github.com/atuinsh/atuin/issues/1675)) 1302 - - Remove the teapot response ([#1496](https://github.com/atuinsh/atuin/issues/1496)) 1303 - - Schema cleanup ([#1522](https://github.com/atuinsh/atuin/issues/1522)) 1304 - - Update funding ([#1543](https://github.com/atuinsh/atuin/issues/1543)) 1305 - - Make clipboard dep optional as a feature ([#1558](https://github.com/atuinsh/atuin/issues/1558)) 1306 - - Add feature to allow always disable check update ([#1628](https://github.com/atuinsh/atuin/issues/1628)) 1307 - - Use resolver 2, update editions + cargo ([#1635](https://github.com/atuinsh/atuin/issues/1635)) 1308 - - Disable nix tests ([#1646](https://github.com/atuinsh/atuin/issues/1646)) 1309 - - Set ATUIN_ variables for development in devshell ([#1653](https://github.com/atuinsh/atuin/issues/1653)) 1310 - 1311 - 1312 - ### Refactor 1313 - 1314 - - *(search)* Refactor vim mode ([#1559](https://github.com/atuinsh/atuin/issues/1559)) 1315 - - *(search)* Refactor handling of key inputs ([#1606](https://github.com/atuinsh/atuin/issues/1606)) 1316 - - *(shell)* Refactor and localize `HISTORY => __atuin_output` ([#1535](https://github.com/atuinsh/atuin/issues/1535)) 1317 - - Use enum instead of magic numbers ([#1499](https://github.com/atuinsh/atuin/issues/1499)) 1318 - - String -> HistoryId ([#1512](https://github.com/atuinsh/atuin/issues/1512)) 1319 - 1320 - 1321 - ### Styling 1322 - 1323 - - *(bash)* Use consistent coding style ([#1528](https://github.com/atuinsh/atuin/issues/1528)) 1324 - 1325 - 1326 - ### Testing 1327 - 1328 - - Add multi-user integration tests ([#1648](https://github.com/atuinsh/atuin/issues/1648)) 1329 - 1330 - 1331 - ### Stats 1332 - 1333 - - Misc improvements ([#1613](https://github.com/atuinsh/atuin/issues/1613)) 1334 - 1335 - 1336 - ## 17.2.1 1337 - 1338 - ### Bug Fixes 1339 - 1340 - - *(server)* Typo with default config ([#1493](https://github.com/atuinsh/atuin/issues/1493)) 1341 - 1342 - 1343 - ## 17.2.0 1344 - 1345 - ### Bug Fixes 1346 - 1347 - - *(bash)* Fix loss of the last output line with enter_accept ([#1463](https://github.com/atuinsh/atuin/issues/1463)) 1348 - - *(bash)* Improve the support for `enter_accept` with `ble.sh` ([#1465](https://github.com/atuinsh/atuin/issues/1465)) 1349 - - *(bash)* Fix small issues of `enter_accept` for the plain Bash ([#1467](https://github.com/atuinsh/atuin/issues/1467)) 1350 - - *(bash)* Fix error by the use of ${PS1@P} in bash < 4.4 ([#1488](https://github.com/atuinsh/atuin/issues/1488)) 1351 - - *(bash,zsh)* Fix quirks on search cancel ([#1483](https://github.com/atuinsh/atuin/issues/1483)) 1352 - - *(clippy)* Ignore struct_field_names ([#1466](https://github.com/atuinsh/atuin/issues/1466)) 1353 - - *(docs)* Fix typo ([#1439](https://github.com/atuinsh/atuin/issues/1439)) 1354 - - *(docs)* Discord link expired 1355 - - *(history)* Disallow deletion if the '--limit' flag is present ([#1436](https://github.com/atuinsh/atuin/issues/1436)) 1356 - - *(import/zsh)* Zsh use a special format to escape some characters ([#1490](https://github.com/atuinsh/atuin/issues/1490)) 1357 - - *(install)* Discord broken link 1358 - - *(shell)* Respect ZSH's $ZDOTDIR environment variable ([#1441](https://github.com/atuinsh/atuin/issues/1441)) 1359 - - *(stats)* Don't require all fields under [stats] ([#1437](https://github.com/atuinsh/atuin/issues/1437)) 1360 - - *(stats)* Time now_local not working 1361 - - *(zsh)* Zsh_autosuggest_strategy for no-unset environment ([#1486](https://github.com/atuinsh/atuin/issues/1486)) 1362 - 1363 - 1364 - ### Documentation 1365 - 1366 - - *(readme)* Add actuated linkback 1367 - - *(readme)* Fix light/dark mode logo 1368 - - *(readme)* Use picture element for logo 1369 - - Add link to forum 1370 - - Align setup links in docs and readme ([#1446](https://github.com/atuinsh/atuin/issues/1446)) 1371 - - Add Void Linux install instruction ([#1445](https://github.com/atuinsh/atuin/issues/1445)) 1372 - - Add fish install script ([#1447](https://github.com/atuinsh/atuin/issues/1447)) 1373 - - Correct link 1374 - - Add docs for zsh-autosuggestion integration ([#1480](https://github.com/atuinsh/atuin/issues/1480)) 1375 - - Remove stray character from README 1376 - - Update logo ([#1481](https://github.com/atuinsh/atuin/issues/1481)) 1377 - 1378 - 1379 - ### Features 1380 - 1381 - - *(bash)* Provide auto-complete source for ble.sh ([#1487](https://github.com/atuinsh/atuin/issues/1487)) 1382 - - *(shell)* Support high-resolution duration if available ([#1484](https://github.com/atuinsh/atuin/issues/1484)) 1383 - - Add semver checking to client requests ([#1456](https://github.com/atuinsh/atuin/issues/1456)) 1384 - - Add TLS to atuin-server ([#1457](https://github.com/atuinsh/atuin/issues/1457)) 1385 - - Integrate with zsh-autosuggestions ([#1479](https://github.com/atuinsh/atuin/issues/1479)) 1386 - 1387 - 1388 - ### Miscellaneous Tasks 1389 - 1390 - - *(repo)* Remove issue config ([#1433](https://github.com/atuinsh/atuin/issues/1433)) 1391 - - Remove issue template ([#1444](https://github.com/atuinsh/atuin/issues/1444)) 1392 - 1393 - 1394 - ### Refactor 1395 - 1396 - - *(bash)* Factorize `__atuin_accept_line` ([#1476](https://github.com/atuinsh/atuin/issues/1476)) 1397 - - *(bash)* Refactor and optimize `__atuin_accept_line` ([#1482](https://github.com/atuinsh/atuin/issues/1482)) 1398 - 1399 - 1400 - ## 17.1.0 1401 - 1402 - ### Bug Fixes 1403 - 1404 - - *(fish)* Clean up the fish script options ([#1370](https://github.com/atuinsh/atuin/issues/1370)) 1405 - - *(fish)* Use fish builtins for `enter_accept` ([#1373](https://github.com/atuinsh/atuin/issues/1373)) 1406 - - *(fish)* Accept multiline commands ([#1418](https://github.com/atuinsh/atuin/issues/1418)) 1407 - - *(nix)* Add Appkit to the package build ([#1358](https://github.com/atuinsh/atuin/issues/1358)) 1408 - - *(zsh)* Bind in the most popular modes ([#1360](https://github.com/atuinsh/atuin/issues/1360)) 1409 - - *(zsh)* Only trigger up-arrow on first line ([#1359](https://github.com/atuinsh/atuin/issues/1359)) 1410 - - Initial list of history in workspace mode ([#1356](https://github.com/atuinsh/atuin/issues/1356)) 1411 - - Make `atuin account delete` void session + key ([#1393](https://github.com/atuinsh/atuin/issues/1393)) 1412 - - New clippy lints ([#1395](https://github.com/atuinsh/atuin/issues/1395)) 1413 - - Reenable enter_accept for bash ([#1408](https://github.com/atuinsh/atuin/issues/1408)) 1414 - - Respect ZSH's $ZDOTDIR environment variable ([#942](https://github.com/atuinsh/atuin/issues/942)) 1415 - 1416 - 1417 - ### Documentation 1418 - 1419 - - Update sync.md ([#1409](https://github.com/atuinsh/atuin/issues/1409)) 1420 - - Update Arch Linux package URL in advanced-install.md ([#1407](https://github.com/atuinsh/atuin/issues/1407)) 1421 - - New stats config ([#1412](https://github.com/atuinsh/atuin/issues/1412)) 1422 - 1423 - 1424 - ### Features 1425 - 1426 - - *(nix)* Add a nixpkgs overlay ([#1357](https://github.com/atuinsh/atuin/issues/1357)) 1427 - - Add metrics server and http metrics ([#1394](https://github.com/atuinsh/atuin/issues/1394)) 1428 - - Add some metrics related to Atuin as an app ([#1399](https://github.com/atuinsh/atuin/issues/1399)) 1429 - - Allow configuring stats prefix ([#1411](https://github.com/atuinsh/atuin/issues/1411)) 1430 - - Allow spaces in stats prefixes ([#1414](https://github.com/atuinsh/atuin/issues/1414)) 1431 - 1432 - 1433 - ### Miscellaneous Tasks 1434 - 1435 - - *(readme)* Add contributor image to README ([#1430](https://github.com/atuinsh/atuin/issues/1430)) 1436 - - Update to sqlx 0.7.3 ([#1416](https://github.com/atuinsh/atuin/issues/1416)) 1437 - - `cargo update` ([#1419](https://github.com/atuinsh/atuin/issues/1419)) 1438 - - Update rusty_paseto and rusty_paserk ([#1420](https://github.com/atuinsh/atuin/issues/1420)) 1439 - - Run dependabot weekly, not daily ([#1423](https://github.com/atuinsh/atuin/issues/1423)) 1440 - - Don't group deps ([#1424](https://github.com/atuinsh/atuin/issues/1424)) 1441 - - Setup git cliff ([#1431](https://github.com/atuinsh/atuin/issues/1431)) 1442 - 1443 - 1444 - ## 17.0.1 1445 - 1446 - ### Bug Fixes 1447 - 1448 - - *(bash)* Improve output of `enter_accept` ([#1342](https://github.com/atuinsh/atuin/issues/1342)) 1449 - - *(enter_accept)* Clear old cmd snippet ([#1350](https://github.com/atuinsh/atuin/issues/1350)) 1450 - - *(fish)* Improve output for `enter_accept` ([#1341](https://github.com/atuinsh/atuin/issues/1341)) 1451 - 1452 - 1453 - ## 17.0.0 1454 - 1455 - ### Bug Fixes 1456 - 1457 - - *(1220)* Workspace Filtermode not handled in skim engine ([#1273](https://github.com/atuinsh/atuin/issues/1273)) 1458 - - *(nu)* Disable the up-arrow keybinding for Nushell ([#1329](https://github.com/atuinsh/atuin/issues/1329)) 1459 - - *(nushell)* Ignore stderr messages ([#1320](https://github.com/atuinsh/atuin/issues/1320)) 1460 - - *(ubuntu/arm*)* Detect non amd64 ubuntu and handle ([#1131](https://github.com/atuinsh/atuin/issues/1131)) 1461 - 1462 - 1463 - ### Documentation 1464 - 1465 - - Update `workspace` config key to `workspaces` ([#1174](https://github.com/atuinsh/atuin/issues/1174)) 1466 - - Document the available format options of History list command ([#1234](https://github.com/atuinsh/atuin/issues/1234)) 1467 - 1468 - 1469 - ### Features 1470 - 1471 - - *(installer)* Try installing via paru for the AUR ([#1262](https://github.com/atuinsh/atuin/issues/1262)) 1472 - - *(keyup)* Configure SearchMode for KeyUp invocation #1216 ([#1224](https://github.com/atuinsh/atuin/issues/1224)) 1473 - - Mouse selection support ([#1209](https://github.com/atuinsh/atuin/issues/1209)) 1474 - - Copy to clipboard ([#1249](https://github.com/atuinsh/atuin/issues/1249)) 1475 - 1476 - 1477 - ### Refactor 1478 - 1479 - - Duplications reduced in order to align implementations of reading history files ([#1247](https://github.com/atuinsh/atuin/issues/1247)) 1480 - 1481 - 1482 - ### Config.md 1483 - 1484 - - Invert mode detailed options ([#1225](https://github.com/atuinsh/atuin/issues/1225)) 1485 - 1486 - 1487 - ## 16.0.0 1488 - 1489 - ### Bug Fixes 1490 - 1491 - - *(docs)* List all presently documented commands ([#1140](https://github.com/atuinsh/atuin/issues/1140)) 1492 - - *(docs)* Correct command overview paths ([#1145](https://github.com/atuinsh/atuin/issues/1145)) 1493 - - *(server)* Teapot is a cup of coffee ([#1137](https://github.com/atuinsh/atuin/issues/1137)) 1494 - - Adjust broken link to supported shells ([#1013](https://github.com/atuinsh/atuin/issues/1013)) 1495 - - Fixes unix specific impl of shutdown_signal ([#1061](https://github.com/atuinsh/atuin/issues/1061)) 1496 - - Nushell empty hooks ([#1138](https://github.com/atuinsh/atuin/issues/1138)) 1497 - 1498 - 1499 - ### Features 1500 - 1501 - - Do not allow empty passwords durring account creation ([#1029](https://github.com/atuinsh/atuin/issues/1029)) 1502 - 1503 - 1504 - ### Skim 1505 - 1506 - - Fix filtering aggregates ([#1114](https://github.com/atuinsh/atuin/issues/1114)) 1507 - 1508 - 1509 - ## 15.0.0 1510 - 1511 - ### Documentation 1512 - 1513 - - Fix broken links in README.md ([#920](https://github.com/atuinsh/atuin/issues/920)) 1514 - - Fix "From source" `cd` command ([#937](https://github.com/atuinsh/atuin/issues/937)) 1515 - 1516 - 1517 - ### Features 1518 - 1519 - - Add delete account option (attempt 2) ([#980](https://github.com/atuinsh/atuin/issues/980)) 1520 - 1521 - 1522 - ### Miscellaneous Tasks 1523 - 1524 - - Uuhhhhhh crypto lol ([#805](https://github.com/atuinsh/atuin/issues/805)) 1525 - - Fix participle "be ran" -> "be run" ([#939](https://github.com/atuinsh/atuin/issues/939)) 1526 - 1527 - 1528 - ### Cwd_filter 1529 - 1530 - - Much like history_filter, only it applies to cwd ([#904](https://github.com/atuinsh/atuin/issues/904)) 1531 - 1532 - 1533 - ## 14.0.0 1534 - 1535 - ### Bug Fixes 1536 - 1537 - - *(client)* Always read session_path from settings ([#757](https://github.com/atuinsh/atuin/issues/757)) 1538 - - *(installer)* Use case-insensitive comparison ([#776](https://github.com/atuinsh/atuin/issues/776)) 1539 - - Many wins were broken :memo: ([#789](https://github.com/atuinsh/atuin/issues/789)) 1540 - - Paste into terminal after switching modes ([#793](https://github.com/atuinsh/atuin/issues/793)) 1541 - - Record negative exit codes ([#821](https://github.com/atuinsh/atuin/issues/821)) 1542 - - Allow nix package to fetch dependencies from git ([#832](https://github.com/atuinsh/atuin/issues/832)) 1543 - 1544 - 1545 - ### Documentation 1546 - 1547 - - *(README)* Fix activity graph link ([#753](https://github.com/atuinsh/atuin/issues/753)) 1548 - 1549 - 1550 - ### Features 1551 - 1552 - - Add common default keybindings ([#719](https://github.com/atuinsh/atuin/issues/719)) 1553 - - Add an inline view mode ([#648](https://github.com/atuinsh/atuin/issues/648)) 1554 - - Add *Nushell* support ([#788](https://github.com/atuinsh/atuin/issues/788)) 1555 - - Add github action to test the nix builds ([#833](https://github.com/atuinsh/atuin/issues/833)) 1556 - 1557 - 1558 - ### Miscellaneous Tasks 1559 - 1560 - - Remove tui vendoring ([#804](https://github.com/atuinsh/atuin/issues/804)) 1561 - - Use fork of skim ([#803](https://github.com/atuinsh/atuin/issues/803)) 1562 - 1563 - 1564 - ### Nix 1565 - 1566 - - Add flake-compat ([#743](https://github.com/atuinsh/atuin/issues/743)) 1567 - 1568 - 1569 - ## 13.0.0 1570 - 1571 - ### Documentation 1572 - 1573 - - *(README)* Add static activity graph example ([#680](https://github.com/atuinsh/atuin/issues/680)) 1574 - - Remove human short flag from docs, duplicate of help -h ([#663](https://github.com/atuinsh/atuin/issues/663)) 1575 - - Fix typo in zh-CN/README.md ([#666](https://github.com/atuinsh/atuin/issues/666)) 1576 - 1577 - 1578 - ### Features 1579 - 1580 - - *(history)* Add new flag to allow custom output format ([#662](https://github.com/atuinsh/atuin/issues/662)) 1581 - 1582 - 1583 - ### Fish 1584 - 1585 - - Fix `atuin init` for the fish shell ([#699](https://github.com/atuinsh/atuin/issues/699)) 1586 - 1587 - 1588 - ### Install.sh 1589 - 1590 - - Fallback to using cargo ([#639](https://github.com/atuinsh/atuin/issues/639)) 1591 - 1592 - 1593 - ## 12.0.0 1594 - 1595 - ### Documentation 1596 - 1597 - - Add more details about date parsing in the stats command ([#579](https://github.com/atuinsh/atuin/issues/579)) 1598 - 1599 - 1600 - ## 0.10.0 1601 - 1602 - ### Miscellaneous Tasks 1603 - 1604 - - Allow specifiying the limited of returned entries ([#364](https://github.com/atuinsh/atuin/issues/364)) 1605 - 1606 - 1607 - ## 0.9.0 1608 - 1609 - ### README 1610 - 1611 - - Add MacPorts installation instructions ([#302](https://github.com/atuinsh/atuin/issues/302)) 1612 - 1613 - 1614 - ## 0.8.1 1615 - 1616 - ### Bug Fixes 1617 - 1618 - - Get install.sh working on UbuntuWSL ([#260](https://github.com/atuinsh/atuin/issues/260)) 1619 - 1620 - 1621 - ## 0.8.0 1622 - 1623 - ### Bug Fixes 1624 - 1625 - - Resolve some issues with install.sh ([#188](https://github.com/atuinsh/atuin/issues/188)) 1626 - 1627 - 1628 - ### Features 1629 - 1630 - - Login/register no longer blocking ([#216](https://github.com/atuinsh/atuin/issues/216)) 1631 - 1632 - 1633 - ## 0.7.2 1634 - 1635 - ### Bug Fixes 1636 - 1637 - - Dockerfile with correct glibc ([#198](https://github.com/atuinsh/atuin/issues/198)) 1638 - 1639 - 1640 - ### Features 1641 - 1642 - - Allow input of credentials from stdin ([#185](https://github.com/atuinsh/atuin/issues/185)) 1643 - 1644 - 1645 - ### Miscellaneous Tasks 1646 - 1647 - - Some new linting ([#201](https://github.com/atuinsh/atuin/issues/201)) 1648 - - Supply pre-build docker image ([#199](https://github.com/atuinsh/atuin/issues/199)) 1649 - - Add more eyre contexts ([#200](https://github.com/atuinsh/atuin/issues/200)) 1650 - - Improve build times ([#213](https://github.com/atuinsh/atuin/issues/213)) 1651 - 1652 - 1653 - ## 0.7.1 1654 - 1655 - ### Features 1656 - 1657 - - Build individual crates ([#109](https://github.com/atuinsh/atuin/issues/109)) 1658 - 1659 - 1660 - ## 0.6.3 1661 - 1662 - ### Bug Fixes 1663 - 1664 - - Help text 1665 - 1666 - 1667 - ### Features 1668 - 1669 - - Use directories project data dir 1670 - 1671 - 1672 - ### Miscellaneous Tasks 1673 - 1674 - - Use structopt wrapper instead of building clap by hand 1675 - 1676 - 1677 - <!-- generated by git-cliff -->
-128
CODE_OF_CONDUCT.md
··· 1 - # Contributor Covenant Code of Conduct 2 - 3 - ## Our Pledge 4 - 5 - We as members, contributors, and leaders pledge to make participation in our 6 - community a harassment-free experience for everyone, regardless of age, body 7 - size, visible or invisible disability, ethnicity, sex characteristics, gender 8 - identity and expression, level of experience, education, socio-economic status, 9 - nationality, personal appearance, race, religion, or sexual identity 10 - and orientation. 11 - 12 - We pledge to act and interact in ways that contribute to an open, welcoming, 13 - diverse, inclusive, and healthy community. 14 - 15 - ## Our Standards 16 - 17 - Examples of behavior that contributes to a positive environment for our 18 - community include: 19 - 20 - * Demonstrating empathy and kindness toward other people 21 - * Being respectful of differing opinions, viewpoints, and experiences 22 - * Giving and gracefully accepting constructive feedback 23 - * Accepting responsibility and apologizing to those affected by our mistakes, 24 - and learning from the experience 25 - * Focusing on what is best not just for us as individuals, but for the 26 - overall community 27 - 28 - Examples of unacceptable behavior include: 29 - 30 - * The use of sexualized language or imagery, and sexual attention or 31 - advances of any kind 32 - * Trolling, insulting or derogatory comments, and personal or political attacks 33 - * Public or private harassment 34 - * Publishing others' private information, such as a physical or email 35 - address, without their explicit permission 36 - * Other conduct which could reasonably be considered inappropriate in a 37 - professional setting 38 - 39 - ## Enforcement Responsibilities 40 - 41 - Community leaders are responsible for clarifying and enforcing our standards of 42 - acceptable behavior and will take appropriate and fair corrective action in 43 - response to any behavior that they deem inappropriate, threatening, offensive, 44 - or harmful. 45 - 46 - Community leaders have the right and responsibility to remove, edit, or reject 47 - comments, commits, code, wiki edits, issues, and other contributions that are 48 - not aligned to this Code of Conduct, and will communicate reasons for moderation 49 - decisions when appropriate. 50 - 51 - ## Scope 52 - 53 - This Code of Conduct applies within all community spaces, and also applies when 54 - an individual is officially representing the community in public spaces. 55 - Examples of representing our community include using an official e-mail address, 56 - posting via an official social media account, or acting as an appointed 57 - representative at an online or offline event. 58 - 59 - ## Enforcement 60 - 61 - Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 - reported to the community leaders responsible for enforcement at 63 - ellie@elliehuxtable.com. 64 - All complaints will be reviewed and investigated promptly and fairly. 65 - 66 - All community leaders are obligated to respect the privacy and security of the 67 - reporter of any incident. 68 - 69 - ## Enforcement Guidelines 70 - 71 - Community leaders will follow these Community Impact Guidelines in determining 72 - the consequences for any action they deem in violation of this Code of Conduct: 73 - 74 - ### 1. Correction 75 - 76 - **Community Impact**: Use of inappropriate language or other behavior deemed 77 - unprofessional or unwelcome in the community. 78 - 79 - **Consequence**: A private, written warning from community leaders, providing 80 - clarity around the nature of the violation and an explanation of why the 81 - behavior was inappropriate. A public apology may be requested. 82 - 83 - ### 2. Warning 84 - 85 - **Community Impact**: A violation through a single incident or series 86 - of actions. 87 - 88 - **Consequence**: A warning with consequences for continued behavior. No 89 - interaction with the people involved, including unsolicited interaction with 90 - those enforcing the Code of Conduct, for a specified period of time. This 91 - includes avoiding interactions in community spaces as well as external channels 92 - like social media. Violating these terms may lead to a temporary or 93 - permanent ban. 94 - 95 - ### 3. Temporary Ban 96 - 97 - **Community Impact**: A serious violation of community standards, including 98 - sustained inappropriate behavior. 99 - 100 - **Consequence**: A temporary ban from any sort of interaction or public 101 - communication with the community for a specified period of time. No public or 102 - private interaction with the people involved, including unsolicited interaction 103 - with those enforcing the Code of Conduct, is allowed during this period. 104 - Violating these terms may lead to a permanent ban. 105 - 106 - ### 4. Permanent Ban 107 - 108 - **Community Impact**: Demonstrating a pattern of violation of community 109 - standards, including sustained inappropriate behavior, harassment of an 110 - individual, or aggression toward or disparagement of classes of individuals. 111 - 112 - **Consequence**: A permanent ban from any sort of public interaction within 113 - the community. 114 - 115 - ## Attribution 116 - 117 - This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 - version 2.0, available at 119 - https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 - 121 - Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 - enforcement ladder](https://github.com/mozilla/diversity). 123 - 124 - [homepage]: https://www.contributor-covenant.org 125 - 126 - For answers to common questions about this code of conduct, see the FAQ at 127 - https://www.contributor-covenant.org/faq. Translations are available at 128 - https://www.contributor-covenant.org/translations.
-134
CONTRIBUTING.md
··· 1 - # Contributing 2 - 3 - Thank you so much for considering contributing to Atuin! We really appreciate it <3 4 - 5 - ## AI 6 - 7 - While we are very happy for you to use AI to build your contribution, it is essential that any pull requests you open are reviewed, understood, and tested by you. Pull requests with giant, AI-written descriptions imply the opposite. Please take the time to write a PR body that outlines your intent, understanding and summary of the change. 8 - 9 - ## Development dependencies 10 - 11 - 1. A rust toolchain ([rustup](https://rustup.rs) recommended) 12 - 13 - We commit to supporting the latest stable version of Rust - nothing more, nothing less, no nightly. 14 - 15 - Before working on anything, we suggest taking a copy of your Atuin data directory (`~/.local/share/atuin` on most \*nix platforms). If anything goes wrong, you can always restore it! 16 - 17 - While data directory backups are always a good idea, you can instruct Atuin to use custom path using the following environment variables: 18 - 19 - ```shell 20 - export ATUIN_RECORD_STORE_PATH=/tmp/atuin_records.db # path to primary record store 21 - export ATUIN_DB_PATH=/tmp/atuin_dev.db # path to materialized history database 22 - export ATUIN_KV__DB_PATH=/tmp/atuin_kv.db # path to key-value store 23 - export ATUIN_SCRIPTS__DB_PATH=/tmp/atuin_scripts.db # path to scripts database 24 - export ATUIN_AI__DB_PATH=/tmp/atuin_ai_sessions.db # path to AI sessions database 25 - export ATUIN_META__DB_PATH=/tmp/atuin_meta.db # path to meta database 26 - ``` 27 - 28 - It is also recommended to update your `$PATH` so that the pre-exec scripts would use the locally built version: 29 - 30 - ```shell 31 - export PATH="./target/release:$PATH" 32 - ``` 33 - 34 - If you'd like to load a different configuration file, set `ATUIN_CONFIG_DIR` to a folder that contains your `config.toml` file: 35 - 36 - ```shell 37 - export ATUIN_CONFIG_DIR=/tmp/atuin-config/ 38 - ``` 39 - 40 - These variable exports can be added in a local `.envrc` file, read by [direnv](https://direnv.net/). 41 - 42 - ## Editor setup (optional) 43 - 44 - `cargo fmt` is the source of truth and CI enforces it. We also have a: 45 - 46 - - [`.editorconfig`](https://editorconfig.org/) which sets sane defaults for `.rs` files. 47 - - [`.nvim.lua`](https://github.com/atuinsh/atuin/blob/main/.nvim.lua) which configures neovim. Note you need `vim.o.exrc = true` and `nvim >= 0.11+`. You can disable it if you prefer, please see the docs at the top of that file. 48 - 49 - ## PRs 50 - 51 - It can speed up the review cycle if you consent to maintainers pushing to your branch. This will only be in the case of small fixes or adjustments, and not anything large. If you feel OK with this, please check the box on the template! 52 - 53 - ## What to work on? 54 - 55 - Any issues labeled "bug" or "help wanted" would be fantastic, just drop a comment and feel free to ask for help! 56 - 57 - If there's anything you want to work on that isn't already an issue, either open a feature request or get in touch on the [forum](https://forum.atuin.sh)/Discord. 58 - 59 - ## Setup 60 - 61 - ``` 62 - git clone https://github.com/atuinsh/atuin 63 - cd atuin 64 - cargo build 65 - ``` 66 - 67 - ## Running 68 - 69 - When iterating on a feature, it's useful to use `cargo run` 70 - 71 - For example, if working on a search feature 72 - 73 - ``` 74 - cargo run -- search --a-new-flag 75 - ``` 76 - 77 - While iterating on the server, I find it helpful to run a new user on my system, with `sync_server` set to be `localhost`. 78 - 79 - ## Tests 80 - 81 - Our test coverage is currently not the best, but we are working on it! Generally tests live in the file next to the functionality they are testing, and are executed just with `cargo test`. 82 - 83 - ## Logging and Debugging 84 - 85 - ### Log Files 86 - 87 - Atuin writes logs to `~/.atuin/logs` unless configured otherwise. Log files are rotated daily and retained for 4 days by default: 88 - 89 - - `search.log.*` - Interactive search session logs 90 - - `daemon.log.*` - Background daemon logs 91 - 92 - ### Log Levels 93 - 94 - You can set the `ATUIN_LOG` environment variable to override log verbosity from the config file: 95 - 96 - ```shell 97 - ATUIN_LOG=debug atuin search # Enable debug logging 98 - ATUIN_LOG=trace atuin search # Enable trace logging (very verbose) 99 - ``` 100 - 101 - ### Span Timing (Performance Profiling) 102 - 103 - For performance analysis, you can capture detailed span timing data as JSON: 104 - 105 - ```shell 106 - ATUIN_SPAN=spans.json atuin search 107 - ``` 108 - 109 - This creates a JSON file with timing information for each instrumented span, including: 110 - - `time.busy` - Time actively executing code 111 - - `time.idle` - Time awaiting async operations (I/O, child tasks) 112 - 113 - The `scripts/span-table.ts` script analyzes these logs: 114 - 115 - ```shell 116 - # Summary view - shows all spans with timing stats 117 - bun scripts/span-table.ts spans.json 118 - 119 - # Detail view - shows individual calls for a specific span 120 - bun scripts/span-table.ts spans.json --detail daemon_search 121 - 122 - # Filter to specific spans 123 - bun scripts/span-table.ts spans.json --filter "search|hydrate" 124 - ``` 125 - 126 - This is useful for comparing performance between different search implementations or identifying bottlenecks. 127 - 128 - ## Migrations 129 - 130 - Be careful creating database migrations - once your database has migrated ahead of current stable, there is no going back 131 - 132 - ### Stickers 133 - 134 - We try to ship anyone contributing to Atuin a sticker! Only contributors get a shiny one. Fill out [this form](https://noteforms.com/forms/contributors-stickers) if you'd like one.
-36
Dockerfile
··· 1 - FROM lukemathwalker/cargo-chef:latest-rust-1.97.0-slim-bookworm AS chef 2 - WORKDIR app 3 - 4 - FROM chef AS planner 5 - COPY . . 6 - RUN cargo chef prepare --recipe-path recipe.json 7 - 8 - FROM chef AS builder 9 - 10 - # Ensure working C compile setup (not installed by default in arm64 images) 11 - RUN apt update && apt install build-essential -y 12 - 13 - COPY --from=planner /app/recipe.json recipe.json 14 - RUN cargo chef cook --release --recipe-path recipe.json 15 - 16 - COPY . . 17 - RUN cargo build --release --bin atuin-server 18 - 19 - FROM debian:bookworm-20260623-slim AS runtime 20 - LABEL org.opencontainers.image.source="https://github.com/atuinsh/atuin" \ 21 - org.opencontainers.image.url="https://atuin.sh" \ 22 - org.opencontainers.image.licenses="MIT" 23 - 24 - RUN useradd -c 'atuin user' atuin && mkdir /config && chown atuin:atuin /config 25 - # Install ca-certificates for webhooks to work 26 - RUN apt update && apt install ca-certificates -y && rm -rf /var/lib/apt/lists/* 27 - WORKDIR app 28 - 29 - USER atuin 30 - 31 - ENV TZ=Etc/UTC 32 - ENV RUST_LOG=atuin_server=info 33 - ENV ATUIN_CONFIG_DIR=/config 34 - 35 - COPY --from=builder /app/target/release/atuin-server /usr/local/bin 36 - ENTRYPOINT ["/usr/local/bin/atuin-server"]
-278
VOUCHED.td
··· 1 - + 0x4A6F 2 - + 13werwolf13 3 - + abatkin 4 - + Absolucy 5 - + Adda0 6 - + Aehmlo 7 - + ajjahn 8 - + akinomyoga 9 - + akirk 10 - + alerque 11 - + alexandregv 12 - + Aloxaf 13 - + amosbird 14 - + andrewaylett 15 - + ap-1 16 - + arcuru 17 - + ardrigh 18 - + aschey 19 - + ataraxia937 20 - + AtomicRobotMan0101 21 - + avinassh 22 - + azzamsa 23 - + b3nj5m1n 24 - + bahdotsh 25 - + baprx 26 - + bdavj 27 - + benwr 28 - + BinaryMuse 29 - + bjschafer 30 - + bradrf 31 - + braelyn-ai 32 - + briankung 33 - + bvergnaud 34 - + c-14 35 - + c-git 36 - + caio96 37 - + candrewlee14 38 - + Carthaca 39 - + chitao1234 40 - + clouserw 41 - + conradludgate 42 - + cosgroveb 43 - + CosmicHorrorDev 44 - + cultpony 45 - + cyqsimon 46 - + dacog 47 - + DanielAtCosmicDNA 48 - + DaniPopes 49 - + david-crespo 50 - + davidolrik 51 - + davlgd 52 - + dcarosone 53 - + deicon 54 - + dennis-tra 55 - + dependabot[bot] 56 - + dhth 57 - + digital-cuttlefish 58 - + dongxuwang 59 - + dotfrag 60 - + dotsam 61 - + drbrain 62 - + drmorr0 63 - + ds-cbo 64 - + eatradish 65 - + eclairevoyant 66 - + edeustua 67 - + edwardloveall 68 - + ekroon 69 - + ellie 70 - + elsbrock 71 - + ElvishJerricco 72 - + enchantednatures 73 - + eopb 74 - + EricCrosson 75 - + eripa 76 - + etbyrd 77 - + eth3lbert 78 - + evanpurkhiser 79 - + felixonmars 80 - + filviu 81 - + fragmede 82 - + frankh 83 - + frukto 84 - + fzakaria 85 - + github-actions[bot] 86 - + hack3ric 87 - + happenslol 88 - + haristhohir 89 - + helbing 90 - + herbygillot 91 - + hesampakdaman 92 - + hezhizhen 93 - + hhamud 94 - + hlxid 95 - + hunger 96 - + iamkroot 97 - + IanManske 98 - + ibayramli 99 - + ijanos 100 - + iloveitaly 101 - + InCogNiTo124 102 - + Indy2222 103 - + injust 104 - + IoSonoPiero 105 - + ismith 106 - + ivan-toriya 107 - + ivvvve 108 - + jamesbrooks 109 - + jamestrew 110 - + janlarres 111 - + jaxvanyang 112 - + jbaiter 113 - + jean-santos 114 - + jeremycline 115 - + jfmontanaro 116 - + jhult 117 - + jingmian 118 - + jinnatar 119 - + jinnko 120 - + jirutka 121 - + JoaquinTrinanes 122 - + jonaylor89 123 - + Jongy 124 - + Josef-Friedrich 125 - + josegonzalez 126 - + JRGould 127 - + julienp 128 - + jyn514 129 - + karlding 130 - + keithamus 131 - + kejadlen 132 - + keysmashes 133 - + kianmeng 134 - + kjetijor 135 - + KorvinSzanto 136 - + kosak 137 - + laurentlbm 138 - + lazzurs 139 - + lchausmann 140 - + LecrisUT 141 - + LeoniePhiline 142 - + liljaylj 143 - + lilydjwg 144 - + lmBored 145 - + lmburns 146 - + ltrzesniewski 147 - + lucacome 148 - + lugoues 149 - + lukebaker 150 - + lukekarrys 151 - + m42e 152 - + macno 153 - + majiayu000 154 - + manelvf 155 - + marius 156 - + mateuscomh 157 - + mattgodbolt 158 - + matthewberryman 159 - + matthiasbeyer 160 - + Matthieu-LAURENT39 161 - + maxim-uvarov 162 - + mb6ockatf 163 - + Mellbourn 164 - + mentalisttraceur 165 - + merc1031 166 - + michaelmior 167 - + millette 168 - + morguldir 169 - + mozzieongit 170 - + mrcjkb 171 - + mrjones2014 172 - + mrkbac 173 - + mundry 174 - + musicinmybrain 175 - + mwotton 176 - + mwpastore 177 - + nc7s 178 - + nebkor 179 - + nekowinston 180 - + Nelyah 181 - + Nemo157 182 - + NeoPhi 183 - + networkException 184 - + nh2 185 - + notjedi 186 - + notrudyyy 187 - + notsatyarth 188 - + noyez 189 - + offbyone 190 - + onedr0p 191 - + OnePieceJoker 192 - + onkelT2 193 - + orhun 194 - + overhacked 195 - + oxo42 196 - + pamburus 197 - + panekj 198 - + papertigers 199 - + paulbarton90 200 - + pdecat 201 - + pevogam 202 - + philn 203 - + philtweir 204 - + phinze 205 - + piec 206 - + pmarschik 207 - + pmodin 208 - + poliorcetics 209 - + popsu 210 - + postmath 211 - + printfn 212 - + r-vdp 213 - + rektide 214 - + remmycat 215 - + Reverier-Xu 216 - + RichardDRJ 217 - + rightaditya 218 - + rigrig 219 - + Rohan5commit 220 - + rriski 221 - + rufo 222 - + s0 223 - + s1ck 224 - + sashkab 225 - + SAY-5 226 - + schrej 227 - + Sciencentistguy 228 - + sdr135284 229 - + senekor 230 - + sftblw 231 - + shgew 232 - + shreve 233 - + shymega 234 - + simon-b 235 - + skx 236 - + slamp 237 - + snaggen 238 - + sophiajt 239 - + sowbug 240 - + Sped0n 241 - + sporeventexplosion 242 - + starsep 243 - + stevenxxiu 244 - + stuartcarnie 245 - + sunshowers 246 - + SuperSandro2000 247 - + svenstaro 248 - + szinn 249 - + takac 250 - + tessus 251 - + thedrow 252 - + thePanz 253 - + tobiasge 254 - + tombh 255 - + tpoliaw 256 - + tranzystorekk 257 - + trygveaa 258 - + Tyarel8 259 - + TymanWasTaken 260 - + UbiquitousPhoton 261 - + utterstep 262 - + VuiMuich 263 - + Vynce 264 - + waldyrious 265 - + WindSoilder 266 - + wpbrz 267 - + wzzrd 268 - + xav-ie 269 - + xfzv 270 - + xqm32 271 - + xvello 272 - + yan 273 - + yannickulrich 274 - + yarikoptic 275 - + yolo2h 276 - + YummyOreo 277 - + yuvipanda 278 - + zygous
-100
cliff.toml
··· 1 - # git-cliff ~ default configuration file 2 - # https://git-cliff.org/docs/configuration 3 - # 4 - # Lines starting with "#" are comments. 5 - # Configuration options are organized into tables and keys. 6 - # See documentation for more information on available options. 7 - 8 - [changelog] 9 - # changelog header 10 - header = """ 11 - # Changelog\n 12 - All notable changes to this project will be documented in this file.\n 13 - """ 14 - # template for the changelog body 15 - # https://keats.github.io/tera/docs/#introduction 16 - body = """ 17 - {% if version %}\ 18 - ## {{ version | trim_start_matches(pat="v") }} 19 - {% else %}\ 20 - ## [unreleased] 21 - {% endif %}\ 22 - {% for group, commits in commits | group_by(attribute="group") %} 23 - ### {{ group | upper_first }} 24 - {% for commit in commits 25 - | filter(attribute="scope") 26 - | sort(attribute="scope") %} 27 - - *({{commit.scope}})* {{ commit.message | upper_first }} 28 - {%- if commit.breaking %} 29 - {% raw %} {% endraw %}- **BREAKING**: {{commit.breaking_description}} 30 - {%- endif -%} 31 - {%- endfor -%} 32 - {% raw %}\n{% endraw %}\ 33 - {%- for commit in commits %} 34 - {%- if commit.scope -%} 35 - {% else -%} 36 - - {{ commit.message | upper_first }} 37 - {% if commit.breaking -%} 38 - {% raw %} {% endraw %}- **BREAKING**: {{commit.breaking_description}} 39 - {% endif -%} 40 - {% endif -%} 41 - {% endfor -%} 42 - {% raw %}\n{% endraw %}\ 43 - {% endfor %}\n 44 - """ 45 - 46 - # remove the leading and trailing whitespace from the template 47 - trim = true 48 - # changelog footer 49 - footer = """ 50 - <!-- generated by git-cliff --> 51 - """ 52 - # postprocessors 53 - postprocessors = [ 54 - { pattern = '<REPO>', replace = "https://github.com/atuinsh/atuin" }, # replace repository URL 55 - ] 56 - [git] 57 - # parse the commits based on https://www.conventionalcommits.org 58 - conventional_commits = true 59 - # filter out the commits that are not conventional 60 - filter_unconventional = true 61 - # process each line of a commit as an individual commit 62 - split_commits = false 63 - # regex for preprocessing the commit messages 64 - commit_preprocessors = [ 65 - { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))" }, # replace issue numbers 66 - ] 67 - # regex for parsing and grouping commits 68 - commit_parsers = [ 69 - { message = "^feat", group = "Features" }, 70 - { message = "^fix", group = "Bug Fixes" }, 71 - { message = "^doc", group = "Documentation" }, 72 - { message = "^perf", group = "Performance" }, 73 - { message = "^refactor", group = "Refactor" }, 74 - { message = "^style", group = "Styling" }, 75 - { message = "^test", group = "Testing" }, 76 - { message = "^chore\\(release\\): prepare for", skip = true }, 77 - { message = "^chore\\(deps\\)", skip = true }, 78 - { message = "^chore\\(pr\\)", skip = true }, 79 - { message = "^chore\\(pull\\)", skip = true }, 80 - { message = "^chore|ci", group = "Miscellaneous Tasks" }, 81 - { body = ".*security", group = "Security" }, 82 - { message = "^revert", group = "Revert" }, 83 - ] 84 - # protect breaking changes from being skipped due to matching a skipping commit_parser 85 - protect_breaking_commits = false 86 - # filter out the commits that are not matched by commit parsers 87 - filter_commits = false 88 - # regex for matching git tags 89 - tag_pattern = "v[0-9].*" 90 - 91 - # regex for skipping tags 92 - skip_tags = "v0.1.0-beta.1" 93 - # regex for ignoring tags 94 - ignore_tags = "prerelease|beta|alpha" 95 - # sort the tags topologically 96 - topo_order = false 97 - # sort the commits inside sections by oldest/newest order 98 - sort_commits = "oldest" 99 - # limit the number of commits included in the changelog. 100 - # limit_commits = 42
-1
contrib/pi/atuin.ts
··· 1 - ../../crates/atuin/contrib/pi/atuin.ts
-105
crates/atuin/contrib/pi/atuin.ts
··· 1 - /** 2 - * Atuin extension for pi. 3 - * 4 - * Tracks bash commands executed by pi in Atuin history with author `pi`. 5 - * 6 - * Install with: 7 - * atuin hook install pi 8 - * 9 - * Then restart pi or run /reload. 10 - */ 11 - 12 - import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent"; 13 - 14 - const ATUIN_AUTHOR = "pi"; 15 - const ATUIN_TIMEOUT_MS = 10_000; 16 - 17 - async function startHistory( 18 - pi: ExtensionAPI, 19 - cwd: string, 20 - command: string, 21 - ): Promise<string | undefined> { 22 - try { 23 - const result = await pi.exec( 24 - "atuin", 25 - ["history", "start", "--author", ATUIN_AUTHOR, "--", command], 26 - { cwd, timeout: ATUIN_TIMEOUT_MS }, 27 - ); 28 - 29 - if (result.code !== 0) return undefined; 30 - 31 - const id = result.stdout.trim(); 32 - return id.length > 0 ? id : undefined; 33 - } catch { 34 - return undefined; 35 - } 36 - } 37 - 38 - async function endHistory( 39 - pi: ExtensionAPI, 40 - cwd: string, 41 - historyId: string, 42 - exitCode: number, 43 - ): Promise<void> { 44 - try { 45 - await pi.exec( 46 - "atuin", 47 - ["history", "end", historyId, "--exit", String(exitCode)], 48 - { cwd, timeout: ATUIN_TIMEOUT_MS }, 49 - ); 50 - } catch { 51 - // Ignore Atuin failures so command execution is never blocked. 52 - } 53 - } 54 - 55 - // The bash tool reports failures by appending a status line to the result 56 - // text rather than exposing a numeric exit code, so recover it from there. 57 - function exitCodeFromResult(result: unknown, isError: boolean): number { 58 - if (!isError) return 0; 59 - 60 - const content = (result as { content?: unknown } | undefined)?.content; 61 - const text = Array.isArray(content) 62 - ? content 63 - .map((part) => { 64 - const t = (part as { text?: unknown } | undefined)?.text; 65 - return typeof t === "string" ? t : ""; 66 - }) 67 - .join("\n") 68 - : ""; 69 - 70 - const exited = text.match(/Command exited with code (\d+)\s*$/); 71 - if (exited) return Number(exited[1]); 72 - if (/Command aborted\s*$/.test(text)) return 130; 73 - if (/Command timed out after \S+ seconds\s*$/.test(text)) return 124; 74 - return 1; 75 - } 76 - 77 - export default function atuinPiExtension(pi: ExtensionAPI) { 78 - // Atuin history IDs for in-flight bash tool calls, keyed by tool call ID. 79 - const pending = new Map<string, string>(); 80 - 81 - // Observe bash executions through events instead of registering a bash 82 - // tool: registering one conflicts with other extensions that provide 83 - // their own bash tool (sandboxes, RTK, remote runners), while events 84 - // fire no matter which extension's bash tool ends up executing the 85 - // command. 86 - pi.on("tool_call", async (event, ctx: ExtensionContext) => { 87 - if (event.toolName !== "bash") return; 88 - 89 - const command = (event.input as { command?: unknown }).command; 90 - if (typeof command !== "string" || command.length === 0) return; 91 - 92 - const historyId = await startHistory(pi, ctx.cwd, command); 93 - if (historyId) pending.set(event.toolCallId, historyId); 94 - }); 95 - 96 - // tool_execution_end also fires when another extension blocks the call, 97 - // unlike tool_result, so entries started above are always closed. 98 - pi.on("tool_execution_end", async (event, ctx: ExtensionContext) => { 99 - const historyId = pending.get(event.toolCallId); 100 - if (!historyId) return; 101 - pending.delete(event.toolCallId); 102 - 103 - await endHistory(pi, ctx.cwd, historyId, exitCodeFromResult(event.result, event.isError)); 104 - }); 105 - }
-10
default.nix
··· 1 - (import 2 - ( 3 - let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in 4 - fetchTarball { 5 - url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; 6 - sha256 = lock.nodes.flake-compat.locked.narHash; 7 - } 8 - ) 9 - { src = ./.; } 10 - ).defaultNix
demo.gif

This is a binary file and will not be displayed.

-1
depot.json
··· 1 - {"id":"v6vqpk6559"}
-29
dist-workspace.toml
··· 1 - [workspace] 2 - members = ["cargo:."] 3 - 4 - # Config for 'dist' 5 - [dist] 6 - # Path that installers should place binaries in 7 - install-path = "~/.atuin/bin" 8 - # The preferred dist version to use in CI (Cargo.toml SemVer syntax) 9 - cargo-dist-version = "0.31.0" 10 - # CI backends to support 11 - ci = "github" 12 - # The installers to generate for each app 13 - installers = ["shell", "powershell"] 14 - # Target platforms to build apps for (Rust target-triple syntax) 15 - targets = ["aarch64-apple-darwin", "aarch64-unknown-linux-gnu", "aarch64-unknown-linux-musl", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", "x86_64-pc-windows-msvc"] 16 - # Which actions to run on pull requests 17 - pr-run-mode = "plan" 18 - # Whether to install an updater program 19 - install-updater = true 20 - # The archive format to use for non-windows builds (defaults .tar.xz) 21 - unix-archive = ".tar.gz" 22 - # Whether to enable GitHub Attestations 23 - github-attestations = true 24 - 25 - [dist.github-custom-runners] 26 - aarch64-unknown-linux-gnu = "depot-ubuntu-24.04-arm-8" 27 - aarch64-unknown-linux-musl = "depot-ubuntu-24.04-arm-8" 28 - x86_64-unknown-linux-gnu = "depot-ubuntu-24.04-8" 29 - x86_64-unknown-linux-musl = "depot-ubuntu-24.04-8"
-20
docs-i18n/.gitignore
··· 1 - # Dependencies 2 - /node_modules 3 - 4 - # Production 5 - /build 6 - 7 - # Generated files 8 - .docusaurus 9 - .cache-loader 10 - 11 - # Misc 12 - .DS_Store 13 - .env.local 14 - .env.development.local 15 - .env.test.local 16 - .env.production.local 17 - 18 - npm-debug.log* 19 - yarn-debug.log* 20 - yarn-error.log*
-146
docs-i18n/ru/config_ru.md
··· 1 - # Конфигурация 2 - 3 - Atuin использует два файла конфигурации. Они хранятся в `~/.config/atuin/`. Данные 4 - хранятся в `~/.local/share/atuin` (если не определено другое в XDG\_\*). 5 - 6 - Путь до каталога конфигурации может быть изменён установкой 7 - параметра `ATUIN_CONFIG_DIR`. Например 8 - 9 - ``` 10 - export ATUIN_CONFIG_DIR = /home/ellie/.atuin 11 - ``` 12 - 13 - ## Пользовательская конфигурация 14 - 15 - ``` 16 - ~/.config/atuin/config.toml 17 - ``` 18 - 19 - Этот файл используется когда клиент работает на локальной машине (не сервере). 20 - 21 - Пример можно увидеть в [config.toml](../../atuin-client/config.toml) 22 - 23 - ### `dialect` 24 - 25 - Этот параметр контролирует как [stats](stats.md) команда обрабатывает данные. 26 - Может принимать одно из двух допустимых значений: 27 - 28 - ``` 29 - dialect = "uk" 30 - ``` 31 - 32 - или 33 - 34 - ``` 35 - dialect = "us" 36 - ``` 37 - 38 - По умолчанию - "us". 39 - 40 - ### `auto_sync` 41 - 42 - Синхронизироваться ли автоматически если выполнен вход. По умолчанию - да (true) 43 - ``` 44 - auto_sync = true/false 45 - ``` 46 - 47 - ### `sync_address` 48 - 49 - Адрес сервера для синхронизации. По умолчанию `https://api.atuin.sh`. 50 - 51 - ``` 52 - sync_address = "https://api.atuin.sh" 53 - ``` 54 - 55 - ### `sync_frequency` 56 - 57 - Как часто клиент синхронизируется с сервером. Может быть указано в 58 - понятном для человека формате. Например, `10s`, `20m`, `1h`, и т.д. 59 - По умолчанию `1h` 60 - 61 - Если стоит значение 0, Atuin будет синхронизироваться после каждой выполненной команды. 62 - Помните, что сервера могут иметь ограничение на количество отправленных запросов. 63 - 64 - ``` 65 - sync_frequency = "1h" 66 - ``` 67 - 68 - ### `db_path` 69 - 70 - Путь до базы данных SQLite. По умолчанию это 71 - `~/.local/share/atuin/history.db`. 72 - 73 - ``` 74 - db_path = "~/.history.db" 75 - ``` 76 - 77 - ### `key_path` 78 - 79 - Путь до ключа шифрования Atuin. По умолчанию, 80 - `~/.local/share/atuin/key`. 81 - 82 - ``` 83 - key = "~/.atuin-key" 84 - ``` 85 - 86 - ### `session_path` 87 - 88 - Путь до серверного файла сессии Atuin. По умолчанию, 89 - `~/.local/share/atuin/session`. На самом деле это просто API токен. 90 - 91 - ``` 92 - key = "~/.atuin-session" 93 - ``` 94 - 95 - ### `search_mode` 96 - 97 - Определяет, какой режим поиска будет использоваться. Atuin поддерживает "prefix", 98 - текст целиком (fulltext) и неточный ("fuzzy") поиск. Режим "prefix" производит 99 - поиск по "запрос\*", "fulltext" по "\*запрос\*", и "fuzzy" использует 100 - [вот такой](#fuzzy-search-syntax) синтаксис. 101 - 102 - По умолчанию стоит значение "fuzzy" 103 - 104 - ### `filter_mode` 105 - 106 - Фильтр, по-умолчанию использующийся для поиска 107 - 108 - | Столбец 1 | Столбец 2 | 109 - |------------------|----------------------------------------------------------| 110 - | global (default) | Искать историю команд со всех хостов, сессий и каталогов | 111 - | host | Искать историю команд с этого хоста | 112 - | session | Искать историю команд этой сессии | 113 - | directory | Искать историю команд, выполненных в текущей папке | 114 - 115 - Режимы поиска могут быть изменены через ctrl-r 116 - 117 - 118 - ``` 119 - search_mode = "fulltext" 120 - ``` 121 - 122 - #### fuzzy search syntax 123 - 124 - Режим поиска "fuzzy" основан на 125 - [fzf search syntax](https://github.com/junegunn/fzf#search-syntax). 126 - 127 - | Токен | Тип совпадений | Описание | 128 - |-----------|----------------------------|-------------------------------------| 129 - | `sbtrkt` | fuzzy-match | Всё, что совпадает с `sbtrkt` | 130 - | `'wild` | exact-match (В кавычках) | Всё, что включает в себя `wild` | 131 - | `^music` | prefix-exact-match | Всё, что начинается с `music` | 132 - | `.mp3$` | suffix-exact-match | Всё, что заканчивается на `.mp3` | 133 - | `!fire` | inverse-exact-match | Всё, что не включает в себя `fire` | 134 - | `!^music` | inverse-prefix-exact-match | Всё, что не начинается с `music` | 135 - | `!.mp3$` | inverse-suffix-exact-match | Всё, что не заканчивается на `.mp3` | 136 - 137 - Знак вертикальной черты означает логическое ИЛИ. Например, запрос ниже вернет 138 - всё, что начинается с `core` и заканчивается либо на `go`, либо на `rb`, либо на `py`. 139 - 140 - ``` 141 - ^core go$ | rb$ | py$ 142 - ``` 143 - 144 - ## Серверная конфигурация 145 - 146 - `// TODO`
-27
docs-i18n/ru/import_ru.md
··· 1 - # `atuin import` 2 - 3 - Atuin может импортировать историю из "старого" файла истории 4 - 5 - `atuin import auto` предпринимает попытку определить тип командного интерфейса 6 - (через \$SHELL) и запускает нужный скрипт импорта. 7 - 8 - К сожалению, эти файлы содержат не так много информации, как Atuin, так что не 9 - все функции будут доступны с импортированными данными. 10 - 11 - # zsh 12 - 13 - ``` 14 - atuin import zsh 15 - ``` 16 - 17 - Если у вас есть HISTFILE, то эта команда должна сработать. Иначе, попробуйте 18 - 19 - ``` 20 - HISTFILE=/path/to/history/file atuin import zsh 21 - ``` 22 - 23 - Этот параметр поддерживает как и упрощённый, так и полный формат. 24 - 25 - # bash 26 - 27 - TODO
-39
docs-i18n/ru/key-binding_ru.md
··· 1 - # Key binding 2 - 3 - По умолчанию, Atuin будет переназначать <kbd>Ctrl-r</kbd> и клавишу 'стрелка вверх'. 4 - Если вы не хотите этого, установите параметр ATUIN_NOBIND прежде чем вызывать `atuin init` 5 - 6 - Например, 7 - 8 - ``` 9 - export ATUIN_NOBIND="true" 10 - eval "$(atuin init zsh)" 11 - ``` 12 - 13 - Таким образом вы можете разрешить переназначение клавиш Atuin, если это необходимо. 14 - Делайте это до инициализирующего вызова. 15 - 16 - # zsh 17 - 18 - Atuin устанавливает виджет ZLE "atuin-search" 19 - 20 - ``` 21 - export ATUIN_NOBIND="true" 22 - eval "$(atuin init zsh)" 23 - 24 - bindkey '^r' atuin-search 25 - 26 - # зависит от режима терминала 27 - bindkey '^[[A' atuin-search 28 - bindkey '^[OA' atuin-search 29 - ``` 30 - 31 - # bash 32 - 33 - ``` 34 - export ATUIN_NOBIND="true" 35 - eval "$(atuin init bash)" 36 - 37 - # Переопределите ctrl-r, и любые другие сочетания горячих клавиш тут 38 - bind -x '"\C-r": __atuin_history' 39 - ```
-11
docs-i18n/ru/list_ru.md
··· 1 - # Вывод истории на экран 2 - 3 - ``` 4 - atuin history list 5 - ``` 6 - 7 - | Аргумент | Описание | 8 - | -------------- | ------------------------------------------------------------------------------ | 9 - | `--cwd/-c` | Каталог, историю команд которой необходимо вывести (по умолчанию все каталоги) | 10 - | `--session/-s` | Выводит историю команд только текущей сессии (по умолчанию false) | 11 - | `--human` | Читаемый формат для времени и периодов времени (по умолчанию false) |
-38
docs-i18n/ru/search_ru.md
··· 1 - # `atuin search` 2 - 3 - ``` 4 - atuin search <query> 5 - ``` 6 - 7 - Поиск в Atuin также поддерживает wildcards со знаками `*` или `%`. 8 - По умолчанию, должен быть указан префикс (т.е. все запросы автоматически дополняются wildcard -ами) 9 - 10 - | Аргумент | Описание | 11 - | ------------------ | ------------------------------------------------------------------------------------------- | 12 - | `--cwd/-c` | Каталог, для которого отображается история (по умолчанию, все каталоги) | 13 - | `--exclude-cwd` | Исключить команды которые запускались в этом каталоге (по умолчанию none) | 14 - | `--exit/-e` | Фильтровать по exit code (по умолчанию none) | 15 - | `--exclude-exit` | Исключить команды, которые завершились с указанным значением (по умолчанию none) | 16 - | `--before` | Включить только команды, которые были запущены до указанного времени (по умолчанию none) | 17 - | `--after` | Включить только команды, которые были запущены после указанного времени (по умолчанию none) | 18 - | `--interactive/-i` | Открыть интерактивный поисковой графический интерфейс (по умолчанию false) | 19 - | `--human` | Использовать читаемое форматирование для времени и периодов времени (по умолчанию false) | 20 - 21 - ## Примеры 22 - 23 - ``` 24 - # Начать интерактивный поиск с текстовым пользовательским интерфейсом 25 - atuin search -i 26 - 27 - # Начать интерактивный поиск с текстовым пользовательским интерфейсом и уже введённым запросом 28 - atuin search -i atuin 29 - 30 - # Искать по всем командам, начиная с cargo, которые успешно завершились 31 - atuin search --exit 0 cargo 32 - 33 - # Искать по всем командам которые завершились ошибками и были вызваны в текущей папке и были запущены до первого апреля 2021 34 - atuin search --exclude-exit 0 --before 01/04/2021 --cwd . 35 - 36 - # Искать по всем командам, начиная с cargo, которые успешно завершились и были запущены после трёх часов дня вчера 37 - atuin search --exit 0 --after "yesterday 3pm" cargo 38 - ```
-160
docs-i18n/ru/server_ru.md
··· 1 - # `atuin server` 2 - 3 - Atuin позволяет запустить свой собственный сервер синхронизации, если вы 4 - не хотите использовать мой :) 5 - 6 - Здесь есть только одна субкоманда, `atuin server start`, которая запустит 7 - Atuin http-сервер синхронизации 8 - 9 - ``` 10 - USAGE: 11 - atuin server start [OPTIONS] 12 - 13 - FLAGS: 14 - --help Prints help information 15 - -V, --version Prints version information 16 - 17 - OPTIONS: 18 - -h, --host <host> 19 - -p, --port <port> 20 - ``` 21 - 22 - ## config 23 - 24 - Серверная конфигурация лежит отдельно от файла пользовательской, даже если 25 - это один и тот же бинарный файл. Серверная конфигурация лежит в `~/.config/atuin/server.toml`. 26 - 27 - Этот файл выглядит как-то так: 28 - 29 - ```toml 30 - host = "0.0.0.0" 31 - port = 8888 32 - open_registration = true 33 - db_uri="postgres://user:password@hostname/database" 34 - ``` 35 - 36 - Конфигурация так же может находиться в переменных окружения. 37 - 38 - ```sh 39 - ATUIN_HOST="0.0.0.0" 40 - ATUIN_PORT=8888 41 - ATUIN_OPEN_REGISTRATION=true 42 - ATUIN_DB_URI="postgres://user:password@hostname/database" 43 - ``` 44 - 45 - ### host 46 - 47 - Адрес хоста, который будет прослушиваться сервером Atuin 48 - 49 - По умолчанию это `127.0.0.1`. 50 - 51 - ### port 52 - 53 - Порт, который будет прослушиваться сервером Atuin. 54 - 55 - По умолчанию это `8888`. 56 - 57 - ### open_registration 58 - 59 - Если `true`, autin будет разрешать регистрацию новых пользователей. 60 - Установите флаг `false`, если после создания вашего аккаунта вы не хотите, чтобы другие 61 - могли пользоваться вашим сервером. 62 - 63 - По умолчанию `false`. 64 - 65 - ### db_uri 66 - 67 - Действующий URI postgres, где будет сохранён аккаунт пользователя и история. 68 - 69 - ## Docker 70 - 71 - Поддерживается образ Docker чтобы сделать проще развертывание сервера в контейнере. 72 - 73 - ```sh 74 - docker run -d -v "$USER/.config/atuin:/config" ghcr.io/ellie/atuin:latest server start 75 - ``` 76 - 77 - ## Docker Compose 78 - 79 - Использование вашего собственного docker-образа с хостингом вашего собственного Atuin может быть реализовано через 80 - файл docker-compose. 81 - 82 - Создайте файл `.env` рядом с `docker-compose.yml` с содержанием наподобие этому: 83 - 84 - ``` 85 - ATUIN_DB_USERNAME=atuin 86 - # Choose your own secure password 87 - ATUIN_DB_PASSWORD=really-insecure 88 - ``` 89 - 90 - Создайте `docker-compose.yml`: 91 - 92 - ```yaml 93 - version: '3.5' 94 - services: 95 - atuin: 96 - restart: always 97 - image: ghcr.io/ellie/atuin:main 98 - command: server start 99 - volumes: 100 - - "./config:/config" 101 - links: 102 - - postgresql:db 103 - ports: 104 - - 8888:8888 105 - environment: 106 - ATUIN_HOST: "0.0.0.0" 107 - ATUIN_OPEN_REGISTRATION: "true" 108 - ATUIN_DB_URI: postgres://$ATUIN_DB_USERNAME:$ATUIN_DB_PASSWORD@db/atuin 109 - postgresql: 110 - image: postgres:14 111 - restart: unless-stopped 112 - volumes: # Don't remove permanent storage for index database files! 113 - - "./database:/var/lib/postgresql/data/" 114 - environment: 115 - POSTGRES_USER: $ATUIN_DB_USERNAME 116 - POSTGRES_PASSWORD: $ATUIN_DB_PASSWORD 117 - POSTGRES_DB: atuin 118 - ``` 119 - 120 - Запустите службы с помощью `docker-compose`: 121 - 122 - ```sh 123 - docker-compose up -d 124 - ``` 125 - 126 - ### Использование systemd для управления сервером Atuin 127 - 128 - `systemd` юнит чтобы управлять службами, контролируемыми `docker-compose`: 129 - 130 - ``` 131 - [Unit] 132 - Description=Docker Compose Atuin Service 133 - Requires=docker.service 134 - After=docker.service 135 - 136 - [Service] 137 - # Where the docker-compose file is located 138 - WorkingDirectory=/srv/atuin-server 139 - ExecStart=/usr/bin/docker-compose up 140 - ExecStop=/usr/bin/docker-compose down 141 - TimeoutStartSec=0 142 - Restart=on-failure 143 - StartLimitBurst=3 144 - 145 - [Install] 146 - WantedBy=multi-user.target 147 - ``` 148 - 149 - Включите и запустите службу командой: 150 - 151 - ```sh 152 - systemctl enable --now atuin 153 - ``` 154 - 155 - Проверьте, работает ли: 156 - 157 - ```sh 158 - systemctl status atuin 159 - ``` 160 -
-20
docs-i18n/ru/shell-completions_ru.md
··· 1 - # `atuin gen-completions` 2 - 3 - [Shell completions](https://en.wikipedia.org/wiki/Command-line_completion) для Atuin 4 - могут быть сгенерированы путём указания каталога для вывода и желаемого shell через субкоманду `gen-completions`. 5 - 6 - ``` 7 - $ atuin gen-completions --shell bash --out-dir $HOME 8 - 9 - Shell completion for BASH is generated in "/home/user" 10 - ``` 11 - 12 - Возможные команды для аргумента `--shell` могут быть следующими: 13 - 14 - - `bash` 15 - - `fish` 16 - - `zsh` 17 - - `powershell` 18 - - `elvish` 19 - 20 - Также рекомендуем прочитать [supported shells](./../../README.md#supported-shells).
-39
docs-i18n/ru/stats_ru.md
··· 1 - # `atuin stats` 2 - 3 - Atuin также может выводить статистику, основанную на истории. Пока что в очень простом виде, 4 - но скоро должно появиться больше возможностей. 5 - 6 - Статистика выводится пока только на английском 7 - # TODO 8 - 9 - ``` 10 - $ atuin stats day last friday 11 - 12 - +---------------------+------------+ 13 - | Statistic | Value | 14 - +---------------------+------------+ 15 - | Most used command | git status | 16 - +---------------------+------------+ 17 - | Commands ran | 450 | 18 - +---------------------+------------+ 19 - | Unique commands ran | 213 | 20 - +---------------------+------------+ 21 - 22 - $ atuin stats day 01/01/21 # also accepts absolute dates 23 - ``` 24 - 25 - Также, может быть выведена статистика всей известной Atuin истории: 26 - 27 - ``` 28 - $ atuin stats all 29 - 30 - +---------------------+-------+ 31 - | Statistic | Value | 32 - +---------------------+-------+ 33 - | Most used command | ls | 34 - +---------------------+-------+ 35 - | Commands ran | 8190 | 36 - +---------------------+-------+ 37 - | Unique commands ran | 2996 | 38 - +---------------------+-------+ 39 - ```
-60
docs-i18n/ru/sync_ru.md
··· 1 - # `atuin sync` 2 - 3 - Atuin может сделать резервную копию вашей истории на сервер чтобы обеспечить использование 4 - разными компьютерами одной и той же истории. Вся история будет зашифрована двусторонним шифрованием, 5 - так что сервер _никогда_ не получит ваши данные! 6 - 7 - Можно сделать свой сервер (запустив `atuin server start`, об этом написано в других 8 - файлах документации), но у меня есть свой https://api.atuin.sh. Это серверный адрес по умолчанию, 9 - который может быть изменён в [конфигурации](config_ru.md). Опять же, я _не_ могу получить ваши данные 10 - и они мне не нужны. 11 - 12 - ## Частота синхронизации 13 - 14 - Синхронизация будет происходить автоматически, если обратное не было указано в конфигурации. 15 - Отконфигурировать сей параметр можно в [config](config_ru.md) 16 - 17 - ## Синхронизация 18 - 19 - Синхронизироваться также можно вручную, используя команду `atuin sync` 20 - 21 - ## Регистрация 22 - 23 - Можно зарегистрировать аккаунт для синхронизации: 24 - 25 - ``` 26 - atuin register -u <USERNAME> -e <EMAIL> -p <PASSWORD> 27 - ``` 28 - 29 - Имена пользователей должны быть уникальны, и электронная почта должна использоваться 30 - только для срочных уведомлений (изменения политик, нарушения безопасности и т.д.) 31 - 32 - После регистрации, вы уже сразу вошли в свой аккаунт :) С этого момента синхронизация 33 - будет проходить автоматически 34 - 35 - ## Ключ 36 - 37 - Поскольку все данные шифруются, Atuin при работе сгенерирует ваш ключ. Он будет сохранён в 38 - каталоге с данными Atuin (`~/.local/share/atuin` на системах с GNU/Linux) 39 - 40 - Также можно сделать это самим: 41 - 42 - ``` 43 - atuin key 44 - ``` 45 - 46 - Никогда не передавайте никому этот ключ! 47 - 48 - ## Вход 49 - 50 - Если вы хотите войти с другого компьютера, вам потребуется ключ безопасности (`atuin key`). 51 - 52 - ``` 53 - atuin login -u <USERNAME> -p <PASSWORD> -k <KEY> 54 - ``` 55 - 56 - ## Выход 57 - 58 - ``` 59 - atuin logout 60 - ```
-234
docs-i18n/zh-CN/README.md
··· 1 - <p align="center"> 2 - <picture> 3 - <source media="(prefers-color-scheme: dark)" srcset="https://github.com/atuinsh/atuin/assets/53315310/13216a1d-1ac0-4c99-b0eb-d88290fe0efd"> 4 - <img alt="Text changing depending on mode. Light: 'So light!' Dark: 'So dark!'" src="https://github.com/atuinsh/atuin/assets/53315310/08bc86d4-a781-4aaa-8d7e-478ae6bcd129"> 5 - </picture> 6 - </p> 7 - 8 - <p align="center"> 9 - <em>神奇的 shell 历史记录</em> 10 - </p> 11 - 12 - <hr/> 13 - 14 - <p align="center"> 15 - <a href="https://github.com/atuinsh/atuin/actions?query=workflow%3ARust"><img src="https://img.shields.io/github/actions/workflow/status/atuinsh/atuin/rust.yml?style=flat-square" /></a> 16 - <a href="https://crates.io/crates/atuin"><img src="https://img.shields.io/crates/v/atuin.svg?style=flat-square" /></a> 17 - <a href="https://crates.io/crates/atuin"><img src="https://img.shields.io/crates/d/atuin.svg?style=flat-square" /></a> 18 - <a href="https://github.com/atuinsh/atuin/blob/main/LICENSE"><img src="https://img.shields.io/crates/l/atuin.svg?style=flat-square" /></a> 19 - <a href="https://discord.gg/Fq8bJSKPHh"><img src="https://img.shields.io/discord/954121165239115808" /></a> 20 - <a rel="me" href="https://hachyderm.io/@atuin"><img src="https://img.shields.io/mastodon/follow/109944632283122560?domain=https%3A%2F%2Fhachyderm.io&style=social"/></a> 21 - <a href="https://twitter.com/atuinsh"><img src="https://img.shields.io/twitter/follow/atuinsh?style=social" /></a> 22 - </p> 23 - 24 - 25 - [English] | [简体中文] 26 - 27 - Atuin 使用 SQLite 数据库取代了你现有的 shell 历史,并为你的命令记录了额外的内容。此外,它还通过 Atuin 服务器,在机器之间提供可选的、完全加密的历史记录同步功能。 28 - 29 - <p align="center"> 30 - <img src="../../demo.gif" alt="animated" width="80%" /> 31 - </p> 32 - 33 - <p align="center"> 34 - <em>显示退出代码、命令持续时间、上次执行时间和执行的命令</em> 35 - </p> 36 - 37 - 除了搜索 UI,它还可以执行以下操作: 38 - 39 - ``` 40 - # 搜索昨天下午3点之后记录的所有成功的 `make` 命令 41 - atuin search --exit 0 --after "yesterday 3pm" make 42 - ``` 43 - 44 - 你可以使用我(ellie)托管的服务器,也可以使用你自己的服务器!或者干脆不使用 sync 功能。所有的历史记录同步都是加密,即使我想,也无法访问你的数据。且我**真的**不想。 45 - 46 - ## 功能 47 - 48 - - 重新绑定 `up` 和 `ctrl-r` 的全屏历史记录搜索UI界面 49 - - 使用 sqlite 数据库存储 shell 历史记录 50 - - 备份以及同步已加密的 shell 历史记录 51 - - 在不同的终端、不同的会话以及不同的机器上都有相同的历史记录 52 - - 记录退出代码、cwd、主机名、会话、命令持续时间,等等。 53 - - 计算统计数据,如 "最常用的命令"。 54 - - 不替换旧的历史文件 55 - - 通过 <kbd>Alt-\<num\></kbd> 快捷键快速跳转到之前的记录 56 - - 通过 ctrl-r 切换过滤模式;可以仅从当前会话、目录或全局来搜索历史记录 57 - 58 - ## 文档 59 - 60 - - [快速开始](#快速开始) 61 - - [安装](#安装) 62 - - [导入](./import.md) 63 - - [配置](./config.md) 64 - - [历史记录搜索](./search.md) 65 - - [历史记录云端同步](./sync.md) 66 - - [历史记录统计](./stats.md) 67 - - [运行你自己的服务器](./server.md) 68 - - [键绑定](./key-binding.md) 69 - - [shell 补全](./shell-completions.md) 70 - 71 - ## 支持的 Shells 72 - 73 - - zsh 74 - - bash 75 - - fish 76 - 77 - ## 社区 78 - 79 - Atuin 有一个 Discord 社区, 可以在 [这里](https://discord.gg/Fq8bJSKPHh) 获得 80 - 81 - # 快速开始 82 - 83 - ## 使用默认的同步服务器 84 - 85 - 这将为您注册由我托管的默认同步服务器。 一切都是端到端加密的,所以你的秘密是安全的! 86 - 87 - 阅读下面的更多信息,了解仅供离线使用或托管您自己的服务器。 88 - 89 - ``` 90 - bash <(curl https://raw.githubusercontent.com/ellie/atuin/main/install.sh) 91 - 92 - atuin register -u <USERNAME> -e <EMAIL> -p <PASSWORD> 93 - atuin import auto 94 - atuin sync 95 - ``` 96 - 97 - ### 使用活跃图 98 - 99 - 除了托管 Atuin 服务器外,还有一个服务可以用来生成你的 shell 历史记录使用活跃图!这个功能的灵感来自于 GitHub 的使用活跃图。 100 - 101 - 例如,这是我的: 102 - 103 - ![](https://api.atuin.sh/img/ellie.png?token=0722830c382b42777bdb652da5b71efb61d8d387) 104 - 105 - 如果你也想要,请在登陆你的同步服务器后,执行 106 - 107 - ``` 108 - curl https://api.atuin.sh/enable -d $(cat ~/.local/share/atuin/session) 109 - ``` 110 - 111 - 执行结果为你的活跃图 URL 地址。可以共享或嵌入这个 URL 地址,令牌(token)并<i>不是</i>加密的,只是用来防止被枚举攻击。 112 - 113 - ## 仅离线 (不同步) 114 - 115 - ``` 116 - bash <(curl https://raw.githubusercontent.com/ellie/atuin/main/install.sh) 117 - 118 - atuin import auto 119 - ``` 120 - 121 - ## 安装 122 - 123 - ### 脚本 (推荐) 124 - 125 - 安装脚本将帮助您完成设置,确保您的 shell 正确配置。 它还将使用以下方法之一,在可能的情况下首选系统包管理器(pacman、homebrew 等)。 126 - 127 - ``` 128 - # 不要以root身份运行,如果需要的话,会要求root。 129 - bash <(curl https://raw.githubusercontent.com/ellie/atuin/main/install.sh) 130 - ``` 131 - 132 - 然后可直接看 <a href="#shell-plugin">Shell 插件</a> 133 - 134 - ### 通过 cargo 135 - 136 - 最好使用 [rustup](https://rustup.rs/) 来设置 Rust 工具链,然后你就可以运行下面的命令: 137 - 138 - ``` 139 - cargo install atuin 140 - ``` 141 - 142 - 然后可直接看 <a href="#shell-plugin">Shell 插件</a> 143 - 144 - ### Homebrew 145 - 146 - ``` 147 - brew install atuin 148 - ``` 149 - 150 - 然后可直接看 <a href="#shell-plugin">Shell 插件</a> 151 - 152 - ### MacPorts 153 - 154 - Atuin 也可以在 [MacPorts](https://ports.macports.org/port/atuin/) 中找到 155 - 156 - ``` 157 - sudo port install atuin 158 - ``` 159 - 160 - 然后可直接看 <a href="#shell-plugin">Shell 插件</a> 161 - 162 - ### Pacman 163 - 164 - Atuin 在 Arch Linux 的 [社区存储库](https://archlinux.org/packages/community/x86_64/atuin/) 中可用。 165 - 166 - ``` 167 - pacman -S atuin 168 - ``` 169 - 170 - 然后可直接看 <a href="#shell-plugin">Shell 插件</a> 171 - 172 - ### 从源码编译安装 173 - 174 - ``` 175 - git clone https://github.com/ellie/atuin.git 176 - cd atuin/crates/atuin 177 - cargo install --path . 178 - ``` 179 - 180 - 然后可直接看 <a href="#shell-plugin">Shell 插件</a> 181 - 182 - ## <a id="shell-plugin">Shell 插件</a> 183 - 184 - 安装二进制文件后,需要安装 shell 插件。 如果你使用的是脚本安装,那么这一切应该都会帮您完成! 185 - 186 - ### zsh 187 - 188 - ``` 189 - echo 'eval "$(atuin init zsh)"' >> ~/.zshrc 190 - ``` 191 - 192 - 或使用插件管理器: 193 - 194 - ``` 195 - zinit load ellie/atuin 196 - ``` 197 - 198 - ### bash 199 - 200 - 我们需要设置一些钩子(hooks), 所以首先需要安装 bash-preexec : 201 - 202 - ``` 203 - curl https://raw.githubusercontent.com/rcaloras/bash-preexec/master/bash-preexec.sh -o ~/.bash-preexec.sh 204 - echo '[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh' >> ~/.bashrc 205 - ``` 206 - 207 - 然后设置 Atuin 208 - 209 - ``` 210 - echo 'eval "$(atuin init bash)"' >> ~/.bashrc 211 - ``` 212 - 213 - ### fish 214 - 215 - 添加 216 - 217 - ``` 218 - atuin init fish | source 219 - ``` 220 - 221 - 到 `~/.config/fish/config.fish` 文件中的 `is-interactive` 块中 222 - 223 - ### Fig 224 - 225 - 通过 [Fig](https://fig.io) 可为 zsh, bash 或 fish 一键安装 `atuin` 脚本插件。 226 - 227 - <a href="https://fig.io/plugins/other/atuin" target="_blank"><img src="https://fig.io/badges/install-with-fig.svg" /></a> 228 - 229 - ## ...这个名字是什么意思? 230 - 231 - Atuin 以 "The Great A'Tuin" 命名, 这是一只来自 Terry Pratchett 的 Discworld 系列书籍的巨龟。 232 - 233 - [English]: ../../README.md 234 - [简体中文]: ./README.md
-137
docs-i18n/zh-CN/config.md
··· 1 - # 配置 2 - 3 - Atuin 维护两个配置文件,存储在 `~/.config/atuin/` 中。 我们将数据存储在 `~/.local/share/atuin` 中(除非被 XDG\_\* 覆盖)。 4 - 5 - 您可以通过设置更改配置目录的路径 `ATUIN_CONFIG_DIR`。 例如 6 - 7 - ``` 8 - export ATUIN_CONFIG_DIR = /home/ellie/.atuin 9 - ``` 10 - 11 - ## 客户端配置 12 - 13 - ``` 14 - ~/.config/atuin/config.toml 15 - ``` 16 - 17 - 客户端运行在用户的机器上,除非你运行的是服务器,否则这就是你所关心的。 18 - 19 - 见 [config.toml](../../atuin-client/config.toml) 中的例子 20 - 21 - ### `dialect` 22 - 23 - 这配置了 [stats](stats.md) 命令解析日期的方式。 它有两个可能的值 24 - 25 - ``` 26 - dialect = "uk" 27 - ``` 28 - 29 - 或者 30 - 31 - ``` 32 - dialect = "us" 33 - ``` 34 - 35 - 默认为 "us". 36 - 37 - ### `auto_sync` 38 - 39 - 配置登录时是否自动同步。默认为 true 40 - 41 - ``` 42 - auto_sync = true/false 43 - ``` 44 - 45 - ### `sync_address` 46 - 47 - 同步的服务器地址! 默认为 `https://api.atuin.sh` 48 - 49 - ``` 50 - sync_address = "https://api.atuin.sh" 51 - ``` 52 - 53 - ### `sync_frequency` 54 - 55 - 多长时间与服务器自动同步一次。这可以用一种"人类可读"的格式给出。例如,`10s`,`20m`,`1h`,等等。默认为 `1h` 。 56 - 57 - 如果设置为 `0`,Atuin将在每个命令之后进行同步。一些服务器可能有潜在的速率限制,这不会造成任何问题。 58 - 59 - ``` 60 - sync_frequency = "1h" 61 - ``` 62 - 63 - ### `db_path` 64 - 65 - Atuin SQlite数据库的路径。默认为 66 - `~/.local/share/atuin/history.db` 67 - 68 - ``` 69 - db_path = "~/.history.db" 70 - ``` 71 - 72 - ### `key_path` 73 - 74 - Atuin加密密钥的路径。默认为 75 - `~/.local/share/atuin/key` 76 - 77 - ``` 78 - key = "~/.atuin-key" 79 - ``` 80 - 81 - ### `session_path` 82 - 83 - Atuin服务器会话文件的路径。默认为 84 - `~/.local/share/atuin/session` 。 这本质上只是一个API令牌 85 - 86 - ``` 87 - key = "~/.atuin-session" 88 - ``` 89 - 90 - ### `search_mode` 91 - 92 - 使用哪种搜索模式。Atuin 支持 "prefix"(前缀)、"fulltext"(全文) 和 "fuzzy"(模糊)搜索模式。前缀(prefix)搜索语法为 "query\*",全文(fulltext)搜索语法为 "\*query\*",而模糊搜索适用的搜索语法 [如下所述](#fuzzy-search-syntax) 。 93 - 94 - 默认配置为 "fuzzy" 95 - 96 - ### `filter_mode` 97 - 98 - 搜索时要使用的默认过滤器 99 - 100 - | 模式 | 描述 | 101 - |--------------- | --------------- | 102 - | global (default) | 从所有主机、所有会话、所有目录中搜索历史记录 | 103 - | host | 仅从该主机搜索历史记录 | 104 - | session | 仅从当前会话中搜索历史记录 | 105 - | directory | 仅从当前目录搜索历史记录| 106 - 107 - 过滤模式仍然可以通过 ctrl-r 来切换 108 - 109 - 110 - ``` 111 - search_mode = "fulltext" 112 - ``` 113 - 114 - #### `fuzzy` 的搜索语法 115 - 116 - `fuzzy` 搜索语法的基础是 [fzf 搜索语法](https://github.com/junegunn/fzf#search-syntax) 。 117 - 118 - | 内容 | 匹配类型 | 描述 | 119 - | --------- | -------------------------- | ------------------------------------ | 120 - | `sbtrkt` | fuzzy-match | 匹配 `sbtrkt` 的项目 | 121 - | `'wild` | exact-match (quoted) | 包含 `wild` 的项目 | 122 - | `^music` | prefix-exact-match | 以 `music` 开头的项目 | 123 - | `.mp3$` | suffix-exact-match | 以 `.mp3` 结尾的项目 | 124 - | `!fire` | inverse-exact-match | 不包括 `fire` 的项目 | 125 - | `!^music` | inverse-prefix-exact-match | 不以 `music` 开头的项目 | 126 - | `!.mp3$` | inverse-suffix-exact-match | 不以 `.mp3` 结尾的项目 | 127 - 128 - 129 - 单个条形字符术语充当 OR 运算符。 例如,以下查询匹配以 `core` 开头并以 `go`、`rb` 或 `py` 结尾的条目。 130 - 131 - ``` 132 - ^core go$ | rb$ | py$ 133 - ``` 134 - 135 - ## 服务端配置 136 - 137 - `// TODO`
-90
docs-i18n/zh-CN/docker.md
··· 1 - # Docker 2 - 3 - Atuin 提供了一个 docker 镜像(image),可以更轻松地将服务器部署为容器(container)。 4 - 5 - ```sh 6 - docker run -d -v "$USER/.config/atuin:/config" ghcr.io/ellie/atuin:latest server start 7 - ``` 8 - 9 - # Docker Compose 10 - 11 - 使用已有的 docker 镜像(image)来托管你自己的 Atuin,可以使用提供的 docker-compose 文件来完成 12 - 13 - 在 docker-compose.yml 同级目录下创建一个 .env 文件,内容如下: 14 - 15 - ``` 16 - ATUIN_DB_USERNAME=atuin 17 - # 填写你的密码 18 - ATUIN_DB_PASSWORD=really-insecure 19 - ``` 20 - 21 - 创建 `docker-compose.yml` 文件: 22 - 23 - ```yaml 24 - version: '3.5' 25 - services: 26 - atuin: 27 - restart: always 28 - image: ghcr.io/ellie/atuin:main 29 - command: server start 30 - volumes: 31 - - "./config:/config" 32 - links: 33 - - postgresql:db 34 - ports: 35 - - 8888:8888 36 - environment: 37 - ATUIN_HOST: "0.0.0.0" 38 - ATUIN_OPEN_REGISTRATION: "true" 39 - ATUIN_DB_URI: postgres://$ATUIN_DB_USERNAME:$ATUIN_DB_PASSWORD@db/atuin 40 - postgresql: 41 - image: postgres:14 42 - restart: unless-stopped 43 - volumes: # 不要删除索引数据库文件的永久存储空间! 44 - - "./database:/var/lib/postgresql/data/" 45 - environment: 46 - POSTGRES_USER: $ATUIN_DB_USERNAME 47 - POSTGRES_PASSWORD: $ATUIN_DB_PASSWORD 48 - POSTGRES_DB: atuin 49 - ``` 50 - 51 - 使用 `docker-compose` 启动服务: 52 - 53 - ```sh 54 - docker-compose up -d 55 - ``` 56 - 57 - ## 使用 systemd 管理你的 atuin 服务器 58 - 59 - 以下 `systemd` 的配置文件用来管理你的 `docker-compose` 托管服务: 60 - 61 - ``` 62 - [Unit] 63 - Description=Docker Compose Atuin Service 64 - Requires=docker.service 65 - After=docker.service 66 - 67 - [Service] 68 - # Where the docker-compose file is located 69 - WorkingDirectory=/srv/atuin-server 70 - ExecStart=/usr/bin/docker-compose up 71 - ExecStop=/usr/bin/docker-compose down 72 - TimeoutStartSec=0 73 - Restart=on-failure 74 - StartLimitBurst=3 75 - 76 - [Install] 77 - WantedBy=multi-user.target 78 - ``` 79 - 80 - 启用服务: 81 - 82 - ```sh 83 - systemctl enable --now atuin 84 - ``` 85 - 86 - 检查服务是否正常运行: 87 - 88 - ```sh 89 - systemctl status atuin 90 - ```
-25
docs-i18n/zh-CN/import.md
··· 1 - # `atuin import` 2 - 3 - Atuin 可以从您的“旧”历史文件中导入您的历史记录 4 - 5 - `atuin import auto` 将尝试找出你的 shell(通过 \$SHELL)并运行正确的导入器 6 - 7 - 不幸的是,这些旧文件没有像 Atuin 那样存储尽可能多的信息,因此并非所有功能都可用于导入的数据。 8 - 9 - # zsh 10 - 11 - ``` 12 - atuin import zsh 13 - ``` 14 - 15 - 如果你设置了 HISTFILE,这应该会被选中!如果没有,可以尝试以下操作 16 - 17 - ``` 18 - HISTFILE=/path/to/history/file atuin import zsh 19 - ``` 20 - 21 - 这支持简单和扩展形式 22 - 23 - # bash 24 - 25 - TODO
-195
docs-i18n/zh-CN/k8s.md
··· 1 - # Kubernetes 2 - 3 - 你可以使用 Kubernetes 来托管你的 Atuin 服务器。 4 - 5 - 为数据库凭证创建 [`secrets.yaml`](../../k8s/secrets.yaml) 文件: 6 - 7 - ```yaml 8 - apiVersion: v1 9 - kind: Secret 10 - metadata: 11 - name: atuin-secrets 12 - type: Opaque 13 - stringData: 14 - ATUIN_DB_USERNAME: atuin 15 - ATUIN_DB_PASSWORD: seriously-insecure 16 - ATUIN_HOST: "127.0.0.1" 17 - ATUIN_PORT: "8888" 18 - ATUIN_OPEN_REGISTRATION: "true" 19 - ATUIN_DB_URI: "postgres://atuin:seriously-insecure@localhost/atuin" 20 - immutable: true 21 - ``` 22 - 23 - 为 Atuin 服务器创建 [`atuin.yaml`](../../k8s/atuin.yaml) 文件: 24 - 25 - 26 - ```yaml 27 - --- 28 - apiVersion: apps/v1 29 - kind: Deployment 30 - metadata: 31 - name: atuin 32 - spec: 33 - replicas: 1 34 - selector: 35 - matchLabels: 36 - io.kompose.service: atuin 37 - template: 38 - metadata: 39 - labels: 40 - io.kompose.service: atuin 41 - spec: 42 - containers: 43 - - args: 44 - - server 45 - - start 46 - env: 47 - - name: ATUIN_DB_URI 48 - valueFrom: 49 - secretKeyRef: 50 - name: atuin-secrets 51 - key: ATUIN_DB_URI 52 - optional: false 53 - - name: ATUIN_HOST 54 - value: 0.0.0.0 55 - - name: ATUIN_PORT 56 - value: "8888" 57 - - name: ATUIN_OPEN_REGISTRATION 58 - value: "true" 59 - image: ghcr.io/atuinsh/atuin:latest 60 - name: atuin 61 - ports: 62 - - containerPort: 8888 63 - resources: 64 - limits: 65 - cpu: 250m 66 - memory: 1Gi 67 - requests: 68 - cpu: 250m 69 - memory: 1Gi 70 - volumeMounts: 71 - - mountPath: /config 72 - name: atuin-claim0 73 - - name: postgresql 74 - image: postgres:14 75 - ports: 76 - - containerPort: 5432 77 - env: 78 - - name: POSTGRES_DB 79 - value: atuin 80 - - name: POSTGRES_PASSWORD 81 - valueFrom: 82 - secretKeyRef: 83 - name: atuin-secrets 84 - key: ATUIN_DB_PASSWORD 85 - optional: false 86 - - name: POSTGRES_USER 87 - valueFrom: 88 - secretKeyRef: 89 - name: atuin-secrets 90 - key: ATUIN_DB_USERNAME 91 - optional: false 92 - resources: 93 - limits: 94 - cpu: 250m 95 - memory: 1Gi 96 - requests: 97 - cpu: 250m 98 - memory: 1Gi 99 - volumeMounts: 100 - - mountPath: /var/lib/postgresql/data/ 101 - name: database 102 - volumes: 103 - - name: database 104 - persistentVolumeClaim: 105 - claimName: database 106 - - name: atuin-claim0 107 - persistentVolumeClaim: 108 - claimName: atuin-claim0 109 - --- 110 - apiVersion: v1 111 - kind: Service 112 - metadata: 113 - labels: 114 - io.kompose.service: atuin 115 - name: atuin 116 - spec: 117 - type: NodePort 118 - ports: 119 - - name: "8888" 120 - port: 8888 121 - nodePort: 30530 122 - selector: 123 - io.kompose.service: atuin 124 - --- 125 - kind: PersistentVolume 126 - apiVersion: v1 127 - metadata: 128 - name: database-pv 129 - labels: 130 - app: database 131 - type: local 132 - spec: 133 - storageClassName: manual 134 - capacity: 135 - storage: 300Mi 136 - accessModes: 137 - - ReadWriteOnce 138 - hostPath: 139 - path: "/Users/firstname.lastname/.kube/database" 140 - --- 141 - apiVersion: v1 142 - kind: PersistentVolumeClaim 143 - metadata: 144 - labels: 145 - io.kompose.service: database 146 - name: database 147 - spec: 148 - storageClassName: manual 149 - accessModes: 150 - - ReadWriteOnce 151 - resources: 152 - requests: 153 - storage: 300Mi 154 - --- 155 - apiVersion: v1 156 - kind: PersistentVolumeClaim 157 - metadata: 158 - labels: 159 - io.kompose.service: atuin-claim0 160 - name: atuin-claim0 161 - spec: 162 - accessModes: 163 - - ReadWriteOnce 164 - resources: 165 - requests: 166 - storage: 10Mi 167 - ``` 168 - 169 - 最后,你可能想让 atuin 使用单独的命名空间(namespace),创建 [`namespace.yaml`](../../k8s/namespaces.yaml) 文件: 170 - 171 - ```yaml 172 - apiVersion: v1 173 - kind: Namespace 174 - metadata: 175 - name: atuin-namespace 176 - labels: 177 - name: atuin 178 - ``` 179 - 180 - 在企业级安装部署时,你可能想要数据库内容永久存储在集群中,而不是在主机系统中。在上述配置中,`storageClassName` 配置为 `manual`,主机系统的挂载目录配置为 `/Users/firstname.lastname/.kube/database`,请注意,这些配置将会使得数据库内容存储在 kubernetes 集群<i>外部</i>中。 181 - 182 - 你还应该将 `secrets.yaml` 文件中的 `ATUIN_DB_PASSWORD` 和 `ATUIN_DB_URI` 修改为更安全的加密字符串。 183 - 184 - Atuin 运行在主机系统的 `30530` 端口上。这是通过 `nodePort` 属性进行陪你的。Kubernetes 有一个严格规则,即不允许暴露小于 30000 的端口号。为了使客户端能够正常工作,你需要在你的 `config.toml` 文件中设置端口号,例如 `sync_address = "http://192.168.1.10:30530"`。 185 - 186 - 使用 `kubectl` 部署 Atuin 服务器: 187 - 188 - ```shell 189 - kubectl apply -f ./namespaces.yaml 190 - kubectl apply -n atuin-namespace \ 191 - -f ./secrets.yaml \ 192 - -f ./atuin.yaml 193 - ``` 194 - 195 - 上面示例同时也位于 atuin 仓库(repository)的 [k8s](../../k8s) 目录下。
-48
docs-i18n/zh-CN/key-binding.md
··· 1 - # 键位绑定 2 - 3 - 默认情况下, Atuin 将会重新绑定 <kbd>Ctrl-r</kbd> 和 `up` 键。如果你不想使用默认绑定,请在调用 `atuin init` 之前设置 ATUIN_NOBIND 4 - 5 - 例如: 6 - 7 - ``` 8 - export ATUIN_NOBIND="true" 9 - eval "$(atuin init zsh)" 10 - ``` 11 - 12 - 如果需要,你可以在调用 `atuin init` 之后对 Atuin 重新进行键绑定 13 - 14 - # zsh 15 - 16 - Atuin 定义了 ZLE 部件 "atuin-search" 17 - 18 - ``` 19 - export ATUIN_NOBIND="true" 20 - eval "$(atuin init zsh)" 21 - 22 - bindkey '^r' atuin-search 23 - 24 - # 取决于终端模式 25 - bindkey '^[[A' atuin-search 26 - bindkey '^[OA' atuin-search 27 - ``` 28 - 29 - # bash 30 - 31 - ``` 32 - export ATUIN_NOBIND="true" 33 - eval "$(atuin init bash)" 34 - 35 - # 绑定到 ctrl-r, 也可以在这里添加任何其他你想要的绑定方式 36 - bind -x '"\C-r": __atuin_history' 37 - ``` 38 - 39 - # fish 40 - 41 - ``` 42 - set -gx ATUIN_NOBIND "true" 43 - atuin init fish | source 44 - 45 - # 在 normal 和 insert 模式下绑定到 ctrl-r,你也可以在此处添加其他键位绑定 46 - bind \cr _atuin_search 47 - bind -M insert \cr _atuin_search 48 - ```
-11
docs-i18n/zh-CN/list.md
··· 1 - # 历史记录列表 2 - 3 - ``` 4 - atuin history list 5 - ``` 6 - 7 - | 参数 | 描述 | 8 - | -------------- | ----------------------------------------------------- | 9 - | `--cwd/-c` | 要列出历史记录的目录(默认:所有目录) | 10 - | `--session/-s` | 只对当前会话启用列表历史(默认:false) | 11 - | `--human` | 对时间戳和持续时间使用人类可读的格式(默认:false)。 |
-37
docs-i18n/zh-CN/search.md
··· 1 - # `atuin search` 2 - 3 - ``` 4 - atuin search <query> 5 - ``` 6 - 7 - Atuin 搜索还支持带有 `*` 或 `%` 字符的通配符。 默认情况下,会执行前缀搜索(即,所有查询都会自动附加通配符)。 8 - 9 - | 参数 | 描述 | 10 - | ------------------ | ----------------------------------------------------- | 11 - | `--cwd/-c` | 列出历史记录的目录(默认:所有目录) | 12 - | `--exclude-cwd` | 不包括在此目录中运行的命令(默认值:none) | 13 - | `--exit/-e` | 按退出代码过滤(默认:none) | 14 - | `--exclude-exit` | 不包括以该值退出的命令(默认值:none) | 15 - | `--before` | 仅包括在此时间之前运行的命令(默认值:none) | 16 - | `--after` | 仅包含在此时间之后运行的命令(默认值:none) | 17 - | `--interactive/-i` | 打开交互式搜索 UI(默认值:false) | 18 - | `--human` | 对时间戳和持续时间使用人类可读的格式(默认值:false) | 19 - 20 - ## 举例 21 - 22 - ``` 23 - # 打开交互式搜索 TUI 24 - atuin search -i 25 - 26 - # 打开预装了查询的交互式搜索 TUI 27 - atuin search -i atuin 28 - 29 - # 搜索所有以 cargo 开头且成功退出的命令。 30 - atuin search --exit 0 cargo 31 - 32 - # 从当前目录中搜索所有在2021年4月1日之前运行且失败的命令。 33 - atuin search --exclude-exit 0 --before 01/04/2021 --cwd . 34 - 35 - # 搜索所有以 cargo 开头,成功退出且是在昨天下午3点之后运行的命令。 36 - atuin search --exit 0 --after "yesterday 3pm" cargo 37 - ```
-75
docs-i18n/zh-CN/server.md
··· 1 - # `atuin server` 2 - 3 - Atuin 允许您运行自己的同步服务器,以防您不想使用我(ellie)托管的服务器 :) 4 - 5 - 目前只有一个子命令,`atuin server start`,它将启动 Atuin http 同步服务器。 6 - 7 - ``` 8 - USAGE: 9 - atuin server start [OPTIONS] 10 - 11 - FLAGS: 12 - --help Prints help information 13 - -V, --version Prints version information 14 - 15 - OPTIONS: 16 - -h, --host <host> 17 - -p, --port <port> 18 - ``` 19 - 20 - ## 配置 21 - 22 - 服务器的配置与客户端的配置是分开的,即使它们是相同的二进制文件。服务器配置可以在 `~/.config/atuin/server.toml` 找到。 23 - 24 - 它看起来像这样: 25 - 26 - ```toml 27 - host = "0.0.0.0" 28 - port = 8888 29 - open_registration = true 30 - db_uri="postgres://user:password@hostname/database" 31 - ``` 32 - 33 - 另外,配置也可以用环境变量来提供。 34 - 35 - ```sh 36 - ATUIN_HOST="0.0.0.0" 37 - ATUIN_PORT=8888 38 - ATUIN_OPEN_REGISTRATION=true 39 - ATUIN_DB_URI="postgres://user:password@hostname/database" 40 - ``` 41 - 42 - ### host 43 - 44 - Atuin 服务器应该监听的地址 45 - 46 - 默认为 `127.0.0.1`. 47 - 48 - ### port 49 - 50 - Atuin 服务器应该监听的端口 51 - 52 - 默认为 `8888`. 53 - 54 - ### open_registration 55 - 56 - 如果为 `true` ,atuin 将接受新用户注册。如果您不希望其他人能够使用您的服务器,请在创建自己的账号后将此设置为 `false` 57 - 58 - 默认为 `false`. 59 - 60 - ### db_uri 61 - 62 - 一个有效的 postgres URI, 用户和历史记录数据将被保存到其中。 63 - 64 - ### path 65 - 66 - path 指的是给 server 添加的路由前缀。值为空字符串将不会添加路由前缀。 67 - 68 - 默认为 `""` 69 - 70 - ## 容器部署说明 71 - 72 - 你可以在容器中部署自己的 atuin 服务器: 73 - 74 - * 有关 docker 配置的示例,请参考 [docker](docker.md)。 75 - * 有关 kubernetes 配置的示例,请参考 [k8s](k8s.md)。
-19
docs-i18n/zh-CN/shell-completions.md
··· 1 - # `atuin gen-completions` 2 - 3 - Atuin 的 [Shell 补全](https://en.wikipedia.org/wiki/Command-line_completion) 可以通过 `gen-completions` 子命令指定输出目录和所需的 shell 来生成。 4 - 5 - ``` 6 - $ atuin gen-completions --shell bash --out-dir $HOME 7 - 8 - Shell completion for BASH is generated in "/home/user" 9 - ``` 10 - 11 - `--shell` 参数的可能值如下: 12 - 13 - - `bash` 14 - - `fish` 15 - - `zsh` 16 - - `powershell` 17 - - `elvish` 18 - 19 - 此外, 请参阅 [支持的 Shells](./README.md#支持的-Shells).
-35
docs-i18n/zh-CN/stats.md
··· 1 - # `atuin stats` 2 - 3 - Atuin 还可以根据你的历史记录进行计算统计数据 - 目前这只是一个小的基本功能,但更多功能即将推出 4 - 5 - ``` 6 - $ atuin stats day last friday 7 - 8 - +---------------------+------------+ 9 - | Statistic | Value | 10 - +---------------------+------------+ 11 - | Most used command | git status | 12 - +---------------------+------------+ 13 - | Commands ran | 450 | 14 - +---------------------+------------+ 15 - | Unique commands ran | 213 | 16 - +---------------------+------------+ 17 - 18 - $ atuin stats day 01/01/21 # 也接受绝对日期 19 - ``` 20 - 21 - 它还可以计算所有已知历史记录的统计数据。 22 - 23 - ``` 24 - $ atuin stats all 25 - 26 - +---------------------+-------+ 27 - | Statistic | Value | 28 - +---------------------+-------+ 29 - | Most used command | ls | 30 - +---------------------+-------+ 31 - | Commands ran | 8190 | 32 - +---------------------+-------+ 33 - | Unique commands ran | 2996 | 34 - +---------------------+-------+ 35 - ```
-51
docs-i18n/zh-CN/sync.md
··· 1 - # `atuin sync` 2 - 3 - Atuin 可以将您的历史记录备份到服务器,并使用它来确保多台机器具有相同的 shell 历史记录。 这都是端到端加密的,因此服务器操作员_永远_看不到您的数据! 4 - 5 - 任何人都可以托管一个服务器(尝试 `atuin server start`,更多文档将在后面介绍),但我(ellie)在 https://api.atuin.sh 上托管了一个。这是默认的服务器地址,可以在 [配置](config.md) 中更改。 同样,我_不能_看到您的数据,也不想。 6 - 7 - ## 同步频率 8 - 9 - 除非另有配置,否则同步将自动执行。同步的频率可在 [配置](config.md) 中配置。 10 - 11 - ## 同步 12 - 13 - 你可以通过 `atuin sync` 来手动触发同步 14 - 15 - ## 注册 16 - 17 - 注册一个同步账号 18 - 19 - ``` 20 - atuin register -u <USERNAME> -e <EMAIL> -p <PASSWORD> 21 - ``` 22 - 23 - 用户名(USERNAME)必须是唯一的,电子邮件(EMAIL)仅用于重要通知(安全漏洞、服务更改等) 24 - 25 - 注册后,意味着你也已经登录了 :) 同步应该从这里自动发生! 26 - 27 - ## 密钥 28 - 29 - 由于你的数据是加密的, Atuin 将为你生成一个密钥。它被存储在 Atuin 的数据目录里( Linux 上为 `~/.local/share/atuin`) 30 - 31 - 你也可以通过以下方式获得它 32 - 33 - ``` 34 - atuin key 35 - ``` 36 - 37 - 千万不要跟任何人分享这个! 38 - 39 - ## 登录 40 - 41 - 如果你想登录到一个新的机器上,你需要你的加密密钥(`atuin key`)。 42 - 43 - ``` 44 - atuin login -u <USERNAME> -p <PASSWORD> -k <KEY> 45 - ``` 46 - 47 - ## 登出 48 - 49 - ``` 50 - atuin logout 51 - ```
-1
docs/.gitignore
··· 1 - site/
-97
docs/docs/ai/command-output.md
··· 1 - # Reading Command Output 2 - 3 - Atuin AI can read the output of commands you've run. Ask "why did that fail?" and it can look at the actual error message, rather than guessing from the command alone. 4 - 5 - Atuin doesn't capture output by default — it needs two pieces set up: the [daemon](../reference/daemon.md), which stores recent output in memory, and [pty-proxy](../reference/pty-proxy.md), which captures it from your terminal. 6 - 7 - ## Setup 8 - 9 - ### 1. Enable the daemon 10 - 11 - Add the following to your Atuin config file (`~/.config/atuin/config.toml` by default): 12 - 13 - ```toml 14 - [daemon] 15 - enabled = true 16 - autostart = true 17 - ``` 18 - 19 - With `autostart = true`, Atuin starts and manages the daemon for you. If you'd rather run it yourself (for example via systemd), see the [daemon documentation](../reference/daemon.md). 20 - 21 - ### 2. Enable pty-proxy 22 - 23 - Add the pty-proxy init line to your shell's init script, as high in the file as possible, _before_ your normal `atuin init` call: 24 - 25 - === "zsh" 26 - 27 - ```shell 28 - eval "$(atuin pty-proxy init zsh)" 29 - ``` 30 - 31 - === "bash" 32 - 33 - ```shell 34 - eval "$(atuin pty-proxy init bash)" 35 - ``` 36 - 37 - === "fish" 38 - 39 - Add 40 - 41 - ```shell 42 - atuin pty-proxy init fish | source 43 - ``` 44 - 45 - to your `is-interactive` block in your `~/.config/fish/config.fish` file 46 - 47 - === "Nushell" 48 - 49 - Run in *Nushell*: 50 - 51 - ```shell 52 - mkdir ~/.local/share/atuin/ 53 - atuin pty-proxy init nu | save -f ~/.local/share/atuin/pty-proxy-init.nu 54 - ``` 55 - 56 - Add to `config.nu`, **before** the regular `atuin init`: 57 - 58 - ```shell 59 - source ~/.local/share/atuin/pty-proxy-init.nu 60 - ``` 61 - 62 - See the [pty-proxy documentation](../reference/pty-proxy.md) for more detail, including what to do if `atuin` is not on your `PATH` when your shell starts. 63 - 64 - ### 3. Restart your shell 65 - 66 - Open a new terminal (or re-source your shell config). From now on, the output of every command you run in that session is captured and available to the AI. 67 - 68 - To try it out, run a command that fails, then press `?` and ask Atuin AI why it failed. It will ask permission to use the `AtuinOutput` tool, then read the output and answer. 69 - 70 - ## How it works 71 - 72 - pty-proxy sits between your terminal and your shell, and uses your shell's prompt markers to work out where each command's output starts and ends. Each captured command is sent to the daemon, which keeps it in memory alongside its Atuin history ID. When Atuin AI wants to see what a command printed, it asks the daemon for the output by history ID. 73 - 74 - ## Privacy and retention 75 - 76 - Captured output is stored in memory, on your machine: 77 - 78 - - The daemon keeps up to 1MB of output per command, and the most recent 128 commands (up to 32MB of output) per shell session. 79 - - Output is lost when the daemon stops. Only commands captured while the daemon was running are available. 80 - 81 - Nothing is sent to the LLM until it requests the output of a specific command, and by default Atuin AI asks your permission first. 82 - 83 - ## Permissions 84 - 85 - Output retrieval is controlled by the `AtuinOutput` permission rule — see [Tools & Permissions](./tools-permissions.md). To let Atuin AI read command output without asking every time: 86 - 87 - ```toml 88 - [permissions] 89 - 90 - allow = ["AtuinOutput"] 91 - ``` 92 - 93 - To turn the capability off entirely, set `ai.capabilities.enable_history_output` to `false` in your Atuin config (see the [settings documentation](./settings.md#capabilities)). 94 - 95 - ## Reading output from other AI tools 96 - 97 - Captured output isn't limited to Atuin AI: external tools like Claude Code and Cursor can read it too, via Atuin's [MCP server](./mcp.md).
docs/docs/ai/images/basic-followup-questions.png

This is a binary file and will not be displayed.

docs/docs/ai/images/basic-refine.png

This is a binary file and will not be displayed.

docs/docs/ai/images/basic.png

This is a binary file and will not be displayed.

docs/docs/ai/images/danger.png

This is a binary file and will not be displayed.

docs/docs/ai/images/question.png

This is a binary file and will not be displayed.

docs/docs/ai/images/tool_atuin_history.png

This is a binary file and will not be displayed.

docs/docs/ai/images/tool_fs.png

This is a binary file and will not be displayed.

docs/docs/ai/images/tool_shell.png

This is a binary file and will not be displayed.

-53
docs/docs/ai/introduction.md
··· 1 - # Atuin AI 2 - 3 - Atuin AI is a subcommand that enables shell command generation and other information lookup via an LLM directly from your terminal. 4 - 5 - Atuin AI requires an account on [Atuin Hub](https://hub.atuin.sh/), and you'll be prompted to login upon first use of the binary. Alternatively, you can [self-host the Atuin AI backend](./self-hosting.md). 6 - 7 - Usage of Atuin AI is currently free. 8 - 9 - ## Getting Started 10 - 11 - Atuin AI currently supports zsh, bash, and fish shells. Your shell's usual `atuin init` call will automatically bind the question mark key to the Atuin AI UI (only when the prompt is empty). 12 - 13 - !!! note "Disabling Atuin AI" 14 - 15 - You can disable the default question mark key binding by passing `--disable-ai` to your shell's `atuin init` call, or by setting `ai.enabled` to `false` in your Atuin config. 16 - 17 - ## Settings 18 - 19 - For a list of settings that control the behavior of Atuin AI, see [its dedicated settings documentation](./settings.md). 20 - 21 - ## Features 22 - 23 - ### Command generation 24 - 25 - Prompt the LLM to create a command, and get one back, no fuss. Press `enter` to run, or `tab` to insert. 26 - 27 - [![Basic Atuin AI usage](./images/basic.png)](./images/basic.png) 28 - 29 - ### Follow-up 30 - 31 - You can follow-up with another prompt to update the command that will be inserted. 32 - 33 - [![Basic Atuin AI refinement usage](./images/basic-refine.png)](./images/basic-refine.png) 34 - 35 - You can also follow-up with questions to get responses in natural language. 36 - 37 - [![Basic Atuin AI refinement informational usage](./images/basic-followup-questions.png)](./images/basic-followup-questions.png) 38 - 39 - You can still use `enter` or `tab` to run or insert the last suggested command, even if it was suggested in a previous turn. 40 - 41 - ### Conversational and search usage 42 - 43 - If you prompt the LLM with a question that doesn't imply you want to generate a command, it can respond in natural language, and use web search if necessary to fetch the data it needs. 44 - 45 - [![Ask it a question](./images/question.png)](./images/question.png) 46 - 47 - ### Dangerous or low-confidence command detection 48 - 49 - The LLM scores its confidence in the command, as well as how dangerous the command is. This information is shown if a threshold is exceeded, and requires an extra confirmation step before running automatically with `enter`. 50 - 51 - The Atuin Hub server also monitors suggested commands for dangerous patterns the LLM didn't catch, and appends its own assessment at the end of the LLM's own assessment. 52 - 53 - [![Potentially dangerous commands are marked](./images/danger.png)](./images/danger.png)
-60
docs/docs/ai/mcp.md
··· 1 - # MCP Server 2 - 3 - Atuin ships with a built-in [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server, giving external AI tools like Claude Code and Cursor access to your shell history. Your agent can look up commands you've run before, check whether they succeeded, and — with [output capture](./command-output.md) set up — read what they printed. 4 - 5 - The server exposes the same history tools that [Atuin AI](./introduction.md) uses. Both tools are read-only: nothing can modify or delete your history, and all data stays on your machine. 6 - 7 - ## Starting the server 8 - 9 - The MCP server runs over stdio, so your MCP client starts it for you — there's nothing to keep running in the background. The command is simply: 10 - 11 - ```shell 12 - atuin mcp 13 - ``` 14 - 15 - ### Claude Code 16 - 17 - ```shell 18 - claude mcp add atuin -- atuin mcp 19 - ``` 20 - 21 - ### Cursor, Claude Desktop, and other clients 22 - 23 - Most MCP clients accept a JSON configuration like this: 24 - 25 - ```json 26 - { 27 - "mcpServers": { 28 - "atuin": { 29 - "command": "atuin", 30 - "args": ["mcp"] 31 - } 32 - } 33 - } 34 - ``` 35 - 36 - If the `atuin` binary is not on your client's `PATH`, use the full path to the binary instead (e.g. `~/.atuin/bin/atuin`). 37 - 38 - ## Tools 39 - 40 - ### `atuin_history` 41 - 42 - Searches your shell history, using the same fuzzy matching as the search TUI. Each result includes the command, when and where it ran, its exit code, and its duration, along with a history ID that can be passed to `atuin_output`. 43 - 44 - Searches can be narrowed down in a few ways: 45 - 46 - - **Filter mode**: the same scopes as [interactive search](../guide/advanced-usage.md) — `global`, `host`, `directory`, `workspace`, or `session`. The `directory` and `workspace` scopes are relative to the directory the server was launched in, which for most editors is your project directory. 47 - - **Failed commands only**: return only commands that exited with a non-zero exit code. 48 - - **Author**: filter to commands you ran yourself, commands run by AI agents, or commands run by one specific agent. See [AI Agent Hooks](../guide/agent-hooks.md) for how agent-run commands are recorded. 49 - 50 - History search reads the Atuin database directly, so it works without any extra setup. 51 - 52 - ### `atuin_output` 53 - 54 - Fetches the captured terminal output of a previous command, identified by a history ID from `atuin_history` results. The agent can fetch specific line ranges, so it doesn't need to read a huge log to find the error at the end. 55 - 56 - Output capture requires the [daemon](../reference/daemon.md) and [pty-proxy](../reference/pty-proxy.md) to be running — see [Reading Command Output](./command-output.md) for setup. Without them, the tool responds with an error explaining that no output is available. 57 - 58 - !!! note "Session scope" 59 - 60 - The `session` filter mode only works when the MCP server is launched from inside an Atuin-enabled shell session. Clients like editors usually launch it outside of one, in which case the other filter modes still work as normal.
-71
docs/docs/ai/self-hosting.md
··· 1 - # Self-Hosting the Atuin AI Backend 2 - 3 - The core of Atuin AI's backend is open source, available [at atuinsh/atuin-ai-server](https://github.com/atuinsh/atuin-ai-server). It's based on [atuin-ai-core](https://github.com/atuinsh/atuin-ai-core), the same Gleam library that powers the production Atuin AI backend. 4 - 5 - The Atuin AI server currently supports any **OpenAI-compatible, chat completions-style endpoint**. For local models, this includes Ollama, vLLM, LM Studio, llama.cpp, and LiteLLM, among others. You can also use OpenAI-compatible web services, like OpenRouter. 6 - 7 - ## Getting Started 8 - 9 - After cloning the repository, copy the example config file, `config.example.toml`, to `config.toml`. Follow the configuration section of the readme to set up your instance. 10 - 11 - Here's a very basic example of an Ollama-based setup: 12 - 13 - ```toml 14 - port = 8080 15 - endpoint = "http://localhost:11434/v1" # or host.docker.internal 16 - api_key = "ollama" 17 - 18 - default_model = "llama31" 19 - 20 - [request.body] 21 - stream_options = { include_usage = true } 22 - 23 - [[models]] 24 - alias = "llama31" 25 - name = "Llama 3.1 70b" 26 - description = "Ollama Llama 3.1 70b" 27 - model = "llama3.1:70b" 28 - 29 - [[models]] 30 - alias = "gemma4" 31 - name = "Gemma 4 r4b" 32 - description = "Ollama Gemma 4 - Effective 4b" 33 - model = "gemma4:e4b" 34 - ``` 35 - 36 - See the [repository readme](https://github.com/atuinsh/atuin-ai-server#readme) for more setup details, including configuring server-side tools, like web search and web content scraping. 37 - 38 - Once done, you can start the server one of two ways: 39 - 40 - ## Running from Source 41 - 42 - If you have Erlang, Elixir, and Gleam installed (see `.tool-versions` for required versions), you can run the server natively: 43 - 44 - ```bash 45 - mix deps.get 46 - mix run --no-halt 47 - ``` 48 - 49 - If your `config.toml` specifies API keys via environment variables, remember to set them when you start the server. 50 - 51 - ## Running with Docker 52 - 53 - To run the server with docker, run the following: 54 - 55 - ```bash 56 - docker run \ 57 - -v ./config.toml:/etc/atuin-ai/config.toml \ 58 - -p 8080:8080 \ 59 - ghcr.io/atuinsh/atuin-ai-server:latest 60 - ``` 61 - 62 - If you're running via Docker and want the Atuin AI server to connect with a local LLM service running on the host, like Ollama, use `host.docker.internal` as the endpoint instead of `localhost` (which would resolve to the container's own loopback interface). 63 - 64 - ## Configuring Atuin AI 65 - 66 - Once your server is running, you can configure Atuin AI to connect to it by setting the endpoint config: 67 - 68 - ```toml 69 - [ai] 70 - endpoint = "http://localhost:8080" 71 - ```
-124
docs/docs/ai/settings.md
··· 1 - # AI Settings 2 - 3 - All the settings that control the behavior of [Atuin AI](./introduction.md) are specified in an `[ai]` section in your `config.toml`. See [the configuration documentation](../configuration/config.md) for more detailed information about Atuin's configuration system. 4 - 5 - ### enabled 6 - 7 - Default: `false` 8 - 9 - Whether or not the AI feature are enabled. When set to `false`, the question mark keybinding will output a message with instructions to run `atuin setup` to enable the feature. 10 - 11 - ### model 12 - 13 - Default: unset 14 - 15 - The Atuin AI model to use for new sessions. If unset, the default model will be used. You can see the available models by running `/model` inside the Atuin AI interface. 16 - 17 - ### db_path 18 - 19 - Default: `ai_sessions.db` in the Atuin data directory. 20 - 21 - The path to the SQLite database where Atuin AI sessions are stored. 22 - 23 - ### session_continue_minutes 24 - 25 - Default: `60` (minutes) 26 - 27 - The amount of time after the last interaction with Atuin AI that a session is considered "recent" and can be automatically continued. If you interact with Atuin AI and then invoke it again within this time window, the second interaction will be part of the same session. If you wait longer than this time window, a new session will be started. You can always start a new session manually by using the `/new` slash command in the Atuin AI interface. 28 - 29 - ### endpoint 30 - 31 - Default: `null` 32 - 33 - The address of the Atuin AI endpoint. Used for AI features like command generation. Most users will not need this setting; it is only necessary for custom AI endpoints. 34 - 35 - ### api_token 36 - 37 - Default: `null` 38 - 39 - The API token for the Atuin AI endpoint. Used for AI features like command generation. Most users will not need this setting; it is only necessary for custom AI endpoints. 40 - 41 - ### endpoint_protocol 42 - 43 - Default: `"auto"` 44 - 45 - How the client talks to the configured `endpoint`. One of: 46 - 47 - - `"auto"` — infer from `endpoint`: official Atuin addresses use the Hub protocol, anything else is treated as an OSS server. 48 - - `"hub"` — treat the endpoint as an Atuin Hub instance: log in via the browser-based Hub flow and report credit usage. Mostly useful for developing against a local Hub instance. 49 - - `"oss"` — treat the endpoint as a standalone AI server, such as [atuin-ai-server](https://github.com/atuinsh/atuin-ai-server). No login flow; requests are authenticated with `api_token` if set. 50 - 51 - With the default of `"auto"`, pointing `endpoint` at your own server just works: set `api_token` if your server requires one. 52 - 53 - ### yolo 54 - 55 - Default: `false` 56 - 57 - Enables YOLO mode, which automatically allows all permission checks. **Use this setting with caution.** 58 - 59 - This setting does _not_ enable any capabilities; it simply bypasses any permission checks. 60 - 61 - ## Capabilities 62 - 63 - Settings that control what capabilities are sent to the LLM, which the LLM uses to understand what features the client has available. These are specified under `[ai.capabilities]`. 64 - 65 - ### enable_history_search 66 - 67 - Default: `true` 68 - 69 - Whether or not to include the "history search" capability in the context sent to the LLM. This allows the AI to request to search your Atuin history for relevant commands when generating suggestions or answering questions. 70 - 71 - ### enable_history_output 72 - 73 - Default: `true` 74 - 75 - Whether or not to include the "history output" capability in the context sent to the LLM. This allows the AI to request to view the output of previous commands. This requires the [pty-proxy](../reference/pty-proxy.md) and [daemon](../reference/daemon.md) to be enabled and running in order for Atuin to capture commands' outputs — see [Reading Command Output](./command-output.md) for setup. 76 - 77 - ### enable_file_tools 78 - 79 - Default: `true` 80 - 81 - Whether or not to include the "file tools" capability in the context sent to the LLM. This allows the AI to request to read and update files on your system. 82 - 83 - ### enable_command_execution 84 - 85 - Default: `true` 86 - 87 - Whether or not to include the "command execution" capability in the context sent to the LLM. This allows the AI to request to execute commands on your system. 88 - 89 - **Example config** 90 - 91 - ```toml 92 - [ai.capabilities] 93 - enable_history_search = false 94 - ``` 95 - 96 - ## Opening context 97 - 98 - Settings that control what context is sent in the opening AI request. These are specified under `[ai.opening]`. 99 - 100 - ### send_cwd 101 - 102 - Default: `false` 103 - 104 - Whether or not to include your current working directory in the context sent to the LLM. By default, only your OS and current shell are sent. 105 - 106 - **Example config** 107 - 108 - ```toml 109 - [ai.opening] 110 - send_cwd = true 111 - ``` 112 - 113 - ### send_last_command 114 - 115 - Default: `false` 116 - 117 - Whether or not to send your previous command as context in the initial request, allowing the AI to provide more relevant suggestions. 118 - 119 - **Example config** 120 - 121 - ```toml 122 - [ai.opening] 123 - send_last_command = true 124 - ```
-97
docs/docs/ai/skills.md
··· 1 - # Skills 2 - 3 - Skills are reusable instruction sets for Atuin AI: playbooks, conventions, workflows, or any structured guidance you want the LLM to follow for specific tasks. 4 - 5 - ## How Skills Work 6 - 7 - Skills are lazily loaded: Atuin sends only skill names and descriptions to the server. The LLM decides which skills are relevant and loads their full content on demand. You can also invoke skills directly with `/skill-name` in the TUI. 8 - 9 - ## Creating a Skill 10 - 11 - A skill is a directory containing a `SKILL.md` file with optional YAML frontmatter: 12 - 13 - ``` 14 - .atuin/skills/code-review/SKILL.md 15 - ``` 16 - 17 - ```markdown 18 - --- 19 - name: code-review 20 - description: Conducts a structured code review. Use when the user asks to review code, a PR, or a diff. 21 - --- 22 - 23 - When reviewing code: 24 - 25 - 1. **Correctness** — Does the code do what it claims? 26 - 2. **Edge cases** — What inputs could break it? 27 - 3. **Style** — Does it match the project's conventions? 28 - 29 - Current branch: !`git branch --show-current` 30 - ``` 31 - 32 - ## Skill Locations 33 - 34 - | Scope | Path | 35 - | ------- | ---------------------------------------- | 36 - | Project | `.atuin/skills/<name>/SKILL.md` | 37 - | Global | `~/.config/atuin/skills/<name>/SKILL.md` | 38 - 39 - Project skills override global skills when names collide. Nested directories are supported for organization (e.g. `.atuin/skills/ops/deploy/SKILL.md`). 40 - 41 - ## Frontmatter 42 - 43 - All frontmatter fields are optional. YAML frontmatter goes between `---` markers at the top of `SKILL.md`. 44 - 45 - | Field | Default | Description | 46 - | -------------------------- | ----------------------- | -------------------------------------------------------------------------------------------- | 47 - | `name` | directory name | Display name. Lowercase letters, numbers, hyphens. | 48 - | `description` | first paragraph of body | What the skill does. Sent to the server so the LLM knows when to load it. | 49 - | `disable-model-invocation` | `false` | If `true`, the LLM cannot discover or load the skill. Only reachable via `/name` in the TUI. | 50 - 51 - Multiline descriptions using YAML's `>` (folded) or `|` (literal) syntax are supported. 52 - 53 - ## Invoking Skills 54 - 55 - ### From the TUI 56 - 57 - Type `/skill-name` to invoke a skill directly. Tab-completion is available. Arguments are supported: 58 - 59 - ``` 60 - /deploy patch 61 - ``` 62 - 63 - The LLM will see the skill content with `[Loaded skill: deploy]` and `[Arguments: patch]` headers. 64 - 65 - ### By the LLM 66 - 67 - When the LLM determines a skill is relevant to your request, it calls `load_skill` automatically to fetch the full content. Skills with `disable-model-invocation: true` are excluded from this — the LLM won't see them. 68 - 69 - ## Dynamic Content 70 - 71 - Skills support the same shell substitution as [user context files](user-context.md): 72 - 73 - - **Inline:** `!`command`` — replaced with command stdout 74 - - **Block:** ` ```! ` code block — entire block replaced with script stdout 75 - 76 - Commands run at skill load time (when invoked), not at discovery time. 77 - 78 - ## Arguments 79 - 80 - When invoking a skill with arguments (e.g. `/deploy patch`), the `$ARGUMENTS` placeholder in the skill body is replaced with the argument string before shell substitution runs: 81 - 82 - ```yaml 83 - --- 84 - name: deploy 85 - description: Deploy the application 86 - disable-model-invocation: true 87 - --- 88 - 89 - Deploy $ARGUMENTS to production. 90 - Current status: !`kubectl get deployment $ARGUMENTS` 91 - ``` 92 - 93 - If the body doesn't contain `$ARGUMENTS` and arguments were provided, they're appended as `ARGUMENTS: <value>`. 94 - 95 - ## Description Budget 96 - 97 - Skill descriptions are packed into the request to the server under a total character budget. Each description is truncated at 512 characters, then skills are included until the budget is exhausted. If skills are omitted, the server is told which ones were left out.
-14
docs/docs/ai/slash-commands.md
··· 1 - # Atuin AI Slash Commands 2 - 3 - Atuin AI includes a number of slash commands to facilitate controlling various aspects of Atuin AI's behavior. To access them, simply type `/` in the Atuin AI prompt, and a list of all available slash commands will appear. You can continue typing to filter the list of commands, and press `tab` to expand the selected command. 4 - 5 - ## Built-in Slash Commands 6 - 7 - - **`/help`** - Show a list of all available slash commands, along with a brief description of each, and a link to this documentation. 8 - - **`/new`** - Start a new session. This will clear the current session's context and history and start fresh. 9 - - **`/reload`** - Reloads cached `TERMINAL.md` files on the next request - run this when you change a `TERMINAL.md` file mid-session to ensure the LLM has the latest context. 10 - - **`/model`** - Select a different model for the current session. This will override the default model specified in your Atuin config. You can see a list of available models by running this command. 11 - 12 - ## Slash Commands from Skills 13 - 14 - Any [user-defined skills](./skills.md) with a name will register that name as a slash command, with the skill's description as the slash command description (shown in `/help` and in the slash command fuzzy picker). For example, if you have a skill named `my-skill`, you can invoke it by typing `/my-skill` in the Atuin AI prompt. If the skill has any parameters, you can provide them after the skill name, separated by spaces.
-177
docs/docs/ai/tools-permissions.md
··· 1 - # Atuin AI Tools & Permissions 2 - 3 - Atuin AI has a number of tools that it can use to interact with your system, given your permission. The AI can use these tools to help answer questions and perform actions on your behalf. 4 - 5 - ## Permission System 6 - 7 - By default, Atuin AI asks your permission before using any client-side tool. You can change these defaults using a _permission file_. 8 - 9 - ### Permission Files 10 - 11 - Permission files live at `.atuin/permissions.ai.toml` in any project. When the AI wants to run a tool, Atuin AI will check its working directory for a `.atuin/permissions.ai.toml` file, and will also check every permission file in parent directories, up to the root of the filesystem. Finally, Atuin AI checks for a `permissions.ai.toml` file in the Atuin config directory (`~/.config/atuin/permissions.ai.toml` by default). 12 - 13 - A permission file is a TOML file with the following format: 14 - 15 - ```toml 16 - [permissions] 17 - 18 - allow = [ 19 - # rules for automatically allowed tools 20 - ] 21 - 22 - deny = [ 23 - # rules for automatically denied tools 24 - ] 25 - 26 - ask = [ 27 - # rules for tools that require asking for permission 28 - ] 29 - ``` 30 - 31 - If Atuin AI doesn't find a matching rule, it defaults to asking for permission before running the tool. 32 - 33 - Permission files found deeper in the filesystem take priority over permission files found higher up. For example, if Atuin AI finds a permission file in the current working directory that allows a tool, it will allow that tool, even if a parent directory has a permission file that denies it. 34 - 35 - Within a permissions file, `ask` rules take priority over `deny` rules, which take priority over `allow` rules. For example, if a permission file has a rule that allows a tool, but also has a rule that asks for permission for that tool, Atuin AI will ask for permission before running the tool. 36 - 37 - ### Permission Scopes 38 - 39 - Most rules can be scoped to a particular path or other context. For example, you can allow Atuin AI to read files in a particular directory, but not in others. For rules pertaining to file operations, the scope is a glob pattern that matches file paths. 40 - 41 - ### Example Config 42 - 43 - Here's an example of a permission file that allows Atuin AI to read and write any markdown files in the current project (because Write implies Read — see below), but denies it access to any `.env` files. Attempts to read or write any _other_ files will result in Atuin AI requesting permission before proceeding. 44 - 45 - ```toml 46 - [permissions] 47 - 48 - allow = [ 49 - "Write(**/*.md)" 50 - ] 51 - 52 - deny = [ 53 - "Read(.env)" 54 - ] 55 - ``` 56 - 57 - ## Tools 58 - 59 - ### Atuin History 60 - 61 - The `AtuinHistory` tool allows Atuin AI to search your Atuin history for relevant commands. This tool is read-only. Atuin AI might ask to use this tool when you ask it to recall a command or information about a command you ran in the past, or when you ask for help with a failing command (e.g. "why did my last command fail?"). 62 - 63 - ![Example of Atuin History tool](../images/tool_atuin_history.png) 64 - 65 - **Permission rule and scope:** `AtuinHistory` 66 - 67 - **Config value:** `ai.capabilities.enable_history_search` (see [settings documentation](./settings.md#capabilities)) 68 - 69 - **Example permissions file:** 70 - 71 - ```toml 72 - [permissions] 73 - 74 - allow = ["AtuinHistory"] 75 - ``` 76 - 77 - ### Atuin Output 78 - 79 - The `AtuinOutput` tool allows Atuin AI to read the captured output of commands in your Atuin history. This tool is read-only. Atuin AI might ask to use this tool when you ask about the result of a command you ran, or for help with a failing command. Output capture requires the daemon and pty-proxy to be set up — see [Reading Command Output](./command-output.md). 80 - 81 - **Permission rule and scope:** `AtuinOutput` 82 - 83 - **Config value:** `ai.capabilities.enable_history_output` (see [settings documentation](./settings.md#capabilities)) 84 - 85 - **Example permissions file:** 86 - 87 - ```toml 88 - [permissions] 89 - 90 - allow = ["AtuinOutput"] 91 - ``` 92 - 93 - ### Read 94 - 95 - The `Read` tool allows Atuin AI to read files on your system. Atuin AI might ask to use this tool when you ask it to analyze the contents of a file, when you ask for edits to the contents of a file, or when you ask a question that is most easily answered by consulting the contents of a file. 96 - 97 - ![Example of Atuin FS Tools](../images/tool_fs.png) 98 - 99 - **Permission rule and scope:** `Read(<glob_pattern>)` (e.g. `Read(**/\*.md)`to allow reading all markdown files in the current directory and subdirectories). A missing glob pattern (e.g.`Read`) matches all files. 100 - 101 - **Config value:** `ai.capabilities.enable_fs_tools` (see [settings documentation](./settings.md#capabilities)) — this setting enables both the `Read` and `Write` tools. 102 - 103 - **Example permissions file:** 104 - 105 - ```toml 106 - [permissions] 107 - allow = ["Read(**/*.md)"] 108 - deny = ["Read(.secret/**)"] 109 - ``` 110 - 111 - !!! warning "Write Implies Read" 112 - 113 - To prevent accidental data loss, Atuin AI is required to read the contents of a file before writing to it. This means that any permission rule that allows the `Write` tool for a particular file or set of files will also automatically allow the `Read` tool for those same files. For example, if you have a rule that allows `Write(**/*.md)`, Atuin AI will also be able to read any markdown files in the current directory and subdirectories, even if you don't have an explicit rule allowing `Read(**/*.md)`. 114 - 115 - ### Write 116 - 117 - The `Write` tool allows Atuin AI to create and edit files on your system. Atuin AI might ask to use this tool when you ask it to update configuration for a tool or help debug a problem. 118 - 119 - ![Example of Atuin FS Tools](../images/tool_fs.png) 120 - 121 - **Permission rule and scope:** `Write(<glob_pattern>)` (e.g. `Write(**/\*.md)`to allow reading all markdown files in the current directory and subdirectories). A missing glob pattern (e.g.`Write`) matches all files. 122 - 123 - **Config value:** `ai.capabilities.enable_fs_tools` (see [settings documentation](./settings.md#capabilities)) — this setting enables both the `Read` and `Write` tools. 124 - 125 - **Example permissions file:** 126 - 127 - ```toml 128 - [permissions] 129 - allow = ["Write(**/*.md)"] 130 - deny = ["Write(.secret/**)"] 131 - ``` 132 - 133 - !!! note "File Backups" 134 - 135 - The first time Atuin AI writes to a file in a session, it creates a backup of the original file and stores it in Atuin's data directory, under `ai/sessions/<session_id>`. A manifest file in that directory maps the original file paths to the backup file paths. In the future, we'll be providing easier ways to recover from accidental data loss. 136 - 137 - ### Shell Command Execution 138 - 139 - The `Shell` tool allows Atuin AI to execute shell commands on your system. Atuin AI might ask to use this tool when you ask it to perform an action that is most easily accomplished by running a shell command itself, or when you ask for help debugging a failing command, or during a multi-step workflow. 140 - 141 - ![Example of Atuin Shell Tool](../images/tool_shell.png) 142 - 143 - **Permission rule and scope:** `Shell(<command pattern>)` (e.g. `Shell(git *)` to allow any command that starts with `git`). A missing command pattern (e.g. `Shell`) matches all commands. 144 - 145 - **Config value:** `ai.capabilities.enable_command_execution` (see [settings documentation](./settings.md#capabilities)) 146 - 147 - **Example permissions file:** 148 - 149 - ```toml 150 - [permissions] 151 - allow = [ 152 - "Shell(git add *)", 153 - "Shell(git commit *)" 154 - ] 155 - ``` 156 - 157 - !!! note "Command Execution Scope" 158 - 159 - The command pattern in a `Shell` permission rule is matched against the words in the command. The `*` wildcard has different behavior depending on where it appears: 160 - 161 - | Pattern | Matches | Does Not Match | 162 - |---------|---------|----------------| 163 - | `*` | Any command | — | 164 - | `git commit *` | `git commit`, `git commit -m "msg"` | `git`, `git push` | 165 - | `ls*` | `ls`, `ls -a`, `lsof` | `cat` | 166 - | `git * --amend` | `git commit --amend`, `git rebase --amend` | `git commit` | 167 - | `git commit` | `git commit` | `git`, `git push`, `git commit -m "msg"` | 168 - 169 - Note the difference between `ls *` (with a space) and `ls*` (without). The space-separated form uses **word-boundary** matching — `ls *` matches `ls` and `ls -a` but _not_ `lsof`. The attached form uses **prefix** matching — `ls*` matches all of those, including `lsof`. 170 - 171 - For `allow` and `ask` rules, a pattern without any wildcard (e.g. `git commit`) is an **exact match** — it only matches when the command words are identical. Use `git commit *` if you want to allow `git commit` with any arguments. 172 - 173 - For `deny` rules, a pattern without any wildcard (e.g. `rm`) is a **prefix match** — it matches any command that starts with that prefix. This means that a `deny` rule of `rm` would deny `rm`, `rm -rf /`, and `rm ./README.md` so be careful when writing `deny` rules without explicit wildcards. 174 - 175 - !!! warning "Compound Commands" 176 - 177 - When the AI runs a compound command (e.g. `git add . && npm test`), Atuin parses it into individual subcommands. For a command to be automatically allowed, all subcommands must be allowed. This means that `git add . && npm test` must be enabled by both `Shell(git add *)` and `Shell(npm test)` for it to be allowed, else it would fall through and ask for permission. However, our parsing is not perfect, and there may be edge cases where it fails to correctly identify the subcommands, and some shells where command parsing is sub-par. For this reason, we recommend being cautious when allowing compound commands with broad patterns.
-48
docs/docs/ai/user-context.md
··· 1 - # Sending Additional Context in Atuin AI 2 - 3 - Atuin AI allows you to send additional context to the LLM beyond just your prompt, similar to `CLAUDE.md` or `AGENTS.md`. 4 - 5 - ## Additional Context Search Paths 6 - 7 - Atuin AI looks for additional context in `TERMINAL.md` and `.atuin/TERMINAL.md` files in the current directory and its parent directories. It also checks `TERMINAL.md` in your Atuin config directory (`~/.config/atuin/TERMINAL.md` by default). If it finds any of these files, it sends their contents as additional context to the LLM. 8 - 9 - - `.atuin/TERMINAL.md` — scoped inside the `.atuin` dotdir 10 - - `TERMINAL.md` — at the directory root (e.g. project root) 11 - 12 - It also checks `TERMINAL.md` in your Atuin config directory (`~/.config/atuin/TERMINAL.md` by default). 13 - 14 - If it finds any of these files, it sends their contents as additional context to the LLM. Atuin AI will send at maximum 10 additional context files, prioritizing files found globally first and then other files in order of filesystem depth, shallowest to deepest, and each file is limited to 10,000 characters. 15 - 16 - ## Dynamic Content 17 - 18 - You can send dynamic content by using shell substitution in your `TERMINAL.md` file: 19 - 20 - ```markdown 21 - My username: !`whoami` 22 - ``` 23 - 24 - When Atuin AI reads this file, it will execute the `whoami` command and include its output in the context sent to the LLM. So if your username is `binarymuse`, the context sent to the LLM would include: 25 - 26 - ```markdown 27 - My username: binarymuse 28 - ``` 29 - 30 - Atuin AI can also run substitutions for code blocks, to run multi-line commands. For example: 31 - 32 - ````markdown 33 - ```! 34 - node --version 35 - npm --version 36 - git status --short 37 - ``` 38 - ```` 39 - 40 - ## Caching 41 - 42 - `TERMINAL.md` files are cached after they are first loaded; if you make changes to them mid-session, use the `/reload` slash command to refresh the data. This will invalidate the server cache on the next request, increasing the latency and token usage for that request. 43 - 44 - ## Why not `AGENTS.md`? 45 - 46 - Most agent files are optimized for _coding_ agents: patterns, tools, coding style, and so on. This is great for coding agents, but not as useful for general-purpose agents. By using `TERMINAL.md` instead, we can provide a more flexible way to send additional context that is not tied to coding-specific patterns. This allows users to provide any kind of context they want, without being constrained by the structure of an agent file. 47 - 48 - If your agent file has relevant information, you can instruct the LLM in `TERMINAL.md` to read from it.
-445
docs/docs/configuration/advanced-key-binding.md
··· 1 - # Advanced Atuin UI Keybinding 2 - 3 - Atuin includes a powerful keybinding system that can be used to fully customize the TUI keyboard shortcuts. Many of the configuration options, like `enter_accept`, `exit_past_line_start`, and `accept_past_line_end`, can be explicitly expressed with this new configuration. 4 - 5 - The `[keymap]` section in your config replaces the older `[keys]` section. If any `[keymap]` settings are present, the `[keys]` section is ignored entirely. 6 - 7 - !!! warning 8 - Modifier keys, F1-F24 keys, and some special characters work best - or _only_ work - with a terminal that implements the kitty keyboard protocol. Notably, the default macOS Terminal app does _not_ include this feature. For more information and a list of terminals that are known to support this protocol, see [https://sw.kovidgoyal.net/kitty/keyboard-protocol/](https://sw.kovidgoyal.net/kitty/keyboard-protocol/). 9 - 10 - ## Keymaps 11 - 12 - The Atuin TUI has multiple modes, each with its own keymap. You configure each one under a separate TOML table: 13 - 14 - | Config section | When it is active | 15 - |----------------------|-------------------| 16 - | `[keymap.emacs]` | Search tab, `keymap_mode = "emacs"` | 17 - | `[keymap.vim-normal]`| Search tab, `keymap_mode = "vim"`, normal mode | 18 - | `[keymap.vim-insert]`| Search tab, `keymap_mode = "vim"`, insert mode | 19 - | `[keymap.inspector]` | Inspector tab (opened with `ctrl-o`) | 20 - | `[keymap.prefix]` | After pressing the prefix key (`ctrl-a` by default) | 21 - 22 - Vim-insert mode inherits all emacs bindings by default, then overrides `esc` and `ctrl-[` to enter normal mode instead of exiting. 23 - 24 - You only need to specify the keys you want to change. Unmentioned keys keep their default bindings. 25 - 26 - !!! warning 27 - If you specify a key in your keymap that would normally be changed by an option, like the `enter` key with the `enter_accept` setting, the setting will not take any affect. Those options modify the default keymap based on their setting, but if you override the key in the keymap, you're responsible for managing correct behavior. 28 - 29 - ## Key format 30 - 31 - Keys are specified as TOML string keys using a human-readable format. 32 - 33 - ### Basic keys 34 - 35 - Lowercase letters, digits, and named keys: 36 - 37 - ``` 38 - "a", "z", "1", "9" 39 - "enter", "esc", "tab", "space", "backspace", "delete" 40 - "up", "down", "left", "right" 41 - "home", "end", "pageup", "pagedown" 42 - "f1", "f2", ... "f12", ... "f24" 43 - ``` 44 - 45 - `return` is an alias for `enter`. `escape` is an alias for `esc`. `del` is an alias for `delete`. 46 - 47 - !!! warning "macOS delete key" 48 - The key labeled "delete" on Mac keyboards sends `backspace` (it deletes the character *before* the cursor). The `delete` key in Atuin refers to forward-delete, which is `fn+delete` on a Mac keyboard. 49 - 50 - ### Modifiers 51 - 52 - Modifiers are prefixed with a dash separator. Multiple modifiers can be combined: 53 - 54 - ``` 55 - "ctrl-c", "alt-f", "ctrl-alt-x" 56 - ``` 57 - 58 - Available modifiers: `ctrl`, `alt`, `shift`, `super` (also accepted as `cmd` or `win`). 59 - 60 - !!! warning 61 - The `super` modifier (Cmd on macOS, Win on Windows) **requires** the kitty keyboard protocol. Only terminals that implement this protocol will report the Super modifier to applications. Even in supported terminals, some Super+key combinations may be intercepted by the terminal or OS (e.g. Cmd+C for copy, Cmd+V for paste, or Cmd+T for opening a new tab). 62 - 63 - ### Uppercase letters 64 - 65 - An uppercase letter represents itself without needing a `shift` modifier. For example, `"G"` matches the `shift+g` key press. 66 - 67 - ### Special characters 68 - 69 - Some special characters are written out directly: 70 - 71 - ``` 72 - "?", "/", "[", "]", "$" 73 - ``` 74 - 75 - ### Shifted and punctuation keys 76 - 77 - When you press a key like `Shift+1`, your terminal sends the resulting character (`!`) rather than "shift-1". To bind shifted punctuation keys, use the character directly: 78 - 79 - ```toml 80 - [keymap.emacs] 81 - "!" = "some-action" # Binds to Shift+1 82 - "@" = "some-action" # Binds to Shift+2 83 - "#" = "some-action" # Binds to Shift+3 84 - "$" = "cursor-end" # Binds to Shift+4 (vim $ motion) 85 - ``` 86 - 87 - Any single character can be used as a key binding. 88 - 89 - !!! note 90 - The `shift` modifier is still valid for non-character keys like `"shift-tab"` or `"shift-up"`. 91 - 92 - ### Media keys 93 - 94 - Media keys are supported on terminals that implement the kitty keyboard protocol with `DISAMBIGUATE_ESCAPE_CODES` enabled: 95 - 96 - ``` 97 - "play", "pause", "playpause", "stop" 98 - "fastforward", "rewind", "tracknext", "trackprevious" 99 - "record", "lowervolume", "raisevolume", "mutevolume", "mute" 100 - ``` 101 - 102 - ### Multi-key sequences 103 - 104 - Separate keys with a space to define a sequence. The first key is buffered until the second key arrives: 105 - 106 - ``` 107 - "g g" 108 - ``` 109 - 110 - If the second key does not complete a known sequence, both keys are handled individually. 111 - 112 - ## Keymap format 113 - 114 - Each entry in a keymap section maps a key to either a simple action or a conditional rule list. 115 - 116 - ### Simple binding 117 - 118 - Maps a key directly to a single action, with no conditions: 119 - 120 - ```toml 121 - [keymap.emacs] 122 - "ctrl-c" = "return-original" 123 - "enter" = "accept" 124 - ``` 125 - 126 - ### Conditional binding 127 - 128 - Maps a key to an ordered list of rules. Each rule has an `action` and an optional `when` condition. Rules are evaluated top-to-bottom; the first rule whose condition matches (or that has no condition) wins. 129 - 130 - ```toml 131 - [keymap.emacs] 132 - "left" = [ 133 - { when = "cursor-at-start", action = "exit" }, 134 - { action = "cursor-left" }, 135 - ] 136 - ``` 137 - 138 - In this example, pressing left when the cursor is at position 0 exits the TUI. Otherwise, it moves the cursor left. 139 - 140 - A rule without a `when` field is unconditional and always matches. It is typically placed last as a fallback. 141 - 142 - !!! warning "Override semantics" 143 - When you specify a key in `[keymap]`, it **replaces** the **entire** default binding for that key. Other keys you don't mention keep their defaults. 144 - 145 - ## Actions 146 - 147 - Actions are specified as kebab-case strings. 148 - 149 - ### Cursor movement 150 - 151 - | Action | Description | 152 - |--------|-------------| 153 - | `cursor-left` | Move cursor one character left | 154 - | `cursor-right` | Move cursor one character right | 155 - | `cursor-word-left` | Move cursor one word left | 156 - | `cursor-word-right` | Move cursor one word right | 157 - | `cursor-word-end` | Move cursor to end of current/next word (vim `e` motion) | 158 - | `cursor-start` | Move cursor to start of line | 159 - | `cursor-end` | Move cursor to end of line | 160 - 161 - ### Editing 162 - 163 - | Action | Description | 164 - |--------|-------------| 165 - | `delete-char-before` | Delete the character before the cursor (backspace) | 166 - | `delete-char-after` | Delete the character after the cursor (delete) | 167 - | `delete-word-before` | Delete the word before the cursor | 168 - | `delete-word-after` | Delete the word after the cursor | 169 - | `delete-to-word-boundary` | Delete to the next word boundary (like `ctrl-w`) | 170 - | `clear-line` | Clear the entire input line | 171 - | `clear-to-start` | Clear the start of input line | 172 - | `clear-to-end` | Clear the end of input line | 173 - 174 - ### List navigation 175 - 176 - | Action | Description | 177 - |--------|-------------| 178 - | `select-next` | Move selection to the next item in the results list | 179 - | `select-previous` | Move selection to the previous item in the results list | 180 - | `scroll-half-page-up` | Scroll half a page up | 181 - | `scroll-half-page-down` | Scroll half a page down | 182 - | `scroll-page-up` | Scroll a full page up | 183 - | `scroll-page-down` | Scroll a full page down | 184 - | `scroll-to-top` | Jump to the top of the list | 185 - | `scroll-to-bottom` | Jump to the bottom of the list | 186 - | `scroll-to-screen-top` | Jump to the top of the visible screen | 187 - | `scroll-to-screen-middle` | Jump to the middle of the visible screen | 188 - | `scroll-to-screen-bottom` | Jump to the bottom of the visible screen | 189 - 190 - Note: `select-next` and `select-previous` respect the `invert` setting. When `invert` is true, the visual direction is flipped. 191 - 192 - ### Commands 193 - 194 - | Action | Description | 195 - |--------|-------------| 196 - | `accept` | Accept the selected entry and **execute it immediately** | 197 - | `accept-N` | Accept the Nth entry below the selection and execute it (e.g. `accept-1` through `accept-9`) | 198 - | `return-selection` | Return the selected entry to the command line **without executing** | 199 - | `return-selection-N` | Return the Nth entry below the selection without executing (e.g. `return-selection-1` through `return-selection-9`) | 200 - | `return-original` | Close the TUI and return the original command line text | 201 - | `return-query` | Close the TUI and return the current search query | 202 - | `copy` | Copy the selected entry to the clipboard | 203 - | `delete` | Delete the selected entry from history | 204 - | `delete-all` | Delete **all** history entries matching the selected command text | 205 - | `exit` | Exit the TUI (behavior depends on the `exit_mode` setting) | 206 - | `redraw` | Redraw the screen | 207 - | `cycle-filter-mode` | Cycle through filter modes (global, host, session, directory) | 208 - | `cycle-search-mode` | Cycle through search modes (fuzzy, prefix, fulltext, skim) | 209 - | `toggle-tab` | Toggle between the search tab and inspector tab | 210 - | `switch-context` | Switch to the [context](../guide/advanced-usage.md#context-switch) of the currently selected command | 211 - | `clear-context` | Return to the initial [context](../guide/advanced-usage.md#context-switch) | 212 - 213 - The difference between `accept` and `return-selection`: `accept` runs the command immediately when the TUI closes, while `return-selection` places it on your command line for further editing before you press enter. The `enter_accept` setting controls which of these the default `enter` key uses. 214 - 215 - ### Mode changes 216 - 217 - | Action | Description | 218 - |--------|-------------| 219 - | `vim-enter-normal` | Switch to vim normal mode | 220 - | `vim-enter-insert` | Switch to vim insert mode (cursor stays in place) | 221 - | `vim-enter-insert-after` | Switch to vim insert mode (cursor moves right, like vim `a`) | 222 - | `vim-enter-insert-at-start` | Move to start of line and enter vim insert mode (like vim `I`) | 223 - | `vim-enter-insert-at-end` | Move to end of line and enter vim insert mode (like vim `A`) | 224 - | `vim-search-insert` | Clear the search input and enter vim insert mode (like vim `?` or `/`) | 225 - | `vim-change-to-end` | Delete to end of line and enter vim insert mode (like vim `C`) | 226 - | `enter-prefix-mode` | Enter prefix mode (waits for one more key, e.g. `d` for delete) | 227 - 228 - ### Inspector 229 - 230 - | Action | Description | 231 - |--------|-------------| 232 - | `inspect-previous` | Inspect the previous entry (in the inspector tab) | 233 - | `inspect-next` | Inspect the next entry (in the inspector tab) | 234 - 235 - ### Special 236 - 237 - | Action | Description | 238 - |--------|-------------| 239 - | `noop` | Do nothing (useful for disabling a default binding) | 240 - 241 - ## Conditions 242 - 243 - Conditions let a single key do different things depending on the current state. They are specified as strings in the `when` field of a rule. 244 - 245 - ### Condition atoms 246 - 247 - | Condition | True when | 248 - |-----------|-----------| 249 - | `cursor-at-start` | The cursor is at position 0 | 250 - | `cursor-at-end` | The cursor is at the end of the input | 251 - | `input-empty` | The input line is empty (no text entered) | 252 - | `original-input-empty` | The original query passed to the TUI was empty | 253 - | `list-at-start` | The selection is at the first entry (index 0) | 254 - | `list-at-end` | The selection is at the last entry | 255 - | `no-results` | The search returned zero results | 256 - | `has-results` | The search returned at least one result | 257 - | `has-context` | The context comes from a previously selected command (`switch-context`) | 258 - 259 - ### Boolean expressions 260 - 261 - Conditions support boolean operators with standard precedence (`!` binds tightest, then `&&`, then `||`). Parentheses can override precedence. 262 - 263 - ```toml 264 - # Negation 265 - { when = "!no-results", action = "select-next" } 266 - 267 - # Conjunction (AND) 268 - { when = "cursor-at-start && input-empty", action = "exit" } 269 - 270 - # Disjunction (OR) 271 - { when = "list-at-start || no-results", action = "exit" } 272 - 273 - # Grouping with parentheses 274 - { when = "(cursor-at-start && !input-empty) || no-results", action = "return-original" } 275 - ``` 276 - 277 - ## Examples 278 - 279 - ### Reproducing the default `[keys]` behaviors 280 - 281 - The default keymaps already encode the standard `[keys]` behaviors. Here is what they look like as explicit `[keymap]` entries for reference. 282 - 283 - **`scroll_exits = true`** (default) -- exit when scrolling past the first entry: 284 - 285 - ```toml 286 - [keymap.emacs] 287 - "down" = [ 288 - { when = "list-at-start", action = "exit" }, 289 - { action = "select-next" }, 290 - ] 291 - ``` 292 - 293 - **`exit_past_line_start = true`** (default) -- exit when pressing left at position 0: 294 - 295 - ```toml 296 - [keymap.emacs] 297 - "left" = [ 298 - { when = "cursor-at-start", action = "exit" }, 299 - { action = "cursor-left" }, 300 - ] 301 - ``` 302 - 303 - **`accept_past_line_end = true`** (default) -- accept when pressing right at the end: 304 - 305 - ```toml 306 - [keymap.emacs] 307 - "right" = [ 308 - { when = "cursor-at-end", action = "accept" }, 309 - { action = "cursor-right" }, 310 - ] 311 - ``` 312 - 313 - **`accept_past_line_start = true`** -- accept when pressing left at position 0 (off by default): 314 - 315 - ```toml 316 - [keymap.emacs] 317 - "left" = [ 318 - { when = "cursor-at-start", action = "accept" }, 319 - { action = "cursor-left" }, 320 - ] 321 - ``` 322 - 323 - **`accept_with_backspace = true`** -- accept when pressing backspace with empty input (off by default): 324 - 325 - ```toml 326 - [keymap.emacs] 327 - "backspace" = [ 328 - { when = "cursor-at-start", action = "accept" }, 329 - { action = "delete-char-before" }, 330 - ] 331 - ``` 332 - 333 - ### Disabling scroll-exit 334 - 335 - To make `down` always scroll without ever exiting: 336 - 337 - ```toml 338 - [keymap.emacs] 339 - "down" = "select-next" 340 - ``` 341 - 342 - ### Disabling a key entirely 343 - 344 - Use `noop` to make a key do nothing: 345 - 346 - ```toml 347 - [keymap.emacs] 348 - "ctrl-d" = "noop" 349 - ``` 350 - 351 - ### ctrl-d to exit only when input is empty 352 - 353 - ```toml 354 - [keymap.emacs] 355 - "ctrl-d" = [ 356 - { when = "input-empty", action = "exit" }, 357 - { action = "delete-char-after" }, 358 - ] 359 - ``` 360 - 361 - ### Making enter return the selection without executing 362 - 363 - ```toml 364 - [keymap.emacs] 365 - "enter" = "return-selection" 366 - ``` 367 - 368 - This is equivalent to setting `enter_accept = false`, but expressed directly as a keybinding. 369 - 370 - ### Custom vim-normal bindings 371 - 372 - ```toml 373 - [keymap.vim-normal] 374 - # Use 'q' to quit 375 - "q" = "exit" 376 - 377 - # Use 'x' to delete the selected entry 378 - "x" = "delete" 379 - 380 - # Use 'y' to copy 381 - "y" = "copy" 382 - ``` 383 - 384 - ### Custom inspector bindings 385 - 386 - ```toml 387 - [keymap.inspector] 388 - # Use 'delete' key in inspector to remove entries 389 - "delete" = "delete" 390 - ``` 391 - 392 - ### Custom prefix bindings 393 - 394 - Prefix mode is a two-step shortcut: press the prefix key (++ctrl+a++ by default), then a second key. This is useful for actions you don't need on a single key. The default prefix bindings are: 395 - 396 - | Key | Action | 397 - |-----|--------| 398 - | `d` | Delete the selected entry | 399 - | `D` | Delete all entries matching the selected command | 400 - | `a` | Move cursor to start of line | 401 - | `c` | Clear context (if in a switched context), otherwise switch context | 402 - 403 - You can customize these with `[keymap.prefix]`: 404 - 405 - ```toml 406 - [keymap.prefix] 407 - # Add a binding to copy the selected entry 408 - "y" = "copy" 409 - 410 - # Make 'x' delete instead of 'd' 411 - "x" = "delete" 412 - "d" = "noop" 413 - ``` 414 - 415 - To change which key enters prefix mode, set `prefix` under `[keys]`: 416 - 417 - ```toml 418 - [keys] 419 - prefix = "x" # ctrl-x instead of ctrl-a 420 - ``` 421 - 422 - Or bind `enter-prefix-mode` directly in your keymap: 423 - 424 - ```toml 425 - [keymap.emacs] 426 - "ctrl-x" = "enter-prefix-mode" 427 - ``` 428 - 429 - ## Relationship with `[keys]` 430 - 431 - The `[keymap]` section is a more powerful replacement for the `[keys]` section. The two are **mutually exclusive**: 432 - 433 - - If you have any `[keymap]` settings, the entire `[keys]` section is ignored. Defaults are built from the standard `[keys]` values, and then your `[keymap]` overrides are applied on top. 434 - - If you have no `[keymap]` settings, the `[keys]` section works as before for backward compatibility. 435 - 436 - If you are migrating from `[keys]` to `[keymap]`, here is how the old flags map: 437 - 438 - | `[keys]` setting | Equivalent `[keymap]` | 439 - |------------------|-----------------------| 440 - | `scroll_exits = false` | `"down" = "select-next"` and `"up" = "select-previous"` in the relevant keymap | 441 - | `exit_past_line_start = false` | `"left" = "cursor-left"` | 442 - | `accept_past_line_end = false` | `"right" = "cursor-right"` | 443 - | `accept_past_line_start = true` | `"left" = [{ when = "cursor-at-start", action = "accept" }, { action = "cursor-left" }]` | 444 - | `accept_with_backspace = true` | `"backspace" = [{ when = "cursor-at-start", action = "accept" }, { action = "delete-char-before" }]` | 445 - | `prefix = "x"` | Prefix key becomes `ctrl-x` (set in the emacs/vim keymaps) |
-1037
docs/docs/configuration/config.md
··· 1 - # Config 2 - 3 - Atuin maintains two configuration files, stored in `~/.config/atuin/`. We store 4 - data in `~/.local/share/atuin` (unless overridden by XDG\_\*). 5 - 6 - The full path to the config file would be `~/.config/atuin/config.toml` 7 - 8 - The config location can be overridden with ATUIN_CONFIG_DIR 9 - 10 - ### `db_path` 11 - 12 - Default: `~/.local/share/atuin/history.db` 13 - 14 - The path to the Atuin SQLite database. 15 - 16 - ```toml 17 - db_path = "~/.history.db" 18 - ``` 19 - 20 - ### `key_path` 21 - 22 - Default: `~/.local/share/atuin/key` 23 - 24 - The path to the Atuin encryption key. 25 - 26 - ```toml 27 - key_path = "~/.atuin-key" 28 - ``` 29 - 30 - ### `session_path` 31 - 32 - Default: `~/.local/share/atuin/session` 33 - 34 - The path to the Atuin server session file. 35 - This is essentially just an API token 36 - 37 - ```toml 38 - session_path = "~/.atuin-session" 39 - ``` 40 - 41 - ### `dialect` 42 - 43 - Default: `us` 44 - 45 - This configures how the [stats](../reference/stats.md) command parses dates. It has two 46 - possible values 47 - 48 - ```toml 49 - dialect = "uk" 50 - ``` 51 - 52 - or 53 - 54 - ```toml 55 - dialect = "us" 56 - ``` 57 - 58 - ### `auto_sync` 59 - 60 - Default: `true` 61 - 62 - Configures whether or not to automatically sync, when logged in. 63 - 64 - ```toml 65 - auto_sync = true/false 66 - ``` 67 - 68 - ### `update_check` 69 - 70 - Default: `true` 71 - 72 - Configures whether or not to automatically check for updates. 73 - 74 - ```toml 75 - update_check = true/false 76 - ``` 77 - 78 - ### `sync_address` 79 - 80 - Default: `https://api.atuin.sh` 81 - 82 - The address of the server to sync with! 83 - 84 - ```toml 85 - sync_address = "https://api.atuin.sh" 86 - ``` 87 - 88 - ### `sync_frequency` 89 - 90 - Default: `1h` 91 - 92 - How often to automatically sync with the server. This can be given in a 93 - "human-readable" format. For example, `10s`, `20m`, `1h`, etc. 94 - 95 - If set to `0`, Atuin will sync after every command. Some servers may potentially 96 - rate limit, which won't cause any issues. 97 - 98 - ```toml 99 - sync_frequency = "1h" 100 - ``` 101 - 102 - ### `search_mode` 103 - 104 - Default: `fuzzy` 105 - 106 - Which search mode to use. Atuin supports "prefix", "fulltext", "fuzzy", "daemon-fuzzy", and 107 - "skim" search modes. 108 - 109 - Prefix mode searches for "query\*"; fulltext mode searches for "\*query\*"; 110 - "fuzzy" applies the [fuzzy search syntax](#fuzzy-search-syntax); 111 - "skim" applies the [skim search syntax](https://github.com/lotabout/skim#search-syntax). 112 - 113 - !!! note "daemon-fuzzy search mode" 114 - 115 - The "daemon-fuzzy" mode is new as of Atuin 18.13. This search mode uses an in-memory index, stored in the daemon, to perform fast and customizable searches. 116 - 117 - To use the new `"daemon-fuzzy"` mode, enable the daemon, set autostart to true (unless you manage its lifecycle yourself), and set the search mode: 118 - 119 - ```toml 120 - search_mode = "daemon-fuzzy" 121 - 122 - [daemon] 123 - enabled = true 124 - autostart = true 125 - ``` 126 - 127 - You can customize the priority given to frequency, recency, and frecency scores in this mode. See [the score multipliers section](#score-multipliers) for more information. 128 - 129 - #### `fuzzy` search syntax 130 - 131 - The "fuzzy" and "daemon-fuzzy" search syntax is based on the 132 - [fzf search syntax](https://github.com/junegunn/fzf#search-syntax). 133 - 134 - | Token | Match type | Description | 135 - | --------- | -------------------------- | ------------------------------------ | 136 - | `sbtrkt` | fuzzy-match | Items that match `sbtrkt` | 137 - | `'wild` | exact-match (quoted) | Items that include `wild` | 138 - | `^music` | prefix-exact-match | Items that start with `music` | 139 - | `.mp3$` | suffix-exact-match | Items that end with `.mp3` | 140 - | `!fire` | inverse-exact-match | Items that do not include `fire` | 141 - | `!^music` | inverse-prefix-exact-match | Items that do not start with `music` | 142 - | `!.mp3$` | inverse-suffix-exact-match | Items that do not end with `.mp3` | 143 - 144 - A single bar character term acts as an OR operator. For example, the following 145 - query matches entries that start with `core` and end with either `go`, `rb`, 146 - or `py`. 147 - 148 - ``` 149 - ^core go$ | rb$ | py$ 150 - ``` 151 - 152 - !!! warning "Bar not supported in daemon-fuzzy" 153 - The "daemon-fuzzy" search mode does not currently support the bar character operator. 154 - 155 - ### `filter_mode` 156 - 157 - Default: `global` 158 - 159 - The default filter to use when searching 160 - 161 - | Mode | Description | 162 - |------------------|--------------------------------------------------------------------------------------| 163 - | global (default) | Search from the full history | 164 - | host | Search history from this host | 165 - | session | Search history from the current session | 166 - | directory | Search history from the current directory | 167 - | workspace | Search history from the current git repository | 168 - | session-preload | Search from the current session and the global history from before the session start | 169 - 170 - Filter modes can still be toggled via ctrl-r 171 - 172 - ```toml 173 - filter_mode = "host" 174 - ``` 175 - 176 - ### `search_mode_shell_up_key_binding` 177 - 178 - Atuin version: >= 17.0 179 - 180 - Default: `fuzzy` 181 - 182 - The default searchmode to use when searching and being invoked from a shell up-key binding. 183 - 184 - Accepts exactly the same options as `search_mode` above 185 - 186 - ```toml 187 - search_mode_shell_up_key_binding = "fuzzy" 188 - ``` 189 - 190 - Defaults to the value specified for `search_mode`. 191 - 192 - ### `filter_mode_shell_up_key_binding` 193 - 194 - Default: `global` 195 - 196 - The default filter to use when searching and being invoked from a shell up-key binding. 197 - 198 - Accepts exactly the same options as `filter_mode` above 199 - 200 - ```toml 201 - filter_mode_shell_up_key_binding = "session" 202 - ``` 203 - 204 - Defaults to the value specified for `filter_mode`. 205 - 206 - ### `inline_height_shell_up_key_binding` 207 - 208 - The maximum number of lines the interface should take up when atuin is invoked from a shell up-key binding. 209 - 210 - The accepted values are identical to those of `inline_height`. 211 - 212 - When unset, the value from `inline_height` is used. 213 - 214 - ### `workspaces` 215 - 216 - Atuin version: >= 17.0 217 - 218 - Default: `false` 219 - 220 - This flag enables a pseudo filter-mode named "workspace": the filter is automatically 221 - activated when you are in a git repository. 222 - 223 - With workspace filtering enabled, Atuin will filter for commands executed in any directory 224 - within a git repository tree. 225 - 226 - Filter modes can still be toggled via ctrl-r. 227 - 228 - ### `style` 229 - 230 - Default: `compact` 231 - 232 - Which style to use. Possible values: `auto`, `full` and `compact`. 233 - 234 - - `compact`: 235 - 236 - ![compact](https://user-images.githubusercontent.com/1710904/161623659-4fec047f-ea4b-471c-9581-861d2eb701a9.png) 237 - 238 - - `full`: 239 - 240 - ![full](https://user-images.githubusercontent.com/1710904/161623547-42afbfa7-a3ef-4820-bacd-fcaf1e324969.png) 241 - 242 - This means that Atuin will automatically switch to `compact` mode when the terminal window is too short for `full` to display properly. 243 - 244 - ### `invert` 245 - 246 - Atuin version: >= 17.0 247 - 248 - Default: `false` 249 - 250 - Invert the UI - put the search bar at the top. 251 - 252 - ```toml 253 - invert = true/false 254 - ``` 255 - 256 - ### `inline_height` 257 - 258 - Default: `40` 259 - 260 - Set the maximum number of lines Atuin's interface should take up. 261 - 262 - If set to `0`, Atuin will always take up as many lines as available (full screen). 263 - 264 - ### `show_preview` 265 - 266 - Default: `true` 267 - 268 - Configure whether or not to show a preview of the selected command. 269 - 270 - Useful when the command is longer than the terminal width and is cut off. 271 - 272 - ### `max_preview_height` 273 - 274 - Atuin version: >= 17.0 275 - 276 - Default: `4` 277 - 278 - Configure the maximum height of the preview to show. 279 - 280 - Useful when you have long scripts in your history that you want to distinguish by more than the first few lines. 281 - 282 - ### `show_help` 283 - 284 - Atuin version: >= 17.0 285 - 286 - Default: `true` 287 - 288 - Configure whether or not to show the help row, which includes the current Atuin version (and whether an update is available), a keymap hint, and the total amount of commands in your history. 289 - 290 - ### `show_tabs` 291 - 292 - Atuin version: >= 18.0 293 - 294 - Default: `true` 295 - 296 - Configure whether or not to show tabs for search and inspect. 297 - 298 - ### `auto_hide_height` 299 - 300 - Atuin version: >= 18.4 301 - 302 - Default: `8` 303 - 304 - Set Atuin to hide lines when a minimum number of rows is subceeded. This has no effect except 305 - when `compact` style is being used (see `style` above), and currently applies to only the 306 - interactive search and inspector. It can be turned off entirely by setting to `0`. 307 - 308 - ### `exit_mode` 309 - 310 - Default: `return-original` 311 - 312 - What to do when the escape key is pressed when searching 313 - 314 - | Value | Behaviour | 315 - | ------------------------- | ---------------------------------------------------------------- | 316 - | return-original (default) | Set the command-line to the value it had before starting search | 317 - | return-query | Set the command-line to the search query you have entered so far | 318 - 319 - Pressing ctrl+c or ctrl+d will always return the original command-line value. 320 - 321 - ```toml 322 - exit_mode = "return-query" 323 - ``` 324 - 325 - ### `history_format` 326 - 327 - Default to `history list` 328 - 329 - The history format allows you to configure the default `history list` format - which can also be specified with the --format arg. 330 - 331 - The specified --format arg will prioritize the config when both are present 332 - 333 - More on [history list](../reference/list.md) 334 - 335 - ### `history_filter` 336 - 337 - The history filter allows you to exclude commands from history tracking - maybe you want to keep ALL of your `curl` commands totally out of your shell history, or maybe just some matching a pattern. 338 - 339 - This supports regular expressions, so you can hide pretty much whatever you want! 340 - 341 - ```toml 342 - ## Note that these regular expressions are unanchored, i.e. if they don't start 343 - ## with ^ or end with $, they'll match anywhere in the command. 344 - history_filter = [ 345 - "^secret-cmd", 346 - "^innocuous-cmd .*--secret=.+" 347 - ] 348 - ``` 349 - 350 - ### `cwd_filter` 351 - 352 - The cwd filter allows you to exclude directories from history tracking. 353 - 354 - This supports regular expressions, so you can hide pretty much whatever you want! 355 - 356 - ```toml 357 - ## Note that these regular expressions are unanchored, i.e. if they don't start 358 - ## with ^ or end with $, they'll match anywhere in the path. 359 - # cwd_filter = [ 360 - # "^/very/secret/directory", 361 - # ] 362 - ``` 363 - 364 - After updating that parameter, you can run [the prune command](../reference/prune.md) to remove old history entries that match the new filters. 365 - 366 - ### `store_failed` 367 - 368 - Atuin version: >= 18.3.0 369 - 370 - Default: `true` 371 - 372 - ```toml 373 - store_failed = true 374 - ``` 375 - 376 - Configures whether to store commands that failed (those with non-zero exit status) or not. 377 - 378 - ### `secrets_filter` 379 - 380 - Atuin version: >= 17.0 381 - 382 - Default: `true` 383 - 384 - ```toml 385 - secrets_filter = true 386 - ``` 387 - 388 - This matches history against a set of default regex, and will not save it if we get a match. Defaults include 389 - 390 - 1. AWS key id 391 - 2. Github pat (old and new) 392 - 3. Slack oauth tokens (bot, user) 393 - 4. Slack webhooks 394 - 5. Stripe live/test keys 395 - 6. Atuin login command 396 - 7. Cloud environment variable patterns (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AZURE_STORAGE_CLASS_KEY`, `GOOGLE_SERVICE_ACCOUNT_KEY`) 397 - 8. Netlify authentication tokens 398 - 9. Npm pat 399 - 10. Pulumi pat 400 - 401 - ### macOS Ctrl-n key shortcuts 402 - 403 - Default: `true` 404 - 405 - macOS does not have an ++alt++ key, although terminal emulators can often be configured to map the ++option++ key to be used as ++alt++. _However_, remapping ++option++ this way may prevent typing some characters, such as using ++option+3++ to type `#` on the British English layout. For such a scenario, set the `ctrl_n_shortcuts` option to `true` in your config file to replace ++alt+0++ to ++alt+9++ shortcuts with ++ctrl+0++ to ++ctrl+9++ instead: 406 - 407 - ```toml 408 - # Use Ctrl-0 .. Ctrl-9 instead of Alt-0 .. Alt-9 UI shortcuts 409 - ctrl_n_shortcuts = true 410 - ``` 411 - 412 - ### show_numeric_shortcuts 413 - 414 - Atuin version: >= 18.9 415 - 416 - Default: `true` 417 - 418 - Whether to show numeric shortcuts (1..9) beside list items in the TUI. Set this to `false` to hide the moving numbers if you find them distracting. 419 - 420 - ### `network_timeout` 421 - 422 - Atuin version: >= 18.0 423 - 424 - Default: `30` 425 - 426 - The max amount of time (in seconds) to wait for a network request. If any 427 - operations with a sync server take longer than this, the code will fail - 428 - rather than wait indefinitely. 429 - 430 - ### `network_connect_timeout` 431 - 432 - Atuin version: >= 18.0 433 - 434 - Default: `5` 435 - 436 - The max time (in seconds) we wait for a connection to become established with a 437 - remote sync server. Any longer than this and the request will fail. 438 - 439 - ### `local_timeout` 440 - 441 - Atuin version: >= 18.0 442 - 443 - Default: `5` 444 - 445 - Timeout (in seconds) for acquiring a local database connection (sqlite). 446 - 447 - ### `command_chaining` 448 - 449 - Atuin version: >= 18.8 450 - 451 - Default: `false` 452 - 453 - Allows building a command chain with the `&&` or `||` operator. When enabled, opening atuin will search for the next command in the chain, and append to the current buffer. 454 - 455 - ### `enter_accept` 456 - 457 - Atuin version: >= 17.0 458 - 459 - Default: `false` 460 - 461 - When set to true, Atuin will default to immediately executing a command rather 462 - than the user having to press enter twice. Pressing tab will return to the 463 - shell and give the user a chance to edit. 464 - 465 - This technically defaults to true for new users, but false for existing. We 466 - have set `enter_accept = true` in the default config file. This is likely to 467 - change to be the default for everyone in a later release. 468 - 469 - ### `keymap_mode` 470 - 471 - Atuin version: >= 18.0 472 - 473 - Default: `emacs` 474 - 475 - The initial keymap mode of the interactive Atuin search (e.g. started by the 476 - keybindings in the shells). There are four supported values: `"emacs"`, 477 - `"vim-normal"`, `"vim-insert"`, and `"auto"`. The keymap mode `"emacs"` is the 478 - most basic one. In the keymap mode `"vim-normal"`, you may use ++k++ 479 - and ++j++ to navigate the history list as in Vim, whilst pressing 480 - 481 - ++i++ changes the keymap mode to `"vim-insert"`. In the keymap mode `"vim-insert"`, 482 - you can search for a string as in the keymap mode `"emacs"`, while pressing ++esc++ 483 - switches the keymap mode to `"vim-normal"`. When set to `"auto"`, the initial 484 - keymap mode is automatically determined based on the shell's keymap that triggered 485 - the Atuin search. `"auto"` is not supported by NuShell at present, where it will 486 - always trigger the Atuin search with the keymap mode `"emacs"`. 487 - 488 - ### `keymap_cursor` 489 - 490 - Atuin version: >= 18.0 491 - 492 - Default: `(empty dictionary)` 493 - 494 - The terminal's cursor style associated with each keymap mode in the Atuin 495 - search. This is specified by a dictionary whose keys and values being the 496 - keymap names and the cursor styles, respectively. A key specifies one of the 497 - keymaps from `emacs`, `vim_insert`, and `vim_normal`. A value is one of the 498 - cursor styles, `default` or `{blink,steady}-{block,underline,bar}`. The 499 - following is an example. 500 - 501 - ```toml 502 - keymap_cursor = { emacs = "blink-block", vim_insert = "blink-block", vim_normal = "steady-block" } 503 - ``` 504 - 505 - If the cursor style is specified, the terminal's cursor style is changed to the 506 - specified one when the Atuin search starts with or switches to the 507 - corresponding keymap mode. Also, the terminal's cursor style is reset to the 508 - one associated with the keymap mode corresponding to the shell's keymap on the 509 - termination of the Atuin search. 510 - 511 - ### `prefers_reduced_motion` 512 - 513 - Atuin version: >= 18.0 514 - 515 - Default: `false` 516 - 517 - Enable this, and Atuin will reduce motion in the TUI as much as possible. Users 518 - with motion sensitivity can find the live-updating timestamps distracting. 519 - 520 - Alternatively, set env var NO_MOTION 521 - 522 - ## search 523 - 524 - ### `filters` 525 - 526 - Atuin version: >= 18.4 527 - 528 - The list of filter modes available in interactive search, in the order they cycle through when you press ctrl-r. By default, all modes are enabled. Removing a mode from this list disables it entirely. The `workspace` mode is skipped when not in a git repository or when `workspaces = false`. See [`filter_mode`](#filter_mode) for a description of each mode. 529 - 530 - The `filter_mode` setting selects the initial mode from this list. If `filter_mode` is set to a mode not in the list, the first available mode is used instead. 531 - 532 - ```toml 533 - [search] 534 - filters = ["global", "host", "session", "directory"] 535 - ``` 536 - 537 - ### Score multipliers 538 - 539 - For the [`"daemon-fuzzy"` search mode](#search_mode), you can control the scoring of matched items. The system scores matches based on three numbers: frequency, recency, and frecency: 540 - 541 - * Frequency — how often this exact match has been run, with diminishing returns 542 - * Recency — how recently this exact match was last run 543 - * Frecency — a combination of frequency and recency 544 - 545 - The frecency calculation is `Recency Score * Recency Multiplier + Frequency Score * Frequency Multiplier`. By changing the options below, you can customize the relative importance of each part of the score calculation. 546 - 547 - For each setting, a value of `1.0` (the default) means the score is used as-is. Values less than `1.0` decrease that score's influence, and values greater than `1.0` increase that score's influence. 548 - 549 - So, for example, if you cared a lot about how frequently you run a command but not as much how recently, you could set `frequency_score_multiplier` to `10.0` and `recency_score_multiplier` to `0.1`. 550 - 551 - !!! warning "daemon-fuzzy mode only" 552 - The score multiplier settings shown here only work with the `"daemon-fuzzy"` search mode. 553 - 554 - #### `frequency_score_multiplier` 555 - 556 - Default: `1.0` 557 - 558 - The multiplier to apply to the frequency score in the frecency calculation. Setting this to `0` disables the frequency portion of the frecency scoring altogether. 559 - 560 - #### `recency_score_multiplier` 561 - 562 - Default: `1.0` 563 - 564 - The multiplier to apply to the recency score in the frecency calculation. Setting this to `0` disables the recency portion of the frecency scoring altogether. 565 - 566 - #### `frecency_score_multiplier` 567 - 568 - Default: `1.0` 569 - 570 - The multiplier used for the final frecency score. Setting this to `0` disables frecency scoring altogether, relying solely on the fuzzy matcher's score. 571 - 572 - Example: 573 - 574 - ```toml 575 - search_mode = "daemon-fuzzy" 576 - 577 - [daemon] 578 - enabled = true 579 - autostart = true 580 - 581 - [search] 582 - recency_score_multiplier = 10.0 583 - frequency_score_multiplier = 0.8 584 - frecency_score_multiplier = 2.0 585 - ``` 586 - 587 - #### `authors` 588 - 589 - Default: `["$all-user"]` 590 - 591 - Filter search results by command author. This controls which commands appear in interactive search based on who (or what) ran them. Useful when AI coding agents are recording commands via [agent hooks](../guide/agent-hooks.md). 592 - 593 - Special values: 594 - 595 - | Value | Meaning | 596 - |-------|---------| 597 - | `$all-user` | Commands from any author that is **not** a known AI agent | 598 - | `$all-agent` | Commands from any known AI agent | 599 - 600 - You can also use literal author names like `"claude-code"`, `"codex"`, `"opencode"`, or `"pi"`. 601 - 602 - ```toml 603 - [search] 604 - # Default: only show human-authored commands 605 - authors = ["$all-user"] 606 - 607 - # Show everything (no author filtering) 608 - # authors = [] 609 - 610 - # Show commands from you and Claude Code 611 - # authors = ["$all-user", "claude-code"] 612 - ``` 613 - 614 - ## Stats 615 - 616 - This section of client config is specifically for configuring Atuin stats calculations 617 - 618 - ``` 619 - [stats] 620 - common_subcommands = [...] 621 - common_prefix = [...] 622 - ``` 623 - 624 - ### `common_subcommands` 625 - 626 - Default: 627 - 628 - ```toml 629 - common_subcommands = [ 630 - "apt", 631 - "cargo", 632 - "composer", 633 - "dnf", 634 - "docker", 635 - "git", 636 - "go", 637 - "ip", 638 - "jj", 639 - "kubectl", 640 - "nix", 641 - "nmcli", 642 - "npm", 643 - "pecl", 644 - "pnpm", 645 - "podman", 646 - "port", 647 - "systemctl", 648 - "tmux", 649 - "yarn", 650 - ] 651 - ``` 652 - 653 - Configures commands where we should consider the subcommand as part of the statistics. For example, consider `kubectl get` rather than just `kubectl`. 654 - 655 - ### `common_prefix` 656 - 657 - Atuin version: >= 17.1 658 - 659 - Default: 660 - 661 - ```toml 662 - common_prefix = [ 663 - "sudo", 664 - ] 665 - ``` 666 - 667 - Configures commands that should be totally stripped from stats calculations. For example, 'sudo' should be ignored. 668 - 669 - ## `dotfiles` 670 - 671 - Atuin version: >= 18.1 672 - 673 - Default: `false` 674 - 675 - To enable sync of shell aliases between hosts. 676 - 677 - Add the new section to the bottom of your config file, for every machine you use Atuin with 678 - 679 - ```toml 680 - [dotfiles] 681 - enabled = true 682 - ``` 683 - 684 - Manage aliases using the command line options 685 - 686 - ``` 687 - # Alias 'k' to 'kubectl' 688 - atuin dotfiles alias set k kubectl 689 - 690 - # List all aliases 691 - atuin dotfiles alias list 692 - 693 - # Delete an alias 694 - atuin dotfiles alias delete k 695 - ``` 696 - 697 - After setting an alias, you will either need to restart your shell or source the init file for the change to take affect 698 - 699 - ## keys 700 - 701 - This section of the client config is specifically for configuring key-related settings. 702 - 703 - ``` 704 - [keys] 705 - scroll_exits = [...] 706 - prefix = 'a' 707 - ``` 708 - 709 - ### `scroll_exits` 710 - 711 - Atuin version: >= 18.1 712 - 713 - Default: `true` 714 - 715 - Configures whether the TUI exits, when scrolled past the last or first entry. 716 - 717 - ### `prefix` 718 - 719 - Atuin version: > 18.3 720 - 721 - Default: `a` 722 - 723 - Which key to use as the prefix. Prefix mode is a two-step shortcut system: you press ++ctrl++ and the prefix key to enter prefix mode, then press a second key to trigger an action. For example, with the default prefix `a`, pressing ++ctrl+a++ then ++d++ deletes the selected entry. 724 - 725 - See the [key binding page](key-binding.md#prefix-mode) for the full list of default prefix shortcuts, or the [advanced key binding page](advanced-key-binding.md#custom-prefix-bindings) to customize them. 726 - 727 - ### `exit_past_line_start` 728 - 729 - Atuin version: >= 18.5 730 - 731 - Default: `true` 732 - 733 - Exits the TUI when scrolling left while the cursor is at the start of the line. 734 - 735 - ### `accept_past_line_end` 736 - 737 - Atuin version: >= 18.5 738 - 739 - Default: `true` 740 - 741 - The right arrow key performs the same functionality as Tab and copies the selected line to the command line to be 742 - modified. 743 - 744 - ### `accept_past_line_start` 745 - 746 - Atuin version: >= 18.9 747 - 748 - Default: `false` 749 - 750 - The left arrow key performs the same functionality as Tab and copies the selected line to the command line to be 751 - modified. 752 - 753 - ### `accept_with_backspace` 754 - 755 - Atuin version: >= 18.9 756 - 757 - Default: `false` 758 - 759 - The backspace key performs the same functionality as Tab and copies the selected line to the command line to be 760 - modified. 761 - 762 - ## preview 763 - 764 - This section of the client config is specifically for configuring preview-related settings. 765 - (In the future the other 2 preview settings will be moved here.) 766 - 767 - ``` 768 - [preview] 769 - strategy = [...] 770 - ``` 771 - 772 - ### `strategy` 773 - 774 - Atuin version: >= 18.3 775 - 776 - Default: `auto` 777 - 778 - Which preview strategy is used to calculate the preview height. It respects `max_preview_height`. 779 - 780 - | Value | Preview height is calculated from the length of the | 781 - | -------------- | --------------------------------------------------- | 782 - | auto (default) | selected command | 783 - | static | longest command in the current result set | 784 - | fixed | use `max_preview_height` as fixed value | 785 - 786 - By using `auto` a preview is shown, if the command is longer than the width of the terminal. 787 - 788 - ## Daemon 789 - 790 - Atuin version: >= 18.3 791 - 792 - ### enabled 793 - 794 - Default: `false` 795 - 796 - Enable the background daemon 797 - 798 - Add the new section to the bottom of your config file 799 - 800 - ```toml 801 - [daemon] 802 - enabled = true 803 - ``` 804 - 805 - ### autostart 806 - 807 - Default: `false` 808 - 809 - Automatically start and manage the daemon when needed. 810 - This is not compatible with `systemd_socket = true`. 811 - If a legacy experimental daemon is already running, restart it manually once before using autostart. 812 - 813 - ```toml 814 - autostart = false 815 - ``` 816 - 817 - ### sync_frequency 818 - 819 - Default: `300` 820 - 821 - How often the daemon should sync, in seconds 822 - 823 - ```toml 824 - sync_frequency = 300 825 - ``` 826 - 827 - ### socket_path 828 - 829 - Default: 830 - 831 - ```toml 832 - socket_path = "~/.local/share/atuin/atuin.sock" 833 - ``` 834 - 835 - Where to bind a unix socket for client -> daemon communication 836 - 837 - If XDG_RUNTIME_DIR is available, then we use this directory instead. 838 - 839 - ### pidfile_path 840 - 841 - Default: 842 - 843 - ```toml 844 - pidfile_path = "~/.local/share/atuin/atuin-daemon.pid" 845 - ``` 846 - 847 - Path to the daemon pidfile used for process coordination. 848 - 849 - ### systemd_socket 850 - 851 - Default `false` 852 - 853 - Use a socket passed via systemd socket activation protocol instead of the path 854 - 855 - ```toml 856 - systemd_socket = false 857 - ``` 858 - 859 - ### tcp_port 860 - 861 - Default: `8889` 862 - 863 - The port to use for client -> daemon communication. Only used on non-unix systems. 864 - 865 - ```toml 866 - tcp_port = 8889 867 - ``` 868 - 869 - ## logs 870 - 871 - Atuin version: >= 18.13 872 - 873 - Behavior of log files. 874 - 875 - ### enabled 876 - 877 - Default: `true` 878 - 879 - Whether or not to enable file-based logging. 880 - 881 - ### dir 882 - 883 - Default: `"~/.atuin/logs"` 884 - 885 - The directory in which to store log files. 886 - 887 - ### level 888 - 889 - Default: `"info"` 890 - 891 - The logging level to use. Valid values are `"trace"`, `"debug"`, `"info"`, `"warn"`, and `"error"`, in order of highest-to-lowest verbosity. 892 - 893 - ### retention 894 - 895 - Default: `4` 896 - 897 - How many days of log files to keep (per file type). Files older than this will be removed. 898 - 899 - ### ai 900 - 901 - A sub-object with specific options for AI logging: 902 - 903 - * `enabled` - whether to output AI logs; defaults to `logs.enabled` 904 - * `file` - the filename to use for the AI logs; defaults to `"ai.log"`. Always relative to `logs.dir`. 905 - * `level` - override the log level for the AI logs; defaults to `logs.level` 906 - * `retention` - how many days to store AI logs; defaults to `logs.retention` 907 - 908 - ### daemon 909 - 910 - A sub-object with specific options for daemon logging: 911 - 912 - * `enabled` - whether to output daemon logs; defaults to `logs.enabled` 913 - * `file` - the filename to use for the daemon logs; defaults to `"daemon.log"`. Always relative to `logs.dir`. 914 - * `level` - override the log level for the daemon logs; defaults to `logs.level` 915 - * `retention` - how many days to store daemon logs; defaults to `logs.retention` 916 - 917 - ### search 918 - 919 - A sub-object with specific options for search logging: 920 - 921 - * `enabled` - whether to output search logs; defaults to `logs.enabled` 922 - * `file` - the filename to use for the search logs; defaults to `"search.log"`. Always relative to `logs.dir`. 923 - * `level` - override the log level for the search logs; defaults to `logs.level` 924 - * `retention` - how many days to store search logs; defaults to `logs.retention` 925 - 926 - ## theme 927 - 928 - Atuin version: >= 18.4 929 - 930 - The theme to use for showing the terminal interface. 931 - 932 - ```toml 933 - [theme] 934 - name = "default" 935 - debug = false 936 - max_depth = 10 937 - ``` 938 - 939 - ### `name` 940 - 941 - Default: `"default"` 942 - 943 - A theme name that must be present as a built-in (unset or `default` for the default, 944 - else `autumn` or `marine`), or found in the themes directory, with the suffix `.toml`. 945 - By default this is `~/.config/atuin/themes/` but can be overridden with the 946 - `ATUIN_THEME_DIR` environment variable. 947 - 948 - ```toml 949 - name = "my-theme" 950 - ``` 951 - 952 - ### `debug` 953 - 954 - Default: `false` 955 - 956 - Output information about why a theme will not load. Independent from other log 957 - levels as it can cause data from the theme file to be printed unfiltered to the 958 - terminal. 959 - 960 - ```toml 961 - debug = false 962 - ``` 963 - 964 - ### `max_depth` 965 - 966 - Default: 10 967 - 968 - Number of levels of "parenthood" that will be traversed for a theme. This should not 969 - need to be added in or changed in normal usage. 970 - 971 - ```toml 972 - max_depth = 10 973 - ``` 974 - 975 - ## ui 976 - 977 - Atuin version: >= 18.5 978 - 979 - Configure the interactive search UI appearance. 980 - 981 - ```toml 982 - [ui] 983 - columns = ["duration", "time", "command"] 984 - ``` 985 - 986 - ### `columns` 987 - 988 - Default: `["duration", "time", "command"]` 989 - 990 - Columns to display in the interactive search, from left to right. The selection 991 - indicator (`" > "`) is always shown first implicitly. 992 - 993 - Each column can be specified as: 994 - - A simple string (uses default width): `"duration"` 995 - - An object with type and optional width/expand: `{ type = "directory", width = 30 }` 996 - 997 - #### Available column types 998 - 999 - | Column | Default Width | Description | 1000 - | --------- | ------------- | ----------------------------------------------- | 1001 - | duration | 5 | Command execution duration (e.g., "123ms") | 1002 - | time | 8 | Relative time since execution (e.g., "59m ago") | 1003 - | datetime | 16 | Absolute timestamp (e.g., "2025-01-22 14:35") | 1004 - | directory | 20 | Working directory (truncated if too long) | 1005 - | host | 15 | Hostname where command was run | 1006 - | user | 10 | Username | 1007 - | exit | 3 | Exit code (colored by success/failure) | 1008 - | command | * | The command itself (expands by default) | 1009 - 1010 - #### Column options 1011 - 1012 - - **type**: The column type (required when using object format) 1013 - - **width**: Custom width in characters (optional, uses default if not specified) 1014 - - **expand**: If `true`, the column fills remaining space. Default is `true` for `command`, `false` for others. Only one column should have `expand = true`. 1015 - 1016 - #### Examples 1017 - 1018 - ```toml 1019 - # Minimal - more space for commands 1020 - columns = ["duration", "command"] 1021 - 1022 - # With custom directory width 1023 - columns = ["duration", { type = "directory", width = 30 }, "command"] 1024 - 1025 - # Show host for multi-machine sync users 1026 - columns = ["duration", "time", "host", "command"] 1027 - 1028 - # Show exit codes prominently 1029 - columns = ["exit", "duration", "command"] 1030 - 1031 - # Make directory expand instead of command 1032 - columns = ["duration", "time", { type = "directory", expand = true }, { type = "command", expand = false }] 1033 - ``` 1034 - 1035 - ## ai 1036 - 1037 - The settings for Atuin AI are listed in [a separate section](../../ai/settings/).
-292
docs/docs/configuration/key-binding.md
··· 1 - # Key Binding 2 - 3 - ## Custom up arrow filter mode 4 - 5 - It can be useful to use a different filter or search mode on the up arrow. For example, you could use ctrl-r for searching globally, but the up arrow for searching history from the current directory only. 6 - 7 - Set your config like this: 8 - 9 - ``` 10 - filter_mode_shell_up_key_binding = "directory" # or global, host, directory, etc 11 - ``` 12 - 13 - ## Disable up arrow 14 - 15 - Our default up-arrow binding can be a bit contentious. Some people love it, some people hate it. Many people who found it a bit jarring at first have since come to love it, so give it a try! 16 - 17 - It becomes much more powerful if you consider binding a different filter mode to the up arrow. For example, on "up" Atuin can default to searching all history for the current directory only, while ctrl-r searches history globally. See the [config](config.md#filter_mode_shell_up_key_binding) for more. 18 - 19 - Otherwise, if you don't like it, it's easy to disable. 20 - 21 - You can also disable either the up-arrow or ++ctrl+r++ bindings individually, by passing 22 - `--disable-up-arrow` or `--disable-ctrl-r` to the call to `atuin init` in your shell config file: 23 - 24 - An example for zsh: 25 - ``` 26 - # Bind ctrl-r but not up arrow 27 - eval "$(atuin init zsh --disable-up-arrow)" 28 - 29 - # Bind up-arrow but not ctrl-r 30 - eval "$(atuin init zsh --disable-ctrl-r)" 31 - ``` 32 - 33 - If you do not want either key to be bound, either pass both `--disable` arguments, or set the 34 - environment variable `ATUIN_NOBIND` to any value before the call to `atuin init`: 35 - 36 - ``` 37 - ## Do not bind any keys 38 - # Either: 39 - eval "$(atuin init zsh --disable-up-arrow --disable-ctrl-r)" 40 - 41 - # Or: 42 - export ATUIN_NOBIND="true" 43 - eval "$(atuin init zsh)" 44 - ``` 45 - 46 - You can then choose to bind Atuin if needed, do this after the call to init. 47 - 48 - ## Enter key behavior 49 - 50 - By default, the `enter` key will directly execute the selected command instead of letting you edit it like the `tab` key. If you want to change this behavior, set `enter_accept = false` in your config. For more details: [enter_accept](config.md#enter_accept). 51 - 52 - ## Ctrl-n key shortcuts 53 - 54 - macOS does not have an ++alt++ key, although terminal emulators can often be configured to map the ++option++ key to be used as ++alt++. *However*, remapping ++option++ this way may prevent typing some characters, such as using ++option+3++ to type `#` on the British English layout. For such a scenario, set the `ctrl_n_shortcuts` option to `true` in your config file to replace ++alt+0++ to ++alt+9++ shortcuts with ++ctrl+0++ to ++ctrl+9++ instead: 55 - 56 - ``` 57 - # Use Ctrl-0 .. Ctrl-9 instead of Alt-0 .. Alt-9 UI shortcuts 58 - ctrl_n_shortcuts = true 59 - ``` 60 - 61 - Ghostty on Linux maps ++alt+1++ .. ++alt+9++ for switching between tabs by number. To disable this behavior either add the following to ~/.config/ghostty/config: 62 - ``` 63 - keybind=alt+one=unbind 64 - keybind=alt+two=unbind 65 - keybind=alt+three=unbind 66 - keybind=alt+four=unbind 67 - keybind=alt+five=unbind 68 - keybind=alt+six=unbind 69 - keybind=alt+seven=unbind 70 - keybind=alt+eight=unbind 71 - keybind=alt+nine=unbind 72 - ``` 73 - (this will disable tab switching by ++alt+n++) 74 - or use the `ctrl_n_shortcuts` as outlined above. 75 - 76 - ## zsh 77 - 78 - If you'd like to customize your bindings further, it's possible to do so with custom shell config: 79 - 80 - Atuin defines the ZLE widgets "atuin-search" and "atuin-up-search". The latter 81 - can be used for the keybindings to the ++up++ key and similar keys. 82 - 83 - Note: instead use the widget names "\_atuin\_search\_widget" and "\_atuin\_up\_search\_widget", respectively, in `atuin < 18.0` 84 - 85 - ``` 86 - export ATUIN_NOBIND="true" 87 - eval "$(atuin init zsh)" 88 - 89 - bindkey '^r' atuin-search 90 - 91 - # bind to the up key, which depends on terminal mode 92 - bindkey '^[[A' atuin-up-search 93 - bindkey '^[OA' atuin-up-search 94 - ``` 95 - 96 - For the keybindings in vi mode, "atuin-search-viins", "atuin-search-vicmd", 97 - "atuin-up-search-viins", and "atuin-up-search-vicmd" (`atuin >= 18.0`) can be 98 - used in combination with the config 99 - ["keymap\_mode"](config.md#keymap_mode) 100 - (`atuin >= 18.0`) to start the Atuin search in respective keymap modes. 101 - 102 - ## bash 103 - 104 - Atuin (`>= 18.10.0`) provides a shell function `atuin-bind` to set up 105 - keybindings easily: 106 - 107 - ``` 108 - atuin-bind [-m KEYMAP] KEYSEQ COMMAND 109 - ``` 110 - 111 - `KEYMAP` is one of `emacs`, `vi-insert`, and `vi-command` and specifies the 112 - target keymap where the keybinding is defined. `KEYSEQ` specifies a key 113 - sequence in the format used in `bind '"KEYSEQ": ...'`. `COMMAND` specifies a 114 - shell command to run with the keybindings. The following special commands can 115 - be used as well as an arbitrary shell command: 116 - 117 - | Command | Description | 118 - | ----------------------- | ----------------------------------------------------------------------------------- | 119 - | `atuin-search` | Standard search | 120 - | `atuin-search-emacs` | Standard search with the `emacs` keymap mode | 121 - | `atuin-search-viins` | Standard search with the `vim-insert` keymap mode | 122 - | `atuin-search-vicmd` | Standard search with the `vim-normal` keymap mode | 123 - | `atuin-up-search` | Search command for <kbd>up</kbd> or similar keys | 124 - | `atuin-up-search-emacs` | Search command for <kbd>up</kbd> or similar keys, with the `emacs` keymap mode | 125 - | `atuin-up-search-viins` | Search command for <kbd>up</kbd> or similar keys, with the `vim-insert` keymap mode | 126 - | `atuin-up-search-vicmd` | Search command for <kbd>up</kbd> or similar keys, with the `vim-nomarl` keymap mode | 127 - 128 - The keymap mode controls the initial keymap in the Atuin search and is 129 - determined in combination with the config 130 - ["keymap\_mode"](config.md#keymap_mode) 131 - (`atuin >= 18.0`). 132 - 133 - 134 - ``` 135 - export ATUIN_NOBIND="true" 136 - eval "$(atuin init bash)" 137 - 138 - # bind to ctrl-r, add any other bindings you want here too 139 - atuin-bind '\C-r' atuin-search 140 - # example of CTRL-upkey 141 - # atuin-bind '\e[1;5A' atuin-search 142 - 143 - # bind to the up key, which depends on terminal mode 144 - atuin-bind '\e[A' atuin-up-search 145 - atuin-bind '\eOA' atuin-up-search 146 - ``` 147 - 148 - With older versions of Atuin, the user needs to bind a bindable shell function 149 - "`__atuin_history`" directly using Bash's `bind`. The flag 150 - `--shell-up-key-binding` can be optionally specified to the first argument for 151 - keybindings to the <kbd>up</kbd> key or similar keys. For the keybindings in 152 - the `vi` editing mode, the options `--keymap-mode=vim-insert` and the keymap 153 - mode `--keymap-mode=vim-normal` (`atuin >= 18.0`) can be additionally specified 154 - to the shell function `__atuin_history`. 155 - 156 - ## fish 157 - Edit key bindings in FISH shell by adding the following to ~/.config/fish/config.fish 158 - 159 - ``` 160 - set -gx ATUIN_NOBIND "true" 161 - atuin init fish | source 162 - 163 - # bind to ctrl-r in normal and insert mode, add any other bindings you want here too 164 - bind \cr _atuin_search 165 - bind -M insert \cr _atuin_search 166 - ``` 167 - 168 - For the ++up++ keybinding, `_atuin_bind_up` can be used instead of `_atuin_search`. 169 - 170 - Adding the useful alternative key binding of ++ctrl+up++ is tricky and determined by the terminals adherence to terminfo(5). 171 - 172 - Conveniently FISH uses a command to capture keystrokes and advises you of the exact command to add for your specific terminal. 173 - In your terminal, run `fish_key_reader` then punch the desired keystroke/s. 174 - 175 - For example, in Gnome Terminal the output to ++ctrl+up++ is `bind \e\[1\;5A 'do something'` 176 - 177 - So, adding this to the above sample, `bind \e\[1\;5A _atuin_search` will provide the additional search keybinding. 178 - 179 - ## nu 180 - 181 - ``` 182 - $env.ATUIN_NOBIND = true 183 - atuin init nu | save -f ~/.local/share/atuin/init.nu #make sure you created the directory beforehand with `mkdir ~/.local/share/atuin/init.nu` 184 - source ~/.local/share/atuin/init.nu 185 - 186 - #bind to ctrl-r in emacs, vi_normal and vi_insert modes, add any other bindings you want here too 187 - $env.config = ( 188 - $env.config | upsert keybindings ( 189 - $env.config.keybindings 190 - | append { 191 - name: atuin 192 - modifier: control 193 - keycode: char_r 194 - mode: [emacs, vi_normal, vi_insert] 195 - event: { send: executehostcommand cmd: (_atuin_search_cmd) } 196 - } 197 - ) 198 - ) 199 - ``` 200 - 201 - 202 - ## Atuin UI shortcuts 203 - 204 - | Shortcut | Action | 205 - |-------------------------------------------|-------------------------------------------------------------------------------| 206 - | enter | Execute selected item | 207 - | tab | Select item and edit | 208 - | ctrl + r | Cycle through filter modes | 209 - | ctrl + s | Cycle through search modes | 210 - | alt + 1 to alt + 9 | Select item by the number located near it | 211 - | ctrl + c / ctrl + d / ctrl + g / esc | Return original | 212 - | ctrl + y | Copy selected item to clipboard | 213 - | ctrl + ← / alt + b | Move the cursor to the previous word | 214 - | ctrl + → / alt + f | Move the cursor to the next word | 215 - | ctrl + b / ← | Move the cursor to the left | 216 - | ctrl + f / → | Move the cursor to the right | 217 - | ctrl + a / home | Move the cursor to the start of the line | 218 - | ctrl + e / end | Move the cursor to the end of the line | 219 - | ctrl + backspace / ctrl + alt + backspace | Remove the previous word / remove the word just before the cursor | 220 - | ctrl + delete / ctrl + alt + delete | Remove the next word or the word just after the cursor | 221 - | ctrl + w | Remove the word before the cursor even if it spans across the word boundaries | 222 - | ctrl + u | Clear the current line | 223 - | ctrl + n / ctrl + j / ↑ | Select the next item on the list | 224 - | ctrl + p / ctrl + k / ↓ | Select the previous item on the list | 225 - | ctrl + o | Open the [inspector](#inspector) | 226 - | page down | Scroll search results one page down | 227 - | page up | Scroll search results one page up | 228 - | ↓ (with no entry selected) | Return original or return query depending on [settings](config.md#exit_mode) | 229 - | ↓ | Select the next item on the list | 230 - | ctrl + a, d | Delete the selected history entry | 231 - | ctrl + a, D | Delete **all** history entries matching the selected command | 232 - | ctrl + a, a | Move cursor to the start of the line | 233 - | ctrl + a, c | Switch to the context of the currently selected command / return to default | 234 - 235 - ### Prefix mode 236 - 237 - The shortcuts above that start with ++ctrl+a++ use **prefix mode** — a two-step key combination. Pressing the prefix key (++ctrl+a++ by default) enters prefix mode, then the next key you press triggers the action. Prefix mode exits automatically after the action runs. 238 - 239 - This is useful for less-frequent actions that don't need a dedicated shortcut. The prefix key can be changed with the [`prefix`](config.md#prefix) setting, and the bindings themselves can be customized with [`[keymap.prefix]`](advanced-key-binding.md#custom-prefix-bindings). 240 - 241 - ### Vim mode 242 - If [vim is enabled in the config](config.md#keymap_mode), the following keybindings are enabled: 243 - 244 - | Shortcut | Mode | Action | 245 - | -------- | ------ | ------------------------------------------ | 246 - | k | Normal | Selects the next item on the list | 247 - | j | Normal | Selects the previous item on the list | 248 - | h | Normal | Move cursor left | 249 - | l | Normal | Move cursor right | 250 - | 0 | Normal | Move cursor to start of line | 251 - | $ | Normal | Move cursor to end of line | 252 - | w | Normal | Move cursor to next word | 253 - | b | Normal | Move cursor to previous word | 254 - | e | Normal | Move cursor to end of current/next word | 255 - | x | Normal | Delete character under cursor | 256 - | dd | Normal | Clear the entire line | 257 - | D | Normal | Delete to end of line | 258 - | C | Normal | Delete to end of line and enter insert | 259 - | i | Normal | Enters insert mode | 260 - | I | Normal | Move to start of line and enter insert | 261 - | a | Normal | Move right and enter insert mode | 262 - | A | Normal | Move to end of line and enter insert | 263 - | Ctrl+u | Normal | Half-page up (toward visual top) | 264 - | Ctrl+d | Normal | Half-page down (toward visual bottom) | 265 - | Ctrl+b | Normal | Full-page up (toward visual top) | 266 - | Ctrl+f | Normal | Full-page down (toward visual bottom) | 267 - | G | Normal | Jump to visual bottom of history | 268 - | gg | Normal | Jump to visual top of history | 269 - | H | Normal | Jump to top of visible screen | 270 - | M | Normal | Jump to middle of visible screen | 271 - | L | Normal | Jump to bottom of visible screen | 272 - | ? or / | Normal | Clear input and enter insert mode | 273 - | 1-9 | Normal | Select item by number | 274 - | enter | Normal | Execute selected item (respects enter_accept) | 275 - | Esc | Insert | Enters normal mode | 276 - 277 - 278 - ### Inspector 279 - Open the inspector with ctrl + o 280 - 281 - | Shortcut | Action | 282 - | --------- | --------------------------------------------- | 283 - | Esc | Close the inspector, returning to the shell | 284 - | ctrl + o | Close the inspector, returning to search view | 285 - | ctrl + d | Delete the inspected item from the history | 286 - | ↑ | Inspect the previous item in the history | 287 - | ↓ | Inspect the next item in the history | 288 - | page up | Inspect the previous item in the history | 289 - | page down | Inspect the next item in the history | 290 - | j / k | Navigate items (when vim mode is enabled) | 291 - | enter | Execute selected item (respects enter_accept) | 292 - | tab | Select current item and edit |
-90
docs/docs/faq.md
··· 1 - # FAQ 2 - 3 - ## Why isn't Atuin recording commands in my IDE's terminal? 4 - 5 - IDEs like PyCharm, VS Code, and others often start non-interactive shells that don't source your shell configuration. This means Atuin's hooks never get installed. 6 - 7 - To fix this, configure your IDE to start an interactive shell (e.g., `/bin/bash -i` instead of `/bin/bash`). 8 - 9 - See [Shell Integration and Interoperability](guide/shell-integration.md) for detailed instructions. 10 - 11 - ## How do I exclude certain commands from my history? 12 - 13 - Use the `history_filter` option in `~/.config/atuin/config.toml`: 14 - 15 - ```toml 16 - history_filter = [ 17 - "^secret-cmd", 18 - "^ls$", 19 - ] 20 - ``` 21 - 22 - You can also exclude commands by directory with `cwd_filter`, or prefix individual commands with a space. 23 - 24 - See [Shell Integration and Interoperability](guide/shell-integration.md#excluding-commands-from-history) for more options. 25 - 26 - ## How do I remove the default up arrow binding? 27 - 28 - Open your shell config file, find the line containing `atuin init`. 29 - 30 - Add `--disable-up-arrow` 31 - 32 - EG: 33 - 34 - ``` 35 - eval "$(atuin init zsh --disable-up-arrow)" 36 - ``` 37 - 38 - See [key binding](../configuration/key-binding.md) for more 39 - 40 - ## How do I remove the default question mark binding for Atuin AI? 41 - 42 - Open your shell config file, find the line containing `atuin init`. 43 - 44 - Add `--disable-ai` 45 - 46 - EG: 47 - 48 - ``` 49 - eval "$(atuin init zsh --disable-ai)" 50 - ``` 51 - 52 - ## How do I edit a command instead of running it immediately? 53 - 54 - Press tab! By default, enter will execute a command, and tab will insert it ready for editing. 55 - 56 - You can make `enter` edit a command by putting `enter_accept = false` into your config file (~/.config/atuin/config.toml) 57 - 58 - ## How do I delete my account? 59 - 60 - **Attention:** This command does not prompt for confirmation. 61 - 62 - ``` 63 - atuin account delete 64 - ``` 65 - 66 - This will delete your account, and all history from the remote server. It will not delete your local data. 67 - 68 - ## I've forgotten my password! How can I reset it? 69 - 70 - We don't currently have a password reset system. So long as you're still logged 71 - in on at least one machine, it's safe to delete and re-create your account. 72 - 73 - ## I did not set up sync, and now I have to reinstall my system! 74 - 75 - If you have a backup of `~/.local/share/atuin`, you can import it by: 76 - 1. disabling atuin by commenting out the shell integration, e.g. for bash it's `eval "$(atuin init bash)"` 77 - 2. copying the backup to `~/.local/share/atuin` 78 - 3. reenabling atuin 79 - 4. setting up sync! 80 - 81 - ## Alternative projects 82 - 83 - If you don't like atuin, perhaps one of these works better for you: 84 - 85 - - https://github.com/ddworken/hishtory 86 - - written in go 87 - - also provides sync'ed history 88 - - https://github.com/cantino/mcfly 89 - - uses a small local neural network for search 90 - - only local history
-49
docs/docs/guide/advanced-usage.md
··· 1 - # Advanced Usage 2 - 3 - Atuin offers you several options to help navigate through the results. 4 - 5 - ## Filter mode 6 - 7 - The command history can be filtered in different ways, letting you narrow the search scope. 8 - 9 - You can cycle through the different modes by pressing **ctrl-r**. 10 - 11 - The available modes are: 12 - 13 - | Mode | Description | 14 - |------------------|--------------------------------------------------------------------------------------| 15 - | global (default) | Search from the full history | 16 - | host | Search history from this host | 17 - | session | Search history from the current session | 18 - | directory | Search history from the current directory | 19 - | workspace | Search history from the current git repository | 20 - | session-preload | Search from the current session and the global history from before the session start | 21 - 22 - See the [`filter_mode` config reference](../configuration/config.md#filter_mode) for more details. 23 - 24 - ## Search mode 25 - 26 - Atuin offers different modes to interpret your search query. 27 - 28 - You can cycle through the different modes by pressing **ctrl-s**. 29 - 30 - The available modes are: 31 - 32 - | Mode | Description | 33 - |-----------------|----------------------------------------------------------------------------------------------------------------| 34 - | fuzzy (default) | Search for commands in a fuzzy way, similar to the [fzf syntax](https://github.com/junegunn/fzf#search-syntax) | 35 - | prefix | Commands that start with your query | 36 - | fulltext | Commands that contain your query as a substring | 37 - | skim | Search for commands using the [skim syntax](https://github.com/lotabout/skim#search-syntax) | 38 - 39 - See the [`search_mode` config reference](../configuration/config.md#search_mode) for more details. 40 - 41 - ## Context switch 42 - 43 - Atuin uses the current context (host, session, directory) to filter the history when you use a filter mode other than *global*. 44 - 45 - You can switch this context to the one of the currently selected command by pressing **ctrl-a** then **c**. 46 - 47 - This will set the filter mode to *session* and clear the search query, which will show you all the commands executed in the same shell session. 48 - 49 - Pressing this key combination again will return to the initial context. You can customize this behavior by setting [custom key bindings](../configuration/advanced-key-binding.md) to the `switch-context` and `clear-context` commands. `switch-context` can be called several times to navigate through multiple command contexts, while `clear-context` will always return to the initial context.
-138
docs/docs/guide/agent-hooks.md
··· 1 - # AI Agent Hooks 2 - 3 - Atuin can capture commands run by AI coding agents (like Claude Code, Codex, and pi) alongside your regular shell history. Each command is tagged with the agent that ran it, so you can filter your history by author. 4 - 5 - ## Quick Start 6 - 7 - Install hooks for your agent, then restart or reload the agent: 8 - 9 - ```shell 10 - # Claude Code 11 - atuin hook install claude-code 12 - 13 - # Codex 14 - atuin hook install codex 15 - 16 - # pi 17 - atuin hook install pi 18 - ``` 19 - 20 - That's it. Commands the agent runs will now appear in your Atuin history, tagged with the agent's name. 21 - 22 - ## How It Works 23 - 24 - AI coding agents support hook systems that notify external tools when they're about to run a shell command and when the command finishes. Atuin uses these hooks to record each command as a history entry, just like commands you type yourself. 25 - 26 - When `atuin hook install` runs, it writes the agent's config file or extension to register Atuin as a hook handler: 27 - 28 - | Agent | Config file / extension | 29 - |-------|-------------------------| 30 - | Claude Code | `~/.claude/settings.json` | 31 - | Codex | `~/.codex/hooks.json` | 32 - | pi | `~/.pi/agent/extensions/atuin.ts` | 33 - 34 - The hook lifecycle: 35 - 36 - 1. **PreToolUse** -- the agent is about to run a Bash command. Atuin records the command, working directory, and timestamp (same as `history start`). 37 - 2. **PostToolUse / PostToolUseFailure** -- the command finished. Atuin records the exit code and duration (same as `history end`). 38 - 39 - Only `Bash` tool invocations are captured. Other tool types (file writes, web fetches, etc.) are ignored. 40 - 41 - ## Filtering by Author 42 - 43 - By default, Atuin's interactive search shows only your own commands. Agent-run commands are hidden so they don't clutter your history. 44 - 45 - Today this default is built into the search UI rather than configurable via `config.toml`. Interactive search uses the equivalent of: 46 - 47 - - `$all-user` — any author that is **not** a known AI agent 48 - 49 - For explicit author filtering, use the CLI `atuin search --author ...` flag. Special values: 50 - 51 - | Value | Meaning | 52 - |-------|---------| 53 - | `$all-user` | Any author that is **not** a known AI agent | 54 - | `$all-agent` | Any known AI agent author | 55 - 56 - You can also use literal author names: 57 - 58 - ```shell 59 - # Show only your own commands and Claude Code commands 60 - atuin search --author '$all-user' --author 'claude-code' -- '' 61 - ``` 62 - 63 - ```shell 64 - # Show everything (no filtering) 65 - atuin search -- '' 66 - ``` 67 - 68 - ```shell 69 - # Show only agent commands 70 - atuin search --author '$all-agent' -- '' 71 - ``` 72 - 73 - Currently recognized agent names are: `claude-code`, `codex`, `copilot`, `opencode`, and `pi`. 74 - 75 - ## Supported Agents 76 - 77 - ### Claude Code 78 - 79 - ```shell 80 - atuin hook install claude-code 81 - ``` 82 - 83 - This adds hook entries to `~/.claude/settings.json`. Claude Code calls `atuin hook claude-code` on each `Bash` tool use, passing the event as JSON on stdin. 84 - 85 - ### Codex 86 - 87 - ```shell 88 - atuin hook install codex 89 - ``` 90 - 91 - This adds hook entries to `~/.codex/hooks.json`. Codex calls `atuin hook codex` on each Bash tool use matching `^Bash$`. 92 - 93 - ### pi 94 - 95 - ```shell 96 - atuin hook install pi 97 - ``` 98 - 99 - This writes Atuin's extension to `~/.pi/agent/extensions/atuin.ts`. 100 - 101 - Then restart pi or run `/reload`. The extension listens to pi's tool events and records every `bash` tool command with author `pi` by calling `atuin history start` before execution and `atuin history end` afterwards. Because it observes events rather than registering its own `bash` tool, it works alongside other extensions that replace pi's bash tool (such as sandboxes or RTK implementations). 102 - 103 - ## Verifying Installation 104 - 105 - After installing hooks and restarting your agent, run a command through the agent and then check your history: 106 - 107 - ```shell 108 - # Show all history including agent commands 109 - atuin search --author '' -- '' 110 - 111 - # Show only agent commands 112 - atuin search --author '$all-agent' -- '' 113 - ``` 114 - 115 - You can also check the agent's config file directly to confirm the hooks are registered: 116 - 117 - ```shell 118 - # Claude Code 119 - cat ~/.claude/settings.json | grep atuin 120 - 121 - # Codex 122 - cat ~/.codex/hooks.json | grep atuin 123 - 124 - # pi 125 - ls ~/.pi/agent/extensions/atuin.ts 126 - ``` 127 - 128 - ## Re-installing 129 - 130 - Running `atuin hook install` again is safe. If hooks are already installed, the command will skip them and print a message: 131 - 132 - ``` 133 - hooks.PreToolUse: already installed, skipping 134 - hooks.PostToolUse: already installed, skipping 135 - hooks.PostToolUseFailure: already installed, skipping 136 - ``` 137 - 138 - For pi, reinstalling will also skip if the managed extension already matches the bundled version.
-65
docs/docs/guide/basic-usage.md
··· 1 - # Basic Usage 2 - 3 - Now that you're all set up and running, here's a quick walkthrough of how you can use Atuin best. 4 - 5 - ## What does Atuin record? 6 - 7 - While you work, Atuin records: 8 - 9 - 1. The command you run 10 - 2. The directory you ran it in 11 - 3. The time you ran it, and how long it took to run 12 - 4. The exit code of the command 13 - 5. The hostname + user of the machine 14 - 6. The shell session you ran it in 15 - 16 - ## Opening and using the TUI 17 - 18 - At any time, you can open the TUI with the default keybindings of the up arrow, or `ctrl-r`. 19 - 20 - Once in the TUI, press enter to immediately execute a command, or press tab to insert it into your shell for editing. 21 - 22 - While searching in the TUI, you can adjust the "filter mode" by repeatedly pressing `ctrl-r`. Atuin can filter by: 23 - 24 - 1. All hosts 25 - 2. Just your local machine 26 - 3. The current directory only 27 - 4. The current shell session only 28 - 29 - See the [advanced usage](advanced-usage.md) page for more options. 30 - 31 - ## Common config adjustment 32 - 33 - For a full set of config values, please see the [config reference page](../configuration/config.md). 34 - 35 - The default configuration file is located at `~/.config/atuin/config.toml`. 36 - 37 - ### Keybindings 38 - 39 - We have a [full page dedicated to keybinding adjustments](../configuration/key-binding.md). 40 - There are a whole bunch of options there, including disabling the up arrow behavior if you don't like it. 41 - 42 - ### Enter to run 43 - 44 - You may prefer that Atuin always inserts the selected command for editing. To configure this, set 45 - 46 - ``` 47 - enter_accept = false 48 - ``` 49 - 50 - in your config file. 51 - 52 - ### Inline window 53 - 54 - If you find the full screen TUI overwhelming or too large, you can adjust it like so: 55 - 56 - ``` 57 - # height of the search window 58 - inline_height = 40 59 - ``` 60 - 61 - You may also prefer the compact UI mode: 62 - 63 - ``` 64 - style = "compact" 65 - ```
-167
docs/docs/guide/delete-history.md
··· 1 - # Deleting History 2 - 3 - Atuin provides several ways to delete history, whether you want to remove a single entry, bulk delete by query, clean up duplicates, or wipe everything. 4 - 5 - All deletion methods are local-first. If you have sync enabled, deletions are propagated to other machines automatically. 6 - 7 - ## Deleting a single entry 8 - 9 - The quickest way to delete a single entry is via the interactive TUI. 10 - 11 - ### Using the inspector 12 - 13 - 1. Open the TUI with ++ctrl+r++ or the up arrow 14 - 2. Search for the entry you want to delete 15 - 3. Press ++ctrl+o++ to open the inspector on the selected entry 16 - 4. Verify this is the correct entry 17 - 5. Press ++ctrl+d++ to delete it 18 - 19 - ### Using the prefix shortcut 20 - 21 - 1. Open the TUI with ++ctrl+r++ or the up arrow 22 - 2. Navigate to the entry you want to delete 23 - 3. Press ++ctrl+a++ then ++d++ to delete the selected entry 24 - 25 - Both methods remove the entry immediately with no further confirmation. 26 - 27 - ## Deleting entries matching a query 28 - 29 - Use `atuin search --delete` to delete all entries matching a search query. This uses the same query syntax as regular search, so you can preview what will be deleted before committing. 30 - 31 - ### Preview first, then delete 32 - 33 - Always run your query without `--delete` first to verify the results: 34 - 35 - ``` 36 - # Step 1: preview - see what matches 37 - atuin search "^curl https://internal" 38 - 39 - # Step 2: delete - once you're satisfied the results are correct 40 - atuin search --delete "^curl https://internal" 41 - ``` 42 - 43 - ### Combining filters 44 - 45 - You can combine `--delete` with any search filter: 46 - 47 - ``` 48 - # Delete all failed commands run from a specific directory 49 - atuin search --delete --exit 1 --cwd /home/user/experiments 50 - 51 - # Delete commands matching a pattern that ran before a certain date 52 - atuin search --delete --before "2024-01-01" "^tmp-script" 53 - 54 - # Delete successful cargo commands run after yesterday at 3pm 55 - atuin search --delete --exit 0 --after "yesterday 3pm" cargo 56 - ``` 57 - 58 - !!! warning 59 - `--delete` requires a query or filter. It will not run without one. This is intentional to prevent accidental bulk deletion. 60 - 61 - ## Deleting all history 62 - 63 - If you want to wipe your entire local history: 64 - 65 - ``` 66 - atuin search --delete-it-all 67 - ``` 68 - 69 - !!! danger 70 - This deletes every entry in your local history database. It cannot be combined with a query or filters. This action is irreversible. 71 - 72 - ### Starting fresh with sync 73 - 74 - If you use sync and want to start completely fresh, `--delete-it-all` alone is not enough. Atuin sync works by recording every action (including deletions) as encrypted records. Deleting 100,000 entries locally creates 100,000 delete records that still need to sync. When your other machines pull those records, they process every single one, and your database still contains the overhead of all that history. 75 - 76 - The cleaner approach is to delete your sync account and start over: 77 - 78 - ``` 79 - # Delete your sync account and all server-side data 80 - atuin account delete 81 - 82 - # Register a new account 83 - atuin register 84 - 85 - # Import your shell history fresh (optional) 86 - atuin import auto 87 - ``` 88 - 89 - This gives you a clean slate on the server with no leftover records. Your other machines can then register with the new account and start fresh too. 90 - 91 - !!! tip 92 - If you only want to delete specific entries and keep the rest, `atuin search --delete` is the right tool. The account reset approach is only better when you want to wipe everything and start over. 93 - 94 - ## Pruning filtered commands 95 - 96 - If you've updated your [`history_filter`](../configuration/config.md#history_filter) config and want to retroactively remove entries that match the new filters: 97 - 98 - ``` 99 - # Preview what will be removed 100 - atuin history prune --dry-run 101 - 102 - # Perform the deletion 103 - atuin history prune 104 - ``` 105 - 106 - This is useful when you add a new pattern to `history_filter` - future commands matching the filter are never recorded, but old entries that were recorded before the filter was set up remain. `prune` cleans those up. 107 - 108 - ## Purging undecryptable local store records 109 - 110 - If `atuin store verify` reports that some local store records cannot be decrypted with your current key, you can remove only those broken local records: 111 - 112 - ```sh 113 - # Check whether every local store record can be decrypted 114 - atuin store verify 115 - 116 - # Delete only the local records that fail decryption 117 - atuin store purge 118 - ``` 119 - 120 - This is useful when one machine ends up with local records that were encrypted with a different key than the one Atuin is currently using. 121 - 122 - !!! warning 123 - `atuin store purge` only affects the local record store on the current machine. It does not wipe your history, delete your sync account, or reset other machines. 124 - 125 - !!! danger 126 - `atuin store purge` permanently deletes the records it cannot decrypt. Before running it, make sure Atuin is using the key you intend to keep, and back up the local store if the records may still be recoverable. Run `atuin store verify` first so you know whether you are cleaning up a real key mismatch and not just deleting data blindly. 127 - 128 - ## Deduplicating history 129 - 130 - Remove duplicate entries (same command, working directory, and hostname): 131 - 132 - ``` 133 - # Preview duplicates that would be removed 134 - atuin history dedup --dry-run --before "2025-01-01" --dupkeep 1 135 - 136 - # Delete them 137 - atuin history dedup --before "2025-01-01" --dupkeep 1 138 - ``` 139 - 140 - | Flag | Description | 141 - |------|-------------| 142 - | `--dry-run`/`-n` | List duplicates without deleting | 143 - | `--before`/`-b` | Only consider entries added before this date (required) | 144 - | `--dupkeep` | Number of recent duplicates to keep | 145 - 146 - ## Deleting your sync account 147 - 148 - To delete your remote sync account and all server-side history: 149 - 150 - ``` 151 - atuin account delete 152 - ``` 153 - 154 - This removes your account and all synchronized history from the server. **Local history is not affected.** See the [sync reference](../reference/sync.md) for more details. 155 - 156 - ## Summary 157 - 158 - | Goal | Command | 159 - |------|---------| 160 - | Delete one entry (TUI) | ++ctrl+o++ then ++ctrl+d++, or ++ctrl+a++ then ++d++ | 161 - | Delete entries by query | `atuin search --delete <query>` | 162 - | Delete all history | `atuin search --delete-it-all` | 163 - | Start fresh (with sync) | `atuin account delete` then re-register | 164 - | Remove filtered entries | `atuin history prune` | 165 - | Remove undecryptable local store records | `atuin store verify` then `atuin store purge` | 166 - | Remove duplicates | `atuin history dedup --before <date> --dupkeep <n>` | 167 - | Delete sync account | `atuin account delete` |
-132
docs/docs/guide/dotfiles.md
··· 1 - # Syncing dotfiles 2 - 3 - While Atuin started as a tool for syncing and searching shell history, we are 4 - building tooling for syncing dotfiles across machines, and making them easier 5 - to work with. 6 - 7 - At the moment, we support managing and syncing of shell aliases and environment variables - with more 8 - coming soon. 9 - 10 - The following shells are supported: 11 - 12 - - zsh 13 - - bash 14 - - fish 15 - - xonsh 16 - - powershell 17 - 18 - Note: Atuin handles your configuration internally, so once it is installed you 19 - no longer need to edit your config files manually. 20 - 21 - ## Required config 22 - 23 - Once Atuin is set up and installed, the following is required in your config file (`~/.config/atuin/config.toml`) 24 - 25 - ``` 26 - [dotfiles] 27 - enabled = true 28 - ``` 29 - 30 - In a later release, this will be enabled by default. 31 - 32 - ## Usage 33 - 34 - ### Aliases 35 - 36 - After creating or deleting an alias, remember to restart your shell! 37 - 38 - #### Creating an alias 39 - 40 - ``` 41 - atuin dotfiles alias set NAME 'COMMAND' 42 - ``` 43 - 44 - For example, to alias `k` to be `kubectl` 45 - 46 - 47 - ``` 48 - atuin dotfiles alias set k 'kubectl' 49 - ``` 50 - 51 - or to alias `ll` to be `ls -lah` 52 - 53 - ``` 54 - atuin dotfiles alias set ll 'ls -lah' 55 - ``` 56 - 57 - #### Deleting an alias 58 - 59 - Deleting an alias is as simple as: 60 - 61 - ``` 62 - atuin dotfiles alias delete NAME 63 - ``` 64 - 65 - For example, to delete the above alias `k`: 66 - 67 - ``` 68 - atuin dotfiles alias delete k 69 - ``` 70 - 71 - #### Listing aliases 72 - 73 - You can list all aliases with: 74 - 75 - ``` 76 - atuin dotfiles alias list 77 - ``` 78 - 79 - ### Env vars 80 - 81 - After creating or deleting an env var, remember to restart your shell! 82 - 83 - #### Creating a var 84 - 85 - ``` 86 - atuin dotfiles var set NAME 'value' 87 - ``` 88 - 89 - For example, to set `FOO` to be `bar` 90 - 91 - 92 - ``` 93 - atuin dotfiles var set FOO 'bar' 94 - ``` 95 - 96 - Vars are exported by default, but you can create a shell var like so 97 - 98 - ``` 99 - atuin dotfiles var set -n foo 'bar' 100 - ``` 101 - 102 - 103 - #### Deleting a var 104 - 105 - Deleting a var is as simple as: 106 - 107 - ``` 108 - atuin dotfiles var delete NAME 109 - ``` 110 - 111 - For example, to delete the above var `FOO`: 112 - 113 - ``` 114 - atuin dotfiles var delete FOO 115 - ``` 116 - 117 - #### Listing vars 118 - 119 - You can list all vars with: 120 - 121 - ``` 122 - atuin dotfiles var list 123 - ``` 124 - 125 - ### Syncing and backing up dotfiles 126 - If you have [set up sync](sync.md), then running 127 - 128 - ``` 129 - atuin sync 130 - ``` 131 - 132 - will back up your config to the server and sync it across machines.
-54
docs/docs/guide/getting-started.md
··· 1 - # Getting Started 2 - 3 - Atuin replaces your existing shell history with a SQLite database, and records 4 - additional context for your commands. With this context, Atuin gives you faster 5 - and better search of your shell history. 6 - 7 - Additionally, Atuin (optionally) syncs your shell history between all of your 8 - machines. Fully end-to-end encrypted, of course. 9 - 10 - You may use either the server I host, or host your own! Or just don't use sync 11 - at all. As all history sync is encrypted, I couldn't access your data even if I 12 - wanted to. And I **really** don't want to. 13 - 14 - If you have any problems, please open an [issue](https://github.com/ellie/atuin/issues) or get in touch on our [Discord](https://discord.gg/Fq8bJSKPHh)! 15 - 16 - ## Supported Shells 17 - 18 - - zsh 19 - - bash 20 - - fish 21 - - nushell 22 - - xonsh 23 - - powershell (tier 2 support) 24 - 25 - ## Quickstart 26 - 27 - Please do try and read this guide, but if you're in a hurry and want to get 28 - started quickly: 29 - 30 - ``` 31 - bash <(curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh) 32 - 33 - atuin register -u <USERNAME> -e <EMAIL> 34 - atuin import auto 35 - atuin sync 36 - ``` 37 - 38 - Now restart your shell! 39 - 40 - Anytime you press ctrl-r or up, you will see the Atuin search UI. Type your 41 - query, enter to execute. If you'd like to select a command without executing 42 - it, press tab. 43 - 44 - You might like to configure an [inline window](../configuration/config.md#inline_height), or [disable up arrow bindings](../configuration/key-binding.md#disable-up-arrow) 45 - 46 - Note: The above sync and registration is fully optional. If you'd like to use Atuin offline, you can run 47 - 48 - ``` 49 - bash <(curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh) 50 - 51 - atuin import auto 52 - ``` 53 - 54 - Your shell history will be local only, not backed up, and not synchronized across devices.
-18
docs/docs/guide/import.md
··· 1 - # Import existing history 2 - 3 - Atuin uses a shell plugin to ensure that we capture new shell history. But for 4 - older history, you will need to import it 5 - 6 - This will import the history for your current shell: 7 - ``` 8 - atuin import auto 9 - ``` 10 - 11 - Alternatively, you can specify the shell like so: 12 - 13 - ``` 14 - atuin import bash 15 - atuin import zsh # etc 16 - ``` 17 - 18 - Your old shell history file will continue to be updated, regardless of Atuin usage.
-308
docs/docs/guide/installation.md
··· 1 - # Installation 2 - 3 - ## Recommended installation approach 4 - 5 - ### On Unix 6 - 7 - Let's get started! First up, you will want to install Atuin. The recommended 8 - approach is to use the installation script, which automatically handles the 9 - installation of Atuin including the requirements for your environment. 10 - 11 - 12 - It will install a binary to `~/.atuin/bin`, and if you'd rather do something else 13 - then the manual steps below offer much more flexibility. 14 - 15 - ```shell 16 - curl --proto '=https' --tlsv1.2 -LsSf https://setup.atuin.sh | sh 17 - ``` 18 - 19 - The install script will walk you through importing your shell history and setting 20 - up a sync account. To skip these interactive prompts (e.g. in CI or 21 - Dockerfiles), pass `--non-interactive`: 22 - 23 - ```shell 24 - curl --proto '=https' --tlsv1.2 -LsSf https://setup.atuin.sh | sh -s -- --non-interactive 25 - ``` 26 - 27 - The script also automatically detects non-interactive environments (piped input, 28 - no TTY) and skips the prompts in those cases. 29 - 30 - [**Set up sync** - Move on to the next step, or read on to manually install Atuin instead.](sync.md) 31 - 32 - ### On Windows 33 - 34 - The recommended approach on Windows is to use WinGet to install Atuin. Then, if you use PowerShell, 35 - add the initialization command to your PowerShell profile, and restart your shell. 36 - 37 - ```shell 38 - winget install -e Atuinsh.Atuin 39 - if (-not (Test-Path -Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force | Out-Null } 40 - Write-Output 'atuin init powershell | Out-String | Invoke-Expression' >> $PROFILE 41 - ``` 42 - 43 - Note that the `$PROFILE` path may depend on your PowerShell version. 44 - 45 - [**Set up sync** - Move on to the next step.](sync.md) 46 - 47 - ## Manual installation 48 - 49 - ### Installing the binary 50 - 51 - If you don't wish to use the installer, the manual installation steps are as follows. 52 - 53 - === "Cargo" 54 - 55 - It's best to use [rustup](https://rustup.rs/) to set up a Rust 56 - toolchain, then you can run: 57 - 58 - ```shell 59 - cargo install atuin --locked 60 - ``` 61 - 62 - === "Homebrew" 63 - 64 - ```shell 65 - brew install atuin 66 - ``` 67 - 68 - === "MacPorts" 69 - 70 - Atuin is also available in [MacPorts](https://ports.macports.org/port/atuin/) 71 - 72 - ```shell 73 - sudo port install atuin 74 - ``` 75 - 76 - === "mise" 77 - 78 - Atuin is also installable using [mise](https://github.com/jdx/mise) 79 - 80 - ```shell 81 - mise use -g atuin@latest 82 - ``` 83 - 84 - === "Nix" 85 - 86 - This repository is a flake, and can be installed using `nix profile`: 87 - 88 - ```shell 89 - nix profile install "github:atuinsh/atuin" 90 - ``` 91 - 92 - Atuin is also available in [nixpkgs](https://github.com/NixOS/nixpkgs): 93 - 94 - ```shell 95 - nix-env -f '<nixpkgs>' -iA atuin 96 - ``` 97 - 98 - === "Pacman" 99 - 100 - Atuin is available in the Arch Linux [extra repository](https://archlinux.org/packages/extra/x86_64/atuin/): 101 - 102 - ```shell 103 - pacman -S atuin 104 - ``` 105 - 106 - === "XBPS" 107 - 108 - Atuin is available in the Void Linux [repository](https://github.com/void-linux/void-packages/tree/master/srcpkgs/atuin): 109 - 110 - ```shell 111 - sudo xbps-install atuin 112 - ``` 113 - 114 - === "Termux" 115 - 116 - Atuin is available in the Termux package repository: 117 - 118 - ```shell 119 - pkg install atuin 120 - ``` 121 - 122 - === "zinit" 123 - 124 - Atuin is installable from github-releases directly: 125 - 126 - ```shell 127 - # line 1: `atuin` binary as command, from github release, only look at .tar.gz files, use the `atuin` file from the extracted archive 128 - # line 2: setup at clone(create init.zsh, completion) 129 - # line 3: pull behavior same as clone, source init.zsh 130 - zinit ice as"command" from"gh-r" bpick"atuin-*.tar.gz" mv"atuin*/atuin -> atuin" \ 131 - atclone"./atuin init zsh > init.zsh; ./atuin gen-completions --shell zsh > _atuin" \ 132 - atpull"%atclone" src"init.zsh" 133 - zinit light atuinsh/atuin 134 - ``` 135 - 136 - === "WinGet" 137 - 138 - Atuin is available on WinGet: 139 - 140 - ```shell 141 - winget install -e Atuinsh.Atuin 142 - ``` 143 - 144 - === "Source" 145 - 146 - Atuin builds on the latest stable version of Rust, and we make no 147 - promises regarding older versions. We recommend using [rustup](https://rustup.rs/). 148 - 149 - ```shell 150 - git clone https://github.com/atuinsh/atuin.git 151 - cd atuin 152 - cargo install --path crates/atuin --locked 153 - ``` 154 - 155 - !!! warning "Please be advised" 156 - 157 - If you choose to manually install Atuin rather than using the recommended installation script, 158 - merely installing the binary is not sufficient, you should also set up the shell plugin. 159 - 160 - --- 161 - 162 - ### Installing the shell plugin 163 - 164 - Once the binary is installed, the shell plugin requires installing. 165 - If you use the install script, this should all be done for you! 166 - After installing, remember to restart your shell. 167 - 168 - === "zsh" 169 - 170 - ```shell 171 - echo 'eval "$(atuin init zsh)"' >> ~/.zshrc 172 - ``` 173 - 174 - === "zinit" 175 - 176 - ```shell 177 - # if you _only_ want to install the shell-plugin, do this; otherwise look above for a "everything via zinit" solution 178 - zinit load atuinsh/atuin 179 - ``` 180 - 181 - === "Antigen" 182 - 183 - ```shell 184 - antigen bundle atuinsh/atuin@main 185 - ``` 186 - 187 - === "Antidote" 188 - 189 - ```shell 190 - antidote install atuinsh/atuin 191 - ``` 192 - 193 - === "bash" 194 - 195 - === "ble.sh" 196 - 197 - Atuin works best in bash when using [ble.sh](https://github.com/akinomyoga/ble.sh) >= 0.4. 198 - 199 - With ble.sh (>= 0.4) installed and loaded in `~/.bashrc`, just add atuin to your `~/.bashrc` 200 - 201 - ```shell 202 - echo 'eval "$(atuin init bash)"' >> ~/.bashrc 203 - ``` 204 - 205 - === "bash-preexec" 206 - 207 - [Bash-preexec](https://github.com/rcaloras/bash-preexec) can also be used, but you may experience 208 - some minor problems with the recorded duration and exit status of some commands. 209 - 210 - !!! warning "Please note" 211 - 212 - bash-preexec currently has an issue where it will stop honoring `ignorespace`. 213 - While Atuin will ignore commands prefixed with whitespace, they may still end up in your bash history. 214 - Please check your configuration! All other shells do not have this issue. 215 - 216 - To use `atuin < 18.10.0` in `bash < 4` with bash-preexec, the option 217 - `enter_accept` needs to be turned on (which is so by default). There is no 218 - restriction in the latest version of Atuin (>= 18.10.0). 219 - 220 - bash-preexec cannot properly invoke the `preexec` hook for subshell commands 221 - `(...)`, function definitions `func() { ...; }`, empty for-in-statements `for 222 - i in; do ...; done`, etc., so those commands and duration may not be recorded 223 - in the Atuin's history correctly. 224 - 225 - To use bash-preexec, download and initialize it 226 - 227 - ```shell 228 - curl https://raw.githubusercontent.com/rcaloras/bash-preexec/master/bash-preexec.sh -o ~/.bash-preexec.sh 229 - echo '[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh' >> ~/.bashrc 230 - ``` 231 - 232 - Then set up Atuin 233 - 234 - ```shell 235 - echo 'eval "$(atuin init bash)"' >> ~/.bashrc 236 - ``` 237 - 238 - === "fish" 239 - 240 - Add 241 - 242 - ```shell 243 - atuin init fish | source 244 - ``` 245 - 246 - to your `is-interactive` block in your `~/.config/fish/config.fish` file 247 - 248 - === "Nushell" 249 - 250 - Run in *Nushell*: 251 - 252 - ```shell 253 - mkdir ~/.local/share/atuin/ 254 - atuin init nu | save ~/.local/share/atuin/init.nu 255 - ``` 256 - 257 - Add to `config.nu`: 258 - 259 - ```shell 260 - source ~/.local/share/atuin/init.nu 261 - ``` 262 - 263 - ??? tip "Optional: Atuin pty-proxy" 264 - pty-proxy is a lightweight pty proxy that renders the Atuin popup over 265 - your previous output, restoring it when closed — no clearing, no 266 - fullscreen. To use pty-proxy with Nushell, generate the init script: 267 - 268 - ```shell 269 - mkdir ~/.local/share/atuin/ 270 - atuin pty-proxy init nu | save -f ~/.local/share/atuin/pty-proxy-init.nu 271 - ``` 272 - 273 - Then source it as early as possible in your `config.nu`, *before* 274 - the regular atuin init: 275 - 276 - ```shell 277 - source ~/.local/share/atuin/pty-proxy-init.nu 278 - source ~/.local/share/atuin/init.nu 279 - ``` 280 - 281 - Nushell's `source` command requires a static file path, so you must 282 - pre-generate both files. 283 - 284 - === "xonsh" 285 - 286 - Add 287 - ```shell 288 - execx($(atuin init xonsh)) 289 - ``` 290 - to the end of your `~/.xonshrc` 291 - 292 - === "PowerShell" 293 - 294 - Add the following to the end of your `$PROFILE` file: 295 - 296 - ```shell 297 - atuin init powershell | Out-String | Invoke-Expression 298 - ``` 299 - 300 - ## Upgrade 301 - 302 - Run `atuin update`, and if that command is not available, run the install script again. 303 - 304 - If you used a package manager to install Atuin, then you should also use your package manager to update Atuin. 305 - 306 - ## Uninstall 307 - 308 - If you'd like to uninstall Atuin, please check out [the uninstall page](../uninstall.md).
-263
docs/docs/guide/shell-integration.md
··· 1 - # Shell Integration and Interoperability 2 - 3 - Atuin uses shell hooks to capture your command history. This page explains how the integration works, why Atuin might not record commands in certain environments, and how to control what gets recorded. 4 - 5 - ## How Atuin's Shell Integration Works 6 - 7 - When you add `eval "$(atuin init <shell>)"` to your shell configuration, Atuin installs hooks that run at specific points in your shell's command lifecycle: 8 - 9 - 1. **Preexec hook**: Runs *before* each command executes. Atuin records the command text, timestamp, and working directory. 10 - 2. **Precmd hook**: Runs *after* each command completes. Atuin records the exit code and duration. 11 - 12 - These hooks only activate under specific conditions: 13 - 14 - - The shell must be **interactive** (started with `-i` or inherently interactive) 15 - - Your shell configuration file must be **sourced** (`.bashrc`, `.zshrc`, etc.) 16 - - The `atuin init` command must run during shell startup 17 - 18 - If any of these conditions aren't met, Atuin's hooks won't be installed, and commands won't be recorded. 19 - 20 - ### Environment Variables 21 - 22 - When Atuin initializes, it sets several environment variables: 23 - 24 - | Variable | Purpose | 25 - |----------|---------| 26 - | `ATUIN_SESSION` | Unique identifier for this shell session | 27 - | `ATUIN_SHLVL` | Tracks shell nesting level | 28 - | `ATUIN_HISTORY_ID` | Temporary ID for the currently executing command | 29 - | `ATUIN_HISTORY_AUTHOR` | Optional command author identity (for example `ellie`, `claude`, `copilot`) | 30 - | `ATUIN_HISTORY_INTENT` | Optional command intent/rationale text | 31 - 32 - These variables are used internally to track command execution and associate commands with sessions. 33 - If `ATUIN_HISTORY_AUTHOR` is not set, Atuin defaults to the local shell username. 34 - 35 - ## Embedded Terminals and IDE Integrations 36 - 37 - Many development tools include embedded terminals: 38 - 39 - - **IDEs**: PyCharm, IntelliJ, VS Code, Cursor, Zed 40 - - **AI coding assistants**: Claude Code, GitHub Copilot CLI, Aider 41 - - **Container environments**: Docker, Podman, devcontainers 42 - 43 - These tools often spawn shells differently than your regular terminal, which can prevent Atuin from working. 44 - 45 - ### Why Atuin Might Not Work 46 - 47 - Embedded terminals commonly: 48 - 49 - 1. **Start non-interactive shells**: Many tools run commands via `bash -c "command"` or similar, which doesn't trigger shell configuration 50 - 2. **Skip shell configuration**: Some tools explicitly avoid sourcing `.bashrc`/`.zshrc` for performance or isolation 51 - 3. **Use different shell paths**: The embedded terminal might use a different shell than your default 52 - 53 - You can verify whether Atuin is active by running: 54 - 55 - ```shell 56 - atuin doctor 57 - ``` 58 - 59 - Look for the `shell.preexec` field in the output. If it shows `none`, Atuin's hooks aren't installed in that shell session. 60 - 61 - ### Enabling Atuin in Embedded Terminals 62 - 63 - If you want Atuin to record commands from an embedded terminal, you'll need to ensure it starts an interactive shell that sources your configuration. 64 - 65 - #### IDE Terminal Settings 66 - 67 - Most IDEs let you customize the shell command used for their integrated terminal: 68 - 69 - **PyCharm / IntelliJ:** 70 - 71 - 1. Go to Settings → Tools → Terminal 72 - 2. Change "Shell path" to include the `-i` flag: 73 - - Linux/macOS: `/bin/bash -i` or `/bin/zsh -i` 74 - - Or create a wrapper script (see below) 75 - 76 - **VS Code:** 77 - 78 - Add to your `settings.json` (substitute the shells for whatever you use): 79 - 80 - ```json 81 - { 82 - "terminal.integrated.profiles.linux": { 83 - "bash": { 84 - "path": "/bin/bash", 85 - "args": ["-i"] 86 - } 87 - }, 88 - "terminal.integrated.profiles.osx": { 89 - "zsh": { 90 - "path": "/bin/zsh", 91 - "args": ["-i"] 92 - } 93 - } 94 - } 95 - ``` 96 - 97 - #### Wrapper Script Approach 98 - 99 - For tools that don't easily support shell arguments, create a wrapper script: 100 - 101 - ```shell 102 - #!/bin/bash 103 - # Save as ~/bin/interactive-bash.sh and chmod +x 104 - exec /bin/bash -i "$@" 105 - ``` 106 - 107 - Then configure your IDE to use `~/bin/interactive-bash.sh` as the shell path. 108 - 109 - #### Verifying the Fix 110 - 111 - After configuring, open a new terminal in your IDE and run: 112 - 113 - ```shell 114 - atuin doctor | grep preexec 115 - ``` 116 - 117 - You should see `built-in`, `bash-preexec`, `blesh`, or similar—not `none`. 118 - 119 - ## Excluding Commands from History 120 - 121 - Sometimes you *don't* want certain commands in your history. This is common when: 122 - 123 - - AI coding tools run many automated commands (git status, file listings, etc.) 124 - - You're running sensitive commands you don't want synced 125 - - Build tools or scripts generate repetitive command noise 126 - 127 - ### Using history_filter 128 - 129 - The `history_filter` option in `~/.config/atuin/config.toml` lets you exclude commands matching specific patterns: 130 - 131 - ```toml 132 - history_filter = [ 133 - "^ls$", # Exclude bare 'ls' commands 134 - "^cd ", # Exclude cd commands 135 - "^cat ", # Exclude cat commands 136 - ] 137 - ``` 138 - 139 - Patterns are regular expressions. They're unanchored by default, so `secret` matches anywhere in a command. Use `^` and `$` for exact matching. 140 - 141 - ### Using cwd_filter 142 - 143 - To exclude all commands run from specific directories: 144 - 145 - ```toml 146 - cwd_filter = [ 147 - "^/tmp", # Exclude commands run from /tmp 148 - "/node_modules/", # Exclude commands from any node_modules 149 - "^/home/user/scratch", # Exclude a scratch directory 150 - ] 151 - ``` 152 - 153 - ### Prefix with Space (ignorespace) 154 - 155 - Most shells support "ignorespace"—commands prefixed with a space aren't saved to history. Atuin honors this convention: 156 - 157 - ```shell 158 - echo "this won't be saved" # Note the leading space 159 - ``` 160 - 161 - !!! warning "Bash with bash-preexec" 162 - When using bash-preexec (not ble.sh), there's a known issue where ignorespace isn't fully honored. The command won't appear in Atuin, but may still appear in your bash history. See [installation](installation.md) for details. 163 - 164 - ### Disabling Atuin for Specific Tools 165 - 166 - If a tool spawns interactive shells but you don't want its commands recorded, you have several options: 167 - 168 - #### Option 1: Environment Variable Check 169 - 170 - Modify your shell configuration to skip Atuin initialization based on an environment variable: 171 - 172 - ```shell 173 - # In .bashrc or .zshrc 174 - if [[ -z "${MY_TOOL_SESSION}" ]]; then 175 - eval "$(atuin init bash)" 176 - fi 177 - ``` 178 - 179 - Then configure your tool to set `MY_TOOL_SESSION=1` when spawning shells. 180 - 181 - #### Option 2: Use history_filter for Tool-Specific Patterns 182 - 183 - If the tool runs predictable commands, filter them: 184 - 185 - ```toml 186 - history_filter = [ 187 - "^git status$", 188 - "^git diff", 189 - "^ls -la$", 190 - ] 191 - ``` 192 - 193 - #### Option 3: Filter by Directory 194 - 195 - If the tool operates in specific directories: 196 - 197 - ```toml 198 - cwd_filter = [ 199 - "^/path/to/tool/workspace", 200 - ] 201 - ``` 202 - 203 - ### Cleaning Up Existing History 204 - 205 - After adding filters, you can remove matching entries from your existing history: 206 - 207 - ```shell 208 - atuin history prune 209 - ``` 210 - 211 - This removes entries that match your current `history_filter` or `cwd_filter` patterns. 212 - 213 - ## Shell-Specific Notes 214 - 215 - ### Bash 216 - 217 - Atuin supports two preexec backends for Bash: 218 - 219 - - **ble.sh** (recommended): Full-featured line editor with accurate timing and proper ignorespace support 220 - - **bash-preexec**: Simpler but has some limitations with subshells and ignorespace 221 - 222 - The shell integration explicitly checks for interactive mode: 223 - 224 - ```bash 225 - if [[ $- != *i* ]]; then 226 - # Not interactive, skip initialization 227 - return 228 - fi 229 - ``` 230 - 231 - ### Zsh 232 - 233 - Zsh has native hook support via `add-zsh-hook`. The integration is straightforward and works reliably in interactive sessions. 234 - 235 - ### Fish 236 - 237 - Fish uses its event system (`fish_preexec` and `fish_postexec` events). It also respects Fish's private mode—commands run with `fish --private` aren't recorded. 238 - 239 - ## Troubleshooting 240 - 241 - ### Commands aren't being recorded 242 - 243 - 1. Run `atuin doctor` and check the output 244 - 2. Verify `shell.preexec` is not `none` 245 - 3. Ensure your shell is interactive (`echo $-` should contain `i`) 246 - 4. Check that `atuin init` is in your shell config and being sourced 247 - 248 - ### Commands from a specific tool aren't recorded 249 - 250 - 1. Check if the tool starts an interactive shell 251 - 2. Try configuring the tool to use `bash -i` or `zsh -i` 252 - 3. Use a wrapper script if the tool doesn't support shell arguments 253 - 254 - ### Too many commands are being recorded 255 - 256 - 1. Add patterns to `history_filter` in your config 257 - 2. Use `cwd_filter` for directory-based exclusion 258 - 3. Prefix sensitive commands with a space 259 - 4. Run `atuin history prune` to clean existing entries 260 - 261 - ### Atuin works in terminal but not in IDE 262 - 263 - This is the most common issue. The IDE's embedded terminal likely isn't starting an interactive shell. See [Enabling Atuin in Embedded Terminals](#enabling-atuin-in-embedded-terminals) above.
-78
docs/docs/guide/sync.md
··· 1 - # Setting up Sync 2 - 3 - At this point, you have Atuin storing and searching your shell history! But it 4 - isn't syncing it just yet. To do so, you'll need to register with the sync 5 - server. All of your history is fully end-to-end encrypted, so there are no 6 - risks of the server snooping on you. 7 - 8 - If you don't have an account, please [register](#register). If you have already registered, 9 - proceed to [login](#login). 10 - 11 - **Note:** You first have to set up your `sync_address` if you want to use a [self hosted server](../self-hosting/server-setup.md). 12 - 13 - ## Register 14 - 15 - ``` 16 - atuin register -u <YOUR_USERNAME> -e <YOUR EMAIL> 17 - ``` 18 - 19 - After registration, Atuin will generate an encryption key for you and store it 20 - locally. This is needed for logging in to other machines, and can be seen with 21 - 22 - ``` 23 - atuin key 24 - ``` 25 - 26 - Please **never** share this key with anyone! The Atuin developers will never 27 - ask you for your key, your password, or the contents of your Atuin directory. 28 - 29 - If you lose your key, we can do nothing to help you. We recommend you store 30 - this somewhere safe, such as in a password manager. 31 - 32 - ## First sync 33 - By default, Atuin will sync your history once per hour. This can be 34 - [configured](../configuration/config.md#sync_frequency). 35 - 36 - To run a sync manually, please run 37 - 38 - ``` 39 - atuin sync 40 - ``` 41 - 42 - Atuin tries to be smart with a sync, and not waste data transfer. However, if 43 - you are seeing some missing data, please try running 44 - 45 - ``` 46 - atuin sync -f 47 - ``` 48 - 49 - This triggers a full sync, which may take longer as it works through historical data. 50 - 51 - ## Login 52 - 53 - When only signed in on one machine, Atuin sync operates as a backup. This is 54 - pretty useful by itself, but syncing multiple machines is where the magic 55 - happens. 56 - 57 - First, ensure you are [registered with the sync server](#register) and make a 58 - note of your key. You can see this with `atuin key`. 59 - 60 - Then, install Atuin on a new machine. Once installed, login with 61 - 62 - ``` 63 - atuin login -u <USERNAME> 64 - ``` 65 - 66 - You will be prompted for your password, and for your key. 67 - 68 - Syncing will happen automatically in the background, but you may wish to run it manually with 69 - 70 - ``` 71 - atuin sync 72 - ``` 73 - 74 - Or, if you see missing data, force a full sync with: 75 - 76 - ``` 77 - atuin sync -f 78 - ```
-138
docs/docs/guide/theming.md
··· 1 - # Theming 2 - 3 - Available in Atuin >= 18.4 4 - 5 - For terminal interface customization, Atuin supports user and built-in color themes. 6 - 7 - Atuin ships with only a couple of built-in alternative themes, but more can be added via TOML files. 8 - 9 - ## Required config 10 - 11 - The following is required in your config file (`~/.config/atuin/config.toml`) 12 - 13 - ``` 14 - [theme] 15 - name = "THEMENAME" 16 - ``` 17 - 18 - Where `THEMENAME` is a known theme. The following themes are available out-of-the-box: 19 - 20 - * `default` theme 21 - * `autumn` theme 22 - * `marine` theme 23 - * `(none)` theme (removes all styling) 24 - 25 - These are present to ensure users and developers can try out theming, but in general, you 26 - will need to download themes or make your own. 27 - 28 - If you are writing your own themes, you can add the following line to get additional output: 29 - 30 - ``` 31 - debug = true 32 - ``` 33 - 34 - to the same config block. This will print out any color names that cannot be parsed from 35 - the requested theme. 36 - 37 - A final optional setting is available: 38 - 39 - ``` 40 - max_depth: 10 41 - ``` 42 - 43 - which sets the maximum levels of theme parents to traverse. This should not need to be 44 - explicitly added in normal use. 45 - 46 - ## Usage 47 - 48 - ### Theme structure 49 - 50 - Themes are maps from *Meanings*, describing the developer's intentions, 51 - to (at present) colors. In future, this may be expanded to allow richer style support. 52 - 53 - *Meanings* are from an enum with the following values: 54 - 55 - * `AlertInfo`: alerting the user at an INFO level 56 - * `AlertWarn`: alerting the user at a WARN level 57 - * `AlertError`: alerting the user at an ERROR level 58 - * `Annotation`: less-critical, supporting text 59 - * `Base`: default foreground color 60 - * `Guidance`: instructing the user as help or context 61 - * `Important`: drawing the user's attention to information 62 - * `Title`: titling a section or view 63 - * `Muted`: anodyne, usually grey, foreground for contrast with other colors. Normally equivalent to the base color, but allows themes to change the base color, with less risk of breaking intentional color contrasts (e.g. stacked bar charts) 64 - 65 - These may expand over time as they are added to Atuin's codebase, but Atuin 66 - should have fallbacks added for any new *Meanings* so that, whether themes limit to 67 - the present list or take advantage of new *Meanings* in future, they should 68 - keep working sensibly. 69 - 70 - **Note for Atuin contributors**: please do identify and, where appropriate during your own 71 - PRs, extend the Meanings enum if needed (along with a fallback Meaning!). 72 - 73 - ### Theme creation 74 - 75 - When a theme name is read but not yet loaded, Atuin will look for it in the folder 76 - `~/.config/atuin/themes/` unless overridden by the `ATUIN_THEME_DIR` environment 77 - variable. It will attempt to open a file of name `THEMENAME.toml` and read it as a 78 - map from *Meanings* to foreground colors. 79 - 80 - Note that, at present, it is not possible to specify the default terminal color explicitly 81 - in a theme file. However, the default theme Base color will always be unset and therefore 82 - will be the user's default terminal color. Hence, you should only override the Base color 83 - in your theme, or derive from a theme that does so, if your theme would not make sense 84 - otherwise (e.g. the `marine` theme is intended to make everything green/blue, so it does, 85 - but the `autumn` theme only seeks to make the custom colors warmer, so it does not). 86 - 87 - Colors may be specified either as names from the [palette](https://ogeon.github.io/docs/palette/master/palette/named/index.html) 88 - crate in lowercase, or as six-character hex codes, prefixed with `#`. To explicitly select ANSI colors by integer, or for greater flexibility in general, you can prefix with `@` and the rest of the string will be handled by crossterm's color parsing. For examples, see [crossterm's color deserialization tests](https://github.com/crossterm-rs/crossterm/blob/5d50d8da62c5e034ef8b2787a771a2c0f9b3b2f9/src/style/types/color.rs#L389), remembering the need to add a `@` prefix for atuin. 89 - 90 - For example, the following are valid color names: 91 - 92 - * `#ff0088` 93 - * `teal` 94 - * `powderblue` 95 - * `@ansi_(255)` 96 - * `@rgb_(255, 128, 0)` 97 - 98 - You can also express colors through Crossterm-supported strings, prefixed by `@`. 99 - For example, 100 - 101 - * `@ansi_(123)` 102 - * `@dark_yellow` 103 - 104 - While there is not currently an official reference, you can see examples in the 105 - [crossterm tests](https://docs.rs/crossterm/latest/src/crossterm/style/types/color.rs.html#376). 106 - As this is passed straight to Crossterm, using [ANSI codes](https://www.ditig.com/256-colors-cheat-sheet) 107 - can be helpful for ensuring your theme is compatible with 256-color terminals. 108 - 109 - A theme file, say `my-theme.toml` can then be built up, such as: 110 - 111 - ```toml 112 - [theme] 113 - name = "my-theme" 114 - parent = "autumn" 115 - 116 - [colors] 117 - AlertInfo = "green" 118 - Guidance = "#888844" 119 - 120 - ``` 121 - 122 - where not all of the *Meanings* need to be explicitly defined. If they are absent, 123 - then the color will be chosen from the parent theme, if one is defined, or if that 124 - key is missing in the `theme` block, from the `default` theme. 125 - 126 - If the entire named theme is missing, which is inherently an error, then the theme 127 - will drop to `(none)` and leave Atuin unstyled, rather than trying to fallback to 128 - the any default, or other, theme. 129 - 130 - This theme file should be moved to `~/.config/atuin/themes/my-theme.toml` and the 131 - following added to `~/.config/atuin/config.toml`: 132 - 133 - ``` 134 - [theme] 135 - name = "my-theme" 136 - ``` 137 - 138 - When you next run Atuin, your theme should be applied.
-48
docs/docs/index.md
··· 1 - # Getting started 2 - 3 - Atuin replaces your existing shell history with a SQLite database, and records 4 - additional context for your commands. With this context, Atuin gives you faster 5 - and better search of your shell history. 6 - 7 - Additionally, Atuin (optionally) syncs your shell history between all of your 8 - machines. Fully end-to-end encrypted, of course. 9 - 10 - You may use either the server I host, or host your own! Or just don't use sync 11 - at all. As all history sync is encrypted, I couldn't access your data even if I 12 - wanted to. And I **really** don't want to. 13 - 14 - If you have any problems, please open a topic on the [forum](https://forum.atuin.sh) 15 - 16 - Alternatively, get in touch on our [Discord](https://discord.gg/Fq8bJSKPHh) or open an [issue](https://github.com/atuinsh/atuin/issues) 17 - 18 - #### Supported Shells 19 - 20 - - zsh 21 - - bash 22 - - fish 23 - - nushell 24 - - xonsh 25 - - powershell (tier 2 support) 26 - 27 - ## Quickstart 28 - 29 - Please do try and read this guide, but if you're in a hurry and want to get 30 - started quickly: 31 - 32 - ```bash 33 - bash <(curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh) 34 - 35 - atuin register -u <USERNAME> -e <EMAIL> 36 - atuin import auto 37 - atuin sync 38 - ``` 39 - 40 - Now restart your shell! 41 - 42 - Anytime you press ctrl-r or up, you will see the Atuin search UI. Type your 43 - query, enter to execute. If you'd like to select a command without executing 44 - it, press tab. 45 - 46 - You might like to configure an [inline window](configuration/config.md#inline_height), or [disable up arrow bindings](configuration/key-binding.md#disable-up-arrow) 47 - 48 - [**Installation** - Install and setup Atuin](guide/installation.md)
-41
docs/docs/integrations.md
··· 1 - # Integrations 2 - 3 - This page covers integrations with shell plugins and tools. For information about how Atuin's shell hooks work and troubleshooting embedded terminals (IDEs, AI coding assistants, etc.), see [Shell Integration and Interoperability](guide/shell-integration.md). 4 - 5 - ## zsh-autosuggestions 6 - 7 - Atuin automatically adds itself as an [autosuggest strategy](https://github.com/zsh-users/zsh-autosuggestions#suggestion-strategy). 8 - 9 - If you'd like to override this, add your own config after `"$(atuin init zsh)"` in your `.zshrc`. 10 - 11 - ## zsh-vi-mode 12 - 13 - If you are using [Zsh Vi Mode](https://github.com/jeffreytse/zsh-vi-mode), you may want to add the following to your `.zshrc` to prevent overriding the default atuin binds: 14 - 15 - ```shell 16 - # Append a command directly (after sourcing zvm) 17 - zvm_after_init_commands+=( 18 - 'eval "$(atuin init zsh)"' 19 - ) 20 - ``` 21 - 22 - ## ble.sh auto-complete (Bash) 23 - 24 - If ble.sh is available when Atuin's integration is loaded in Bash, Atuin automatically defines and registers an auto-complete source for the autosuggestion feature of ble.sh. 25 - 26 - If you'd like to change the behavior, please overwrite the shell function `ble/complete/auto-complete/source:atuin-history` after `eval "$(atuin init bash)"` in your `.bashrc`. 27 - 28 - If you would not like Atuin's auto-complete source, please add the following setting after `eval "$(atuin init bash)"` in your `.bashrc`: 29 - 30 - ```shell 31 - # bashrc (after eval "$(atuin init bash)") 32 - 33 - ble/util/import/eval-after-load core-complete ' 34 - ble/array#remove _ble_complete_auto_source atuin-history' 35 - ``` 36 - 37 - ## Embedded Terminals and IDEs 38 - 39 - Atuin may not work out of the box in embedded terminals found in IDEs (PyCharm, VS Code, etc.) or AI coding assistants (Claude Code, etc.). This is because these tools often start non-interactive shells that don't source your shell configuration. 40 - 41 - For solutions and workarounds, see [Shell Integration and Interoperability](guide/shell-integration.md).
-4
docs/docs/known-issues.md
··· 1 - # Known Issues 2 - 3 - - SQLite has some issues with ZFS in certain configurations. As Atuin uses SQLite, this may cause your shell to become slow! We have an [issue](https://github.com/atuinsh/atuin/issues/952) to track, with some workarounds 4 - - SQLite also does not tend to like network filesystems (eg, NFS)
-127
docs/docs/reference/config.md
··· 1 - # config 2 - 3 - ## `atuin config` 4 - 5 - Read, write, and inspect Atuin configuration values. Atuin resolves 6 - configuration from multiple sources (defaults, config file, environment 7 - variables). The `config` command lets you see what is set where, and change 8 - values in your `config.toml` without opening an editor. 9 - 10 - ## Subcommands 11 - 12 - ### `atuin config get <key>` 13 - 14 - Print the value of a key as it appears in your config file. 15 - 16 - ``` 17 - $ atuin config get search_mode 18 - fuzzy 19 - 20 - $ atuin config get daemon 21 - [daemon] 22 - enabled = true 23 - socket_path = "/tmp/atuin_daemon.sock" 24 - ``` 25 - 26 - If the key is not present in the config file, you'll see: 27 - 28 - ``` 29 - $ atuin config get enter_accept 30 - (not set in config file) 31 - ``` 32 - 33 - #### `--resolved` / `-r` 34 - 35 - Print the effective value after merging defaults, the config file, and 36 - environment variable overrides: 37 - 38 - ``` 39 - $ atuin config get enter_accept --resolved 40 - false 41 - ``` 42 - 43 - This also works for table keys, showing all resolved children as flat 44 - dotted key=value pairs: 45 - 46 - ``` 47 - $ atuin config get logs --resolved 48 - logs.ai.file = ai.log 49 - logs.daemon.file = daemon.log 50 - logs.dir = /home/user/.local/share/atuin/logs 51 - logs.enabled = true 52 - logs.level = info 53 - logs.search.file = search.log 54 - ``` 55 - 56 - #### `--verbose` / `-v` 57 - 58 - Show both the config file value and the resolved value side by side: 59 - 60 - ``` 61 - $ atuin config get enter_accept --verbose 62 - Config file: 63 - (not set in config file) 64 - 65 - Resolved: 66 - false 67 - ``` 68 - 69 - ### `atuin config set <key> <value>` 70 - 71 - Set a configuration value in your `config.toml`. The file's existing 72 - formatting and comments are preserved. 73 - 74 - ``` 75 - $ atuin config set search_mode fuzzy 76 - $ atuin config set daemon.enabled true 77 - ``` 78 - 79 - #### Type detection 80 - 81 - By default, `set` matches the TOML type of the existing value when the key 82 - is already in the config file. This prevents accidentally changing a string 83 - like `"300"` into an integer `300`. 84 - 85 - For new keys (not already in the file), `set` auto-detects the type: 86 - 87 - | Value | Detected type | 88 - |---------------|---------------| 89 - | `true`/`false`| boolean | 90 - | `42`, `-1` | integer | 91 - | `3.14` | float | 92 - | anything else | string | 93 - 94 - !!! warning "Scalar values only" 95 - `atuin config set` can only set config entries with scalar values; for tables or arrays, edit the config file manually. 96 - 97 - #### `--type` / `-t` 98 - 99 - Override type detection with an explicit type: 100 - 101 - ``` 102 - $ atuin config set sync_frequency 600 --type string 103 - ``` 104 - 105 - Possible values: `auto`, `string`, `boolean`, `integer`, `float`. 106 - 107 - Setting a key that is currently a table will produce an error directing you 108 - to use a dotted key instead: 109 - 110 - ``` 111 - $ atuin config set logs true 112 - Error: 'logs' is a table; use a dotted key like 'logs.key' to set a value within it 113 - ``` 114 - 115 - ### `atuin config print [key]` 116 - 117 - Print configuration values from your config file in TOML format. Without a 118 - key, prints the entire file. With a key, prints that section: 119 - 120 - ``` 121 - $ atuin config print daemon 122 - [daemon] 123 - enabled = true 124 - socket_path = "/tmp/atuin_daemon.sock" 125 - pidfile_path = "/tmp/atuin_daemon.pid" 126 - autostart = false 127 - ```
-32
docs/docs/reference/daemon.md
··· 1 - # daemon 2 - 3 - ## `atuin daemon` 4 - 5 - The Atuin daemon is a background daemon designed to 6 - 7 - 1. Speed up database writes 8 - 2. Allow machines to sync when not in use, so they're ready to go right away 9 - 3. Provides a hot in-memory fuzzy searcher 10 - 4. Perform background maintenance 11 - 12 - It may also work around issues with ZFS/SQLite performance. 13 - 14 - ## To enable 15 - 16 - Add the following to the bottom of your Atuin config file 17 - 18 - ```toml 19 - [daemon] 20 - enabled = true 21 - autostart = true 22 - ``` 23 - 24 - With `autostart = true`, the CLI will automatically start and manage a local daemon for history hook calls. 25 - If you use systemd socket activation, keep `autostart = false`. 26 - If a legacy experimental daemon is already running, autostart cannot upgrade it in-place. Restart the daemon manually once. 27 - 28 - If you prefer running the daemon yourself (for example via systemd/tmux), keep `autostart = false` and run `atuin daemon`. 29 - 30 - ## Extra config 31 - 32 - See the [config section](../configuration/config.md#daemon)
-38
docs/docs/reference/doctor.md
··· 1 - # doctor 2 - 3 - ## `atuin doctor` 4 - 5 - This command will attempt to diagnose common problems. It will also dump information about your system 6 - 7 - Please include its output with issues and support requests. 8 - 9 - Example output: 10 - 11 - ``` 12 - Atuin Doctor 13 - Checking for diagnostics 14 - 15 - 16 - Please include the output below with any bug reports or issues 17 - 18 - atuin: 19 - version: 18.1.0 20 - sync: 21 - cloud: true 22 - records: true 23 - auto_sync: true 24 - last_sync: 2024-03-05 14:54:48.447677 +00:00:00 25 - shell: 26 - name: zsh 27 - plugins: 28 - - atuin 29 - system: 30 - os: Darwin 31 - arch: arm64 32 - version: 14.4 33 - disks: 34 - - name: Macintosh HD 35 - filesystem: apfs 36 - - name: Macintosh HD 37 - filesystem: apfs 38 - ```
-20
docs/docs/reference/gen-completions.md
··· 1 - # gen-completions 2 - 3 - [Shell completions](https://en.wikipedia.org/wiki/Command-line_completion) for Atuin can be generated by specifying the output directory and desired shell via `gen-completions` subcommand. 4 - 5 - ``` 6 - $ atuin gen-completions --shell bash --out-dir $HOME 7 - 8 - Shell completion for BASH is generated in "/home/user" 9 - ``` 10 - 11 - Possible values for the `--shell` argument are the following: 12 - 13 - - `bash` 14 - - `fish` 15 - - `zsh` 16 - - `nushell` 17 - - `powershell` 18 - - `elvish` 19 - 20 - Also, see the [supported shells](https://github.com/atuinsh/atuin#supported-shells).
-1
docs/docs/reference/hex.md
··· 1 - `atuin hex` has been renamed `atuin pty-proxy` as of Atuin v18.17.0.
-109
docs/docs/reference/import.md
··· 1 - # import 2 - 3 - ## `atuin import` 4 - 5 - Atuin can import your history from your "old" history file 6 - 7 - `atuin import auto` will attempt to figure out your shell (via \$SHELL) and run 8 - the correct importer 9 - 10 - Unfortunately these older files do not store as much information as Atuin does, 11 - so not all features are available with imported data. 12 - 13 - Except as noted otherwise, you can set the `HISTFILE` environment variable to 14 - control which file is read, otherwise each importer will try some default filenames. 15 - 16 - ``` 17 - HISTFILE=/path/to/history/file atuin import zsh 18 - ``` 19 - 20 - Note that for shells such as Xonsh that store history in many files rather than a 21 - single file, `$HISTFILE` should be set to the directory in which those files reside. 22 - 23 - For formats that don't store timestamps, timestamps will be generated starting at 24 - the current time plus 1ms for each additional command in the history. 25 - 26 - Most importers will discard commands found that have invalid UTF-8. 27 - 28 - ## bash 29 - 30 - This will read the history from `$HISTFILE` or `$HOME/.bash_history`. 31 - 32 - Warnings will be issued if timestamps are found to be out of order, which could also 33 - happen when a history file starts without timestamps but later entries include them. 34 - 35 - ## fish 36 - 37 - fish supports multiple history sessions, so the importer will default to the `fish` 38 - session unless the `fish_history` environment variable is set. The file to be read 39 - will be `{session}_history` in `$XDG_DATA_HOME/fish/` (or `$HOME/.local/share/fish`). 40 - 41 - Not all of the data in the fish history is preserved, some data about filenames used 42 - for each command are not used by Atuin, so it is discarded. 43 - 44 - ## nu 45 - 46 - This importer reads from Nushell's text history format, which is stored in 47 - `$XDG_CONFIG_HOME/nushell/history.txt` or `$HOME/.config/nushell/history.txt`. 48 - There is no way to set the filename otherwise. 49 - 50 - ## nu-hist-db 51 - 52 - This importer reads from Nushell's SQLite history database, which is stored in 53 - `$XDG_CONFIG_HOME/nushell/history.sqlite3` or `$HOME/.config/nushell/history.sqlite3`. 54 - There is no way to set the filename otherwise. 55 - 56 - ## powershell 57 - 58 - This importer reads from 59 - [PowerShell's history file](https://learn.microsoft.com/en-us/powershell/module/psreadline/about/about_psreadline#command-history). 60 - On Windows, the file is located at 61 - `$APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt`. 62 - On other systems, it is located at 63 - `$XDG_DATA_HOME/powershell/PSReadLine/ConsoleHost_history.txt` 64 - or `$HOME/.local/share/powershell/PSReadLine/ConsoleHost_history.txt`. 65 - 66 - ## replxx 67 - 68 - The [replxx](https://github.com/AmokHuginnsson/replxx) importer will read from 69 - `$HISTFILE` or `$HOME/.histfile`. 70 - 71 - ## resh 72 - 73 - The [RESH](https://github.com/curusarn/resh) importer will read from `$HISTFILE` 74 - or `$HOME/.resh_history.json`. 75 - 76 - ## xonsh 77 - 78 - The Xonsh importer will read from all JSON files it finds in the Xonsh history 79 - directory. The location of the directory is determined as follows: 80 - * If `$HISTFILE` is set, its value is used as the history directory. 81 - * If `$XONSH_DATA_DIR` is set (as it typically will be if the importer is invoked 82 - from within Xonsh), `$XONSH_DATA_DIR/history_json` is used. 83 - * If `$XDG_DATA_HOME` is set, `$XDG_DATA_HOME/xonsh/history_json` is used. 84 - * Otherwise, `$HOME/.local/share/xonsh/history_json` is used. 85 - 86 - Not all data present in Xonsh history JSON files is used by Atuin. Xonsh stores the 87 - environment variables present when each session was initiated, but this data is 88 - discarded by Atuin. Xonsh optionally stores the output of each command; if present 89 - this data is also ignored by Atuin. 90 - 91 - ## xonsh-sqlite 92 - 93 - The Xonsh SQLite importer will read from the Xonsh SQLite history file. The history 94 - file's location is determined by the same process as the regular Xonsh importer, 95 - but with `history_json` replaced by `xonsh-history.sqlite`. 96 - 97 - The Xonsh SQLite backend does not store environment variables, but like the JSON 98 - backend it can optionally store the output of each command. As with the JSON backend, 99 - if present this data will be ignored by Atuin. 100 - 101 - ## zsh 102 - 103 - This will read the Zsh history from `$HISTFILE` or `$HOME/.zhistory` 104 - or `$HOME/.zsh_history` in either the simple or extended format. 105 - 106 - ## zsh-hist-db 107 - 108 - This will read the Zsh histdb SQLite file from `$HISTDB_FILE` or 109 - `$HOME/.histdb/zsh-history.db`.
-22
docs/docs/reference/info.md
··· 1 - # info 2 - 3 - ## `atuin info` 4 - 5 - This command shows the location of config files on your system 6 - 7 - Example output: 8 - 9 - ``` 10 - Config files: 11 - client config: "/Users/ellie/.config/atuin/config.toml" 12 - server config: "/Users/ellie/.config/atuin/server.toml" 13 - client db path: "/Users/ellie/.local/share/atuin/history.db" 14 - key path: "/Users/ellie/.local/share/atuin/key" 15 - session path: "/Users/ellie/.local/share/atuin/session" 16 - 17 - Env Vars: 18 - ATUIN_CONFIG_DIR = "None" 19 - 20 - Version info: 21 - version: 18.1.0 22 - ```
-31
docs/docs/reference/list.md
··· 1 - # history list 2 - 3 - ## `atuin history list` 4 - 5 - 6 - | Arg | Description | 7 - |------------------|-------------------------------------------------------------------------------| 8 - | `--cwd`/`-c` | List history for the current directory only (default: all dirs) | 9 - | `--session`/`-s` | List history for the current session only (default: false) | 10 - | `--human` | Use human-readable formatting for the timestamp and duration (default: false) | 11 - | `--cmd-only` | Show only the text of the command (default: false) | 12 - | `--reverse` | Reverse the order of the output (default: false) | 13 - | `--format` | Specify the formatting of a command (see below) | 14 - | `--print0` | Terminate the output with a null, for better multiline support | 15 - 16 - 17 - ## Format 18 - 19 - Customize the output of `history list` 20 - 21 - Example 22 - 23 - ``` 24 - atuin history list --format "{time} - {duration} - {command}" 25 - ``` 26 - 27 - Supported variables 28 - 29 - ``` 30 - {command}, {directory}, {duration}, {user}, {host} and {time} 31 - ```
-15
docs/docs/reference/prune.md
··· 1 - # history prune 2 - 3 - ## `atuin history prune` 4 - 5 - This command deletes history entries matching the [history_filter](../configuration/config.md#history_filter) configuration parameter. 6 - 7 - These may be commands that match the current `history_filter` configuration, but were saved to history before the filter was set up, and therefore were not excluded from history at the time of execution. 8 - 9 - It may be useful to run the prune command after updating `history_filter` to remove old history entries that match the new filters. 10 - 11 - It can be run with `--dry-run` first to list history entries that will be removed. 12 - 13 - | Argument | Description | 14 - |------------------|--------------------------------------------------------------------| 15 - | `--dry-run`/`-n` | List matching history lines without performing the actual deletion |
-69
docs/docs/reference/pty-proxy.md
··· 1 - # pty-proxy 2 - 3 - Atuin pty-proxy is an experimental lightweight PTY proxy, providing new features without needing to replace your existing terminal or shell. It currently supports bash, zsh, fish, and nu. 4 - 5 - !!! Note "Previously `atuin hex`" 6 - 7 - `atuin pty-proxy` is a replacement for the old `atuin hex` command. `atuin hex` still works for backward compatibility reasons, but will eventually be removed. 8 - 9 - ## TUI Rendering 10 - 11 - The search TUI exposes a tradeoff: the UI is either in fullscreen alt-screen mode that takes over your terminal, or inline mode that clears your previous output. Neither is great. 12 - 13 - With pty-proxy, the Atuin popup renders over the top of your previous output, but when it's closed we can restore the output successfully. 14 - 15 - ## Initialization 16 - 17 - Atuin pty-proxy needs to be initialized separately from your existing Atuin config. Place the init line shown below in your shell's init script, as high in the document as possible, _before_ your normal `atuin init` call. 18 - 19 - === "zsh" 20 - 21 - ```shell 22 - eval "$(atuin pty-proxy init zsh)" 23 - ``` 24 - 25 - === "bash" 26 - 27 - ```shell 28 - eval "$(atuin pty-proxy init bash)" 29 - ``` 30 - 31 - === "fish" 32 - 33 - Add 34 - 35 - ```shell 36 - atuin pty-proxy init fish | source 37 - ``` 38 - 39 - to your `is-interactive` block in your `~/.config/fish/config.fish` file 40 - 41 - === "Nushell" 42 - 43 - Run in *Nushell*: 44 - 45 - ```shell 46 - mkdir ~/.local/share/atuin/ 47 - atuin pty-proxy init nu | save -f ~/.local/share/atuin/pty-proxy-init.nu 48 - ``` 49 - 50 - Add to `config.nu`, **before** the regular `atuin init`: 51 - 52 - ```shell 53 - source ~/.local/share/atuin/pty-proxy-init.nu 54 - ``` 55 - Nushell's `source` command requires a static file path, so you must 56 - pre-generate the file. 57 - 58 - --- 59 - 60 - If the `atuin` binary is not in your `PATH` by default, you should initialize pty-proxy as soon as it is set. For example, for a bash user with Atuin installed in `~/.atuin/bin/atuin`, a config file might look like this: 61 - 62 - ```bash 63 - export PATH=$HOME/.atuin/bin:$PATH 64 - eval "$(atuin pty-proxy init bash)" 65 - 66 - # ... other shell configuration ... 67 - 68 - eval "$(atuin init bash)" 69 - ```
-65
docs/docs/reference/search.md
··· 1 - # search 2 - 3 - Atuin search supports wildcards, with either the `*` or `%` character. By 4 - default, a prefix search is performed (ie, all queries are automatically 5 - appended with a wildcard). 6 - 7 - | Arg &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| Description | 8 - | -------------------- | ----------------------------------------------------------------------------- | 9 - | `--cwd`/`-c` | The directory to list history for (default: all dirs) | 10 - | `--exclude-cwd` | Do not include commands that ran in this directory (default: none) | 11 - | `--exit`/`-e` | Filter by exit code (default: none) | 12 - | `--exclude-exit` | Do not include commands that exited with this value (default: none) | 13 - | `--before` | Only include commands ran before this time(default: none) | 14 - | `--after` | Only include commands ran after this time(default: none) | 15 - | `--interactive`/`-i` | Open the interactive search UI (default: false) | 16 - | `--human` | Use human-readable formatting for the timestamp and duration (default: false) | 17 - | `--limit` | Limit the number of results (default: none) | 18 - | `--offset` | Offset from the start of the results (default: none) | 19 - | `--delete` | Delete history matching this query | 20 - | `--delete-it-all` | Delete all shell history | 21 - | `--reverse` | Reverse order of search results, oldest first | 22 - | `--format`/`-f` | Available variables: {command}, {directory}, {duration}, {user}, {host}, {time}, {exit} and {relativetime}. Example: --format "{time} - [{duration}] - {directory}$\t{command}" | 23 - | `--inline-height` | Set the maximum number of lines Atuin's interface should take up | 24 - | `--help`/`-h` | Print help | 25 - 26 - ## `atuin search -i` 27 - 28 - Atuin's interactive search TUI allows you to fuzzy search through your history. 29 - 30 - ![compact](https://user-images.githubusercontent.com/1710904/161623659-4fec047f-ea4b-471c-9581-861d2eb701a9.png) 31 - 32 - You can replay the `nth` command with `alt + #` where `#` is the line number of the command you would like to replay. 33 - 34 - Note: This is not yet supported on macOS. 35 - 36 - ## Examples 37 - 38 - ``` 39 - # Open the interactive search TUI 40 - atuin search -i 41 - 42 - # Open the interactive search TUI preloaded with a query 43 - atuin search -i atuin 44 - 45 - # Search for all commands, beginning with cargo, that exited successfully 46 - atuin search --exit 0 cargo 47 - 48 - # Search for all commands, that failed, from the current dir, and were ran before April 1st 2021 49 - atuin search --exclude-exit 0 --before 01/04/2021 --cwd . 50 - 51 - # Search for all commands, beginning with cargo, that exited successfully, and were ran after yesterday at 3pm 52 - atuin search --exit 0 --after "yesterday 3pm" cargo 53 - 54 - # Delete all commands, beginning with cargo, that exited successfully, and were ran after yesterday at 3pm 55 - atuin search --delete --exit 0 --after "yesterday 3pm" cargo 56 - 57 - # Search for a command beginning with cargo, return exactly one result. 58 - atuin search --limit 1 cargo 59 - 60 - # Search for a single result for a command beginning with cargo, skipping (offsetting) one result 61 - atuin search --offset 1 --limit 1 cargo 62 - 63 - # Find the oldest cargo command 64 - atuin search --limit 1 --reverse cargo 65 - ```
-50
docs/docs/reference/stats.md
··· 1 - # stats 2 - 3 - Atuin can also calculate stats based on your history - this is currently a 4 - little basic, but more features to come. 5 - 6 - ## 1-day stats 7 - 8 - You provide the starting point, and Atuin computes the stats for 24h from that point. 9 - Date parsing is provided by `interim`, which supports different formats 10 - for full or relative dates. Certain formats rely on the dialect option in your 11 - [configuration](../configuration/config.md#dialect) to differentiate day from month. 12 - Refer to [the module's documentation](https://docs.rs/interim/0.1.0/interim/#supported-formats) for more details on the supported date formats. 13 - 14 - ``` 15 - $ atuin stats last friday 16 - 17 - +---------------------+------------+ 18 - | Statistic | Value | 19 - +---------------------+------------+ 20 - | Most used command | git status | 21 - +---------------------+------------+ 22 - | Commands ran | 450 | 23 - +---------------------+------------+ 24 - | Unique commands ran | 213 | 25 - +---------------------+------------+ 26 - 27 - # A few more examples: 28 - $ atuin stats 2018-04-01 29 - $ atuin stats April 1 30 - $ atuin stats 01/04/22 31 - $ atuin stats last thursday 3pm # between last thursday 3:00pm and the following friday 3:00pm 32 - ``` 33 - 34 - ## Full history stats 35 - 36 - ``` 37 - $ atuin stats 38 - # or 39 - $ atuin stats all 40 - 41 - +---------------------+-------+ 42 - | Statistic | Value | 43 - +---------------------+-------+ 44 - | Most used command | ls | 45 - +---------------------+-------+ 46 - | Commands ran | 8190 | 47 - +---------------------+-------+ 48 - | Unique commands ran | 2996 | 49 - +---------------------+-------+ 50 - ```
-77
docs/docs/reference/sync.md
··· 1 - # sync 2 - 3 - Atuin can back up your history to a server, and use this to ensure multiple 4 - machines have the same shell history. This is all encrypted end-to-end, so the 5 - server operator can _never_ see your data! 6 - 7 - Anyone can host a server (see the [self-hosting docs](../self-hosting/server-setup.md)), but I 8 - host one at https://api.atuin.sh. This is the default server address, which can 9 - be changed in the [config](../configuration/config.md#sync_address). Again, I _cannot_ see your data, and 10 - do not want to. 11 - 12 - ## Sync frequency 13 - 14 - Syncing will happen automatically, unless configured otherwise. The sync 15 - frequency is configurable in [config](../configuration/config.md#sync_frequency) 16 - 17 - ## Sync 18 - 19 - You can manually trigger a sync with `atuin sync` 20 - 21 - ## Register 22 - 23 - Register for a sync account with 24 - 25 - ``` 26 - atuin register -u <USERNAME> -e <EMAIL> -p <PASSWORD> 27 - ``` 28 - 29 - If you don't want to have your password be included in shell history, you can omit 30 - the password flag and you will be prompted to provide it through stdin. 31 - 32 - Usernames must be unique and only contain alphanumerics or hyphens, 33 - and emails shall only be used for important notifications (security breaches, changes to service, etc). 34 - 35 - Upon success, you are also logged in :) Syncing should happen automatically from 36 - here! 37 - 38 - ## Delete 39 - 40 - You can delete your sync account with 41 - 42 - ``` 43 - atuin account delete 44 - ``` 45 - 46 - This will remove your account and all synchronized history from the server. Local data will not be touched! 47 - 48 - ## Key 49 - 50 - As all your data is encrypted, Atuin generates a key for you. It's stored in the 51 - Atuin data directory (`~/.local/share/atuin` on Linux). 52 - 53 - You can also get this with 54 - 55 - ``` 56 - atuin key 57 - ``` 58 - 59 - Never share this with anyone! 60 - 61 - ## Login 62 - 63 - If you want to log in to a new machine, you will require your encryption key 64 - (`atuin key`). 65 - 66 - ``` 67 - atuin login -u <USERNAME> -p <PASSWORD> -k <KEY> 68 - ``` 69 - 70 - If you don't want to have your password or encryption key be included in shell history, you can omit 71 - the corresponding flag and you will be prompted to provide it through stdin. 72 - 73 - ## Logout 74 - 75 - ``` 76 - atuin logout 77 - ```
-131
docs/docs/self-hosting/docker.md
··· 1 - # Docker 2 - 3 - !!! warning 4 - If you are self hosting, we strongly suggest you stick to [tagged releases](https://github.com/atuinsh/atuin/releases), and do not follow `main` or `latest` 5 - 6 - Follow the GitHub releases, and please read the notes for each release. Most of the time, upgrades can occur without any manual intervention. 7 - 8 - We cannot guarantee that all updates will apply cleanly, and some may require some extra steps. 9 - 10 - There is a supplied docker image to make deploying a server as a container easier. The "LATEST TAGGED RELEASE" can be found on the [releases page](https://github.com/atuinsh/atuin/releases). 11 - 12 - ```sh 13 - CONFIG="$HOME/.config/atuin" 14 - mkdir "$CONFIG" 15 - chown 1000:1000 "$CONFIG" 16 - docker run -d -v "$CONFIG:/config" ghcr.io/atuinsh/atuin:<LATEST TAGGED RELEASE> start 17 - ``` 18 - 19 - ## Docker Compose 20 - 21 - Using the already build docker image hosting your own Atuin can be done using the supplied docker-compose file. 22 - 23 - Create a `docker-compose.yml`: 24 - 25 - ```yaml 26 - services: 27 - atuin: 28 - restart: always 29 - image: ghcr.io/atuinsh/atuin:<LATEST TAGGED RELEASE> 30 - command: start 31 - volumes: 32 - - "./config:/config" 33 - ports: 34 - - 8888:8888 35 - environment: 36 - ATUIN_HOST: "0.0.0.0" 37 - ATUIN_OPEN_REGISTRATION: "true" 38 - ATUIN_DB_URI: postgres://${ATUIN_DB_USERNAME}:${ATUIN_DB_PASSWORD}@db/${ATUIN_DB_NAME} 39 - RUST_LOG: info,atuin_server=debug 40 - depends_on: 41 - - db 42 - db: 43 - image: postgres:18 44 - restart: unless-stopped 45 - volumes: # Don't remove permanent storage for index database files! 46 - - "./database:/var/lib/postgresql/" 47 - environment: 48 - POSTGRES_USER: ${ATUIN_DB_USERNAME} 49 - POSTGRES_PASSWORD: ${ATUIN_DB_PASSWORD} 50 - POSTGRES_DB: ${ATUIN_DB_NAME} 51 - ``` 52 - 53 - Create a `.env` file next to `docker-compose.yml` with contents like this: 54 - 55 - ```ini 56 - ATUIN_DB_NAME=atuin 57 - ATUIN_DB_USERNAME=atuin 58 - # Choose your own secure password. Stick to [A-Za-z0-9.~_-] 59 - ATUIN_DB_PASSWORD=really-insecure 60 - ``` 61 - 62 - 63 - Start the services using `docker compose`: 64 - 65 - ```sh 66 - mkdir config 67 - chown 1000:1000 config 68 - docker compose up -d 69 - ``` 70 - 71 - ## Using systemd to manage your atuin server 72 - 73 - The following `systemd` unit file to manage your `docker-compose` managed service: 74 - 75 - ```ini 76 - [Unit] 77 - Description=Docker Compose Atuin Service 78 - Requires=docker.service 79 - After=docker.service 80 - 81 - [Service] 82 - # Where the docker-compose file is located 83 - WorkingDirectory=/srv/atuin-server 84 - ExecStart=/usr/bin/docker compose up 85 - ExecStop=/usr/bin/docker compose down 86 - TimeoutStartSec=0 87 - Restart=on-failure 88 - StartLimitBurst=3 89 - 90 - [Install] 91 - WantedBy=multi-user.target 92 - ``` 93 - 94 - Start and enable the service with: 95 - 96 - ```sh 97 - systemctl enable --now atuin 98 - ``` 99 - 100 - Check if its running with: 101 - 102 - ```sh 103 - systemctl status atuin 104 - ``` 105 - 106 - ## Creating backups of the Postgres database 107 - 108 - You can add another service to your `docker-compose.yml` file to have it run daily backups. It should look like this: 109 - 110 - ```yaml 111 - backup: 112 - container_name: atuin_db_dumper 113 - image: prodrigestivill/postgres-backup-local 114 - env_file: 115 - - .env 116 - environment: 117 - POSTGRES_HOST: postgresql 118 - POSTGRES_DB: ${ATUIN_DB_NAME} 119 - POSTGRES_USER: ${ATUIN_DB_USERNAME} 120 - POSTGRES_PASSWORD: ${ATUIN_DB_PASSWORD} 121 - SCHEDULE: "@daily" 122 - BACKUP_DIR: /db_dumps 123 - volumes: 124 - - ./db_dumps:/db_dumps 125 - depends_on: 126 - - postgresql 127 - ``` 128 - 129 - This will create daily backups of your database for that additional layer of comfort. 130 - 131 - PLEASE NOTE: The `./db_dumps` mount MUST be a POSIX-compliant filesystem to store the backups (mainly with support for hardlinks and softlinks). So filesystems like VFAT, EXFAT, SMB/CIFS, ... can't be used with this docker image. See https://github.com/prodrigestivill/docker-postgres-backup-local for more details on how this works. There are additional settings for the number of backups retained, etc., all explained on the linked page.
-289
docs/docs/self-hosting/kubernetes.md
··· 1 - # Kubernetes 2 - 3 - !!! warning 4 - If you are self hosting, we strongly suggest you stick to tagged releases, and do not follow `main` or `latest` 5 - 6 - Follow the GitHub releases, and please read the notes for each release. Most of the time, upgrades can occur without any manual intervention. 7 - 8 - We cannot guarantee that all updates will apply cleanly, and some may require some extra steps. 9 - 10 - You could host your own Atuin server using the Kubernetes platform. 11 - 12 - Create a [`secrets.yaml`](https://github.com/atuinsh/atuin/blob/main/k8s/secrets.yaml) file for the database credentials: 13 - 14 - ```yaml 15 - apiVersion: v1 16 - kind: Secret 17 - metadata: 18 - name: atuin-secrets 19 - type: Opaque 20 - stringData: 21 - ATUIN_DB_USERNAME: atuin 22 - ATUIN_DB_PASSWORD: seriously-insecure 23 - ATUIN_HOST: "127.0.0.1" 24 - ATUIN_PORT: "8888" 25 - ATUIN_OPEN_REGISTRATION: "true" 26 - ATUIN_DB_URI: "postgres://atuin:seriously-insecure@postgres/atuin" 27 - immutable: true 28 - ``` 29 - 30 - Create a [`atuin.yaml`](https://github.com/atuinsh/atuin/blob/main/k8s/atuin.yaml) file for the Atuin server: 31 - 32 - ```yaml 33 - --- 34 - apiVersion: apps/v1 35 - kind: Deployment 36 - metadata: 37 - name: postgres 38 - namespace: atuin 39 - spec: 40 - replicas: 1 41 - strategy: 42 - type: Recreate # This is important to ensure duplicate pods don't run and cause corruption 43 - selector: 44 - matchLabels: 45 - io.kompose.service: postgres 46 - template: 47 - metadata: 48 - labels: 49 - io.kompose.service: postgres 50 - spec: 51 - containers: 52 - - name: postgresql 53 - image: postgres:14 54 - ports: 55 - - containerPort: 5432 56 - env: 57 - - name: POSTGRES_DB 58 - value: atuin 59 - - name: POSTGRES_PASSWORD 60 - valueFrom: 61 - secretKeyRef: 62 - name: atuin-secrets 63 - key: ATUIN_DB_PASSWORD 64 - optional: false 65 - - name: POSTGRES_USER 66 - valueFrom: 67 - secretKeyRef: 68 - name: atuin-secrets 69 - key: ATUIN_DB_USERNAME 70 - optional: false 71 - lifecycle: 72 - preStop: 73 - exec: 74 - # This ensures graceful shutdown see: https://stackoverflow.com/a/75829325/3437018 75 - # Potentially consider using a `StatefulSet` instead of a `Deployment` 76 - command: ["/usr/local/bin/pg_ctl stop -D /var/lib/postgresql/data -w -t 60 -m fast"] 77 - resources: 78 - requests: 79 - cpu: 100m 80 - memory: 100Mi 81 - limits: 82 - cpu: 250m 83 - memory: 600Mi 84 - volumeMounts: 85 - - mountPath: /var/lib/postgresql/data/ 86 - name: database 87 - volumes: 88 - - name: database 89 - persistentVolumeClaim: 90 - claimName: database 91 - --- 92 - apiVersion: apps/v1 93 - kind: Deployment 94 - metadata: 95 - name: atuin 96 - spec: 97 - replicas: 1 98 - selector: 99 - matchLabels: 100 - io.kompose.service: atuin 101 - template: 102 - metadata: 103 - labels: 104 - io.kompose.service: atuin 105 - spec: 106 - containers: 107 - - args: 108 - - start 109 - env: 110 - - name: ATUIN_DB_URI 111 - valueFrom: 112 - secretKeyRef: 113 - name: atuin-secrets 114 - key: ATUIN_DB_URI 115 - optional: false 116 - - name: ATUIN_HOST 117 - value: 0.0.0.0 118 - - name: ATUIN_PORT 119 - value: "8888" 120 - - name: ATUIN_OPEN_REGISTRATION 121 - value: "true" 122 - image: ghcr.io/atuinsh/atuin:latest 123 - name: atuin 124 - ports: 125 - - containerPort: 8888 126 - resources: 127 - limits: 128 - cpu: 250m 129 - memory: 1Gi 130 - requests: 131 - cpu: 250m 132 - memory: 1Gi 133 - volumeMounts: 134 - - mountPath: /config 135 - name: atuin-claim0 136 - volumes: 137 - - name: atuin-claim0 138 - persistentVolumeClaim: 139 - claimName: atuin-claim0 140 - --- 141 - apiVersion: v1 142 - kind: Service 143 - metadata: 144 - labels: 145 - io.kompose.service: atuin 146 - name: atuin 147 - spec: 148 - type: NodePort 149 - ports: 150 - - name: "8888" 151 - port: 8888 152 - nodePort: 30530 153 - selector: 154 - io.kompose.service: atuin 155 - --- 156 - apiVersion: v1 157 - kind: Service 158 - metadata: 159 - labels: 160 - io.kompose.service: postgres 161 - name: postgres 162 - spec: 163 - type: ClusterIP 164 - selector: 165 - io.kompose.service: postgres 166 - ports: 167 - - protocol: TCP 168 - port: 5432 169 - targetPort: 5432 170 - --- 171 - kind: PersistentVolume 172 - apiVersion: v1 173 - metadata: 174 - name: database-pv 175 - labels: 176 - app: database 177 - type: local 178 - spec: 179 - storageClassName: manual 180 - capacity: 181 - storage: 300Mi 182 - accessModes: 183 - - ReadWriteOnce 184 - hostPath: 185 - path: "/Users/firstname.lastname/.kube/database" 186 - --- 187 - apiVersion: v1 188 - kind: PersistentVolumeClaim 189 - metadata: 190 - labels: 191 - io.kompose.service: database 192 - name: database 193 - spec: 194 - storageClassName: manual 195 - accessModes: 196 - - ReadWriteOnce 197 - resources: 198 - requests: 199 - storage: 300Mi 200 - --- 201 - apiVersion: v1 202 - kind: PersistentVolumeClaim 203 - metadata: 204 - labels: 205 - io.kompose.service: atuin-claim0 206 - name: atuin-claim0 207 - spec: 208 - accessModes: 209 - - ReadWriteOnce 210 - resources: 211 - requests: 212 - storage: 10Mi 213 - ``` 214 - 215 - Finally, you may want to use a separate namespace for atuin, by creating a [`namespaces.yaml`](https://github.com/atuinsh/atuin/blob/main/k8s/namespaces.yaml) file: 216 - 217 - ```yaml 218 - apiVersion: v1 219 - kind: Namespace 220 - metadata: 221 - name: atuin-namespace 222 - labels: 223 - name: atuin 224 - ``` 225 - 226 - Note that this configuration will store the database folder _outside_ the kubernetes cluster, in the folder `/Users/firstname.lastname/.kube/database` of the host system by configuring the `storageClassName` to be `manual`. In a real enterprise setup, you would probably want to store the database content permanently in the cluster, and not in the host system. 227 - 228 - You should also change the password string in `ATUIN_DB_PASSWORD` and `ATUIN_DB_URI` in the`secrets.yaml` file to a more secure one. 229 - 230 - The atuin service on the port `30530` of the host system. That is configured by the `nodePort` property. Kubernetes has a strict rule that you are not allowed to expose a port numbered lower than 30000. To make the clients work, you can simply set the port in your `config.toml` file, e.g. `sync_address = "http://192.168.1.10:30530"`. 231 - 232 - Deploy the Atuin server using `kubectl`: 233 - 234 - ```shell 235 - kubectl apply -f ./namespaces.yaml 236 - kubectl apply -n atuin-namespace \ 237 - -f ./secrets.yaml \ 238 - -f ./atuin.yaml 239 - ``` 240 - 241 - The sample files above are also in the [k8s folder](https://github.com/atuinsh/atuin/tree/main/k8s) of the atuin repository. 242 - 243 - ## Creating backups of the Postgres database 244 - 245 - Now you're up and running it's a good time to think about backups. 246 - 247 - You can create a [`CronJob`](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) which uses [`pg_dump`](https://www.postgresql.org/docs/current/app-pgdump.html) to create a backup of the database. This example runs weekly and dumps to the local disk on the node. 248 - 249 - ```yaml 250 - apiVersion: batch/v1 251 - kind: CronJob 252 - metadata: 253 - name: atuin-db-backup 254 - spec: 255 - schedule: "0 0 * * 0" # Run every Sunday at midnight 256 - jobTemplate: 257 - spec: 258 - template: 259 - spec: 260 - containers: 261 - - name: atuin-db-backup-pg-dump 262 - image: postgres:14 263 - command: [ 264 - "/bin/bash", 265 - "-c", 266 - "pg_dump --host=postgres --username=atuin --format=c --file=/backup/atuin-backup-$(date +'%Y-%m-%d').pg_dump", 267 - ] 268 - env: 269 - - name: PGPASSWORD 270 - valueFrom: 271 - secretKeyRef: 272 - name: atuin-secrets 273 - key: ATUIN_DB_PASSWORD 274 - optional: false 275 - volumeMounts: 276 - - name: backup-volume 277 - mountPath: /backup 278 - restartPolicy: OnFailure 279 - volumes: 280 - - name: backup-volume 281 - hostPath: 282 - path: /somewhere/on/node/for/database-backups 283 - type: Directory 284 - ``` 285 - 286 - Configure/update the example `yaml` with the following: 287 - - Set a more or less frequent schedule with the `schedule` property. 288 - - Replace `/somewhere/on/node/for/database-backups` with a path on your node or reconfigure to use a `PersistentVolume` instead of `hostPath`. 289 - - `--format=c` outputs a format that can be restored with `pg_restore`. Use [`plain`](https://www.postgresql.org/docs/current/app-pgdump.html) if you want `.sql` files outputted instead.
-73
docs/docs/self-hosting/server-setup.md
··· 1 - # Server setup 2 - 3 - While we offer a public sync server, and cannot view your data (as it is encrypted), you may still wish to self host your own Atuin sync server. 4 - 5 - The requirements to do so are pretty minimal! You need to be able to run a binary or docker container, and have a PostgreSQL database setup. Atuin requires PostgreSQL 14 or above. 6 - 7 - Atuin also supports sqlite 3 and above. 8 - 9 - The server is distributed as a separate binary, `atuin-server`. Prebuilt binaries and an installer are published with every release on the [GitHub releases page](https://github.com/atuinsh/atuin/releases). For example, to install the latest release: 10 - 11 - ```shell 12 - curl --proto '=https' --tlsv1.2 -LsSf https://github.com/atuinsh/atuin/releases/latest/download/atuin-server-installer.sh | sh 13 - ``` 14 - 15 - Once installed, start the server with: 16 - 17 - ```shell 18 - atuin-server start 19 - ``` 20 - 21 - !!! note 22 - Prior to v18.12.0, the server was bundled into the main `atuin` binary and started with `atuin server start`. If you are upgrading from an older release, you will need to install the new `atuin-server` binary and update any service files (systemd, docker, k8s) to invoke `atuin-server` instead of `atuin server`. See the [release notes](https://github.com/atuinsh/atuin/releases) for details. 23 - 24 - ## Configuration 25 - 26 - The server's config lives at `~/.config/atuin/server.toml`, separate from the 27 - client's config. 28 - 29 - It looks something like this for PostgreSQL: 30 - 31 - ```toml 32 - host = "0.0.0.0" 33 - port = 8888 34 - open_registration = true 35 - db_uri="postgres://user:password@hostname/database" 36 - ``` 37 - 38 - Alternatively, configuration can also be provided with environment variables. 39 - 40 - ```sh 41 - ATUIN_HOST="0.0.0.0" 42 - ATUIN_PORT=8888 43 - ATUIN_OPEN_REGISTRATION=true 44 - ATUIN_DB_URI="postgres://user:password@hostname/database" 45 - ``` 46 - 47 - | Parameter | Description | 48 - | ------------------- | -------------------------------------------------------------- | 49 - | `host` | The host to listen on (default: 127.0.0.1) | 50 - | `port` | The TCP port to listen on (default: 8888) | 51 - | `open_registration` | If `true`, accept new user registrations (default: false) | 52 - | `db_uri` | A valid PostgreSQL URI, for saving history (default: false) | 53 - | `path` | A path to prepend to all routes of the server (default: false) | 54 - 55 - For sqlite, use the following in your server.toml: 56 - 57 - ```toml 58 - db_uri="sqlite:///config/atuin.db" 59 - ``` 60 - 61 - Alternatively, provide the Database URI via an environment variable 62 - 63 - ```sh 64 - ATUIN_DB_URI="sqlite:///config/atuin.db" 65 - ``` 66 - 67 - These will create the database in the `/config` directory. Be sure to map a persistent volume to the `/config` directory that is writable by the atuin server. 68 - 69 - ### TLS 70 - 71 - For TLS/HTTPS support, we recommend using a reverse proxy such as nginx, caddy, or traefik in front of the Atuin server. This is the standard approach for containerized applications and provides better flexibility for certificate management. 72 - 73 - > **Note:** The built-in `[tls]` configuration option has been removed. If you were previously using it, please migrate to a reverse proxy setup. Any existing `[tls]` sections in your config will be ignored.
-71
docs/docs/self-hosting/systemd.md
··· 1 - # Systemd 2 - 3 - !!! note 4 - These instructions assume the `atuin-server` binary is on your `PATH`. Since 5 - v18.12.0, the server is distributed as a separate binary — install it from 6 - the [releases page](https://github.com/atuinsh/atuin/releases) (see [Server 7 - setup](./server-setup.md) for the installer). 8 - 9 - First, create the service unit file 10 - [`atuin-server.service`](https://github.com/atuinsh/atuin/raw/main/systemd/atuin-server.service) at 11 - `/etc/systemd/system/atuin-server.service` with contents like this: 12 - 13 - ```ini 14 - [Unit] 15 - Description=Start the Atuin server syncing service 16 - After=network-online.target 17 - Wants=network-online.target systemd-networkd-wait-online.service 18 - 19 - [Service] 20 - ExecStart=atuin-server start 21 - Restart=on-failure 22 - User=atuin 23 - Group=atuin 24 - 25 - Environment=ATUIN_CONFIG_DIR=/etc/atuin 26 - ReadWritePaths=/etc/atuin 27 - 28 - # Hardening options 29 - CapabilityBoundingSet= 30 - AmbientCapabilities= 31 - NoNewPrivileges=true 32 - ProtectHome=true 33 - ProtectSystem=strict 34 - ProtectKernelTunables=true 35 - ProtectKernelModules=true 36 - ProtectControlGroups=true 37 - PrivateTmp=true 38 - PrivateDevices=true 39 - LockPersonality=true 40 - 41 - [Install] 42 - WantedBy=multi-user.target 43 - ``` 44 - 45 - This is the official Atuin service unit file which includes a lot of hardening options to increase 46 - security. 47 - 48 - Next, create [`atuin-server.conf`](https://github.com/atuinsh/atuin/raw/main/systemd/atuin-server.sysusers) at 49 - `/etc/sysusers.d/atuin-server.conf` with contents like this: 50 - 51 - ``` 52 - u atuin - "Atuin synchronized shell history" 53 - ``` 54 - This file will ensure a system user is created in the proper manner. 55 - 56 - Afterwards, run 57 - ```sh 58 - systemctl restart systemd-sysusers 59 - ``` 60 - to make sure the file is read. A new `atuin-server` user should then be available. 61 - 62 - Now, you can attempt to run the Atuin server: 63 - ```sh 64 - systemctl enable --now atuin-server 65 - ``` 66 - 67 - ```sh 68 - systemctl status atuin-server 69 - ``` 70 - 71 - If it started fine, it should have created the default config inside `/etc/atuin/`.
-14
docs/docs/self-hosting/usage.md
··· 1 - # Using a self hosted server 2 - 3 - !!! warning 4 - If you are self hosting, we strongly suggest you stick to tagged releases, and do not follow `main` or `latest` 5 - 6 - Follow the GitHub releases, and please read the notes for each release. Most of the time, upgrades can occur without any manual intervention. 7 - 8 - We cannot guarantee that all updates will apply cleanly, and some may require some extra steps. 9 - 10 - ## Client setup 11 - 12 - In order use a self hosted server with Atuin, you'll have to set up the `sync_address` in the config file at `~/.config/atuin/config.toml`. See the [config](../configuration/config.md#sync_address) page for more details on how to set the `sync_address`. 13 - 14 - Alternatively you can set the environment variable `ATUIN_SYNC_ADDRESS` to the correct host ie.: `ATUIN_SYNC_ADDRESS=https://api.atuin.sh`.
-21
docs/docs/uninstall.md
··· 1 - # Uninstalling Atuin 2 - 3 - Sorry to see you go! 4 - 5 - If you used the Atuin installer, you can totally delete it by removing the following 6 - 7 - 1. Delete the `~/.atuin` directory 8 - 2. Delete the `~/.config/atuin` directory 9 - 3. Delete the `~/.local/share/atuin` directory 10 - 4. Remove the line referencing "atuin init" from your shell config 11 - 5. Fish users: delete `~/.config/fish/conf.d/atuin.env.fish` if it exists 12 - 13 - Otherwise, uninstalling Atuin depends on your system, and how you installed it. 14 - 15 - EG, on macOS, you'd want to run 16 - 17 - ``` 18 - brew uninstall atuin 19 - ``` 20 - 21 - and then remove the shell integration.
-175
docs/mkdocs.yml
··· 1 - site_name: Atuin CLI Docs 2 - site_url: https://docs.atuin.sh/cli/ 3 - 4 - repo_name: atuinsh/atuin 5 - repo_url: https://github.com/atuinsh/atuin 6 - edit_uri: edit/main/docs/docs/ 7 - 8 - theme: 9 - name: material 10 - palette: 11 - - scheme: default 12 - primary: deep purple 13 - accent: deep purple 14 - toggle: 15 - icon: material/brightness-7 16 - name: Switch to dark mode 17 - - scheme: slate 18 - primary: deep purple 19 - accent: deep purple 20 - toggle: 21 - icon: material/brightness-4 22 - name: Switch to light mode 23 - features: 24 - - navigation.sections 25 - - navigation.expand 26 - - search.suggest 27 - - search.highlight 28 - - content.code.copy 29 - - content.action.edit 30 - - content.action.view 31 - 32 - # NOTE: to enable ToC and heading anchor links in local (non-multirepo) development, 33 - # comment out the `multirepo` plugin and all its settings. 34 - # Note that this changes the top-level directory when developing locally 35 - # from `/cli/CLI/` to `/cli/. 36 - 37 - plugins: 38 - - search 39 - - multirepo: 40 - imported_repo: true 41 - url: https://github.com/atuinsh/docs 42 - section_name: CLI 43 - paths: ["mkdocs.yml", "docs/index.md", "docs/stylesheets/*"] 44 - yml_file: mkdocs.yml 45 - branch: mkt/docs-migration 46 - - llmstxt: 47 - base_url: https://docs.atuin.sh/cli 48 - full_output: llms-full.txt 49 - markdown_description: | 50 - Atuin replaces your shell's built-in history with a SQLite database, adding context 51 - (cwd, exit code, duration, hostname) and optionally syncing across machines with 52 - end-to-end encryption. These docs cover the CLI tool - installation, configuration, 53 - usage, self-hosting, and AI features. 54 - sections: 55 - Overview: 56 - - index.md: Getting started with Atuin - quickstart, supported shells, and links. 57 - Guide: 58 - - guide/getting-started.md: First steps - install, import history, and start using Atuin. 59 - - guide/installation.md: Install via script, Homebrew, WinGet, Cargo, Nix, or from source. 60 - - guide/sync.md: Register an account and set up end-to-end encrypted history sync. 61 - - guide/import.md: Import existing shell history from bash, zsh, fish, and others. 62 - - guide/basic-usage.md: What Atuin records, how to use the TUI, and common config tweaks. 63 - - guide/advanced-usage.md: Filter modes (global, host, session, directory, workspace) and search modes (fuzzy, full-text, skim). 64 - - guide/shell-integration.md: How shell hooks work, environment variables, embedded terminals, and excluding commands. 65 - - guide/agent-hooks.md: Capture commands from AI coding agents (Claude Code, Codex, pi) and filter by author. 66 - - guide/delete-history.md: Delete single entries, bulk delete by query, remove duplicates, or wipe everything. 67 - - guide/dotfiles.md: Sync shell aliases and environment variables across machines. 68 - - guide/theming.md: Customize the TUI with color themes. 69 - Configuration: 70 - - configuration/config.md: Complete reference for ~/.config/atuin/config.toml - all settings with defaults and examples. 71 - - configuration/key-binding.md: Custom up-arrow filter mode, disable up-arrow or ctrl-r, vim mode. 72 - - configuration/advanced-key-binding.md: Full keymap customization with emacs, vim-normal, vim-insert, and inspector modes. 73 - Reference: 74 - - reference/config.md: The `atuin config` command - get, set, list, and resolve configuration values. 75 - - reference/daemon.md: Background daemon for faster writes, auto-sync, and in-memory fuzzy search. 76 - - reference/doctor.md: Diagnose common problems and dump system info for bug reports. 77 - - reference/gen-completions.md: Generate shell completions for bash, fish, zsh, nushell, powershell, elvish. 78 - - reference/hex.md: The old name for `atuin pty-proxy` 79 - - reference/pty-proxy.md: Experimental PTY proxy with popup rendering over existing terminal output. 80 - - reference/import.md: Import history from bash, fish, zsh, replxx, mcfly, resh, and xonsh. 81 - - reference/info.md: Show config file paths, env vars, and version info. 82 - - reference/list.md: List history entries with formatting, filtering by cwd/session, and custom output templates. 83 - - reference/prune.md: Delete entries matching history_filter config (useful after updating filters). 84 - - reference/search.md: Search history with wildcards, filters (cwd, exit code, before/after), and delete mode. 85 - - reference/stats.md: Compute stats for a time period - most used command, command count, unique commands. 86 - - reference/sync.md: Sync commands - register, login, manual sync, and account management. 87 - Self Hosting: 88 - - self-hosting/server-setup.md: Run your own Atuin sync server with PostgreSQL or SQLite. 89 - - self-hosting/usage.md: Configure the client to use a self-hosted server. 90 - - self-hosting/docker.md: Deploy with Docker or Docker Compose. 91 - - self-hosting/kubernetes.md: Full Kubernetes deployment with Postgres, secrets, and ingress. 92 - - self-hosting/systemd.md: Systemd service unit with hardening options. 93 - AI: 94 - - ai/introduction.md: Atuin AI - command generation and lookup via LLM from your terminal. 95 - - ai/settings.md: AI configuration in config.toml - enabled, endpoint, session timeout. 96 - - ai/slash-commands.md: Slash commands available in Atuin AI. 97 - - ai/user-context.md: Send additional context to the LLM via TERMINAL.md files and dynamic shell substitution. 98 - - ai/skills.md: Reusable instruction sets (skills) for Atuin AI - playbooks, conventions, workflows. 99 - - ai/tools-permissions.md: Tools the AI can use (shell, filesystem) and permission files to control access. 100 - - ai/command-output.md: Let Atuin AI read command outputs - capture via pty-proxy and the daemon. 101 - - ai/mcp.md: Built-in MCP server exposing history search and command output to Claude Code, Cursor, and other AI tools. 102 - - ai/self-hosting.md: Self-hosting the Atuin AI backend. 103 - Misc: 104 - - known-issues.md: Known issues with ZFS and network filesystems. 105 - - integrations.md: Integrations with zsh-autosuggestions, zsh-vi-mode, ble.sh, and mcfly. 106 - - faq.md: Frequently asked questions - IDE terminals, history filtering, up-arrow, uninstalling. 107 - - uninstall.md: How to uninstall Atuin and remove all data. 108 - 109 - markdown_extensions: 110 - - pymdownx.highlight: 111 - anchor_linenums: true 112 - - pymdownx.superfences 113 - - pymdownx.tabbed: 114 - alternate_style: true 115 - - admonition 116 - - pymdownx.details 117 - - attr_list 118 - - md_in_html 119 - - tables 120 - - pymdownx.keys 121 - - pymdownx.emoji: 122 - emoji_index: !!python/name:material.extensions.emoji.twemoji 123 - emoji_generator: !!python/name:material.extensions.emoji.to_svg 124 - 125 - nav: 126 - - Home: index.md 127 - - Guide: 128 - - Getting Started: guide/getting-started.md 129 - - Installation: guide/installation.md 130 - - Setting up sync: guide/sync.md 131 - - Import existing history: guide/import.md 132 - - Basic usage: guide/basic-usage.md 133 - - Advanced usage: guide/advanced-usage.md 134 - - Shell Integration: guide/shell-integration.md 135 - - AI Agent Hooks: guide/agent-hooks.md 136 - - Deleting history: guide/delete-history.md 137 - - Syncing dotfiles: guide/dotfiles.md 138 - - Theming: guide/theming.md 139 - - Configuration: 140 - - Config: configuration/config.md 141 - - Key Binding: configuration/key-binding.md 142 - - Advanced Key Binding: configuration/advanced-key-binding.md 143 - - Reference: 144 - - config: reference/config.md 145 - - daemon: reference/daemon.md 146 - - doctor: reference/doctor.md 147 - - gen-completions: reference/gen-completions.md 148 - - pty-proxy: reference/pty-proxy.md 149 - - import: reference/import.md 150 - - info: reference/info.md 151 - - history list: reference/list.md 152 - - history prune: reference/prune.md 153 - - search: reference/search.md 154 - - stats: reference/stats.md 155 - - sync: reference/sync.md 156 - - Self Hosting: 157 - - Server Setup: self-hosting/server-setup.md 158 - - Usage: self-hosting/usage.md 159 - - Docker: self-hosting/docker.md 160 - - Kubernetes: self-hosting/kubernetes.md 161 - - Systemd: self-hosting/systemd.md 162 - - AI: 163 - - Introduction: ai/introduction.md 164 - - Settings: ai/settings.md 165 - - "Slash Commands": ai/slash-commands.md 166 - - "User-Defined Context": ai/user-context.md 167 - - Skills: ai/skills.md 168 - - "Tools & Permissions": ai/tools-permissions.md 169 - - "Reading Command Output": ai/command-output.md 170 - - "MCP Server": ai/mcp.md 171 - - "Self Hosting & Local Models": ai/self-hosting.md 172 - - Known Issues: known-issues.md 173 - - Integrations: integrations.md 174 - - FAQ: faq.md 175 - - Uninstall: uninstall.md
-21
docs/pyproject.toml
··· 1 - [project] 2 - name = "atuin-cli-docs" 3 - version = "1.0.0" 4 - description = "Atuin CLI documentation" 5 - requires-python = ">=3.11" 6 - dependencies = [ 7 - "mkdocs-material>=9.5", 8 - "mkdocs-multirepo-plugin @ git+https://github.com/atuinsh/mkdocs-multirepo-plugin@mkt/imported_repo", 9 - "mkdocs-git-revision-date-localized-plugin>=1.2", 10 - "mkdocs-glightbox>=0.4", 11 - "mkdocs-redirects>=1.2.2", 12 - "mkdocs-llmstxt>=0.5", 13 - ] 14 - 15 - [tool.uv] 16 - override-dependencies = [ 17 - "click==8.2.1", 18 - ] 19 - 20 - [dependency-groups] 21 - dev = []
-860
docs/uv.lock
··· 1 - version = 1 2 - revision = 3 3 - requires-python = ">=3.11" 4 - 5 - [manifest] 6 - overrides = [{ name = "click", specifier = "==8.2.1" }] 7 - 8 - [[package]] 9 - name = "atuin-cli-docs" 10 - version = "1.0.0" 11 - source = { virtual = "." } 12 - dependencies = [ 13 - { name = "mkdocs-git-revision-date-localized-plugin" }, 14 - { name = "mkdocs-glightbox" }, 15 - { name = "mkdocs-llmstxt" }, 16 - { name = "mkdocs-material" }, 17 - { name = "mkdocs-multirepo-plugin" }, 18 - { name = "mkdocs-redirects" }, 19 - ] 20 - 21 - [package.metadata] 22 - requires-dist = [ 23 - { name = "mkdocs-git-revision-date-localized-plugin", specifier = ">=1.2" }, 24 - { name = "mkdocs-glightbox", specifier = ">=0.4" }, 25 - { name = "mkdocs-llmstxt", specifier = ">=0.5" }, 26 - { name = "mkdocs-material", specifier = ">=9.5" }, 27 - { name = "mkdocs-multirepo-plugin", git = "https://github.com/atuinsh/mkdocs-multirepo-plugin?rev=mkt%2Fimported_repo" }, 28 - { name = "mkdocs-redirects", specifier = ">=1.2.2" }, 29 - ] 30 - 31 - [package.metadata.requires-dev] 32 - dev = [] 33 - 34 - [[package]] 35 - name = "babel" 36 - version = "2.17.0" 37 - source = { registry = "https://pypi.org/simple" } 38 - sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } 39 - wheels = [ 40 - { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, 41 - ] 42 - 43 - [[package]] 44 - name = "backrefs" 45 - version = "6.1" 46 - source = { registry = "https://pypi.org/simple" } 47 - sdist = { url = "https://files.pythonhosted.org/packages/86/e3/bb3a439d5cb255c4774724810ad8073830fac9c9dee123555820c1bcc806/backrefs-6.1.tar.gz", hash = "sha256:3bba1749aafe1db9b915f00e0dd166cba613b6f788ffd63060ac3485dc9be231", size = 7011962, upload-time = "2025-11-15T14:52:08.323Z" } 48 - wheels = [ 49 - { url = "https://files.pythonhosted.org/packages/3b/ee/c216d52f58ea75b5e1841022bbae24438b19834a29b163cb32aa3a2a7c6e/backrefs-6.1-py310-none-any.whl", hash = "sha256:2a2ccb96302337ce61ee4717ceacfbf26ba4efb1d55af86564b8bbaeda39cac1", size = 381059, upload-time = "2025-11-15T14:51:59.758Z" }, 50 - { url = "https://files.pythonhosted.org/packages/e6/9a/8da246d988ded941da96c7ed945d63e94a445637eaad985a0ed88787cb89/backrefs-6.1-py311-none-any.whl", hash = "sha256:e82bba3875ee4430f4de4b6db19429a27275d95a5f3773c57e9e18abc23fd2b7", size = 392854, upload-time = "2025-11-15T14:52:01.194Z" }, 51 - { url = "https://files.pythonhosted.org/packages/37/c9/fd117a6f9300c62bbc33bc337fd2b3c6bfe28b6e9701de336b52d7a797ad/backrefs-6.1-py312-none-any.whl", hash = "sha256:c64698c8d2269343d88947c0735cb4b78745bd3ba590e10313fbf3f78c34da5a", size = 398770, upload-time = "2025-11-15T14:52:02.584Z" }, 52 - { url = "https://files.pythonhosted.org/packages/eb/95/7118e935b0b0bd3f94dfec2d852fd4e4f4f9757bdb49850519acd245cd3a/backrefs-6.1-py313-none-any.whl", hash = "sha256:4c9d3dc1e2e558965202c012304f33d4e0e477e1c103663fd2c3cc9bb18b0d05", size = 400726, upload-time = "2025-11-15T14:52:04.093Z" }, 53 - { url = "https://files.pythonhosted.org/packages/1d/72/6296bad135bfafd3254ae3648cd152980a424bd6fed64a101af00cc7ba31/backrefs-6.1-py314-none-any.whl", hash = "sha256:13eafbc9ccd5222e9c1f0bec563e6d2a6d21514962f11e7fc79872fd56cbc853", size = 412584, upload-time = "2025-11-15T14:52:05.233Z" }, 54 - { url = "https://files.pythonhosted.org/packages/02/e3/a4fa1946722c4c7b063cc25043a12d9ce9b4323777f89643be74cef2993c/backrefs-6.1-py39-none-any.whl", hash = "sha256:a9e99b8a4867852cad177a6430e31b0f6e495d65f8c6c134b68c14c3c95bf4b0", size = 381058, upload-time = "2025-11-15T14:52:06.698Z" }, 55 - ] 56 - 57 - [[package]] 58 - name = "beautifulsoup4" 59 - version = "4.14.3" 60 - source = { registry = "https://pypi.org/simple" } 61 - dependencies = [ 62 - { name = "soupsieve" }, 63 - { name = "typing-extensions" }, 64 - ] 65 - sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737, upload-time = "2025-11-30T15:08:26.084Z" } 66 - wheels = [ 67 - { url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" }, 68 - ] 69 - 70 - [[package]] 71 - name = "certifi" 72 - version = "2025.11.12" 73 - source = { registry = "https://pypi.org/simple" } 74 - sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } 75 - wheels = [ 76 - { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, 77 - ] 78 - 79 - [[package]] 80 - name = "charset-normalizer" 81 - version = "3.4.4" 82 - source = { registry = "https://pypi.org/simple" } 83 - sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } 84 - wheels = [ 85 - { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, 86 - { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, 87 - { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, 88 - { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, 89 - { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, 90 - { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, 91 - { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, 92 - { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, 93 - { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, 94 - { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, 95 - { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, 96 - { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, 97 - { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, 98 - { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, 99 - { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, 100 - { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, 101 - { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, 102 - { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, 103 - { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, 104 - { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, 105 - { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, 106 - { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, 107 - { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, 108 - { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, 109 - { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, 110 - { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, 111 - { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, 112 - { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, 113 - { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, 114 - { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, 115 - { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, 116 - { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, 117 - { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, 118 - { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, 119 - { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, 120 - { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, 121 - { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, 122 - { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, 123 - { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, 124 - { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, 125 - { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, 126 - { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, 127 - { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, 128 - { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, 129 - { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, 130 - { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, 131 - { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, 132 - { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, 133 - { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, 134 - { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, 135 - { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, 136 - { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, 137 - { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, 138 - { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, 139 - { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, 140 - { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, 141 - { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, 142 - { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, 143 - { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, 144 - { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, 145 - { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, 146 - { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, 147 - { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, 148 - { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, 149 - { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, 150 - ] 151 - 152 - [[package]] 153 - name = "click" 154 - version = "8.2.1" 155 - source = { registry = "https://pypi.org/simple" } 156 - dependencies = [ 157 - { name = "colorama", marker = "sys_platform == 'win32'" }, 158 - ] 159 - sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } 160 - wheels = [ 161 - { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, 162 - ] 163 - 164 - [[package]] 165 - name = "colorama" 166 - version = "0.4.6" 167 - source = { registry = "https://pypi.org/simple" } 168 - sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } 169 - wheels = [ 170 - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, 171 - ] 172 - 173 - [[package]] 174 - name = "dacite" 175 - version = "1.9.2" 176 - source = { registry = "https://pypi.org/simple" } 177 - sdist = { url = "https://files.pythonhosted.org/packages/55/a0/7ca79796e799a3e782045d29bf052b5cde7439a2bbb17f15ff44f7aacc63/dacite-1.9.2.tar.gz", hash = "sha256:6ccc3b299727c7aa17582f0021f6ae14d5de47c7227932c47fec4cdfefd26f09", size = 22420, upload-time = "2025-02-05T09:27:29.757Z" } 178 - wheels = [ 179 - { url = "https://files.pythonhosted.org/packages/94/35/386550fd60316d1e37eccdda609b074113298f23cef5bddb2049823fe666/dacite-1.9.2-py3-none-any.whl", hash = "sha256:053f7c3f5128ca2e9aceb66892b1a3c8936d02c686e707bee96e19deef4bc4a0", size = 16600, upload-time = "2025-02-05T09:27:24.345Z" }, 180 - ] 181 - 182 - [[package]] 183 - name = "ghp-import" 184 - version = "2.1.0" 185 - source = { registry = "https://pypi.org/simple" } 186 - dependencies = [ 187 - { name = "python-dateutil" }, 188 - ] 189 - sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943, upload-time = "2022-05-02T15:47:16.11Z" } 190 - wheels = [ 191 - { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, 192 - ] 193 - 194 - [[package]] 195 - name = "gitdb" 196 - version = "4.0.12" 197 - source = { registry = "https://pypi.org/simple" } 198 - dependencies = [ 199 - { name = "smmap" }, 200 - ] 201 - sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" } 202 - wheels = [ 203 - { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" }, 204 - ] 205 - 206 - [[package]] 207 - name = "gitpython" 208 - version = "3.1.45" 209 - source = { registry = "https://pypi.org/simple" } 210 - dependencies = [ 211 - { name = "gitdb" }, 212 - ] 213 - sdist = { url = "https://files.pythonhosted.org/packages/9a/c8/dd58967d119baab745caec2f9d853297cec1989ec1d63f677d3880632b88/gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c", size = 215076, upload-time = "2025-07-24T03:45:54.871Z" } 214 - wheels = [ 215 - { url = "https://files.pythonhosted.org/packages/01/61/d4b89fec821f72385526e1b9d9a3a0385dda4a72b206d28049e2c7cd39b8/gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77", size = 208168, upload-time = "2025-07-24T03:45:52.517Z" }, 216 - ] 217 - 218 - [[package]] 219 - name = "idna" 220 - version = "3.11" 221 - source = { registry = "https://pypi.org/simple" } 222 - sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } 223 - wheels = [ 224 - { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, 225 - ] 226 - 227 - [[package]] 228 - name = "jinja2" 229 - version = "3.1.6" 230 - source = { registry = "https://pypi.org/simple" } 231 - dependencies = [ 232 - { name = "markupsafe" }, 233 - ] 234 - sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } 235 - wheels = [ 236 - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, 237 - ] 238 - 239 - [[package]] 240 - name = "markdown" 241 - version = "3.10" 242 - source = { registry = "https://pypi.org/simple" } 243 - sdist = { url = "https://files.pythonhosted.org/packages/7d/ab/7dd27d9d863b3376fcf23a5a13cb5d024aed1db46f963f1b5735ae43b3be/markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e", size = 364931, upload-time = "2025-11-03T19:51:15.007Z" } 244 - wheels = [ 245 - { url = "https://files.pythonhosted.org/packages/70/81/54e3ce63502cd085a0c556652a4e1b919c45a446bd1e5300e10c44c8c521/markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c", size = 107678, upload-time = "2025-11-03T19:51:13.887Z" }, 246 - ] 247 - 248 - [[package]] 249 - name = "markdown-it-py" 250 - version = "3.0.0" 251 - source = { registry = "https://pypi.org/simple" } 252 - dependencies = [ 253 - { name = "mdurl" }, 254 - ] 255 - sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } 256 - wheels = [ 257 - { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, 258 - ] 259 - 260 - [[package]] 261 - name = "markdownify" 262 - version = "1.2.2" 263 - source = { registry = "https://pypi.org/simple" } 264 - dependencies = [ 265 - { name = "beautifulsoup4" }, 266 - { name = "six" }, 267 - ] 268 - sdist = { url = "https://files.pythonhosted.org/packages/3f/bc/c8c8eea5335341306b0fa7e1cb33c5e1c8d24ef70ddd684da65f41c49c92/markdownify-1.2.2.tar.gz", hash = "sha256:b274f1b5943180b031b699b199cbaeb1e2ac938b75851849a31fd0c3d6603d09", size = 18816, upload-time = "2025-11-16T19:21:18.565Z" } 269 - wheels = [ 270 - { url = "https://files.pythonhosted.org/packages/43/ce/f1e3e9d959db134cedf06825fae8d5b294bd368aacdd0831a3975b7c4d55/markdownify-1.2.2-py3-none-any.whl", hash = "sha256:3f02d3cc52714084d6e589f70397b6fc9f2f3a8531481bf35e8cc39f975e186a", size = 15724, upload-time = "2025-11-16T19:21:17.622Z" }, 271 - ] 272 - 273 - [[package]] 274 - name = "markupsafe" 275 - version = "3.0.3" 276 - source = { registry = "https://pypi.org/simple" } 277 - sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } 278 - wheels = [ 279 - { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, 280 - { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, 281 - { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, 282 - { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, 283 - { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, 284 - { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, 285 - { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, 286 - { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, 287 - { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, 288 - { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, 289 - { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, 290 - { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, 291 - { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, 292 - { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, 293 - { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, 294 - { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, 295 - { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, 296 - { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, 297 - { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, 298 - { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, 299 - { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, 300 - { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, 301 - { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, 302 - { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, 303 - { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, 304 - { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, 305 - { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, 306 - { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, 307 - { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, 308 - { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, 309 - { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, 310 - { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, 311 - { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, 312 - { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, 313 - { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, 314 - { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, 315 - { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, 316 - { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, 317 - { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, 318 - { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, 319 - { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, 320 - { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, 321 - { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, 322 - { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, 323 - { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, 324 - { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, 325 - { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, 326 - { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, 327 - { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, 328 - { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, 329 - { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, 330 - { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, 331 - { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, 332 - { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, 333 - { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, 334 - { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, 335 - { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, 336 - { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, 337 - { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, 338 - { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, 339 - { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, 340 - { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, 341 - { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, 342 - { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, 343 - { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, 344 - { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, 345 - ] 346 - 347 - [[package]] 348 - name = "mdformat" 349 - version = "0.7.22" 350 - source = { registry = "https://pypi.org/simple" } 351 - dependencies = [ 352 - { name = "markdown-it-py" }, 353 - ] 354 - sdist = { url = "https://files.pythonhosted.org/packages/fc/eb/b5cbf2484411af039a3d4aeb53a5160fae25dd8c84af6a4243bc2f3fedb3/mdformat-0.7.22.tar.gz", hash = "sha256:eef84fa8f233d3162734683c2a8a6222227a229b9206872e6139658d99acb1ea", size = 34610, upload-time = "2025-01-30T18:00:51.418Z" } 355 - wheels = [ 356 - { url = "https://files.pythonhosted.org/packages/f2/6f/94a7344f6d634fe3563bea8b33bccedee37f2726f7807e9a58440dc91627/mdformat-0.7.22-py3-none-any.whl", hash = "sha256:61122637c9e1d9be1329054f3fa216559f0d1f722b7919b060a8c2a4ae1850e5", size = 34447, upload-time = "2025-01-30T18:00:48.708Z" }, 357 - ] 358 - 359 - [[package]] 360 - name = "mdformat-tables" 361 - version = "1.0.0" 362 - source = { registry = "https://pypi.org/simple" } 363 - dependencies = [ 364 - { name = "mdformat" }, 365 - { name = "wcwidth" }, 366 - ] 367 - sdist = { url = "https://files.pythonhosted.org/packages/64/fc/995ba209096bdebdeb8893d507c7b32b7e07d9a9f2cdc2ec07529947794b/mdformat_tables-1.0.0.tar.gz", hash = "sha256:a57db1ac17c4a125da794ef45539904bb8a9592e80557d525e1f169c96daa2c8", size = 6106, upload-time = "2024-08-23T23:41:33.413Z" } 368 - wheels = [ 369 - { url = "https://files.pythonhosted.org/packages/2a/37/d78e37d14323da3f607cd1af7daf262cb87fe614a245c15ad03bb03a2706/mdformat_tables-1.0.0-py3-none-any.whl", hash = "sha256:94cd86126141b2adc3b04c08d1441eb1272b36c39146bab078249a41c7240a9a", size = 5104, upload-time = "2024-08-23T23:41:31.863Z" }, 370 - ] 371 - 372 - [[package]] 373 - name = "mdurl" 374 - version = "0.1.2" 375 - source = { registry = "https://pypi.org/simple" } 376 - sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } 377 - wheels = [ 378 - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, 379 - ] 380 - 381 - [[package]] 382 - name = "mergedeep" 383 - version = "1.3.4" 384 - source = { registry = "https://pypi.org/simple" } 385 - sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661, upload-time = "2021-02-05T18:55:30.623Z" } 386 - wheels = [ 387 - { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, 388 - ] 389 - 390 - [[package]] 391 - name = "mkdocs" 392 - version = "1.6.1" 393 - source = { registry = "https://pypi.org/simple" } 394 - dependencies = [ 395 - { name = "click" }, 396 - { name = "colorama", marker = "sys_platform == 'win32'" }, 397 - { name = "ghp-import" }, 398 - { name = "jinja2" }, 399 - { name = "markdown" }, 400 - { name = "markupsafe" }, 401 - { name = "mergedeep" }, 402 - { name = "mkdocs-get-deps" }, 403 - { name = "packaging" }, 404 - { name = "pathspec" }, 405 - { name = "pyyaml" }, 406 - { name = "pyyaml-env-tag" }, 407 - { name = "watchdog" }, 408 - ] 409 - sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159, upload-time = "2024-08-30T12:24:06.899Z" } 410 - wheels = [ 411 - { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" }, 412 - ] 413 - 414 - [[package]] 415 - name = "mkdocs-get-deps" 416 - version = "0.2.0" 417 - source = { registry = "https://pypi.org/simple" } 418 - dependencies = [ 419 - { name = "mergedeep" }, 420 - { name = "platformdirs" }, 421 - { name = "pyyaml" }, 422 - ] 423 - sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239, upload-time = "2023-11-20T17:51:09.981Z" } 424 - wheels = [ 425 - { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521, upload-time = "2023-11-20T17:51:08.587Z" }, 426 - ] 427 - 428 - [[package]] 429 - name = "mkdocs-git-revision-date-localized-plugin" 430 - version = "1.5.0" 431 - source = { registry = "https://pypi.org/simple" } 432 - dependencies = [ 433 - { name = "babel" }, 434 - { name = "gitpython" }, 435 - { name = "mkdocs" }, 436 - { name = "tzdata", marker = "sys_platform == 'win32'" }, 437 - ] 438 - sdist = { url = "https://files.pythonhosted.org/packages/0f/c5/1d3c4e6ddae6230b89d09105cb79de711655e3ebd6745f7a92efea0f5160/mkdocs_git_revision_date_localized_plugin-1.5.0.tar.gz", hash = "sha256:17345ccfdf69a1905dc96fb1070dce82d03a1eb6b0d48f958081a7589ce3c248", size = 460697, upload-time = "2025-10-31T16:11:34.44Z" } 439 - wheels = [ 440 - { url = "https://files.pythonhosted.org/packages/bc/51/fe0e3fdb16f6eed65c9459d12bae6a4e1f0bb4e2228cb037e7907b002678/mkdocs_git_revision_date_localized_plugin-1.5.0-py3-none-any.whl", hash = "sha256:933f9e35a8c135b113f21bb57610d82e9b7bcc71dd34fb06a029053c97e99656", size = 26153, upload-time = "2025-10-31T16:11:32.987Z" }, 441 - ] 442 - 443 - [[package]] 444 - name = "mkdocs-glightbox" 445 - version = "0.5.2" 446 - source = { registry = "https://pypi.org/simple" } 447 - dependencies = [ 448 - { name = "selectolax" }, 449 - ] 450 - sdist = { url = "https://files.pythonhosted.org/packages/8d/26/c793459622da8e31f954c6f5fb51e8f098143fdfc147b1e3c25bf686f4aa/mkdocs_glightbox-0.5.2.tar.gz", hash = "sha256:c7622799347c32310878e01ccf14f70648445561010911c80590cec0353370ac", size = 510586, upload-time = "2025-10-23T14:55:18.909Z" } 451 - wheels = [ 452 - { url = "https://files.pythonhosted.org/packages/4e/ca/03624e017e5ee2d7ce8a08d89f81c1e535eb3c30d7b2dc4a435ea3fbbeae/mkdocs_glightbox-0.5.2-py3-none-any.whl", hash = "sha256:23a431ea802b60b1030c73323db2eed6ba859df1a0822ce575afa43e0ea3f47e", size = 26458, upload-time = "2025-10-23T14:55:17.43Z" }, 453 - ] 454 - 455 - [[package]] 456 - name = "mkdocs-llmstxt" 457 - version = "0.5.0" 458 - source = { registry = "https://pypi.org/simple" } 459 - dependencies = [ 460 - { name = "beautifulsoup4" }, 461 - { name = "markdownify" }, 462 - { name = "mdformat" }, 463 - { name = "mdformat-tables" }, 464 - ] 465 - sdist = { url = "https://files.pythonhosted.org/packages/7f/f5/4c31cdffa7c09bf48d8c7a50d8342dc100abac98ac4150826bc11afc0c9f/mkdocs_llmstxt-0.5.0.tar.gz", hash = "sha256:b2fa9e6d68df41d7467e948a4745725b6c99434a36b36204857dbd7bb3dfe041", size = 33909, upload-time = "2025-11-20T14:02:24.861Z" } 466 - wheels = [ 467 - { url = "https://files.pythonhosted.org/packages/ad/2b/82928cc9e8d9269cd79e7ebf015efdc4945e6c646e86ec1d4dba1707f215/mkdocs_llmstxt-0.5.0-py3-none-any.whl", hash = "sha256:753c699913d2d619a9072604b26b6dc9f5fb6d257d9b107857f80c8a0b787533", size = 12040, upload-time = "2025-11-20T14:02:23.483Z" }, 468 - ] 469 - 470 - [[package]] 471 - name = "mkdocs-material" 472 - version = "9.7.0" 473 - source = { registry = "https://pypi.org/simple" } 474 - dependencies = [ 475 - { name = "babel" }, 476 - { name = "backrefs" }, 477 - { name = "colorama" }, 478 - { name = "jinja2" }, 479 - { name = "markdown" }, 480 - { name = "mkdocs" }, 481 - { name = "mkdocs-material-extensions" }, 482 - { name = "paginate" }, 483 - { name = "pygments" }, 484 - { name = "pymdown-extensions" }, 485 - { name = "requests" }, 486 - ] 487 - sdist = { url = "https://files.pythonhosted.org/packages/9c/3b/111b84cd6ff28d9e955b5f799ef217a17bc1684ac346af333e6100e413cb/mkdocs_material-9.7.0.tar.gz", hash = "sha256:602b359844e906ee402b7ed9640340cf8a474420d02d8891451733b6b02314ec", size = 4094546, upload-time = "2025-11-11T08:49:09.73Z" } 488 - wheels = [ 489 - { url = "https://files.pythonhosted.org/packages/04/87/eefe8d5e764f4cf50ed91b943f8e8f96b5efd65489d8303b7a36e2e79834/mkdocs_material-9.7.0-py3-none-any.whl", hash = "sha256:da2866ea53601125ff5baa8aa06404c6e07af3c5ce3d5de95e3b52b80b442887", size = 9283770, upload-time = "2025-11-11T08:49:06.26Z" }, 490 - ] 491 - 492 - [[package]] 493 - name = "mkdocs-material-extensions" 494 - version = "1.3.1" 495 - source = { registry = "https://pypi.org/simple" } 496 - sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847, upload-time = "2023-11-22T19:09:45.208Z" } 497 - wheels = [ 498 - { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728, upload-time = "2023-11-22T19:09:43.465Z" }, 499 - ] 500 - 501 - [[package]] 502 - name = "mkdocs-multirepo-plugin" 503 - version = "0.8.3" 504 - source = { git = "https://github.com/atuinsh/mkdocs-multirepo-plugin?rev=mkt%2Fimported_repo#e2aed29184af719cce2bc0dddb90ceec99af21b9" } 505 - dependencies = [ 506 - { name = "dacite" }, 507 - { name = "mkdocs" }, 508 - { name = "python-slugify" }, 509 - { name = "typing-inspect" }, 510 - ] 511 - 512 - [[package]] 513 - name = "mkdocs-redirects" 514 - version = "1.2.2" 515 - source = { registry = "https://pypi.org/simple" } 516 - dependencies = [ 517 - { name = "mkdocs" }, 518 - ] 519 - sdist = { url = "https://files.pythonhosted.org/packages/f1/a8/6d44a6cf07e969c7420cb36ab287b0669da636a2044de38a7d2208d5a758/mkdocs_redirects-1.2.2.tar.gz", hash = "sha256:3094981b42ffab29313c2c1b8ac3969861109f58b2dd58c45fc81cd44bfa0095", size = 7162, upload-time = "2024-11-07T14:57:21.109Z" } 520 - wheels = [ 521 - { url = "https://files.pythonhosted.org/packages/c4/ec/38443b1f2a3821bbcb24e46cd8ba979154417794d54baf949fefde1c2146/mkdocs_redirects-1.2.2-py3-none-any.whl", hash = "sha256:7dbfa5647b79a3589da4401403d69494bd1f4ad03b9c15136720367e1f340ed5", size = 6142, upload-time = "2024-11-07T14:57:19.143Z" }, 522 - ] 523 - 524 - [[package]] 525 - name = "mypy-extensions" 526 - version = "1.1.0" 527 - source = { registry = "https://pypi.org/simple" } 528 - sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } 529 - wheels = [ 530 - { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, 531 - ] 532 - 533 - [[package]] 534 - name = "packaging" 535 - version = "25.0" 536 - source = { registry = "https://pypi.org/simple" } 537 - sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } 538 - wheels = [ 539 - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, 540 - ] 541 - 542 - [[package]] 543 - name = "paginate" 544 - version = "0.5.7" 545 - source = { registry = "https://pypi.org/simple" } 546 - sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252, upload-time = "2024-08-25T14:17:24.139Z" } 547 - wheels = [ 548 - { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" }, 549 - ] 550 - 551 - [[package]] 552 - name = "pathspec" 553 - version = "0.12.1" 554 - source = { registry = "https://pypi.org/simple" } 555 - sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } 556 - wheels = [ 557 - { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, 558 - ] 559 - 560 - [[package]] 561 - name = "platformdirs" 562 - version = "4.5.1" 563 - source = { registry = "https://pypi.org/simple" } 564 - sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" } 565 - wheels = [ 566 - { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" }, 567 - ] 568 - 569 - [[package]] 570 - name = "pygments" 571 - version = "2.19.2" 572 - source = { registry = "https://pypi.org/simple" } 573 - sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } 574 - wheels = [ 575 - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, 576 - ] 577 - 578 - [[package]] 579 - name = "pymdown-extensions" 580 - version = "10.19" 581 - source = { registry = "https://pypi.org/simple" } 582 - dependencies = [ 583 - { name = "markdown" }, 584 - { name = "pyyaml" }, 585 - ] 586 - sdist = { url = "https://files.pythonhosted.org/packages/1f/4e/e73e88f4f2d0b26cbd2e100074107470984f0a6055869805fc181b847ac7/pymdown_extensions-10.19.tar.gz", hash = "sha256:01bb917ea231f9ce14456fa9092cdb95ac3e5bd32202a3ee61dbd5ad2dd9ef9b", size = 847701, upload-time = "2025-12-11T18:20:46.093Z" } 587 - wheels = [ 588 - { url = "https://files.pythonhosted.org/packages/d4/56/fa9edaceb3805e03ac9faf68ca1ddc660a75b49aee5accb493511005fef5/pymdown_extensions-10.19-py3-none-any.whl", hash = "sha256:dc5f249fc3a1b6d8a6de4634ba8336b88d0942cee75e92b18ac79eaf3503bf7c", size = 266670, upload-time = "2025-12-11T18:20:44.736Z" }, 589 - ] 590 - 591 - [[package]] 592 - name = "python-dateutil" 593 - version = "2.9.0.post0" 594 - source = { registry = "https://pypi.org/simple" } 595 - dependencies = [ 596 - { name = "six" }, 597 - ] 598 - sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } 599 - wheels = [ 600 - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, 601 - ] 602 - 603 - [[package]] 604 - name = "python-slugify" 605 - version = "8.0.4" 606 - source = { registry = "https://pypi.org/simple" } 607 - dependencies = [ 608 - { name = "text-unidecode" }, 609 - ] 610 - sdist = { url = "https://files.pythonhosted.org/packages/87/c7/5e1547c44e31da50a460df93af11a535ace568ef89d7a811069ead340c4a/python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856", size = 10921, upload-time = "2024-02-08T18:32:45.488Z" } 611 - wheels = [ 612 - { url = "https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8", size = 10051, upload-time = "2024-02-08T18:32:43.911Z" }, 613 - ] 614 - 615 - [[package]] 616 - name = "pyyaml" 617 - version = "6.0.3" 618 - source = { registry = "https://pypi.org/simple" } 619 - sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } 620 - wheels = [ 621 - { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, 622 - { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, 623 - { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, 624 - { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, 625 - { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, 626 - { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, 627 - { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, 628 - { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, 629 - { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, 630 - { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, 631 - { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, 632 - { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, 633 - { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, 634 - { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, 635 - { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, 636 - { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, 637 - { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, 638 - { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, 639 - { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, 640 - { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, 641 - { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, 642 - { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, 643 - { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, 644 - { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, 645 - { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, 646 - { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, 647 - { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, 648 - { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, 649 - { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, 650 - { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, 651 - { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, 652 - { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, 653 - { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, 654 - { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, 655 - { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, 656 - { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, 657 - { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, 658 - { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, 659 - { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, 660 - { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, 661 - { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, 662 - { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, 663 - { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, 664 - { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, 665 - { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, 666 - { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, 667 - { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, 668 - ] 669 - 670 - [[package]] 671 - name = "pyyaml-env-tag" 672 - version = "1.1" 673 - source = { registry = "https://pypi.org/simple" } 674 - dependencies = [ 675 - { name = "pyyaml" }, 676 - ] 677 - sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737, upload-time = "2025-05-13T15:24:01.64Z" } 678 - wheels = [ 679 - { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, 680 - ] 681 - 682 - [[package]] 683 - name = "requests" 684 - version = "2.32.5" 685 - source = { registry = "https://pypi.org/simple" } 686 - dependencies = [ 687 - { name = "certifi" }, 688 - { name = "charset-normalizer" }, 689 - { name = "idna" }, 690 - { name = "urllib3" }, 691 - ] 692 - sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } 693 - wheels = [ 694 - { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, 695 - ] 696 - 697 - [[package]] 698 - name = "selectolax" 699 - version = "0.4.6" 700 - source = { registry = "https://pypi.org/simple" } 701 - sdist = { url = "https://files.pythonhosted.org/packages/fb/c5/959b8661d200d9fd3cf52061ce6f1d7087ec94823bb324fe1ca76c80b250/selectolax-0.4.6.tar.gz", hash = "sha256:bd9326cfc9bbd5bfcda980b0452b9761b3cf134015154e95d83fa32cbfbb751b", size = 4793248, upload-time = "2025-12-06T12:35:48.513Z" } 702 - wheels = [ 703 - { url = "https://files.pythonhosted.org/packages/a0/76/9b5358d82353b68c5828cc8ceae4ff1073495462979d2035c1089f4421dd/selectolax-0.4.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:751f727c9963584fcfa101b2696e0dd31236142901bbe7866a8e39f2ec346cc4", size = 2052057, upload-time = "2025-12-06T12:34:24.448Z" }, 704 - { url = "https://files.pythonhosted.org/packages/e3/d1/9f8c8841f414a1b72174acef916d4ed38cc0fa041d3e933013e2b3213f30/selectolax-0.4.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6f45737b638836b9fe2a4e7ccfbcd48a315ebb96da76a79a04b8227c1a967ee", size = 2050379, upload-time = "2025-12-06T12:34:26.383Z" }, 705 - { url = "https://files.pythonhosted.org/packages/bc/c4/8e5ab9275a185a31d06b5ea58e3ba61d57e57700964cbd56fe074dbe458c/selectolax-0.4.6-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15a22c5cd9c23f09227b2b9c227d986396125a9b0eb21be655f22fe4ccc5679a", size = 2238005, upload-time = "2025-12-06T12:34:28.2Z" }, 706 - { url = "https://files.pythonhosted.org/packages/ea/af/f4299d931a8e11ba1998cac70d407c5338436978325232eb252ac7f5aba2/selectolax-0.4.6-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e64f771807f1a7353f4d6878c303bfbd6c6fe58897e301aa6d0de7e5e60cef61", size = 2272927, upload-time = "2025-12-06T12:34:29.955Z" }, 707 - { url = "https://files.pythonhosted.org/packages/7b/5e/9afbb0e8495846bf97fa7725a6f97622ad85efc654cb3cbf4c881bd345de/selectolax-0.4.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a0144a37fbf01695ccf2d0d24caaa058a28449cecb2c754bb9e616f339468d74", size = 2250901, upload-time = "2025-12-06T12:34:31.442Z" }, 708 - { url = "https://files.pythonhosted.org/packages/d5/6b/914cc9c977fd21949af5776d25b9c011b6e72fb38569161ab6ca83d6130a/selectolax-0.4.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c9bdd4a9b3f71f28a0ee558a105451debd33cbe1ed350ebba7ad6b68d62815c", size = 2279842, upload-time = "2025-12-06T12:34:32.739Z" }, 709 - { url = "https://files.pythonhosted.org/packages/e1/30/b32d79d31c893cf5ccea5a5be4565db1eda9bbf458ddfe402559267f2d31/selectolax-0.4.6-cp311-cp311-win32.whl", hash = "sha256:b91c34b854fdd5d21c8353f130899f8413b7104a96078acbca59c8b2d57e9352", size = 1730462, upload-time = "2025-12-06T12:34:34.435Z" }, 710 - { url = "https://files.pythonhosted.org/packages/8f/f1/c7ba048d4fcc4c8d5857233c59d07f18e60b21400a8ad8e8d7da670024c2/selectolax-0.4.6-cp311-cp311-win_amd64.whl", hash = "sha256:901064121e706bc86ed13f6e0dbe478398ad05ab112f5efbc8d722320a087b93", size = 1831442, upload-time = "2025-12-06T12:34:35.846Z" }, 711 - { url = "https://files.pythonhosted.org/packages/d5/55/b33853f66b1f875bbbbfc2294ce7a4065774621ab6ebf20e8abf19965846/selectolax-0.4.6-cp311-cp311-win_arm64.whl", hash = "sha256:609c6c19f5b7cb669a6321a1d4133d2e2b443f23f7d454de76904118a91236a6", size = 1781850, upload-time = "2025-12-06T12:34:37.175Z" }, 712 - { url = "https://files.pythonhosted.org/packages/ee/81/1fdf6633df840afd9d7054a3441f04cfb1fc9d098c6c9f3bd46a64fb632e/selectolax-0.4.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:20615062d6062b197b61fd646e667591e987be3a894e8a8408d2a482ccddc747", size = 2051021, upload-time = "2025-12-06T12:34:38.495Z" }, 713 - { url = "https://files.pythonhosted.org/packages/cc/54/d59738d090cb4df3a3a6297b7ec216b86d3ba7f320013c4bc8d4841c9f5d/selectolax-0.4.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c436006e2af6ade80b96411cf46652c11ced4f230032e25e1f5210b7522a4fe3", size = 2047409, upload-time = "2025-12-06T12:34:39.875Z" }, 714 - { url = "https://files.pythonhosted.org/packages/fc/67/3b163ec18a128df3a3b59ce676a2dacfb26e714da81ba8a98e184b4ef187/selectolax-0.4.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:705a70b6f4e553e8c5299881269d3735a7df8a23711927a33caa16b4eaef580f", size = 2237052, upload-time = "2025-12-06T12:34:41.24Z" }, 715 - { url = "https://files.pythonhosted.org/packages/f0/04/c3ae4a77e8cfa647b9177e727a7e80f64b160b65ad0db0dcb3738a4ef4a0/selectolax-0.4.6-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c04fd180689ed9450ad2453a3cba74cff2475a4281f76db9e18a658b7823e594", size = 2275615, upload-time = "2025-12-06T12:34:43.114Z" }, 716 - { url = "https://files.pythonhosted.org/packages/12/de/aaa016c44e63a1efd5525f6da6eac807388a06c70671091c735d93f13b74/selectolax-0.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cb33eb0809e70ba4a475105d164c3f90a4bb711744ca69e20037298256b8e9d7", size = 2249186, upload-time = "2025-12-06T12:34:44.84Z" }, 717 - { url = "https://files.pythonhosted.org/packages/76/9a/a9cf9f0158b0804c7ea404d790af031830eb6452a4948853f7582eea6c51/selectolax-0.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:97f30b7c731f9f3328e9c6aef7ca3c17fbcbc4495e286a2cdad9a77bcadfadf1", size = 2282041, upload-time = "2025-12-06T12:34:46.19Z" }, 718 - { url = "https://files.pythonhosted.org/packages/4c/ea/85de7ab8a9fc0301d1b428e69dc0bced9c1cd7379872d576a2b88eb91933/selectolax-0.4.6-cp312-cp312-win32.whl", hash = "sha256:f4375b352b609508e4a6980431dc6cc1812b97658ad1aa8caa61e01565de0d7d", size = 1727544, upload-time = "2025-12-06T12:34:47.541Z" }, 719 - { url = "https://files.pythonhosted.org/packages/50/70/4aac2df64920112672cda846941d85c90b8152b2eddc9cf2615181551957/selectolax-0.4.6-cp312-cp312-win_amd64.whl", hash = "sha256:1d02637a6746bf1ba7de1dfc00a0344ffb30bedd1b5d4e61727c960225bf6ce0", size = 1827825, upload-time = "2025-12-06T12:34:49.283Z" }, 720 - { url = "https://files.pythonhosted.org/packages/8d/b0/09648383afed1a10df97ce30527d30714edc4072086915b4bb1a0d81a728/selectolax-0.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:bb0b371c3e2a94e6658ba4b5af88fc35aaf44f57f5a066ecaf96b4875a47aec4", size = 1775233, upload-time = "2025-12-06T12:34:51.576Z" }, 721 - { url = "https://files.pythonhosted.org/packages/4d/87/7ed053cce7de8b29746c602851c67654287e25ec404d575911c6f40b671f/selectolax-0.4.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8303af0eeef6ab2f06f2b18e3c825df4f6984405a862c8e9e654621c26558aca", size = 2050412, upload-time = "2025-12-06T12:34:53.086Z" }, 722 - { url = "https://files.pythonhosted.org/packages/44/74/e8cd9b9b53da0e849b27a2ef68580915321ee52a662f015275a1cf6cca85/selectolax-0.4.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d8b1fb5507d90e719de705d93eaa3bdd5f2d69facf012fb67b7da8a9cd20ea6b", size = 2046513, upload-time = "2025-12-06T12:34:54.583Z" }, 723 - { url = "https://files.pythonhosted.org/packages/a0/ca/c1cc7f03b681d272dbb0dc47cf9d0df857ae156d7ea54d88cc25ec23c8e9/selectolax-0.4.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30ac51bd5bfcd6bffe58720b1fc5f97666681f0793d79d292069b3a3f8599ef0", size = 2234404, upload-time = "2025-12-06T12:34:55.971Z" }, 724 - { url = "https://files.pythonhosted.org/packages/df/00/a6e5c4d65243147fbd8837951267f098d9bee66ada4dc0c99d97259e052c/selectolax-0.4.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cfee4d1269fd462256641abdf6c2ee4dd799ba82c578acab0bcde07547637826", size = 2272678, upload-time = "2025-12-06T12:34:57.3Z" }, 725 - { url = "https://files.pythonhosted.org/packages/ab/a2/05351e0f0da62d1bc01b7820a990f1e4dec688206e0278ee8faeeb878940/selectolax-0.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fce09eeb5dd19fba672a829f63e3c40238af4a929ce1e5fd16dcbc4fd253e300", size = 2247471, upload-time = "2025-12-06T12:34:59.048Z" }, 726 - { url = "https://files.pythonhosted.org/packages/ea/95/1ab9e3ad2d53dbcd7141af149c7259c693dc2dc46e27d72b7a68f17f3364/selectolax-0.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4e97ca71d545cab9c57ba3b18358cbc96ef0dcd01920ea903a531386ca1f849", size = 2278271, upload-time = "2025-12-06T12:35:00.487Z" }, 727 - { url = "https://files.pythonhosted.org/packages/04/41/ca80ca68fb9990cb46d753363d8dc0771225bc9bb9a77247a1987e52d2d5/selectolax-0.4.6-cp313-cp313-win32.whl", hash = "sha256:98fce08839cb8fd5d8788cbed2724cd892c78182cd923e246ef586d552a29a94", size = 1727514, upload-time = "2025-12-06T12:35:02.081Z" }, 728 - { url = "https://files.pythonhosted.org/packages/f0/47/f048994ab32773fda8eda57a874afb30d0b2bf30952c009006e81737e07e/selectolax-0.4.6-cp313-cp313-win_amd64.whl", hash = "sha256:cdc8e7833d2456331e519fe901d1c8844d120a26b21b6429f47ae946e65b0c04", size = 1829070, upload-time = "2025-12-06T12:35:03.857Z" }, 729 - { url = "https://files.pythonhosted.org/packages/50/94/ab0d86b1a719c090e2bde9f7d9037439900e86fb50c258b5fd9f6530521b/selectolax-0.4.6-cp313-cp313-win_arm64.whl", hash = "sha256:d6f8c976ad067a6607b2a052b141149ae23584819b73288c32f08a1ece23d60a", size = 1774935, upload-time = "2025-12-06T12:35:05.323Z" }, 730 - { url = "https://files.pythonhosted.org/packages/d2/38/93b4907c596487e13f8261129b1663559c96fc37ea2c973c98a393307484/selectolax-0.4.6-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:961c037ac41a12bf9db35a95d6076461f9b127d361c9ef26a77f76c45b1056eb", size = 2069131, upload-time = "2025-12-06T12:35:06.737Z" }, 731 - { url = "https://files.pythonhosted.org/packages/f6/04/d29769a8313ccb9db6278401840e79662f341b716d268f7468b6270d15e1/selectolax-0.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f2be076a69a12657a38933b99d31c604d95d63911e0799f89305da8e89918874", size = 2066134, upload-time = "2025-12-06T12:35:08.163Z" }, 732 - { url = "https://files.pythonhosted.org/packages/29/a2/1c26b4cc6a708d234e39199bd75acdc1cfdcf4f3138e16d25e3e7aa0295d/selectolax-0.4.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25ae5dd7c20035312211de43952934981e8ff4e1502467ce78665f57bc5eaf7f", size = 2240810, upload-time = "2025-12-06T12:35:09.556Z" }, 733 - { url = "https://files.pythonhosted.org/packages/1f/de/b021342d306bd08c92d0d9e9072a3ed6a3038f78387187d37fb775196fa0/selectolax-0.4.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cfe1274930affe2b986fd20cbf2916ddf4a760edf30a7eeb9151b31e8cbe6027", size = 2274401, upload-time = "2025-12-06T12:35:11.023Z" }, 734 - { url = "https://files.pythonhosted.org/packages/29/77/b2816be2f4878f4e86fabca5932610401dc88d956948d97a82947e27d8bc/selectolax-0.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e52174a75236c1321f0f0353b5d97ba575c61428f16c2d78159cb154fa407e97", size = 2271054, upload-time = "2025-12-06T12:35:12.878Z" }, 735 - { url = "https://files.pythonhosted.org/packages/1f/3a/ae48b9febf2af21a0fdd4fba07861ae3e13bd7235df3fa39918d33004058/selectolax-0.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5032187ed8f8d77da6dee5467a87fe9b1553c10c63671fe830e87a2d347ef8ae", size = 2297773, upload-time = "2025-12-06T12:35:14.383Z" }, 736 - { url = "https://files.pythonhosted.org/packages/f9/8c/4e120b2b6dc55543bf2ffc43e78589022e59c02fa93dea0b4d22dfe3fc27/selectolax-0.4.6-cp314-cp314-win32.whl", hash = "sha256:8a4f50eb37abffe118730c062827a204a732cc1b9cd28b5dbf40752c371e9339", size = 1838289, upload-time = "2025-12-06T12:35:16.278Z" }, 737 - { url = "https://files.pythonhosted.org/packages/c4/2f/51f15b06f4fcf9d5845d6bba534f7f2ed531f148c77ed8fff105cd770aa5/selectolax-0.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:11527cd430cb6d1d1a422209d87aec5767befff424f2affaa3daa2789878cf9f", size = 1938201, upload-time = "2025-12-06T12:35:17.694Z" }, 738 - { url = "https://files.pythonhosted.org/packages/f3/8d/c099dcbb385e7d2145c4f19da183639bf4e429e1524dcba31ea311c5d276/selectolax-0.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:254d7f59580631dac1fcb861bb01f45039e3ac53187f07d8ccc3519110bacad0", size = 1886188, upload-time = "2025-12-06T12:35:19.538Z" }, 739 - { url = "https://files.pythonhosted.org/packages/54/ce/f3fa904517745ecd289b6ce18845ae968cf7d0b17e65ab781259f2746254/selectolax-0.4.6-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:48a9bce389c281fec8bf3b5a36bd376f1ad1f36ff072dcedaa977188b3882be1", size = 2088107, upload-time = "2025-12-06T12:35:21.061Z" }, 740 - { url = "https://files.pythonhosted.org/packages/4f/18/359da9723d3ec1235819cea0958bc417ce6a12699977920854b300ad4529/selectolax-0.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ff1632c1767f6005adc2dff7b72ea9d0b6493702e86e04ee5cf934ab630172aa", size = 2090836, upload-time = "2025-12-06T12:35:22.421Z" }, 741 - { url = "https://files.pythonhosted.org/packages/e2/20/199f2a05ca8dfd9bc146af03fbfaa1e2050601d3141267070a2a023ea68f/selectolax-0.4.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:64a56dd91c22e809305e127bbd4cd75ad1016dd329a4e945a176c6f3376d00e2", size = 2248608, upload-time = "2025-12-06T12:35:23.946Z" }, 742 - { url = "https://files.pythonhosted.org/packages/f9/67/261c06cdae29fad287008d39f51a80431f3fce66c2865b880e61d04cdfd2/selectolax-0.4.6-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:223471d2c9095406d69faf461aa217782575d62362d36809e350f6d3c2f69f4e", size = 2275653, upload-time = "2025-12-06T12:35:25.423Z" }, 743 - { url = "https://files.pythonhosted.org/packages/10/80/f2519487a86b5366acadd9e07c212b38fb657bb62b9e01de9fb24c3ada27/selectolax-0.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8c1043e61df29f4f8ef49f9f623b3d710f0c545d9a7939eee52c49987b06aef7", size = 2283495, upload-time = "2025-12-06T12:35:26.843Z" }, 744 - { url = "https://files.pythonhosted.org/packages/66/cc/35a0fd896371e0b5a84365b03f88c7dbe8984862e34ce32baed81ee6f486/selectolax-0.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b323ad4ebcf2edad2488022402fbc73ee158ffe81607ec1ce5eb1039eab94086", size = 2300207, upload-time = "2025-12-06T12:35:28.23Z" }, 745 - { url = "https://files.pythonhosted.org/packages/51/b2/dc83cce2f38a3c72d6bf9268ef6c1708ab1b4d546074384e7e0d097bf4f6/selectolax-0.4.6-cp314-cp314t-win32.whl", hash = "sha256:f5017f6e2408160604c87fb21490d9af802d09dbc1b91ac89acd9922b7b04d31", size = 1890595, upload-time = "2025-12-06T12:35:29.625Z" }, 746 - { url = "https://files.pythonhosted.org/packages/87/f9/8da49637643b1dffbcadc8972f1fee519c126978acaf5df59405e48424f4/selectolax-0.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:56adb0f014ab55627f20f53888a7bf1ec53aac8189fe344aec3d5077a7ad9889", size = 2005252, upload-time = "2025-12-06T12:35:31.116Z" }, 747 - { url = "https://files.pythonhosted.org/packages/94/7f/f783e2254db082df4f6bc00fe3b32b9dd27c3b7302a44c8c37728bb67fb7/selectolax-0.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:66558cfb1c7402fed0f47b9a2692eed53e3e2f345526314b493b5093cb951e21", size = 1906079, upload-time = "2025-12-06T12:35:32.951Z" }, 748 - ] 749 - 750 - [[package]] 751 - name = "six" 752 - version = "1.17.0" 753 - source = { registry = "https://pypi.org/simple" } 754 - sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } 755 - wheels = [ 756 - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, 757 - ] 758 - 759 - [[package]] 760 - name = "smmap" 761 - version = "5.0.2" 762 - source = { registry = "https://pypi.org/simple" } 763 - sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329, upload-time = "2025-01-02T07:14:40.909Z" } 764 - wheels = [ 765 - { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303, upload-time = "2025-01-02T07:14:38.724Z" }, 766 - ] 767 - 768 - [[package]] 769 - name = "soupsieve" 770 - version = "2.8.3" 771 - source = { registry = "https://pypi.org/simple" } 772 - sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" } 773 - wheels = [ 774 - { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" }, 775 - ] 776 - 777 - [[package]] 778 - name = "text-unidecode" 779 - version = "1.3" 780 - source = { registry = "https://pypi.org/simple" } 781 - sdist = { url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", size = 76885, upload-time = "2019-08-30T21:36:45.405Z" } 782 - wheels = [ 783 - { url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", size = 78154, upload-time = "2019-08-30T21:37:03.543Z" }, 784 - ] 785 - 786 - [[package]] 787 - name = "typing-extensions" 788 - version = "4.15.0" 789 - source = { registry = "https://pypi.org/simple" } 790 - sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } 791 - wheels = [ 792 - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, 793 - ] 794 - 795 - [[package]] 796 - name = "typing-inspect" 797 - version = "0.8.0" 798 - source = { registry = "https://pypi.org/simple" } 799 - dependencies = [ 800 - { name = "mypy-extensions" }, 801 - { name = "typing-extensions" }, 802 - ] 803 - sdist = { url = "https://files.pythonhosted.org/packages/72/23/bed3ea644bcd77ffe9a7f591eb058c00739747e33ab94d80cc4319ddee8e/typing_inspect-0.8.0.tar.gz", hash = "sha256:8b1ff0c400943b6145df8119c41c244ca8207f1f10c9c057aeed1560e4806e3d", size = 13550, upload-time = "2022-08-17T14:00:05.915Z" } 804 - wheels = [ 805 - { url = "https://files.pythonhosted.org/packages/be/01/59b743dca816c4b6ca891b9e0f84d20513cd61bdbbaa8615de8f5aab68c1/typing_inspect-0.8.0-py3-none-any.whl", hash = "sha256:5fbf9c1e65d4fa01e701fe12a5bca6c6e08a4ffd5bc60bfac028253a447c5188", size = 8710, upload-time = "2022-08-17T14:00:03.093Z" }, 806 - ] 807 - 808 - [[package]] 809 - name = "tzdata" 810 - version = "2025.2" 811 - source = { registry = "https://pypi.org/simple" } 812 - sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } 813 - wheels = [ 814 - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, 815 - ] 816 - 817 - [[package]] 818 - name = "urllib3" 819 - version = "2.6.2" 820 - source = { registry = "https://pypi.org/simple" } 821 - sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" } 822 - wheels = [ 823 - { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" }, 824 - ] 825 - 826 - [[package]] 827 - name = "watchdog" 828 - version = "6.0.0" 829 - source = { registry = "https://pypi.org/simple" } 830 - sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } 831 - wheels = [ 832 - { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, 833 - { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, 834 - { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, 835 - { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, 836 - { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, 837 - { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, 838 - { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, 839 - { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, 840 - { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, 841 - { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, 842 - { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, 843 - { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, 844 - { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, 845 - { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, 846 - { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, 847 - { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, 848 - { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, 849 - { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, 850 - { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, 851 - ] 852 - 853 - [[package]] 854 - name = "wcwidth" 855 - version = "0.7.0" 856 - source = { registry = "https://pypi.org/simple" } 857 - sdist = { url = "https://files.pythonhosted.org/packages/2c/ee/afaf0f85a9a18fe47a67f1e4422ed6cf1fe642f0ae0a2f81166231303c52/wcwidth-0.7.0.tar.gz", hash = "sha256:90e3a7ea092341c44b99562e75d09e4d5160fe7a3974c6fb842a101a95e7eed0", size = 182132, upload-time = "2026-05-02T16:04:12.653Z" } 858 - wheels = [ 859 - { url = "https://files.pythonhosted.org/packages/41/52/e465037f5375f43533d1a80b6923955201596a99142ed524d77b571a1418/wcwidth-0.7.0-py3-none-any.whl", hash = "sha256:5d69154c429a82910e241c738cd0e2976fac8a2dd47a1a805f4afed1c0f136f2", size = 110825, upload-time = "2026-05-02T16:04:11.033Z" }, 860 - ]
-17
fossier.toml
··· 1 - [repo] 2 - owner = "atuinsh" 3 - name = "atuin" 4 - 5 - [thresholds] 6 - allow_score = 70.0 7 - deny_score = 40.0 8 - min_confidence = 0.5 9 - 10 - [actions.deny] 11 - close_pr = true 12 - comment = true 13 - label = "fossier:spam-likely" 14 - 15 - [actions.review] 16 - comment = true 17 - label = "fossier:needs-review"
-156
k8s/atuin.yaml
··· 1 - --- 2 - apiVersion: apps/v1 3 - kind: Deployment 4 - metadata: 5 - name: atuin 6 - spec: 7 - replicas: 1 8 - selector: 9 - matchLabels: 10 - io.kompose.service: atuin 11 - template: 12 - metadata: 13 - labels: 14 - io.kompose.service: atuin 15 - spec: 16 - containers: 17 - - args: 18 - - start 19 - env: 20 - - name: ATUIN_DB_URI 21 - valueFrom: 22 - secretKeyRef: 23 - name: atuin-secrets 24 - key: ATUIN_DB_URI 25 - optional: false 26 - - name: ATUIN_HOST 27 - value: 0.0.0.0 28 - - name: ATUIN_PORT 29 - value: "8888" 30 - - name: ATUIN_OPEN_REGISTRATION 31 - value: "true" 32 - image: ghcr.io/atuinsh/atuin:latest 33 - name: atuin 34 - ports: 35 - - containerPort: &port 8888 36 - resources: 37 - limits: 38 - cpu: 250m 39 - memory: 1Gi 40 - requests: 41 - cpu: 250m 42 - memory: 1Gi 43 - startupProbe: 44 - httpGet: 45 - path: /healthz 46 - port: *port 47 - failureThreshold: 30 48 - periodSeconds: 10 49 - livenessProbe: 50 - httpGet: 51 - path: /healthz 52 - port: *port 53 - initialDelaySeconds: 3 54 - periodSeconds: 3 55 - readinessProbe: 56 - tcpSocket: 57 - port: *port 58 - initialDelaySeconds: 15 59 - periodSeconds: 10 60 - volumeMounts: 61 - - mountPath: /config 62 - name: atuin-claim0 63 - - name: postgresql 64 - image: postgres:14 65 - ports: 66 - - containerPort: 5432 67 - env: 68 - - name: POSTGRES_DB 69 - value: atuin 70 - - name: POSTGRES_PASSWORD 71 - valueFrom: 72 - secretKeyRef: 73 - name: atuin-secrets 74 - key: ATUIN_DB_PASSWORD 75 - optional: false 76 - - name: POSTGRES_USER 77 - valueFrom: 78 - secretKeyRef: 79 - name: atuin-secrets 80 - key: ATUIN_DB_USERNAME 81 - optional: false 82 - resources: 83 - limits: 84 - cpu: 250m 85 - memory: 1Gi 86 - requests: 87 - cpu: 250m 88 - memory: 1Gi 89 - volumeMounts: 90 - - mountPath: /var/lib/postgresql/data/ 91 - name: database 92 - volumes: 93 - - name: database 94 - persistentVolumeClaim: 95 - claimName: database 96 - - name: atuin-claim0 97 - persistentVolumeClaim: 98 - claimName: atuin-claim0 99 - --- 100 - apiVersion: v1 101 - kind: Service 102 - metadata: 103 - labels: 104 - io.kompose.service: atuin 105 - name: atuin 106 - spec: 107 - type: NodePort 108 - ports: 109 - - name: "8888" 110 - port: 8888 111 - nodePort: 31929 112 - selector: 113 - io.kompose.service: atuin 114 - --- 115 - kind: PersistentVolume 116 - apiVersion: v1 117 - metadata: 118 - name: database-pv 119 - labels: 120 - app: database 121 - type: local 122 - spec: 123 - storageClassName: manual 124 - capacity: 125 - storage: 300Mi 126 - accessModes: 127 - - ReadWriteOnce 128 - hostPath: 129 - path: "/Users/firstname.lastname/.kube/database" 130 - --- 131 - apiVersion: v1 132 - kind: PersistentVolumeClaim 133 - metadata: 134 - labels: 135 - io.kompose.service: database 136 - name: database 137 - spec: 138 - storageClassName: manual 139 - accessModes: 140 - - ReadWriteOnce 141 - resources: 142 - requests: 143 - storage: 300Mi 144 - --- 145 - apiVersion: v1 146 - kind: PersistentVolumeClaim 147 - metadata: 148 - labels: 149 - io.kompose.service: atuin-claim0 150 - name: atuin-claim0 151 - spec: 152 - accessModes: 153 - - ReadWriteOnce 154 - resources: 155 - requests: 156 - storage: 10Mi
-6
k8s/namespaces.yaml
··· 1 - apiVersion: v1 2 - kind: Namespace 3 - metadata: 4 - name: atuin-namespace 5 - labels: 6 - name: atuin
-13
k8s/secrets.yaml
··· 1 - apiVersion: v1 2 - kind: Secret 3 - metadata: 4 - name: atuin-secrets 5 - type: Opaque 6 - stringData: 7 - ATUIN_DB_USERNAME: atuin 8 - ATUIN_DB_PASSWORD: seriously-insecure 9 - ATUIN_HOST: "127.0.0.1" 10 - ATUIN_PORT: "8888" 11 - ATUIN_OPEN_REGISTRATION: "true" 12 - ATUIN_DB_URI: "postgres://atuin:seriously-insecure@localhost/atuin" 13 - immutable: true
-508
scripts/release.sh
··· 1 - #!/usr/bin/env bash 2 - # 3 - # Atuin CLI Release Script 4 - # 5 - # But first — make a cup of tea. Releases without tea are a crime. 🫖 6 - # 7 - 8 - set -euo pipefail 9 - 10 - WORKDIR="" 11 - 12 - cleanup_on_error() { 13 - if [[ $? -ne 0 && -n "$WORKDIR" ]]; then 14 - echo "" 15 - echo -e " \033[0;31m✗\033[0m Script failed. Working directory preserved at:" 16 - echo -e " \033[2m$WORKDIR\033[0m" 17 - fi 18 - } 19 - trap cleanup_on_error EXIT 20 - 21 - # ════════════════════════════════════════════════════════════════════ 22 - # Formatting 23 - # ════════════════════════════════════════════════════════════════════ 24 - 25 - RED='\033[0;31m' 26 - GREEN='\033[0;32m' 27 - YELLOW='\033[1;33m' 28 - BLUE='\033[0;34m' 29 - CYAN='\033[0;36m' 30 - MAGENTA='\033[0;35m' 31 - BOLD='\033[1m' 32 - DIM='\033[2m' 33 - NC='\033[0m' 34 - 35 - info() { echo -e " ${BLUE}▸${NC} $*"; } 36 - success() { echo -e " ${GREEN}✓${NC} $*"; } 37 - warn() { echo -e " ${YELLOW}⚠${NC} $*"; } 38 - die() { echo -e " ${RED}✗${NC} $*" >&2; exit 1; } 39 - 40 - step() { 41 - echo "" 42 - echo -e " ${MAGENTA}${BOLD}━━━ $* ━━━${NC}" 43 - echo "" 44 - } 45 - 46 - confirm() { 47 - echo -en " ${CYAN}▸${NC} $1 ${DIM}[y/N]${NC} " 48 - read -r reply 49 - [[ "$reply" =~ ^[Yy]$ ]] 50 - } 51 - 52 - # ════════════════════════════════════════════════════════════════════ 53 - # Banner 54 - # ════════════════════════════════════════════════════════════════════ 55 - 56 - banner() { 57 - echo "" 58 - echo -e "${CYAN}" 59 - cat <<'BANNER' 60 - 61 - : 62 - =#*#= 63 - #*+*#. 64 - #**++*+ 65 - =#*++++#. 66 - **+++++** 67 - :#++++++*#. 68 - **+++++++*# 69 - -#*+++++++*#- 70 - ##*****#####* 71 - -*##########:.+####*. 72 - ***********####*****+ 73 - :**#############*#+ 74 - #+----------------*- 75 - -*###########**+++##-----=##=-----=##=# 76 - .#*-==.. =*------------------* 77 - -#-::::::*=----------#*---------=----=--=* 78 - +*:::::::--:::::::::::**---+#=----===---=* 79 - #*::::::::=::::::::::::**-----+#*=-----+#- 80 - .#+::::::::=-::::::::::::**--------=*#### 81 - #=::::::::=*:::::::::::::+*---------=#-*#= 82 - ##-:::-**+=+*-:::::::::::-#=--------=#=##- 83 - :#+**+========++=::::-=++=#+--------+#+#* 84 - +##++============+*#+=====*+--------+#*# 85 - *=*#*+==+**++++*#++*====+###--------*###* 86 - *=-*##=+#=-------#**===+#+---------=##*=# 87 - *=-=*#**+---------#*+==+#----------*##--# 88 - :#*- ###=---------#+*==+#=-------=###=-=# 89 - +=---------#+#+++#*++++*##*== .. # 90 - ...... +=--*++*+=-#####+-. -+****=. 91 - ....... =*== . + ........... 92 - ............::-:............................ 93 - ............................................ 94 - ....###....########.##.....##.####.##....##. 95 - ...##.##......##....##.....##..##..###...##. 96 - ..##...##.....##....##.....##..##..####..##. 97 - .##.....##....##....##.....##..##..##.##.##. 98 - .#########....##....##.....##..##..##..####. 99 - .##.....##....##....##.....##..##..##...###. 100 - .##.....##....##.....#######..####.##....##. 101 - ............................................ 102 - 103 - ~ Magical Shell History ~ 104 - Release Script 105 - 106 - BANNER 107 - echo -e "${NC}" 108 - echo "" 109 - } 110 - 111 - # ════════════════════════════════════════════════════════════════════ 112 - # 1. Dependency check 113 - # ════════════════════════════════════════════════════════════════════ 114 - 115 - check_deps() { 116 - step "Dependencies" 117 - 118 - local missing=() 119 - local deps=(git gsed cargo gh git-cliff) 120 - 121 - for cmd in "${deps[@]}"; do 122 - if command -v "$cmd" &>/dev/null; then 123 - success "${BOLD}$cmd${NC} ${DIM}$(command -v "$cmd")${NC}" 124 - else 125 - echo -e " ${RED}✗${NC} ${BOLD}$cmd${NC} not found" 126 - missing+=("$cmd") 127 - fi 128 - done 129 - 130 - if (( ${#missing[@]} )); then 131 - echo "" 132 - die "Missing required tools: ${missing[*]}\n Install with: ${DIM}brew install ${missing[*]}${NC}" 133 - fi 134 - } 135 - 136 - # ════════════════════════════════════════════════════════════════════ 137 - # 2. Clone into working directory 138 - # ════════════════════════════════════════════════════════════════════ 139 - 140 - setup_workdir() { 141 - step "Working Directory" 142 - 143 - WORKDIR=$(mktemp -d) 144 - info "Created ${DIM}$WORKDIR${NC}" 145 - 146 - info "Cloning atuinsh/atuin..." 147 - git clone --quiet git@github.com:atuinsh/atuin.git "$WORKDIR" 148 - cd "$WORKDIR" 149 - success "Repository cloned" 150 - } 151 - 152 - # ════════════════════════════════════════════════════════════════════ 153 - # 3. Version 154 - # ════════════════════════════════════════════════════════════════════ 155 - 156 - detect_current_version() { 157 - sed -n '/^\[workspace\.package\]/,/^\[/s/^version = "\(.*\)"/\1/p' Cargo.toml 158 - } 159 - 160 - get_version() { 161 - step "Version" 162 - 163 - CURRENT_VERSION=$(detect_current_version) 164 - info "Current version: ${BOLD}$CURRENT_VERSION${NC}" 165 - 166 - # Suggest the next version based on conventional commits 167 - local suggested 168 - suggested=$(git-cliff --bumped-version 2>/dev/null | sed 's/^v//' || true) 169 - if [[ -n "$suggested" && "$suggested" != "$CURRENT_VERSION" ]]; then 170 - info "Suggested next: ${BOLD}$suggested${NC} ${DIM}(based on conventional commits)${NC}" 171 - fi 172 - 173 - echo "" 174 - 175 - if [[ -n "${NEW_VERSION:-}" ]]; then 176 - info "Using version from environment: ${BOLD}$NEW_VERSION${NC}" 177 - else 178 - echo -en " ${CYAN}▸${NC} New version ${DIM}(without 'v' prefix)${NC}: " 179 - read -r NEW_VERSION 180 - fi 181 - 182 - [[ -n "$NEW_VERSION" ]] || die "Version cannot be empty" 183 - 184 - IS_PRERELEASE=false 185 - if [[ "$NEW_VERSION" == *-* ]]; then 186 - IS_PRERELEASE=true 187 - warn "Pre-release detected" 188 - fi 189 - 190 - echo "" 191 - info "${BOLD}$CURRENT_VERSION${NC} → ${BOLD}$NEW_VERSION${NC}" 192 - echo "" 193 - confirm "Proceed with release?" || { info "Aborted."; exit 0; } 194 - } 195 - 196 - # ════════════════════════════════════════════════════════════════════ 197 - # 4. Update version numbers 198 - # ════════════════════════════════════════════════════════════════════ 199 - 200 - update_versions() { 201 - step "Updating Versions" 202 - 203 - info "Creating release branch: ${BOLD}$NEW_VERSION${NC}" 204 - git checkout -b "$NEW_VERSION" --quiet 205 - 206 - local version_pattern="${CURRENT_VERSION//./\\.}" 207 - 208 - info "Replacing ${DIM}$CURRENT_VERSION${NC} → ${DIM}$NEW_VERSION${NC} in Cargo.toml files..." 209 - find . -type f -name 'Cargo.toml' -not -path './.git/*' \ 210 - -exec gsed -i "s/$version_pattern/$NEW_VERSION/g" {} \; 211 - 212 - info "Running ${DIM}cargo check${NC} to update Cargo.lock (this may take a moment)..." 213 - cargo check --quiet 2>&1 || cargo check 214 - 215 - echo "" 216 - info "Changed files:" 217 - git diff --stat | sed 's/^/ /' 218 - 219 - echo "" 220 - 221 - # Verify the workspace version was updated 222 - local new_ws_version 223 - new_ws_version=$(detect_current_version) 224 - if [[ "$new_ws_version" == "$NEW_VERSION" ]]; then 225 - success "Workspace version updated" 226 - else 227 - die "Workspace version is '$new_ws_version', expected '$NEW_VERSION'" 228 - fi 229 - 230 - # Verify we didn't break anything unexpected — show version-related 231 - # lines in the diff for review 232 - echo "" 233 - info "Version changes in diff:" 234 - git diff --unified=0 -- '*.toml' \ 235 - | grep -E '^\+.*version' \ 236 - | grep -v '^\+\+\+' \ 237 - | sed 's/^/ /' || true 238 - echo "" 239 - 240 - confirm "Version changes look correct?" || { die "Aborting — fix versions manually in $WORKDIR"; } 241 - } 242 - 243 - # ════════════════════════════════════════════════════════════════════ 244 - # 5. Changelog 245 - # ════════════════════════════════════════════════════════════════════ 246 - 247 - update_changelog() { 248 - step "Changelog" 249 - 250 - # cliff.toml's ignore_tags already ignores beta/alpha tags, so 251 - # --unreleased always gives us everything since the last stable release. 252 - # 253 - # Prereleases: heading is ## [unreleased] (running tally) 254 - # Stable: heading is ## X.Y.Z (versioned entry) 255 - local cliff_args=(--unreleased --strip all) 256 - 257 - if $IS_PRERELEASE; then 258 - info "Updating ${BOLD}Unreleased${NC} section..." 259 - else 260 - cliff_args+=(--tag "v$NEW_VERSION") 261 - info "Generating changelog for ${BOLD}$NEW_VERSION${NC}..." 262 - fi 263 - 264 - local new_entry 265 - new_entry=$(git-cliff "${cliff_args[@]}" 2>/dev/null || true) 266 - 267 - # Check if the entry is empty (just a heading with no content) 268 - if [[ -z "$new_entry" ]] || [[ "$(echo "$new_entry" | grep -c '[a-zA-Z]')" -le 1 ]]; then 269 - warn "No unreleased changes detected by git-cliff" 270 - warn "You may want to add entries manually in the editor" 271 - if $IS_PRERELEASE; then 272 - new_entry="## [unreleased]" 273 - else 274 - new_entry="## $NEW_VERSION" 275 - fi 276 - else 277 - local commit_count 278 - commit_count=$(echo "$new_entry" | grep -c '^- ' || true) 279 - success "Generated entry with ${BOLD}$commit_count${NC} item(s)" 280 - fi 281 - 282 - # Remove any existing [unreleased] section — we'll replace it with 283 - # either an updated unreleased section or a versioned one 284 - if grep -qi '^\## \[unreleased\]' CHANGELOG.md; then 285 - info "Removing old Unreleased section..." 286 - awk ' 287 - /^## \[[Uu]nreleased\]/ { skip=1; next } 288 - /^## / { skip=0 } 289 - !skip 290 - ' CHANGELOG.md > CHANGELOG.md.tmp 291 - mv CHANGELOG.md.tmp CHANGELOG.md 292 - fi 293 - 294 - # Insert the new entry before the first existing version heading 295 - local insert_line 296 - insert_line=$(grep -n '^## ' CHANGELOG.md | head -1 | cut -d: -f1) 297 - 298 - if [[ -n "$insert_line" ]]; then 299 - { 300 - head -n "$((insert_line - 1))" CHANGELOG.md 301 - echo "$new_entry" 302 - echo "" 303 - echo "" 304 - tail -n "+$insert_line" CHANGELOG.md 305 - } > CHANGELOG.md.tmp 306 - mv CHANGELOG.md.tmp CHANGELOG.md 307 - else 308 - warn "No existing version headings found — appending to end" 309 - echo "" >> CHANGELOG.md 310 - echo "$new_entry" >> CHANGELOG.md 311 - fi 312 - 313 - echo "" 314 - info "Opening CHANGELOG.md in your editor for review..." 315 - info "${DIM}Verify the entry, make any edits, then save and close.${NC}" 316 - echo "" 317 - echo -en " ${DIM}Press Enter to open editor...${NC}" 318 - read -r 319 - "${EDITOR:-${VISUAL:-vi}}" CHANGELOG.md 320 - success "Changelog finalized" 321 - } 322 - 323 - # ════════════════════════════════════════════════════════════════════ 324 - # 6. Commit and push 325 - # ════════════════════════════════════════════════════════════════════ 326 - 327 - commit_and_push() { 328 - step "Commit & Push" 329 - 330 - git add . 331 - git commit --quiet -m "chore(release): prepare for release $NEW_VERSION" 332 - success "Committed" 333 - 334 - info "Pushing branch..." 335 - git push --quiet --set-upstream origin "$(git branch --show-current)" 2>&1 336 - success "Pushed to origin/${BOLD}$NEW_VERSION${NC}" 337 - } 338 - 339 - # ════════════════════════════════════════════════════════════════════ 340 - # 7. Pull request 341 - # ════════════════════════════════════════════════════════════════════ 342 - 343 - extract_changelog_entry() { 344 - # Extract the changelog body (without the heading) for the entry we just wrote. 345 - # Prereleases use ## [unreleased], stable uses ## X.Y.Z 346 - local heading 347 - if $IS_PRERELEASE; then 348 - heading='## \[unreleased\]' 349 - else 350 - heading="## ${NEW_VERSION//./\\.}" 351 - fi 352 - awk "/^${heading}/{found=1; next} /^## /{if(found) exit} found" CHANGELOG.md 353 - } 354 - 355 - create_pr() { 356 - step "Pull Request" 357 - 358 - local changelog_body 359 - changelog_body=$(extract_changelog_entry) 360 - 361 - local pr_body 362 - pr_body="Release preparation for v${NEW_VERSION}." 363 - if [[ -n "$changelog_body" ]]; then 364 - pr_body="$(cat <<EOF 365 - Release preparation for v${NEW_VERSION}. 366 - 367 - ## Changelog 368 - 369 - $changelog_body 370 - EOF 371 - )" 372 - fi 373 - 374 - info "Creating PR..." 375 - PR_URL=$(gh pr create \ 376 - --title "chore(release): prepare for release $NEW_VERSION" \ 377 - --body "$pr_body" \ 378 - --repo atuinsh/atuin) 379 - 380 - success "PR created: ${BOLD}$PR_URL${NC}" 381 - 382 - local pr_number 383 - pr_number=$(echo "$PR_URL" | grep -o '[0-9]*$') 384 - 385 - echo "" 386 - info "Waiting for PR #${BOLD}$pr_number${NC} to be merged..." 387 - info "${DIM}Review and merge the PR — this script will detect it automatically.${NC}" 388 - echo "" 389 - 390 - while true; do 391 - local state 392 - state=$(gh pr view "$pr_number" --repo atuinsh/atuin --json state --jq '.state' 2>/dev/null || echo "UNKNOWN") 393 - 394 - case "$state" in 395 - MERGED) 396 - echo "" 397 - success "PR #$pr_number merged!" 398 - break 399 - ;; 400 - CLOSED) 401 - echo "" 402 - die "PR #$pr_number was closed without merging" 403 - ;; 404 - *) 405 - printf "\r ${DIM}⏳ PR #%s is %s — checking again in 5s...${NC} " "$pr_number" "$state" 406 - sleep 5 407 - ;; 408 - esac 409 - done 410 - } 411 - 412 - # ════════════════════════════════════════════════════════════════════ 413 - # 8. Tag 414 - # ════════════════════════════════════════════════════════════════════ 415 - 416 - tag_release() { 417 - step "Tag & Release" 418 - 419 - info "Switching to main and pulling..." 420 - git checkout main --quiet 421 - git pull --quiet 422 - 423 - info "Creating tag ${BOLD}v$NEW_VERSION${NC}" 424 - git tag "v$NEW_VERSION" 425 - 426 - info "Pushing tag..." 427 - git push --tags 428 - success "Tag ${BOLD}v$NEW_VERSION${NC} pushed — release workflow triggered" 429 - } 430 - 431 - # ════════════════════════════════════════════════════════════════════ 432 - # 9. Publish to crates.io 433 - # ════════════════════════════════════════════════════════════════════ 434 - 435 - publish_crates() { 436 - step "Publish to crates.io" 437 - 438 - if $IS_PRERELEASE; then 439 - warn "Pre-release — skipping crates.io publish" 440 - return 441 - fi 442 - 443 - if ! confirm "Publish to crates.io?"; then 444 - info "Skipping" 445 - return 446 - fi 447 - 448 - local crates=( 449 - atuin-common 450 - atuin-client 451 - atuin-ai 452 - atuin-dotfiles 453 - atuin-history 454 - atuin-nucleo/matcher 455 - atuin-nucleo 456 - atuin-daemon 457 - atuin-kv 458 - atuin-scripts 459 - atuin-server-database 460 - atuin-server-postgres 461 - atuin-server-sqlite 462 - atuin-server 463 - atuin-pty-proxy 464 - atuin 465 - ) 466 - 467 - for crate in "${crates[@]}"; do 468 - info "Publishing ${BOLD}$crate${NC}..." 469 - local output 470 - # --no-verify: skip rebuild during publish — the code already passed 471 - # CI, and verification fails on workspace crates whose freshly-published 472 - # dependencies haven't been indexed by crates.io yet 473 - if output=$(cd "crates/$crate" && cargo publish --no-verify 2>&1); then 474 - success "$crate published" 475 - elif echo "$output" | grep -q "already uploaded"; then 476 - warn "$crate already published, skipping" 477 - else 478 - echo "$output" >&2 479 - die "Failed to publish $crate" 480 - fi 481 - done 482 - } 483 - 484 - # ════════════════════════════════════════════════════════════════════ 485 - # Main 486 - # ════════════════════════════════════════════════════════════════════ 487 - 488 - main() { 489 - banner 490 - check_deps 491 - setup_workdir 492 - get_version 493 - update_versions 494 - update_changelog 495 - commit_and_push 496 - create_pr 497 - tag_release 498 - publish_crates 499 - 500 - step "Done 🎉" 501 - success "Released ${BOLD}v$NEW_VERSION${NC}" 502 - echo "" 503 - info "Working directory: ${DIM}$WORKDIR${NC}" 504 - info "Clean up with: ${DIM}rm -rf $WORKDIR${NC}" 505 - echo "" 506 - } 507 - 508 - main "$@"
-420
scripts/span-table.ts
··· 1 - #!/usr/bin/env bun 2 - /** 3 - * Analyze span timing JSON logs generated with ATUIN_SPAN 4 - * 5 - * Usage: bun scripts/span-table.ts <file.json> [options] 6 - * --filter <pattern> Only show spans matching pattern (regex) 7 - * --sort <field> Sort by: calls, avg, total, p99 (default: total) 8 - * --top <n> Show top N spans (default: 20) 9 - * --detail <span> Show individual calls for a specific span 10 - * --all Include internal/library spans 11 - */ 12 - 13 - import { readFileSync } from "fs"; 14 - 15 - interface SpanEvent { 16 - timestamp: string; 17 - level: string; 18 - fields: { 19 - message: string; 20 - "time.busy"?: string; 21 - "time.idle"?: string; 22 - }; 23 - target: string; 24 - span?: { 25 - name: string; 26 - [key: string]: unknown; 27 - }; 28 - spans?: Array<{ name: string; [key: string]: unknown }>; 29 - } 30 - 31 - interface SpanStats { 32 - name: string; 33 - calls: number; 34 - busyTimes: number[]; // in microseconds 35 - idleTimes: number[]; 36 - parentCounts: Map<string, number>; // parent span name -> count 37 - } 38 - 39 - // Parse duration strings like "1.23ms", "456µs", "789ns" to microseconds 40 - function parseDuration(duration: string): number { 41 - const match = duration.match(/^([\d.]+)(ns|µs|us|ms|s)$/); 42 - if (!match) return 0; 43 - 44 - const value = parseFloat(match[1]); 45 - const unit = match[2]; 46 - 47 - switch (unit) { 48 - case "ns": 49 - return value / 1000; 50 - case "µs": 51 - case "us": 52 - return value; 53 - case "ms": 54 - return value * 1000; 55 - case "s": 56 - return value * 1_000_000; 57 - default: 58 - return 0; 59 - } 60 - } 61 - 62 - // Format microseconds for display 63 - function formatDuration(us: number): string { 64 - if (us < 1) { 65 - return `${(us * 1000).toFixed(0)}ns`; 66 - } else if (us < 1000) { 67 - return `${us.toFixed(2)}µs`; 68 - } else if (us < 1_000_000) { 69 - return `${(us / 1000).toFixed(2)}ms`; 70 - } else { 71 - return `${(us / 1_000_000).toFixed(2)}s`; 72 - } 73 - } 74 - 75 - function percentile(arr: number[], p: number): number { 76 - if (arr.length === 0) return 0; 77 - const sorted = [...arr].sort((a, b) => a - b); 78 - const idx = Math.floor(sorted.length * p); 79 - return sorted[Math.min(idx, sorted.length - 1)]; 80 - } 81 - 82 - function parseJsonLines(content: string): SpanEvent[] { 83 - const events: SpanEvent[] = []; 84 - for (const line of content.trim().split("\n")) { 85 - if (!line.trim()) continue; 86 - try { 87 - events.push(JSON.parse(line)); 88 - } catch { 89 - // Skip malformed lines 90 - } 91 - } 92 - return events; 93 - } 94 - 95 - function main() { 96 - const args = process.argv.slice(2); 97 - 98 - // Parse arguments 99 - let filterPattern: RegExp | null = null; 100 - let sortField = "total"; 101 - let topN = 20; 102 - let detailSpan: string | null = null; 103 - let showAll = false; 104 - const files: string[] = []; 105 - 106 - for (let i = 0; i < args.length; i++) { 107 - if (args[i] === "--filter" && args[i + 1]) { 108 - filterPattern = new RegExp(args[++i]); 109 - } else if (args[i] === "--sort" && args[i + 1]) { 110 - sortField = args[++i]; 111 - } else if (args[i] === "--top" && args[i + 1]) { 112 - topN = parseInt(args[++i], 10); 113 - } else if (args[i] === "--detail" && args[i + 1]) { 114 - detailSpan = args[++i]; 115 - } else if (args[i] === "--all") { 116 - showAll = true; 117 - } else if (!args[i].startsWith("-")) { 118 - files.push(args[i]); 119 - } 120 - } 121 - 122 - if (files.length === 0) { 123 - console.error("Usage: bun scripts/span-table.ts <file.json> [options]"); 124 - console.error(" --filter <pattern> Only show spans matching pattern (regex)"); 125 - console.error(" --sort <field> Sort by: calls, avg, total, p99 (default: total)"); 126 - console.error(" --top <n> Show top N spans (default: 20)"); 127 - console.error(" --detail <span> Show individual calls for a specific span"); 128 - console.error(" --all Include internal/library spans"); 129 - process.exit(1); 130 - } 131 - 132 - // Parse all files 133 - const allEvents: SpanEvent[] = []; 134 - for (const file of files) { 135 - const content = readFileSync(file, "utf-8"); 136 - for (const event of parseJsonLines(content)) { 137 - allEvents.push(event); 138 - } 139 - } 140 - 141 - // Filter to close events and aggregate by span name 142 - const spans = new Map<string, SpanStats>(); 143 - 144 - for (const event of allEvents) { 145 - if (event.fields?.message !== "close") continue; 146 - if (!event.span?.name) continue; 147 - if (!event.fields["time.busy"]) continue; 148 - 149 - const name = event.span.name; 150 - 151 - // Apply filter if specified 152 - if (filterPattern && !filterPattern.test(name)) continue; 153 - 154 - // Skip noisy internal spans unless explicitly requested 155 - if ( 156 - !showAll && 157 - !filterPattern && 158 - !detailSpan && 159 - (name.startsWith("FramedRead::") || 160 - name.startsWith("FramedWrite::") || 161 - name.startsWith("Prioritize::") || 162 - name === "poll" || 163 - name === "poll_ready" || 164 - name === "Connection" || 165 - name.startsWith("assign_") || 166 - name.startsWith("reserve_") || 167 - name.startsWith("try_") || 168 - name.startsWith("send_") || 169 - name.startsWith("pop_")) 170 - ) { 171 - continue; 172 - } 173 - 174 - if (!spans.has(name)) { 175 - spans.set(name, { name, calls: 0, busyTimes: [], idleTimes: [], parentCounts: new Map() }); 176 - } 177 - 178 - const stats = spans.get(name)!; 179 - stats.calls++; 180 - stats.busyTimes.push(parseDuration(event.fields["time.busy"])); 181 - if (event.fields["time.idle"]) { 182 - stats.idleTimes.push(parseDuration(event.fields["time.idle"])); 183 - } 184 - 185 - // Track parent relationship (immediate parent is the last element in spans array) 186 - const parents = event.spans || []; 187 - const parentName = parents.length > 0 ? parents[parents.length - 1].name : "__root__"; 188 - stats.parentCounts.set(parentName, (stats.parentCounts.get(parentName) || 0) + 1); 189 - } 190 - 191 - if (spans.size === 0) { 192 - console.error("No matching span close events found"); 193 - process.exit(1); 194 - } 195 - 196 - // Detail mode: show individual calls for a specific span 197 - if (detailSpan) { 198 - const detailEvents: Array<{ 199 - timestamp: string; 200 - busy: number; 201 - idle: number; 202 - fields: Record<string, unknown>; 203 - parents: string[]; 204 - }> = []; 205 - 206 - for (const event of allEvents) { 207 - if (event.fields?.message !== "close") continue; 208 - if (event.span?.name !== detailSpan) continue; 209 - if (!event.fields["time.busy"]) continue; 210 - 211 - // Extract span fields (excluding name) 212 - const fields: Record<string, unknown> = {}; 213 - if (event.span) { 214 - for (const [k, v] of Object.entries(event.span)) { 215 - if (k !== "name") fields[k] = v; 216 - } 217 - } 218 - 219 - // Get parent span names 220 - const parents = (event.spans || []).map((s) => s.name); 221 - 222 - detailEvents.push({ 223 - timestamp: event.timestamp, 224 - busy: parseDuration(event.fields["time.busy"]), 225 - idle: event.fields["time.idle"] ? parseDuration(event.fields["time.idle"]) : 0, 226 - fields, 227 - parents, 228 - }); 229 - } 230 - 231 - if (detailEvents.length === 0) { 232 - console.error(`No events found for span "${detailSpan}"`); 233 - process.exit(1); 234 - } 235 - 236 - console.log(""); 237 - console.log(`Individual calls for: ${detailSpan}`); 238 - console.log("-".repeat(110)); 239 - console.log( 240 - "#".padStart(4) + 241 - "Wall".padStart(12) + 242 - "Busy".padStart(12) + 243 - "Idle".padStart(12) + 244 - " Fields" 245 - ); 246 - console.log("-".repeat(110)); 247 - 248 - detailEvents.forEach((e, i) => { 249 - const fieldsStr = Object.keys(e.fields).length > 0 250 - ? JSON.stringify(e.fields) 251 - : ""; 252 - 253 - console.log( 254 - (i + 1).toString().padStart(4) + 255 - formatDuration(e.busy + e.idle).padStart(12) + 256 - formatDuration(e.busy).padStart(12) + 257 - formatDuration(e.idle).padStart(12) + 258 - " " + 259 - fieldsStr 260 - ); 261 - }); 262 - 263 - // Summary stats 264 - const busyTimes = detailEvents.map((e) => e.busy); 265 - const wallTimes = detailEvents.map((e) => e.busy + e.idle); 266 - console.log(""); 267 - console.log( 268 - `Summary: ${detailEvents.length} calls\n` + 269 - ` Wall: avg=${formatDuration(wallTimes.reduce((a, b) => a + b, 0) / wallTimes.length)}, ` + 270 - `min=${formatDuration(Math.min(...wallTimes))}, ` + 271 - `max=${formatDuration(Math.max(...wallTimes))}, ` + 272 - `p50=${formatDuration(percentile(wallTimes, 0.5))}, ` + 273 - `p99=${formatDuration(percentile(wallTimes, 0.99))}\n` + 274 - ` Busy: avg=${formatDuration(busyTimes.reduce((a, b) => a + b, 0) / busyTimes.length)}, ` + 275 - `min=${formatDuration(Math.min(...busyTimes))}, ` + 276 - `max=${formatDuration(Math.max(...busyTimes))}, ` + 277 - `p50=${formatDuration(percentile(busyTimes, 0.5))}, ` + 278 - `p99=${formatDuration(percentile(busyTimes, 0.99))}` 279 - ); 280 - return; 281 - } 282 - 283 - // Calculate stats 284 - const results = [...spans.values()].map((s) => { 285 - // Calculate wall times (busy + idle) for each call 286 - const wallTimes = s.busyTimes.map((busy, i) => busy + (s.idleTimes[i] || 0)); 287 - 288 - // Find most common parent 289 - let mostCommonParent = "__root__"; 290 - let maxCount = 0; 291 - for (const [parent, count] of s.parentCounts) { 292 - if (count > maxCount) { 293 - maxCount = count; 294 - mostCommonParent = parent; 295 - } 296 - } 297 - 298 - return { 299 - name: s.name, 300 - calls: s.calls, 301 - total: s.busyTimes.reduce((a, b) => a + b, 0), 302 - avg: s.busyTimes.reduce((a, b) => a + b, 0) / s.calls, 303 - min: Math.min(...s.busyTimes), 304 - max: Math.max(...s.busyTimes), 305 - p50: percentile(s.busyTimes, 0.5), 306 - p99: percentile(s.busyTimes, 0.99), 307 - avgWall: wallTimes.reduce((a, b) => a + b, 0) / s.calls, 308 - p50Wall: percentile(wallTimes, 0.5), 309 - p99Wall: percentile(wallTimes, 0.99), 310 - parent: mostCommonParent, 311 - }; 312 - }); 313 - 314 - // Build tree structure 315 - const childrenOf = new Map<string, string[]>(); 316 - childrenOf.set("__root__", []); 317 - for (const r of results) { 318 - if (!childrenOf.has(r.name)) { 319 - childrenOf.set(r.name, []); 320 - } 321 - if (!childrenOf.has(r.parent)) { 322 - childrenOf.set(r.parent, []); 323 - } 324 - childrenOf.get(r.parent)!.push(r.name); 325 - } 326 - 327 - // Sort children by the specified field 328 - const resultMap = new Map(results.map(r => [r.name, r])); 329 - const sortChildren = (children: string[]) => { 330 - children.sort((a, b) => { 331 - const ra = resultMap.get(a); 332 - const rb = resultMap.get(b); 333 - if (!ra || !rb) return 0; 334 - switch (sortField) { 335 - case "calls": 336 - return rb.calls - ra.calls; 337 - case "avg": 338 - return rb.avg - ra.avg; 339 - case "p99": 340 - return rb.p99 - ra.p99; 341 - case "total": 342 - default: 343 - return rb.total - ra.total; 344 - } 345 - }); 346 - }; 347 - 348 - // Traverse tree to build ordered display list with depths 349 - const displayResults: Array<{ result: typeof results[0]; depth: number }> = []; 350 - const visited = new Set<string>(); 351 - 352 - function traverse(name: string, depth: number) { 353 - if (visited.has(name)) return; 354 - visited.add(name); 355 - 356 - const result = resultMap.get(name); 357 - if (result) { 358 - displayResults.push({ result, depth }); 359 - } 360 - 361 - const children = childrenOf.get(name) || []; 362 - sortChildren(children); 363 - for (const child of children) { 364 - traverse(child, depth + 1); 365 - } 366 - } 367 - 368 - // Start from roots 369 - const roots = childrenOf.get("__root__") || []; 370 - sortChildren(roots); 371 - for (const root of roots) { 372 - traverse(root, 0); 373 - } 374 - 375 - // Add any orphaned spans (whose parent wasn't in our span list) 376 - for (const r of results) { 377 - if (!visited.has(r.name)) { 378 - displayResults.push({ result: r, depth: 0 }); 379 - } 380 - } 381 - 382 - // Apply topN limit 383 - const limitedResults = displayResults.slice(0, topN); 384 - 385 - console.log(""); 386 - console.log( 387 - "Span Name".padEnd(40) + 388 - "Calls".padStart(6) + 389 - "Avg(wall)".padStart(11) + 390 - "P50(wall)".padStart(11) + 391 - "P99(wall)".padStart(11) + 392 - "Avg(busy)".padStart(11) + 393 - "P50(busy)".padStart(11) + 394 - "P99(busy)".padStart(11) 395 - ); 396 - console.log("-".repeat(112)); 397 - 398 - for (const { result: r, depth } of limitedResults) { 399 - const indent = " ".repeat(depth); 400 - const maxNameLen = 38 - indent.length; 401 - const truncatedName = r.name.length > maxNameLen ? "..." + r.name.slice(-(maxNameLen - 3)) : r.name; 402 - const displayName = indent + truncatedName; 403 - 404 - console.log( 405 - displayName.padEnd(40) + 406 - r.calls.toString().padStart(6) + 407 - formatDuration(r.avgWall).padStart(11) + 408 - formatDuration(r.p50Wall).padStart(11) + 409 - formatDuration(r.p99Wall).padStart(11) + 410 - formatDuration(r.avg).padStart(11) + 411 - formatDuration(r.p50).padStart(11) + 412 - formatDuration(r.p99).padStart(11) 413 - ); 414 - } 415 - 416 - console.log(""); 417 - console.log(`Showing ${limitedResults.length} of ${results.length} spans (sorted by ${sortField})`); 418 - } 419 - 420 - main();
-29
systemd/atuin-server.service
··· 1 - [Unit] 2 - Description=Start the Atuin server syncing service 3 - After=network-online.target 4 - Wants=network-online.target systemd-networkd-wait-online.service 5 - 6 - [Service] 7 - ExecStart=atuin-server start 8 - Restart=on-failure 9 - User=atuin 10 - Group=atuin 11 - 12 - Environment=ATUIN_CONFIG_DIR=/etc/atuin 13 - ReadWritePaths=/etc/atuin 14 - 15 - # Hardening options 16 - CapabilityBoundingSet= 17 - AmbientCapabilities= 18 - NoNewPrivileges=true 19 - ProtectHome=true 20 - ProtectSystem=strict 21 - ProtectKernelTunables=true 22 - ProtectKernelModules=true 23 - ProtectControlGroups=true 24 - PrivateTmp=true 25 - PrivateDevices=true 26 - LockPersonality=true 27 - 28 - [Install] 29 - WantedBy=multi-user.target
-1
systemd/atuin-server.sysusers
··· 1 - u atuin - "Atuin synchronized shell history"