aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-06-11 00:54:30 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-06-11 00:54:30 +0200
commit5c39e7cf284a1f6e9a1657f2deb44e359fc47eb8 (patch)
treec64baa8d5866c8e339eaf660dd3f94f30a3f7d8a
parentchore: Somewhat simplify sync code (diff)
downloadatuin-5c39e7cf284a1f6e9a1657f2deb44e359fc47eb8.zip
chore: Move everything into one big crate
That helps remove duplicated code and rustc/cargo will now also show dead code correctly.
-rw-r--r--Cargo.lock284
-rw-r--r--Cargo.toml66
-rw-r--r--crates/atuin-client/Cargo.toml82
-rw-r--r--crates/atuin-client/config.toml371
-rw-r--r--crates/atuin-client/meta-migrations/20260203030924_create_meta.sql5
-rw-r--r--crates/atuin-client/migrations/20210422143411_create_history.sql16
-rw-r--r--crates/atuin-client/migrations/20220505083406_create-events.sql11
-rw-r--r--crates/atuin-client/migrations/20220806155627_interactive_search_index.sql6
-rw-r--r--crates/atuin-client/migrations/20230315220114_drop-events.sql2
-rw-r--r--crates/atuin-client/migrations/20230319185725_deleted_at.sql2
-rw-r--r--crates/atuin-client/migrations/20260224000100_history_author_intent.sql2
-rw-r--r--crates/atuin-client/record-migrations/20230531212437_create-records.sql16
-rw-r--r--crates/atuin-client/record-migrations/20231127090831_create-store.sql15
-rw-r--r--crates/atuin-client/tests/data/xonsh-history.sqlitebin12288 -> 0 bytes
-rw-r--r--crates/atuin-client/tests/data/xonsh/xonsh-82eafbf5-9f43-489a-80d2-61c7dc6ef542.json12
-rw-r--r--crates/atuin-client/tests/data/xonsh/xonsh-de16af90-9148-4461-8df3-5b5659c6420d.json12
-rw-r--r--crates/atuin-common/Cargo.toml31
-rw-r--r--crates/atuin-daemon/Cargo.toml52
-rw-r--r--crates/atuin-daemon/build.rs25
-rw-r--r--crates/atuin-daemon/tests/lifecycle.rs222
-rw-r--r--crates/atuin-history/Cargo.toml30
-rw-r--r--crates/atuin-history/benches/smart_sort.rs35
-rw-r--r--crates/atuin-pty-proxy/Cargo.toml21
-rw-r--r--crates/atuin-pty-proxy/src/lib.rs48
-rw-r--r--crates/atuin-server-database/Cargo.toml21
-rw-r--r--crates/atuin-server-postgres/Cargo.toml25
-rw-r--r--crates/atuin-server-postgres/build.rs5
-rw-r--r--crates/atuin-server-postgres/migrations/20210425153745_create_history.sql11
-rw-r--r--crates/atuin-server-postgres/migrations/20210425153757_create_users.sql10
-rw-r--r--crates/atuin-server-postgres/migrations/20210425153800_create_sessions.sql6
-rw-r--r--crates/atuin-server-postgres/migrations/20220419082412_add_count_trigger.sql51
-rw-r--r--crates/atuin-server-postgres/migrations/20220421073605_fix_count_trigger_delete.sql35
-rw-r--r--crates/atuin-server-postgres/migrations/20220421174016_larger-commands.sql3
-rw-r--r--crates/atuin-server-postgres/migrations/20220426172813_user-created-at.sql1
-rw-r--r--crates/atuin-server-postgres/migrations/20220505082442_create-events.sql14
-rw-r--r--crates/atuin-server-postgres/migrations/20220610074049_history-length.sql2
-rw-r--r--crates/atuin-server-postgres/migrations/20230315220537_drop-events.sql2
-rw-r--r--crates/atuin-server-postgres/migrations/20230315224203_create-deleted.sql5
-rw-r--r--crates/atuin-server-postgres/migrations/20230515221038_trigger-delete-only.sql30
-rw-r--r--crates/atuin-server-postgres/migrations/20230623070418_records.sql15
-rw-r--r--crates/atuin-server-postgres/migrations/20231202170508_create-store.sql15
-rw-r--r--crates/atuin-server-postgres/migrations/20231203124112_create-store-idx.sql2
-rw-r--r--crates/atuin-server-postgres/migrations/20240108124837_drop-some-defaults.sql4
-rw-r--r--crates/atuin-server-postgres/migrations/20240614104159_idx-cache.sql8
-rw-r--r--crates/atuin-server-postgres/migrations/20240621110731_user-verified.sql8
-rw-r--r--crates/atuin-server-postgres/migrations/20240702094825_idx_cache_index.sql1
-rw-r--r--crates/atuin-server-postgres/migrations/20260127000000_remove-email-verification.sql2
-rw-r--r--crates/atuin-server-sqlite/Cargo.toml24
-rw-r--r--crates/atuin-server-sqlite/build.rs5
-rw-r--r--crates/atuin-server-sqlite/migrations/20231203124112_create-store.sql17
-rw-r--r--crates/atuin-server-sqlite/migrations/20240108124830_create-history.sql15
-rw-r--r--crates/atuin-server-sqlite/migrations/20240108124831_create-sessions.sql6
-rw-r--r--crates/atuin-server-sqlite/migrations/20240621110730_create-users.sql12
-rw-r--r--crates/atuin-server-sqlite/migrations/20240621110731_create-user-verification-token.sql6
-rw-r--r--crates/atuin-server-sqlite/migrations/20240702094825_create-store-idx-cache.sql10
-rw-r--r--crates/atuin-server-sqlite/migrations/20260127000000_remove-email-verification.sql2
l---------crates/atuin-server/CHANGELOG.md1
-rw-r--r--crates/atuin-server/Cargo.toml45
-rw-r--r--crates/atuin-server/server.toml38
-rw-r--r--crates/atuin-server/src/bin/main.rs73
l---------crates/atuin/CHANGELOG.md1
-rw-r--r--crates/atuin/Cargo.toml87
-rw-r--r--crates/atuin/LICENSE21
l---------crates/atuin/README.md1
-rw-r--r--crates/atuin/build.rs11
-rw-r--r--crates/atuin/src/command/client/default_config.rs5
-rw-r--r--crates/atuin/tests/common/mod.rs117
-rw-r--r--crates/atuin/tests/sync.rs45
-rw-r--r--crates/atuin/tests/users.rs121
-rw-r--r--crates/turtle/Cargo.toml142
-rw-r--r--crates/turtle/build.rs39
-rw-r--r--crates/turtle/proto/control.proto (renamed from crates/atuin-daemon/proto/control.proto)0
-rw-r--r--crates/turtle/proto/history.proto (renamed from crates/atuin-daemon/proto/history.proto)0
-rw-r--r--crates/turtle/proto/search.proto (renamed from crates/atuin-daemon/proto/search.proto)0
-rw-r--r--crates/turtle/proto/semantic.proto (renamed from crates/atuin-daemon/proto/semantic.proto)0
-rw-r--r--crates/turtle/src/atuin_client/api_client.rs (renamed from crates/atuin-client/src/api_client.rs)7
-rw-r--r--crates/turtle/src/atuin_client/auth.rs (renamed from crates/atuin-client/src/auth.rs)29
-rw-r--r--crates/turtle/src/atuin_client/database.rs (renamed from crates/atuin-client/src/database.rs)9
-rw-r--r--crates/turtle/src/atuin_client/distro.rs (renamed from crates/atuin-client/src/distro.rs)0
-rw-r--r--crates/turtle/src/atuin_client/encryption.rs (renamed from crates/atuin-client/src/encryption.rs)2
-rw-r--r--crates/turtle/src/atuin_client/history.rs (renamed from crates/atuin-client/src/history.rs)26
-rw-r--r--crates/turtle/src/atuin_client/history/builder.rs (renamed from crates/atuin-client/src/history/builder.rs)0
-rw-r--r--crates/turtle/src/atuin_client/history/store.rs (renamed from crates/atuin-client/src/history/store.rs)9
-rw-r--r--crates/turtle/src/atuin_client/import/bash.rs (renamed from crates/atuin-client/src/import/bash.rs)9
-rw-r--r--crates/turtle/src/atuin_client/import/fish.rs (renamed from crates/atuin-client/src/import/fish.rs)4
-rw-r--r--crates/turtle/src/atuin_client/import/mod.rs (renamed from crates/atuin-client/src/import/mod.rs)2
-rw-r--r--crates/turtle/src/atuin_client/import/nu.rs (renamed from crates/atuin-client/src/import/nu.rs)4
-rw-r--r--crates/turtle/src/atuin_client/import/nu_histdb.rs (renamed from crates/atuin-client/src/import/nu_histdb.rs)4
-rw-r--r--crates/turtle/src/atuin_client/import/powershell.rs (renamed from crates/atuin-client/src/import/powershell.rs)4
-rw-r--r--crates/turtle/src/atuin_client/import/replxx.rs (renamed from crates/atuin-client/src/import/replxx.rs)4
-rw-r--r--crates/turtle/src/atuin_client/import/resh.rs (renamed from crates/atuin-client/src/import/resh.rs)6
-rw-r--r--crates/turtle/src/atuin_client/import/xonsh.rs (renamed from crates/atuin-client/src/import/xonsh.rs)4
-rw-r--r--crates/turtle/src/atuin_client/import/xonsh_sqlite.rs (renamed from crates/atuin-client/src/import/xonsh_sqlite.rs)4
-rw-r--r--crates/turtle/src/atuin_client/import/zsh.rs (renamed from crates/atuin-client/src/import/zsh.rs)4
-rw-r--r--crates/turtle/src/atuin_client/import/zsh_histdb.rs (renamed from crates/atuin-client/src/import/zsh_histdb.rs)8
-rw-r--r--crates/turtle/src/atuin_client/login.rs (renamed from crates/atuin-client/src/login.rs)4
-rw-r--r--crates/turtle/src/atuin_client/logout.rs (renamed from crates/atuin-client/src/logout.rs)2
-rw-r--r--crates/turtle/src/atuin_client/meta.rs (renamed from crates/atuin-client/src/meta.rs)7
-rw-r--r--crates/turtle/src/atuin_client/mod.rs (renamed from crates/atuin-client/src/lib.rs)5
-rw-r--r--crates/turtle/src/atuin_client/ordering.rs (renamed from crates/atuin-client/src/ordering.rs)0
-rw-r--r--crates/turtle/src/atuin_client/plugin.rs (renamed from crates/atuin-client/src/plugin.rs)0
-rw-r--r--crates/turtle/src/atuin_client/record/encryption.rs (renamed from crates/atuin-client/src/record/encryption.rs)4
-rw-r--r--crates/turtle/src/atuin_client/record/mod.rs (renamed from crates/atuin-client/src/record/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_client/record/sqlite_store.rs (renamed from crates/atuin-client/src/record/sqlite_store.rs)7
-rw-r--r--crates/turtle/src/atuin_client/record/store.rs (renamed from crates/atuin-client/src/record/store.rs)2
-rw-r--r--crates/turtle/src/atuin_client/record/sync.rs (renamed from crates/atuin-client/src/record/sync.rs)15
-rw-r--r--crates/turtle/src/atuin_client/register.rs (renamed from crates/atuin-client/src/register.rs)4
-rw-r--r--crates/turtle/src/atuin_client/secrets.rs (renamed from crates/atuin-client/src/secrets.rs)0
-rw-r--r--crates/turtle/src/atuin_client/settings.rs (renamed from crates/atuin-client/src/settings.rs)46
-rw-r--r--crates/turtle/src/atuin_client/settings/meta.rs (renamed from crates/atuin-client/src/settings/meta.rs)2
-rw-r--r--crates/turtle/src/atuin_client/settings/watcher.rs (renamed from crates/atuin-client/src/settings/watcher.rs)4
-rw-r--r--crates/turtle/src/atuin_client/sync.rs (renamed from crates/atuin-client/src/sync.rs)5
-rw-r--r--crates/turtle/src/atuin_client/theme.rs (renamed from crates/atuin-client/src/theme.rs)4
-rw-r--r--crates/turtle/src/atuin_client/utils.rs (renamed from crates/atuin-client/src/utils.rs)0
-rw-r--r--crates/turtle/src/atuin_common/api.rs (renamed from crates/atuin-common/src/api.rs)0
-rw-r--r--crates/turtle/src/atuin_common/calendar.rs (renamed from crates/atuin-common/src/calendar.rs)0
-rw-r--r--crates/turtle/src/atuin_common/mod.rs (renamed from crates/atuin-common/src/lib.rs)2
-rw-r--r--crates/turtle/src/atuin_common/record.rs (renamed from crates/atuin-common/src/record.rs)8
-rw-r--r--crates/turtle/src/atuin_common/shell.rs (renamed from crates/atuin-common/src/shell.rs)0
-rw-r--r--crates/turtle/src/atuin_common/tls.rs (renamed from crates/atuin-common/src/tls.rs)0
-rw-r--r--crates/turtle/src/atuin_common/utils.rs (renamed from crates/atuin-common/src/utils.rs)0
-rw-r--r--crates/turtle/src/atuin_daemon/client.rs (renamed from crates/atuin-daemon/src/client.rs)126
-rw-r--r--crates/turtle/src/atuin_daemon/components/history.rs (renamed from crates/atuin-daemon/src/components/history.rs)4
-rw-r--r--crates/turtle/src/atuin_daemon/components/mod.rs (renamed from crates/atuin-daemon/src/components/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_daemon/components/search.rs (renamed from crates/atuin-daemon/src/components/search.rs)6
-rw-r--r--crates/turtle/src/atuin_daemon/components/semantic.rs (renamed from crates/atuin-daemon/src/components/semantic.rs)29
-rw-r--r--crates/turtle/src/atuin_daemon/components/sync.rs (renamed from crates/atuin-daemon/src/components/sync.rs)4
-rw-r--r--crates/turtle/src/atuin_daemon/control/mod.rs (renamed from crates/atuin-daemon/src/control/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_daemon/control/service.rs (renamed from crates/atuin-daemon/src/control/service.rs)4
-rw-r--r--crates/turtle/src/atuin_daemon/daemon.rs (renamed from crates/atuin-daemon/src/daemon.rs)4
-rw-r--r--crates/turtle/src/atuin_daemon/events.rs (renamed from crates/atuin-daemon/src/events.rs)4
-rw-r--r--crates/turtle/src/atuin_daemon/history/mod.rs (renamed from crates/atuin-daemon/src/history/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_daemon/mod.rs (renamed from crates/atuin-daemon/src/lib.rs)14
-rw-r--r--crates/turtle/src/atuin_daemon/search/index.rs (renamed from crates/atuin-daemon/src/search/index.rs)13
-rw-r--r--crates/turtle/src/atuin_daemon/search/mod.rs (renamed from crates/atuin-daemon/src/search/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_daemon/semantic/mod.rs (renamed from crates/atuin-daemon/src/semantic/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_daemon/server.rs (renamed from crates/atuin-daemon/src/server.rs)75
-rw-r--r--crates/turtle/src/atuin_history/mod.rs (renamed from crates/atuin-history/src/lib.rs)0
-rw-r--r--crates/turtle/src/atuin_history/sort.rs (renamed from crates/atuin-history/src/sort.rs)2
-rw-r--r--crates/turtle/src/atuin_history/stats.rs (renamed from crates/atuin-history/src/stats.rs)6
-rw-r--r--crates/turtle/src/atuin_pty_proxy/capture.rs (renamed from crates/atuin-pty-proxy/src/capture.rs)2
-rw-r--r--crates/turtle/src/atuin_pty_proxy/debug.rs (renamed from crates/atuin-pty-proxy/src/debug.rs)2
-rw-r--r--crates/turtle/src/atuin_pty_proxy/mod.rs17
-rw-r--r--crates/turtle/src/atuin_pty_proxy/osc133.rs (renamed from crates/atuin-pty-proxy/src/osc133.rs)0
-rw-r--r--crates/turtle/src/atuin_pty_proxy/pty_proxy.rs (renamed from crates/atuin-pty-proxy/src/pty_proxy.rs)2
-rw-r--r--crates/turtle/src/atuin_pty_proxy/runtime.rs (renamed from crates/atuin-pty-proxy/src/runtime.rs)8
-rw-r--r--crates/turtle/src/atuin_pty_proxy/screen.rs (renamed from crates/atuin-pty-proxy/src/screen.rs)0
-rw-r--r--crates/turtle/src/atuin_server/handlers/health.rs (renamed from crates/atuin-server/src/handlers/health.rs)0
-rw-r--r--crates/turtle/src/atuin_server/handlers/history.rs (renamed from crates/atuin-server/src/handlers/history.rs)6
-rw-r--r--crates/turtle/src/atuin_server/handlers/mod.rs (renamed from crates/atuin-server/src/handlers/mod.rs)6
-rw-r--r--crates/turtle/src/atuin_server/handlers/record.rs (renamed from crates/atuin-server/src/handlers/record.rs)4
-rw-r--r--crates/turtle/src/atuin_server/handlers/status.rs (renamed from crates/atuin-server/src/handlers/status.rs)6
-rw-r--r--crates/turtle/src/atuin_server/handlers/user.rs (renamed from crates/atuin-server/src/handlers/user.rs)8
-rw-r--r--crates/turtle/src/atuin_server/handlers/v0/me.rs (renamed from crates/atuin-server/src/handlers/v0/me.rs)6
-rw-r--r--crates/turtle/src/atuin_server/handlers/v0/mod.rs (renamed from crates/atuin-server/src/handlers/v0/mod.rs)0
-rw-r--r--crates/turtle/src/atuin_server/handlers/v0/record.rs (renamed from crates/atuin-server/src/handlers/v0/record.rs)6
-rw-r--r--crates/turtle/src/atuin_server/handlers/v0/store.rs (renamed from crates/atuin-server/src/handlers/v0/store.rs)4
-rw-r--r--crates/turtle/src/atuin_server/metrics.rs (renamed from crates/atuin-server/src/metrics.rs)0
-rw-r--r--crates/turtle/src/atuin_server/mod.rs (renamed from crates/atuin-server/src/lib.rs)5
-rw-r--r--crates/turtle/src/atuin_server/router.rs (renamed from crates/atuin-server/src/router.rs)6
-rw-r--r--crates/turtle/src/atuin_server/settings.rs (renamed from crates/atuin-server/src/settings.rs)31
-rw-r--r--crates/turtle/src/atuin_server/utils.rs (renamed from crates/atuin-server/src/utils.rs)0
-rw-r--r--crates/turtle/src/atuin_server_database/calendar.rs (renamed from crates/atuin-server-database/src/calendar.rs)0
-rw-r--r--crates/turtle/src/atuin_server_database/mod.rs (renamed from crates/atuin-server-database/src/lib.rs)4
-rw-r--r--crates/turtle/src/atuin_server_database/models.rs (renamed from crates/atuin-server-database/src/models.rs)0
-rw-r--r--crates/turtle/src/atuin_server_postgres/mod.rs (renamed from crates/atuin-server-postgres/src/lib.rs)16
-rw-r--r--crates/turtle/src/atuin_server_postgres/wrappers.rs (renamed from crates/atuin-server-postgres/src/wrappers.rs)4
-rw-r--r--crates/turtle/src/atuin_server_sqlite/mod.rs (renamed from crates/atuin-server-sqlite/src/lib.rs)16
-rw-r--r--crates/turtle/src/atuin_server_sqlite/wrappers.rs (renamed from crates/atuin-server-sqlite/src/wrappers.rs)4
l---------crates/turtle/src/command/CONTRIBUTORS (renamed from crates/atuin/src/command/CONTRIBUTORS)0
-rw-r--r--crates/turtle/src/command/client.rs (renamed from crates/atuin/src/command/client.rs)9
-rw-r--r--crates/turtle/src/command/client/account.rs (renamed from crates/atuin/src/command/client/account.rs)4
-rw-r--r--crates/turtle/src/command/client/account/change_password.rs (renamed from crates/atuin/src/command/client/account/change_password.rs)2
-rw-r--r--crates/turtle/src/command/client/account/delete.rs (renamed from crates/atuin/src/command/client/account/delete.rs)2
-rw-r--r--crates/turtle/src/command/client/account/login.rs (renamed from crates/atuin/src/command/client/account/login.rs)4
-rw-r--r--crates/turtle/src/command/client/account/logout.rs (renamed from crates/atuin/src/command/client/account/logout.rs)2
-rw-r--r--crates/turtle/src/command/client/account/register.rs (renamed from crates/atuin/src/command/client/account/register.rs)6
-rw-r--r--crates/turtle/src/command/client/config.rs (renamed from crates/atuin/src/command/client/config.rs)2
-rw-r--r--crates/turtle/src/command/client/daemon.rs (renamed from crates/atuin/src/command/client/daemon.rs)27
-rw-r--r--crates/turtle/src/command/client/default_config.rs4
-rw-r--r--crates/turtle/src/command/client/doctor.rs (renamed from crates/atuin/src/command/client/doctor.rs)10
-rw-r--r--crates/turtle/src/command/client/history.rs (renamed from crates/atuin/src/command/client/history.rs)21
-rw-r--r--crates/turtle/src/command/client/import.rs (renamed from crates/atuin/src/command/client/import.rs)2
-rw-r--r--crates/turtle/src/command/client/info.rs (renamed from crates/atuin/src/command/client/info.rs)4
-rw-r--r--crates/turtle/src/command/client/init.rs (renamed from crates/atuin/src/command/client/init.rs)2
-rw-r--r--crates/turtle/src/command/client/init/bash.rs (renamed from crates/atuin/src/command/client/init/bash.rs)2
-rw-r--r--crates/turtle/src/command/client/init/fish.rs (renamed from crates/atuin/src/command/client/init/fish.rs)2
-rw-r--r--crates/turtle/src/command/client/init/powershell.rs (renamed from crates/atuin/src/command/client/init/powershell.rs)2
-rw-r--r--crates/turtle/src/command/client/init/xonsh.rs (renamed from crates/atuin/src/command/client/init/xonsh.rs)2
-rw-r--r--crates/turtle/src/command/client/init/zsh.rs (renamed from crates/atuin/src/command/client/init/zsh.rs)2
-rw-r--r--crates/turtle/src/command/client/search.rs (renamed from crates/atuin/src/command/client/search.rs)4
-rw-r--r--crates/turtle/src/command/client/search/cursor.rs (renamed from crates/atuin/src/command/client/search/cursor.rs)2
-rw-r--r--crates/turtle/src/command/client/search/duration.rs (renamed from crates/atuin/src/command/client/search/duration.rs)0
-rw-r--r--crates/turtle/src/command/client/search/engines.rs (renamed from crates/atuin/src/command/client/search/engines.rs)2
-rw-r--r--crates/turtle/src/command/client/search/engines/daemon.rs (renamed from crates/atuin/src/command/client/search/engines/daemon.rs)13
-rw-r--r--crates/turtle/src/command/client/search/engines/db.rs (renamed from crates/atuin/src/command/client/search/engines/db.rs)2
-rw-r--r--crates/turtle/src/command/client/search/engines/skim.rs (renamed from crates/atuin/src/command/client/search/engines/skim.rs)2
-rw-r--r--crates/turtle/src/command/client/search/history_list.rs (renamed from crates/atuin/src/command/client/search/history_list.rs)4
-rw-r--r--crates/turtle/src/command/client/search/inspector.rs (renamed from crates/atuin/src/command/client/search/inspector.rs)4
-rw-r--r--crates/turtle/src/command/client/search/interactive.rs (renamed from crates/atuin/src/command/client/search/interactive.rs)82
-rw-r--r--crates/turtle/src/command/client/search/keybindings/actions.rs (renamed from crates/atuin/src/command/client/search/keybindings/actions.rs)0
-rw-r--r--crates/turtle/src/command/client/search/keybindings/conditions.rs (renamed from crates/atuin/src/command/client/search/keybindings/conditions.rs)0
-rw-r--r--crates/turtle/src/command/client/search/keybindings/defaults.rs (renamed from crates/atuin/src/command/client/search/keybindings/defaults.rs)28
-rw-r--r--crates/turtle/src/command/client/search/keybindings/key.rs (renamed from crates/atuin/src/command/client/search/keybindings/key.rs)0
-rw-r--r--crates/turtle/src/command/client/search/keybindings/keymap.rs (renamed from crates/atuin/src/command/client/search/keybindings/keymap.rs)0
-rw-r--r--crates/turtle/src/command/client/search/keybindings/mod.rs (renamed from crates/atuin/src/command/client/search/keybindings/mod.rs)0
-rw-r--r--crates/turtle/src/command/client/server.rs61
-rw-r--r--crates/turtle/src/command/client/setup.rs (renamed from crates/atuin/src/command/client/setup.rs)2
-rw-r--r--crates/turtle/src/command/client/stats.rs (renamed from crates/atuin/src/command/client/stats.rs)4
-rw-r--r--crates/turtle/src/command/client/store.rs (renamed from crates/atuin/src/command/client/store.rs)2
-rw-r--r--crates/turtle/src/command/client/store/pull.rs (renamed from crates/atuin/src/command/client/store/pull.rs)2
-rw-r--r--crates/turtle/src/command/client/store/purge.rs (renamed from crates/atuin/src/command/client/store/purge.rs)2
-rw-r--r--crates/turtle/src/command/client/store/push.rs (renamed from crates/atuin/src/command/client/store/push.rs)4
-rw-r--r--crates/turtle/src/command/client/store/rebuild.rs (renamed from crates/atuin/src/command/client/store/rebuild.rs)4
-rw-r--r--crates/turtle/src/command/client/store/rekey.rs (renamed from crates/atuin/src/command/client/store/rekey.rs)2
-rw-r--r--crates/turtle/src/command/client/store/verify.rs (renamed from crates/atuin/src/command/client/store/verify.rs)2
-rw-r--r--crates/turtle/src/command/client/sync.rs (renamed from crates/atuin/src/command/client/sync.rs)4
-rw-r--r--crates/turtle/src/command/client/sync/status.rs (renamed from crates/atuin/src/command/client/sync/status.rs)2
-rw-r--r--crates/turtle/src/command/client/wrapped.rs (renamed from crates/atuin/src/command/client/wrapped.rs)12
-rw-r--r--crates/turtle/src/command/contributors.rs (renamed from crates/atuin/src/command/contributors.rs)0
-rw-r--r--crates/turtle/src/command/external.rs (renamed from crates/atuin/src/command/external.rs)2
-rw-r--r--crates/turtle/src/command/gen_completions.rs (renamed from crates/atuin/src/command/gen_completions.rs)0
-rw-r--r--crates/turtle/src/command/mod.rs (renamed from crates/atuin/src/command/mod.rs)26
-rw-r--r--crates/turtle/src/main.rs (renamed from crates/atuin/src/main.rs)12
-rw-r--r--crates/turtle/src/print_error.rs (renamed from crates/atuin/src/print_error.rs)2
-rw-r--r--crates/turtle/src/shell/.gitattributes (renamed from crates/atuin/src/shell/.gitattributes)0
-rw-r--r--crates/turtle/src/shell/atuin.bash (renamed from crates/atuin/src/shell/atuin.bash)0
-rw-r--r--crates/turtle/src/shell/atuin.fish (renamed from crates/atuin/src/shell/atuin.fish)0
-rw-r--r--crates/turtle/src/shell/atuin.nu (renamed from crates/atuin/src/shell/atuin.nu)0
-rw-r--r--crates/turtle/src/shell/atuin.ps1 (renamed from crates/atuin/src/shell/atuin.ps1)0
-rw-r--r--crates/turtle/src/shell/atuin.xsh (renamed from crates/atuin/src/shell/atuin.xsh)0
-rw-r--r--crates/turtle/src/shell/atuin.zsh (renamed from crates/atuin/src/shell/atuin.zsh)0
-rw-r--r--crates/turtle/src/sync.rs (renamed from crates/atuin/src/sync.rs)6
233 files changed, 750 insertions, 2855 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d10c4402..cfe35268 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -189,86 +189,65 @@ name = "atuin"
version = "18.16.1"
dependencies = [
"arboard",
+ "argon2",
"async-trait",
- "atuin-client",
- "atuin-common",
- "atuin-daemon",
- "atuin-history",
+ "atuin-nucleo",
"atuin-nucleo-matcher",
- "atuin-pty-proxy",
- "atuin-server",
- "atuin-server-database",
- "atuin-server-postgres",
+ "axum",
+ "base64",
"clap",
"clap_complete",
"clap_complete_nushell",
"colored",
- "crossterm",
- "daemonize",
- "eyre",
- "fs-err",
- "fs4",
- "futures-util",
- "fuzzy-matcher",
- "indicatif",
- "interim",
- "itertools",
- "log",
- "norm",
- "open",
- "ratatui",
- "regex",
- "rpassword",
- "runtime-format",
- "rustix",
- "semver",
- "serde",
- "serde_json",
- "shlex",
- "sysinfo",
- "tempfile",
- "time",
- "tokio",
- "toml_edit",
- "tracing",
- "tracing-appender",
- "tracing-subscriber",
- "tracing-tree",
- "unicode-width 0.2.2",
- "uuid",
-]
-
-[[package]]
-name = "atuin-client"
-version = "18.16.1"
-dependencies = [
- "async-trait",
- "atuin-common",
- "base64",
- "clap",
"config",
"crossterm",
"crypto_secretbox",
+ "daemonize",
+ "dashmap",
"directories",
+ "divan",
"eyre",
"fs-err",
+ "fs4",
"futures",
+ "futures-util",
+ "fuzzy-matcher",
"generic-array",
+ "getrandom 0.2.17",
+ "glob-match",
"hex",
"humantime",
+ "hyper-util",
+ "imara-diff",
"indicatif",
"interim",
"itertools",
+ "lasso",
+ "listenfd",
"log",
"memchr",
+ "metrics",
+ "metrics-exporter-prometheus",
+ "minijinja",
"minspan",
+ "norm",
"notify",
+ "open",
"palette",
+ "portable-pty",
"pretty_assertions",
+ "prost",
+ "prost-types",
+ "protox",
"rand 0.8.5",
+ "ratatui",
"regex",
"reqwest",
"rmp",
+ "rpassword",
+ "runtime-format",
+ "rustix",
+ "rustls",
"rusty_paserk",
"rusty_paseto",
"semver",
@@ -278,83 +257,40 @@ dependencies = [
"serde_with",
"sha2",
"shellexpand",
+ "shlex",
+ "signal-hook",
"sql-builder",
"sqlx",
"strum",
"strum_macros",
- "testing_logger",
- "thiserror 2.0.18",
- "time",
- "tokio",
- "typed-builder",
- "urlencoding",
- "uuid",
- "whoami 2.1.1",
-]
-
-[[package]]
-name = "atuin-common"
-version = "18.16.1"
-dependencies = [
- "base64",
- "directories",
- "eyre",
- "getrandom 0.2.17",
- "pretty_assertions",
- "rustls",
- "semver",
- "serde",
- "sqlx",
"sysinfo",
- "thiserror 2.0.18",
- "time",
- "typed-builder",
- "uuid",
-]
-
-[[package]]
-name = "atuin-daemon"
-version = "18.16.1"
-dependencies = [
- "atuin-client",
- "atuin-common",
- "atuin-history",
- "atuin-nucleo",
- "dashmap",
- "eyre",
- "hyper-util",
- "lasso",
- "listenfd",
- "prost",
- "prost-types",
- "protox",
- "rand 0.8.5",
"tempfile",
+ "testing_logger",
+ "thiserror 2.0.18",
"time",
"tokio",
"tokio-stream",
+ "toml_edit",
"tonic",
"tonic-build",
"tonic-prost",
"tonic-prost-build",
"tonic-types",
"tower",
+ "tower-http",
"tracing",
+ "tracing-appender",
"tracing-subscriber",
- "uuid",
-]
-
-[[package]]
-name = "atuin-history"
-version = "18.16.1"
-dependencies = [
- "atuin-client",
- "crossterm",
- "divan",
- "rand 0.8.5",
- "serde",
- "time",
+ "tracing-tree",
+ "typed-builder",
"unicode-segmentation",
+ "unicode-width 0.2.2",
+ "url",
+ "urlencoding",
+ "uuid",
+ "vt100",
+ "whoami 2.1.1",
+ "xxhash-rust",
]
[[package]]
@@ -385,96 +321,6 @@ dependencies = [
]
[[package]]
-name = "atuin-pty-proxy"
-version = "18.16.1"
-dependencies = [
- "clap",
- "crossterm",
- "eyre",
- "portable-pty",
- "signal-hook",
- "vt100",
-]
-
-[[package]]
-name = "atuin-server"
-version = "18.16.1"
-dependencies = [
- "argon2",
- "atuin-common",
- "atuin-server-database",
- "atuin-server-postgres",
- "atuin-server-sqlite",
- "axum",
- "clap",
- "config",
- "eyre",
- "fs-err",
- "metrics",
- "metrics-exporter-prometheus",
- "rand 0.8.5",
- "reqwest",
- "semver",
- "serde",
- "serde_json",
- "time",
- "tokio",
- "tower",
- "tower-http",
- "tracing",
- "tracing-subscriber",
-]
-
-[[package]]
-name = "atuin-server-database"
-version = "18.16.1"
-dependencies = [
- "async-trait",
- "atuin-common",
- "eyre",
- "serde",
- "sqlx",
- "time",
- "tracing",
- "url",
-]
-
-[[package]]
-name = "atuin-server-postgres"
-version = "18.16.1"
-dependencies = [
- "async-trait",
- "atuin-common",
- "atuin-server-database",
- "eyre",
- "futures-util",
- "metrics",
- "rand 0.8.5",
- "serde",
- "sqlx",
- "time",
- "tracing",
- "uuid",
-]
-
-[[package]]
-name = "atuin-server-sqlite"
-version = "18.16.1"
-dependencies = [
- "async-trait",
- "atuin-common",
- "atuin-server-database",
- "eyre",
- "futures-util",
- "metrics",
- "serde",
- "sqlx",
- "time",
- "tracing",
- "uuid",
-]
-
-[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1695,6 +1541,12 @@ dependencies = [
]
[[package]]
+name = "glob-match"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d"
+
+[[package]]
name = "h2"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2064,6 +1916,16 @@ dependencies = [
]
[[package]]
+name = "imara-diff"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f01d462f766df78ab820dd06f5eb700233c51f0f4c2e846520eaf4ba6aa5c5c"
+dependencies = [
+ "hashbrown 0.15.5",
+ "memchr",
+]
+
+[[package]]
name = "indenter"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2513,6 +2375,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15"
[[package]]
+name = "memo-map"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38d1115007560874e373613744c6fba374c17688327a71c1476d1a5954cc857b"
+
+[[package]]
name = "memoffset"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2590,6 +2458,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
+name = "minijinja"
+version = "2.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2929e494b2280e1e18959bb2e121da03347ae896896fdfaceaab43c88a02803f"
+dependencies = [
+ "memo-map",
+ "serde",
+]
+
+[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6377,6 +6255,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
[[package]]
+name = "xxhash-rust"
+version = "0.8.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3"
+
+[[package]]
name = "yansi"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index cc88e07f..4c87b914 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,12 +1,12 @@
[workspace]
members = [
- "crates/*",
"crates/atuin-nucleo/matcher",
"crates/atuin-nucleo/bench",
+ "crates/turtle"
]
resolver = "2"
-exclude = ["ui/backend", "crates/atuin-nucleo/matcher/fuzz"]
+exclude = ["crates/atuin-nucleo/matcher/fuzz"]
[workspace.package]
version = "18.16.1"
@@ -18,67 +18,5 @@ repository = "https://github.com/atuinsh/atuin"
readme = "README.md"
[workspace.dependencies]
-async-trait = "0.1.58"
-atuin-client = { path = "crates/atuin-client", version = "18.16.1" }
-atuin-common = { path = "crates/atuin-common", version = "18.16.1" }
-atuin-daemon = { path = "crates/atuin-daemon", version = "18.16.1" }
-atuin-history = { path = "crates/atuin-history", version = "18.16.1" }
-atuin-server = { path = "crates/atuin-server", version = "18.16.1" }
-atuin-server-database = { path = "crates/atuin-server-database", version = "18.16.1" }
-atuin-server-postgres = { path = "crates/atuin-server-postgres", version = "18.16.1" }
-atuin-server-sqlite = { path = "crates/atuin-server-sqlite", version = "18.16.1" }
atuin-nucleo = { path = "crates/atuin-nucleo", version = "0.6.0" }
atuin-nucleo-matcher = { path = "crates/atuin-nucleo/matcher", version = "0.3.1" }
-base64 = "0.22"
-crossterm = "0.29.0"
-log = "0.4"
-time = { version = "0.3.47", features = [
- "serde-human-readable",
- "macros",
- "local-offset",
-] }
-clap = { version = "4.5.7", features = ["derive"] }
-config = { version = "0.15.8", default-features = false, features = ["toml"] }
-directories = "6.0.0"
-eyre = "0.6"
-fs-err = "3.1"
-interim = { version = "0.2.0", features = ["time_0_3"] }
-itertools = "0.14.0"
-rand = { version = "0.8.5", features = ["std"] }
-semver = "1.0.20"
-serde = { version = "1.0.202", features = ["derive"] }
-serde_json = "1.0.119"
-shellexpand = "3"
-tokio = { version = "1", features = ["full"] }
-uuid = { version = "1.9", features = ["v4", "v7", "serde"] }
-whoami = "2.1.0"
-typed-builder = "0.18.2"
-pretty_assertions = "1.3.0"
-thiserror = "2"
-rustix = { version = "1.1.4", features = ["process", "fs"] }
-tower = "0.5"
-tracing = "0.1"
-ratatui = "0.30.0"
-sql-builder = "3"
-tempfile = { version = "3.19" }
-minijinja = "2.9.0"
-rustls = { version = "0.23", default-features = false, features = [
- "ring",
- "std",
- "tls12",
-] }
-glob-match = "0.2.1"
-imara-diff = "0.2"
-xxhash-rust = { version = "0.8", features = ["xxh3"] }
-vt100 = "0.16"
-regex = "1.10.5"
-toml_edit = "0.25.4"
-tracing-subscriber = { version = "0.3", features = ["ansi", "fmt", "registry", "env-filter", "json"] }
-reqwest = { version = "0.13", features = ["json", "rustls-no-provider", "stream"], default-features = false }
-sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "time", "postgres", "uuid"] }
-
-# The profile that 'cargo dist' will build with
-[profile.dist]
-inherits = "release"
-lto = "thin"
-strip = "symbols"
diff --git a/crates/atuin-client/Cargo.toml b/crates/atuin-client/Cargo.toml
deleted file mode 100644
index c6a0f261..00000000
--- a/crates/atuin-client/Cargo.toml
+++ /dev/null
@@ -1,82 +0,0 @@
-[package]
-name = "atuin-client"
-edition = "2024"
-description = "client library for atuin"
-
-rust-version = { workspace = true }
-version = { workspace = true }
-authors = { workspace = true }
-license = { workspace = true }
-homepage = { workspace = true }
-repository = { workspace = true }
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[features]
-default = ["sync", "daemon"]
-sync = ["urlencoding", "reqwest", "sha2", "hex"]
-daemon = []
-check-update = []
-
-[dependencies]
-atuin-common = { path = "../atuin-common", version = "18.16.1" }
-
-log = { workspace = true }
-base64 = { workspace = true }
-time = { workspace = true, features = ["macros", "formatting", "parsing"] }
-clap = { workspace = true }
-eyre = { workspace = true }
-directories = { workspace = true }
-uuid = { workspace = true }
-whoami = { workspace = true }
-interim = { workspace = true }
-config = { workspace = true }
-serde = { workspace = true }
-serde_json = { workspace = true }
-humantime = "2.1.0"
-async-trait = { workspace = true }
-itertools = { workspace = true }
-rand = { workspace = true }
-shellexpand = { workspace = true }
-sqlx = { workspace = true, features = ["sqlite", "regexp"] }
-minspan = "0.1.5"
-regex = { workspace = true }
-serde_regex = "1.1.0"
-fs-err = { workspace = true }
-sql-builder = { workspace = true }
-memchr = "2.7"
-rmp = { version = "0.8.14" }
-typed-builder = { workspace = true }
-tokio = { workspace = true }
-semver = { workspace = true }
-thiserror = { workspace = true }
-futures = "0.3"
-notify = "7"
-crypto_secretbox = "0.1.1"
-generic-array = { version = "0.14", features = ["serde"] }
-serde_with = "3.8.1"
-
-# encryption
-rusty_paseto = { version = "0.8.0", default-features = false }
-rusty_paserk = { version = "0.5.0", default-features = false, features = [
- "v4",
- "serde",
-] }
-
-# sync
-urlencoding = { version = "2.1.0", optional = true }
-reqwest = { workspace = true, optional = true }
-hex = { version = "0.4", optional = true }
-sha2 = { version = "0.10", optional = true }
-indicatif = "0.18.0"
-
-# theme
-crossterm = { workspace = true, features = ["serde"] }
-palette = { version = "0.7.5", features = ["serializing"] }
-strum_macros = "0.27"
-strum = { version = "0.27", features = ["strum_macros"] }
-
-[dev-dependencies]
-tokio = { version = "1", features = ["full"] }
-pretty_assertions = { workspace = true }
-testing_logger = "0.1.1"
diff --git a/crates/atuin-client/config.toml b/crates/atuin-client/config.toml
deleted file mode 100644
index 0d0672bf..00000000
--- a/crates/atuin-client/config.toml
+++ /dev/null
@@ -1,371 +0,0 @@
-## Base directory for Atuin data files (databases, keys, session, etc.)
-## All data file paths default to being relative to this directory.
-## linux/mac: ~/.local/share/atuin (or XDG_DATA_HOME/atuin)
-## windows: %USERPROFILE%/.local/share/atuin
-# data_dir = "~/.local/share/atuin"
-
-## where to store your database, default is your system data directory
-## linux/mac: ~/.local/share/atuin/history.db
-## windows: %USERPROFILE%/.local/share/atuin/history.db
-# db_path = "~/.history.db"
-
-## where to store your encryption key, default is your system data directory
-## linux/mac: ~/.local/share/atuin/key
-## windows: %USERPROFILE%/.local/share/atuin/key
-# key_path = "~/.key"
-
-## where to store your auth session token, default is your system data directory
-## linux/mac: ~/.local/share/atuin/session
-## windows: %USERPROFILE%/.local/share/atuin/session
-# session_path = "~/.session"
-
-## date format used, either "us" or "uk"
-# dialect = "us"
-
-## default timezone to use when displaying time
-## either "l", "local" to use the system's current local timezone, or an offset
-## from UTC in the format of "<+|->H[H][:M[M][:S[S]]]"
-## for example: "+9", "-05", "+03:30", "-01:23:45", etc.
-# timezone = "local"
-
-## enable or disable automatic sync
-# auto_sync = true
-
-## enable or disable automatic update checks
-# update_check = true
-
-## address of the sync server
-# sync_address = "https://api.atuin.sh"
-
-## how often to sync history. note that this is only triggered when a command
-## is ran, so sync intervals may well be longer
-## set it to 0 to sync after every command
-# sync_frequency = "10m"
-
-## which search mode to use
-## possible values: prefix, fulltext, fuzzy, skim
-# search_mode = "fuzzy"
-
-## which filter mode to use by default
-## possible values: "global", "host", "session", "session-preload", "directory", "workspace"
-## consider using search.filters to customize the enablement and order of filter modes
-# filter_mode = "global"
-
-## With workspace filtering enabled, Atuin will filter for commands executed
-## in any directory within a git repository tree (default: false).
-##
-## To use workspace mode by default when available, set this to true and
-## set filter_mode to "workspace" or leave it unspecified and
-## set search.filters to include "workspace" before other filter modes.
-# workspaces = false
-
-## which filter mode to use when atuin is invoked from a shell up-key binding
-## the accepted values are identical to those of "filter_mode"
-## leave unspecified to use same mode set in "filter_mode"
-# filter_mode_shell_up_key_binding = "global"
-
-## which search mode to use when atuin is invoked from a shell up-key binding
-## the accepted values are identical to those of "search_mode"
-## leave unspecified to use same mode set in "search_mode"
-# search_mode_shell_up_key_binding = "fuzzy"
-
-## which style to use
-## possible values: auto, full, compact
-# style = "auto"
-
-## the maximum number of lines the interface should take up
-## set it to 0 to always go full screen
-# inline_height = 0
-
-## the maximum number of lines the interface should take up
-## when atuin is invoked from a shell up-key binding
-## the accepted values are identical to those of "inline_height"
-# inline_height_shell_up_key_binding = 0
-
-## Invert the UI - put the search bar at the top , Default to `false`
-# invert = false
-
-## enable or disable showing a preview of the selected command
-## useful when the command is longer than the terminal width and is cut off
-# show_preview = true
-
-## what to do when the escape key is pressed when searching
-## possible values: return-original, return-query
-# exit_mode = "return-original"
-
-## possible values: emacs, subl
-# word_jump_mode = "emacs"
-
-## characters that count as a part of a word
-# word_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
-
-## number of context lines to show when scrolling by pages
-# scroll_context_lines = 1
-
-## use ctrl instead of alt as the shortcut modifier key for numerical UI shortcuts
-## alt-0 .. alt-9
-# ctrl_n_shortcuts = false
-
-## Show numeric shortcuts (1..9) beside list items in the TUI
-## set to false to hide the moving numbers if you find them distracting
-# show_numeric_shortcuts = true
-
-## default history list format - can also be specified with the --format arg
-# history_format = "{time}\t{command}\t{duration}"
-
-## Defaults to true. If enabled, strip trailing spaces and tabs from commands
-## before saving them to history.
-## Escaped trailing spaces (for example `printf foo\\ `) are preserved.
-# strip_trailing_whitespace = true
-
-## prevent commands matching any of these regexes from being written to history.
-## Note that these regular expressions are unanchored, i.e. if they don't start
-## with ^ or end with $, they'll match anywhere in the command.
-## For details on the supported regular expression syntax, see
-## https://docs.rs/regex/latest/regex/#syntax
-# history_filter = [
-# "^secret-cmd",
-# "^innocuous-cmd .*--secret=.+",
-# ]
-
-## prevent commands run with cwd matching any of these regexes from being written
-## to history. Note that these regular expressions are unanchored, i.e. if they don't
-## start with ^ or end with $, they'll match anywhere in CWD.
-## For details on the supported regular expression syntax, see
-## https://docs.rs/regex/latest/regex/#syntax
-# cwd_filter = [
-# "^/very/secret/area",
-# ]
-
-## Configure the maximum height of the preview to show.
-## Useful when you have long scripts in your history that you want to distinguish
-## by more than the first few lines.
-# max_preview_height = 4
-
-## 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.
-# show_help = true
-
-## Configure whether or not to show tabs for search and inspect
-# show_tabs = true
-
-## Configure whether or not the tabs row may be auto-hidden, which includes the current Atuin
-## tab, such as Search or Inspector, and other tabs you may wish to see. This will
-## only be hidden if there are fewer than this count of lines available, and does not affect the use
-## of keyboard shortcuts to switch tab. 0 to never auto-hide, default is 8 (lines).
-## This is ignored except in `compact` mode.
-# auto_hide_height = 8
-
-## Defaults to true. This matches history against a set of default regex, and will not save it if we get a match. Defaults include
-## 1. AWS key id
-## 2. Github pat (old and new)
-## 3. Slack oauth tokens (bot, user)
-## 4. Slack webhooks
-## 5. Stripe live/test keys
-# secrets_filter = true
-
-## Defaults to true. If enabled, upon hitting enter Atuin will immediately execute the command,
-## whereas tab will put the command in the prompt for editing.
-## If set to false, both enter and tab will place the command in the prompt for editing.
-## This applies for new installs. Old installs will keep the old behaviour unless configured otherwise.
-enter_accept = true
-
-## Defaults to false. If enabled, when triggered after &&, || or |, Atuin will complete commands to chain rather than replace the current line.
-# command_chaining = false
-
-## Defaults to "emacs". This specifies the keymap on the startup of `atuin
-## search`. If this is set to "auto", the startup keymap mode in the Atuin
-## search is automatically selected based on the shell's keymap where the
-## keybinding is defined. If this is set to "emacs", "vim-insert", or
-## "vim-normal", the startup keymap mode in the Atuin search is forced to be
-## the specified one.
-# keymap_mode = "auto"
-
-## Cursor style in each keymap mode. If specified, the cursor style is changed
-## in entering the cursor shape. Available values are "default" and
-## "{blink,steady}-{block,underline,bar}".
-# keymap_cursor = { emacs = "blink-block", vim_insert = "blink-block", vim_normal = "steady-block" }
-
-# network_connect_timeout = 5
-# network_timeout = 5
-
-## Timeout (in seconds) for acquiring a local database connection (sqlite)
-# local_timeout = 5
-
-## Set this to true and Atuin will minimize motion in the UI - timers will not update live, etc.
-## Alternatively, set env NO_MOTION=true
-# prefers_reduced_motion = false
-
-[stats]
-## Set commands where we should consider the subcommand for statistics. Eg, kubectl get vs just kubectl
-# common_subcommands = [
-# "apt",
-# "cargo",
-# "composer",
-# "dnf",
-# "docker",
-# "dotnet",
-# "git",
-# "go",
-# "ip",
-# "jj",
-# "kubectl",
-# "nix",
-# "nmcli",
-# "npm",
-# "pecl",
-# "pnpm",
-# "podman",
-# "port",
-# "systemctl",
-# "tmux",
-# "yarn",
-# ]
-
-## Set commands that should be totally stripped and ignored from stats
-# common_prefix = ["sudo"]
-
-## Set commands that will be completely ignored from stats
-# ignored_commands = [
-# "cd",
-# "ls",
-# "vi"
-# ]
-
-[keys]
-# Defaults to true. If disabled, using the up/down key won't exit the TUI when scrolled past the first/last entry.
-# scroll_exits = true
-
-# Defaults to true. The left arrow key will exit the TUI when scrolling before the first character
-# exit_past_line_start = true
-
-# Defaults to true. The right arrow key performs the same functionality as Tab and copies the selected line to the command line to be modified.
-# accept_past_line_end = true
-
-# Defaults to false. The left arrow key performs the same functionality as Tab and copies the selected line to the command line to be modified.
-# accept_past_line_start = false
-
-# Defaults to false. The backspace key performs the same functionality as Tab and copies the selected line to the command line to be modified when at the start of the line.
-# accept_with_backspace = false
-
-[sync]
-# Enable sync v2 by default
-# This ensures that sync v2 is enabled for new installs only
-# In a later release it will become the default across the board
-records = true
-
-[preview]
-## which preview strategy to use to calculate the preview height (respects max_preview_height).
-## possible values: auto, static
-## auto: length of the selected command.
-## static: length of the longest command stored in the history.
-## fixed: use max_preview_height as fixed height.
-# strategy = "auto"
-
-[daemon]
-## Enables using the daemon to sync.
-# enabled = false
-
-## Automatically start and manage the daemon when needed.
-## Not compatible with `systemd_socket = true`.
-# autostart = false
-
-## How often the daemon should sync in seconds
-# sync_frequency = 300
-
-## The path to the unix socket used by the daemon (on unix systems)
-## linux/mac: ~/.local/share/atuin/atuin.sock
-## windows: Not Supported
-# socket_path = "~/.local/share/atuin/atuin.sock"
-
-## The daemon pidfile used for lifecycle management.
-## Defaults to the Atuin data directory.
-# pidfile_path = "~/.local/share/atuin/atuin-daemon.pid"
-
-## Use systemd socket activation rather than opening the given path (the path must still be correct for the client)
-## linux: false
-## mac/windows: Not Supported
-# systemd_socket = false
-
-## The port that should be used for TCP on non unix systems
-# tcp_port = 8889
-
-# [theme]
-## Color theme to use for rendering in the terminal.
-## There are some built-in themes, including the base theme ("default"),
-## "autumn" and "marine". You can add your own themes to the "./themes" subdirectory of your
-## Atuin config (or ATUIN_THEME_DIR, if provided) as TOML files whose keys should be one or
-## more of AlertInfo, AlertWarn, AlertError, Annotation, Base, Guidance, Important, and
-## the string values as lowercase entries from this list:
-## https://ogeon.github.io/docs/palette/master/palette/named/index.html
-## If you provide a custom theme file, it should be called "NAME.toml" and the theme below
-## should be the stem, i.e. `theme = "NAME"` for your chosen NAME.
-# name = "autumn"
-
-## Whether the theme manager should output normal or extra information to help fix themes.
-## Boolean, true or false. If unset, left up to the theme manager.
-# debug = true
-
-[search]
-## The list of enabled filter modes, in order of priority.
-## The "workspace" mode is skipped when not in a workspace or workspaces = false.
-## Default filter mode can be overridden with the filter_mode setting.
-# filters = [ "global", "host", "session", "session-preload", "workspace", "directory" ]
-
-[tmux]
-## Enable using atuin with tmux popup (requires tmux >= 3.2)
-## When enabled and running inside tmux, Atuin will use a popup window for interactive search.
-## Set to false to disable the popup.
-## This can also be controlled with the ATUIN_TMUX_POPUP environment variable.
-## Note: The tmux popup is currently supported in zsh, bash, and fish shells. This currently doesn't work with iTerm native tmux integration.
-# enabled = false
-
-## Width of the tmux popup window
-## Can be a percentage, or integer (e.g. "100" means 100 characters wide)
-# width = "80%"
-
-## Height of the tmux popup window
-## Can be a percentage, or integer (e.g. "100" means 100 lines tall)
-# height = "60%"
-
-[ui]
-## Columns to display in the interactive search, from left to right.
-## The selection indicator (" > ") is always shown first implicitly.
-##
-## Each column can be specified as a simple string (uses default width)
-## or as an object with type, width, and expand:
-## { type = "directory", width = 30, expand = true }
-##
-## Available column types (with default widths):
-## duration (5) - Command execution duration (e.g., "123ms")
-## time (8) - Relative time since execution (e.g., "59m ago")
-## datetime (16) - Absolute timestamp (e.g., "2025-01-22 14:35")
-## directory (20) - Working directory (truncated if too long)
-## host (15) - Hostname where command was run
-## user (10) - Username
-## exit (3) - Exit code (colored by success/failure)
-## command (*) - The command itself (expands by default)
-##
-## The "expand" option (default: true for command, false for others) makes a
-## column fill remaining space. Only one column should have expand = true.
-##
-## Default:
-# columns = ["duration", "time", "command"]
-##
-## Examples:
-##
-## Minimal - more space for commands:
-# columns = ["duration", "command"]
-##
-## With wider directory column:
-# columns = ["duration", { type = "directory", width = 30 }, "command"]
-##
-## Show host for multi-machine sync users:
-# columns = ["duration", "time", "host", "command"]
-##
-## Show exit codes prominently:
-# columns = ["exit", "duration", "command"]
-##
-## Make directory expand instead of command:
-# columns = ["duration", "time", { type = "directory", expand = true }, { type = "command", expand = false }]
diff --git a/crates/atuin-client/meta-migrations/20260203030924_create_meta.sql b/crates/atuin-client/meta-migrations/20260203030924_create_meta.sql
deleted file mode 100644
index 26c3c142..00000000
--- a/crates/atuin-client/meta-migrations/20260203030924_create_meta.sql
+++ /dev/null
@@ -1,5 +0,0 @@
-create table if not exists meta (
- key text not null primary key,
- value text not null,
- updated_at integer not null default (strftime('%s', 'now'))
-);
diff --git a/crates/atuin-client/migrations/20210422143411_create_history.sql b/crates/atuin-client/migrations/20210422143411_create_history.sql
deleted file mode 100644
index 1f3f8686..00000000
--- a/crates/atuin-client/migrations/20210422143411_create_history.sql
+++ /dev/null
@@ -1,16 +0,0 @@
--- Add migration script here
-create table if not exists history (
- id text primary key,
- timestamp integer not null,
- duration integer not null,
- exit integer not null,
- command text not null,
- cwd text not null,
- session text not null,
- hostname text not null,
-
- unique(timestamp, cwd, command)
-);
-
-create index if not exists idx_history_timestamp on history(timestamp);
-create index if not exists idx_history_command on history(command);
diff --git a/crates/atuin-client/migrations/20220505083406_create-events.sql b/crates/atuin-client/migrations/20220505083406_create-events.sql
deleted file mode 100644
index f6cafeba..00000000
--- a/crates/atuin-client/migrations/20220505083406_create-events.sql
+++ /dev/null
@@ -1,11 +0,0 @@
-create table if not exists events (
- id text primary key,
- timestamp integer not null,
- hostname text not null,
- event_type text not null,
-
- history_id text not null
-);
-
--- Ensure there is only ever one of each event type per history item
-create unique index history_event_idx ON events(event_type, history_id);
diff --git a/crates/atuin-client/migrations/20220806155627_interactive_search_index.sql b/crates/atuin-client/migrations/20220806155627_interactive_search_index.sql
deleted file mode 100644
index b5770e62..00000000
--- a/crates/atuin-client/migrations/20220806155627_interactive_search_index.sql
+++ /dev/null
@@ -1,6 +0,0 @@
--- Interactive search filters by command then by the max(timestamp) for that
--- command. Create an index that covers those
-create index if not exists idx_history_command_timestamp on history(
- command,
- timestamp
-);
diff --git a/crates/atuin-client/migrations/20230315220114_drop-events.sql b/crates/atuin-client/migrations/20230315220114_drop-events.sql
deleted file mode 100644
index fe3cae17..00000000
--- a/crates/atuin-client/migrations/20230315220114_drop-events.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Add migration script here
-drop table events;
diff --git a/crates/atuin-client/migrations/20230319185725_deleted_at.sql b/crates/atuin-client/migrations/20230319185725_deleted_at.sql
deleted file mode 100644
index 6c422abc..00000000
--- a/crates/atuin-client/migrations/20230319185725_deleted_at.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Add migration script here
-alter table history add column deleted_at integer;
diff --git a/crates/atuin-client/migrations/20260224000100_history_author_intent.sql b/crates/atuin-client/migrations/20260224000100_history_author_intent.sql
deleted file mode 100644
index 2bed17e9..00000000
--- a/crates/atuin-client/migrations/20260224000100_history_author_intent.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-alter table history add column author text;
-alter table history add column intent text;
diff --git a/crates/atuin-client/record-migrations/20230531212437_create-records.sql b/crates/atuin-client/record-migrations/20230531212437_create-records.sql
deleted file mode 100644
index 4f4b304a..00000000
--- a/crates/atuin-client/record-migrations/20230531212437_create-records.sql
+++ /dev/null
@@ -1,16 +0,0 @@
--- Add migration script here
-create table if not exists records (
- id text primary key,
- parent text unique, -- null if this is the first one
- host text not null,
-
- timestamp integer not null,
- tag text not null,
- version text not null,
- data blob not null,
- cek blob not null
-);
-
-create index host_idx on records (host);
-create index tag_idx on records (tag);
-create index host_tag_idx on records (host, tag);
diff --git a/crates/atuin-client/record-migrations/20231127090831_create-store.sql b/crates/atuin-client/record-migrations/20231127090831_create-store.sql
deleted file mode 100644
index 53d78860..00000000
--- a/crates/atuin-client/record-migrations/20231127090831_create-store.sql
+++ /dev/null
@@ -1,15 +0,0 @@
--- Add migration script here
-create table if not exists store (
- id text primary key, -- globally unique ID
-
- idx integer, -- incrementing integer ID unique per (host, tag)
- host text not null, -- references the host row
- tag text not null,
-
- timestamp integer not null,
- version text not null,
- data blob not null,
- cek blob not null
-);
-
-create unique index record_uniq ON store(host, tag, idx);
diff --git a/crates/atuin-client/tests/data/xonsh-history.sqlite b/crates/atuin-client/tests/data/xonsh-history.sqlite
deleted file mode 100644
index 744fcf86..00000000
--- a/crates/atuin-client/tests/data/xonsh-history.sqlite
+++ /dev/null
Binary files differ
diff --git a/crates/atuin-client/tests/data/xonsh/xonsh-82eafbf5-9f43-489a-80d2-61c7dc6ef542.json b/crates/atuin-client/tests/data/xonsh/xonsh-82eafbf5-9f43-489a-80d2-61c7dc6ef542.json
deleted file mode 100644
index 339a09f1..00000000
--- a/crates/atuin-client/tests/data/xonsh/xonsh-82eafbf5-9f43-489a-80d2-61c7dc6ef542.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{"locs": [ 69, 3371, 3451, 3978],
- "index": {"offsets":{"__total__":0,"cmds":[{"__total__":10,"cwd":18,"inp":78,"rtn":96,"ts":[106,125,105]},{"__total__":149,"cwd":157,"inp":217,"rtn":234,"ts":[244,263,243]},9],"env":{"ATUIN_SESSION":314,"BASH_COMPLETIONS":370,"COLORTERM":433,"DBUS_SESSION_BUS_ADDRESS":474,"DESKTOP_SESSION":529,"DISPLAY":550,"GDMSESSION":570,"GIO_LAUNCHED_DESKTOP_FILE":609,"GIO_LAUNCHED_DESKTOP_FILE_PID":704,"GJS_DEBUG_OUTPUT":734,"GJS_DEBUG_TOPICS":764,"GNOME_DESKTOP_SESSION_ID":811,"GNOME_SETUP_DISPLAY":856,"GNOME_SHELL_SESSION_MODE":890,"GTK_MODULES":915,"HOME":942,"IM_CONFIG_PHASE":976,"INVOCATION_ID":998,"JOURNAL_STREAM":1052,"LANG":1071,"LOGNAME":1097,"MANAGERPID":1118,"MOZ_ENABLE_WAYLAND":1148,"PATH":1161,"PWD":1736,"PYENV_DIR":1802,"PYENV_HOOK_PATH":1874,"PYENV_ROOT":2048,"PYENV_SHELL":2086,"PYENV_VERSION":2111,"QT_ACCESSIBILITY":2141,"QT_IM_MODULE":2162,"SESSION_MANAGER":2189,"SHELL":2279,"SHLVL":2303,"SSH_AGENT_LAUNCHER":2330,"SSH_AUTH_SOCK":2364,"SSL_CERT_DIR":2415,"SSL_CERT_FILE":2458,"SYSTEMD_EXEC_PID":2525,"TERM":2541,"TERM_PROGRAM":2575,"TERM_PROGRAM_VERSION":2610,"THREAD_SUBPROCS":2657,"USER":2670,"USERNAME":2689,"WAYLAND_DISPLAY":2715,"WEZTERM_CONFIG_DIR":2750,"WEZTERM_CONFIG_FILE":2806,"WEZTERM_EXECUTABLE":2874,"WEZTERM_EXECUTABLE_DIR":2927,"WEZTERM_PANE":2957,"WEZTERM_UNIX_SOCKET":2986,"XAUTHORITY":3047,"XDG_CONFIG_DIRS":3116,"XDG_CURRENT_DESKTOP":3176,"XDG_DATA_DIRS":3209,"XDG_MENU_PREFIX":3316,"XDG_RUNTIME_DIR":3345,"XDG_SESSION_CLASS":3387,"XDG_SESSION_DESKTOP":3418,"XDG_SESSION_TYPE":3448,"XMODIFIERS":3473,"XONSHRC":3496,"XONSHRC_DIR":3594,"XONSH_CAPTURE_ALWAYS":3674,"XONSH_CONFIG_DIR":3698,"XONSH_DATA_DIR":3747,"XONSH_INTERACTIVE":3805,"XONSH_LOGIN":3825,"XONSH_VERSION":3847,"__total__":296},"locked":3869,"sessionid":3889,"ts":[3936,3956,3935]},"sizes":{"__total__":3978,"cmds":[{"__total__":137,"cwd":51,"inp":9,"rtn":1,"ts":[17,18,40]},{"__total__":136,"cwd":51,"inp":8,"rtn":1,"ts":[17,18,40]},278],"env":{"ATUIN_SESSION":34,"BASH_COMPLETIONS":48,"COLORTERM":11,"DBUS_SESSION_BUS_ADDRESS":34,"DESKTOP_SESSION":8,"DISPLAY":4,"GDMSESSION":8,"GIO_LAUNCHED_DESKTOP_FILE":60,"GIO_LAUNCHED_DESKTOP_FILE_PID":8,"GJS_DEBUG_OUTPUT":8,"GJS_DEBUG_TOPICS":17,"GNOME_DESKTOP_SESSION_ID":20,"GNOME_SETUP_DISPLAY":4,"GNOME_SHELL_SESSION_MODE":8,"GTK_MODULES":17,"HOME":13,"IM_CONFIG_PHASE":3,"INVOCATION_ID":34,"JOURNAL_STREAM":9,"LANG":13,"LOGNAME":5,"MANAGERPID":6,"MOZ_ENABLE_WAYLAND":3,"PATH":566,"PWD":51,"PYENV_DIR":51,"PYENV_HOOK_PATH":158,"PYENV_ROOT":21,"PYENV_SHELL":6,"PYENV_VERSION":8,"QT_ACCESSIBILITY":3,"QT_IM_MODULE":6,"SESSION_MANAGER":79,"SHELL":13,"SHLVL":3,"SSH_AGENT_LAUNCHER":15,"SSH_AUTH_SOCK":33,"SSL_CERT_DIR":24,"SSL_CERT_FILE":45,"SYSTEMD_EXEC_PID":6,"TERM":16,"TERM_PROGRAM":9,"TERM_PROGRAM_VERSION":26,"THREAD_SUBPROCS":3,"USER":5,"USERNAME":5,"WAYLAND_DISPLAY":11,"WEZTERM_CONFIG_DIR":31,"WEZTERM_CONFIG_FILE":44,"WEZTERM_EXECUTABLE":25,"WEZTERM_EXECUTABLE_DIR":12,"WEZTERM_PANE":4,"WEZTERM_UNIX_SOCKET":45,"XAUTHORITY":48,"XDG_CONFIG_DIRS":35,"XDG_CURRENT_DESKTOP":14,"XDG_DATA_DIRS":86,"XDG_MENU_PREFIX":8,"XDG_RUNTIME_DIR":19,"XDG_SESSION_CLASS":6,"XDG_SESSION_DESKTOP":8,"XDG_SESSION_TYPE":9,"XMODIFIERS":10,"XONSHRC":81,"XONSHRC_DIR":54,"XONSH_CAPTURE_ALWAYS":2,"XONSH_CONFIG_DIR":29,"XONSH_DATA_DIR":35,"XONSH_INTERACTIVE":3,"XONSH_LOGIN":3,"XONSH_VERSION":8,"__total__":3561},"locked":5,"sessionid":38,"ts":[18,18,41]}},
- "data": {"cmds": [{"cwd": "\/home\/user\/Documents\/code\/atuin\/atuin-client", "inp": "false\n", "rtn": 1, "ts": [1707241291.142516, 1707241291.1527853]
-}
-, {"cwd": "\/home\/user\/Documents\/code\/atuin\/atuin-client", "inp": "exit\n", "rtn": 0, "ts": [1707241292.271584, 1707241292.2758434]
-}
-]
-, "env": {"ATUIN_SESSION": "018d7f82ad167dc4888ca0bf294d2bfd", "BASH_COMPLETIONS": "\/usr\/share\/bash-completion\/bash_completion", "COLORTERM": "truecolor", "DBUS_SESSION_BUS_ADDRESS": "unix:path=\/run\/user\/1000\/bus", "DESKTOP_SESSION": "ubuntu", "DISPLAY": ":0", "GDMSESSION": "ubuntu", "GIO_LAUNCHED_DESKTOP_FILE": "\/usr\/share\/applications\/org.wezfurlong.wezterm.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "196859", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_SETUP_DISPLAY": ":1", "GNOME_SHELL_SESSION_MODE": "ubuntu", "GTK_MODULES": "gail:atk-bridge", "HOME": "\/home\/user", "IM_CONFIG_PHASE": "1", "INVOCATION_ID": "4f121e7ad56c41a6b84aa3cbe1ad61fa", "JOURNAL_STREAM": "8:37187", "LANG": "en_US.UTF-8", "LOGNAME": "user", "MANAGERPID": "2118", "MOZ_ENABLE_WAYLAND": "1", "PATH": "\/home\/user\/.pyenv\/versions\/3.12.0\/bin:\/home\/user\/.pyenv\/libexec:\/home\/user\/.pyenv\/plugins\/python-build\/bin:\/home\/user\/.pyenv\/plugins\/pyenv-virtualenv\/bin:\/home\/user\/.pyenv\/plugins\/pyenv-update\/bin:\/home\/user\/.pyenv\/plugins\/pyenv-doctor\/bin:\/home\/user\/.cargo\/bin:\/home\/user\/.pyenv\/shims:\/home\/user\/.pyenv\/bin:\/home\/user\/bin:\/home\/user\/bin:\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin:\/usr\/games:\/usr\/local\/games:\/snap\/bin:\/snap\/bin:\/home\/user\/.local\/share\/JetBrains\/Toolbox\/scripts", "PWD": "\/home\/user\/Documents\/code\/atuin\/atuin-client", "PYENV_DIR": "\/home\/user\/Documents\/code\/atuin\/atuin-client", "PYENV_HOOK_PATH": "\/home\/user\/.pyenv\/pyenv.d:\/usr\/local\/etc\/pyenv.d:\/etc\/pyenv.d:\/usr\/lib\/pyenv\/hooks:\/home\/user\/.pyenv\/plugins\/pyenv-virtualenv\/etc\/pyenv.d", "PYENV_ROOT": "\/home\/user\/.pyenv", "PYENV_SHELL": "bash", "PYENV_VERSION": "3.12.0", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "SESSION_MANAGER": "local\/box:@\/tmp\/.ICE-unix\/2452,unix\/box:\/tmp\/.ICE-unix\/2452", "SHELL": "\/bin\/bash", "SHLVL": "1", "SSH_AGENT_LAUNCHER": "gnome-keyring", "SSH_AUTH_SOCK": "\/run\/user\/1000\/keyring\/ssh", "SSL_CERT_DIR": "\/usr\/lib\/ssl\/certs", "SSL_CERT_FILE": "\/usr\/lib\/ssl\/certs\/ca-certificates.crt", "SYSTEMD_EXEC_PID": "2470", "TERM": "xterm-256color", "TERM_PROGRAM": "WezTerm", "TERM_PROGRAM_VERSION": "20240127-113634-bbcac864", "THREAD_SUBPROCS": "1", "USER": "user", "USERNAME": "user", "WAYLAND_DISPLAY": "wayland-0", "WEZTERM_CONFIG_DIR": "\/home\/user\/.config\/wezterm", "WEZTERM_CONFIG_FILE": "\/home\/user\/.config\/wezterm\/wezterm.lua", "WEZTERM_EXECUTABLE": "\/usr\/bin\/wezterm-gui", "WEZTERM_EXECUTABLE_DIR": "\/usr\/bin", "WEZTERM_PANE": "41", "WEZTERM_UNIX_SOCKET": "\/run\/user\/1000\/wezterm\/gui-sock-196859", "XAUTHORITY": "\/run\/user\/1000\/.mutter-Xwaylandauth.T986H2", "XDG_CONFIG_DIRS": "\/etc\/xdg\/xdg-ubuntu:\/etc\/xdg", "XDG_CURRENT_DESKTOP": "ubuntu:GNOME", "XDG_DATA_DIRS": "\/usr\/share\/ubuntu:\/usr\/local\/share\/:\/usr\/share\/:\/var\/lib\/snapd\/desktop", "XDG_MENU_PREFIX": "gnome-", "XDG_RUNTIME_DIR": "\/run\/user\/1000", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "ubuntu", "XDG_SESSION_TYPE": "wayland", "XMODIFIERS": "@im=ibus", "XONSHRC": "\/etc\/xonsh\/xonshrc:\/home\/user\/.config\/xonsh\/rc.xsh:\/home\/user\/.xonshrc", "XONSHRC_DIR": "\/etc\/xonsh\/rc.d:\/home\/user\/.config\/xonsh\/rc.d", "XONSH_CAPTURE_ALWAYS": "", "XONSH_CONFIG_DIR": "\/home\/user\/.config\/xonsh", "XONSH_DATA_DIR": "\/home\/user\/.local\/share\/xonsh", "XONSH_INTERACTIVE": "1", "XONSH_LOGIN": "1", "XONSH_VERSION": "0.14.2"}
-, "locked": false, "sessionid": "82eafbf5-9f43-489a-80d2-61c7dc6ef542", "ts": [1707241286.9361255, 1707241292.3081477]
-}
-
-}
diff --git a/crates/atuin-client/tests/data/xonsh/xonsh-de16af90-9148-4461-8df3-5b5659c6420d.json b/crates/atuin-client/tests/data/xonsh/xonsh-de16af90-9148-4461-8df3-5b5659c6420d.json
deleted file mode 100644
index 72694f04..00000000
--- a/crates/atuin-client/tests/data/xonsh/xonsh-de16af90-9148-4461-8df3-5b5659c6420d.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{"locs": [ 69, 3372, 3452, 3936],
- "index": {"offsets":{"__total__":0,"cmds":[{"__total__":10,"cwd":18,"inp":64,"rtn":94,"ts":[104,124,103]},{"__total__":148,"cwd":156,"inp":202,"rtn":220,"ts":[230,250,229]},9],"env":{"ATUIN_SESSION":300,"BASH_COMPLETIONS":356,"COLORTERM":419,"DBUS_SESSION_BUS_ADDRESS":460,"DESKTOP_SESSION":515,"DISPLAY":536,"GDMSESSION":556,"GIO_LAUNCHED_DESKTOP_FILE":595,"GIO_LAUNCHED_DESKTOP_FILE_PID":690,"GJS_DEBUG_OUTPUT":720,"GJS_DEBUG_TOPICS":750,"GNOME_DESKTOP_SESSION_ID":797,"GNOME_SETUP_DISPLAY":842,"GNOME_SHELL_SESSION_MODE":876,"GTK_MODULES":901,"HOME":928,"IM_CONFIG_PHASE":962,"INVOCATION_ID":984,"JOURNAL_STREAM":1038,"LANG":1057,"LOGNAME":1083,"MANAGERPID":1104,"MOZ_ENABLE_WAYLAND":1134,"PATH":1147,"PWD":1722,"PYENV_DIR":1774,"PYENV_HOOK_PATH":1832,"PYENV_ROOT":2006,"PYENV_SHELL":2044,"PYENV_VERSION":2069,"QT_ACCESSIBILITY":2099,"QT_IM_MODULE":2120,"SESSION_MANAGER":2147,"SHELL":2237,"SHLVL":2261,"SSH_AGENT_LAUNCHER":2288,"SSH_AUTH_SOCK":2322,"SSL_CERT_DIR":2373,"SSL_CERT_FILE":2416,"SYSTEMD_EXEC_PID":2483,"TERM":2499,"TERM_PROGRAM":2533,"TERM_PROGRAM_VERSION":2568,"THREAD_SUBPROCS":2615,"USER":2628,"USERNAME":2647,"WAYLAND_DISPLAY":2673,"WEZTERM_CONFIG_DIR":2708,"WEZTERM_CONFIG_FILE":2764,"WEZTERM_EXECUTABLE":2832,"WEZTERM_EXECUTABLE_DIR":2885,"WEZTERM_PANE":2915,"WEZTERM_UNIX_SOCKET":2944,"XAUTHORITY":3005,"XDG_CONFIG_DIRS":3074,"XDG_CURRENT_DESKTOP":3134,"XDG_DATA_DIRS":3167,"XDG_MENU_PREFIX":3274,"XDG_RUNTIME_DIR":3303,"XDG_SESSION_CLASS":3345,"XDG_SESSION_DESKTOP":3376,"XDG_SESSION_TYPE":3406,"XMODIFIERS":3431,"XONSHRC":3454,"XONSHRC_DIR":3552,"XONSH_CAPTURE_ALWAYS":3632,"XONSH_CONFIG_DIR":3656,"XONSH_DATA_DIR":3705,"XONSH_INTERACTIVE":3763,"XONSH_LOGIN":3783,"XONSH_VERSION":3805,"__total__":282},"locked":3827,"sessionid":3847,"ts":[3894,3914,3893]},"sizes":{"__total__":3936,"cmds":[{"__total__":136,"cwd":37,"inp":21,"rtn":1,"ts":[18,18,41]},{"__total__":123,"cwd":37,"inp":9,"rtn":1,"ts":[18,17,40]},264],"env":{"ATUIN_SESSION":34,"BASH_COMPLETIONS":48,"COLORTERM":11,"DBUS_SESSION_BUS_ADDRESS":34,"DESKTOP_SESSION":8,"DISPLAY":4,"GDMSESSION":8,"GIO_LAUNCHED_DESKTOP_FILE":60,"GIO_LAUNCHED_DESKTOP_FILE_PID":8,"GJS_DEBUG_OUTPUT":8,"GJS_DEBUG_TOPICS":17,"GNOME_DESKTOP_SESSION_ID":20,"GNOME_SETUP_DISPLAY":4,"GNOME_SHELL_SESSION_MODE":8,"GTK_MODULES":17,"HOME":13,"IM_CONFIG_PHASE":3,"INVOCATION_ID":34,"JOURNAL_STREAM":9,"LANG":13,"LOGNAME":5,"MANAGERPID":6,"MOZ_ENABLE_WAYLAND":3,"PATH":566,"PWD":37,"PYENV_DIR":37,"PYENV_HOOK_PATH":158,"PYENV_ROOT":21,"PYENV_SHELL":6,"PYENV_VERSION":8,"QT_ACCESSIBILITY":3,"QT_IM_MODULE":6,"SESSION_MANAGER":79,"SHELL":13,"SHLVL":3,"SSH_AGENT_LAUNCHER":15,"SSH_AUTH_SOCK":33,"SSL_CERT_DIR":24,"SSL_CERT_FILE":45,"SYSTEMD_EXEC_PID":6,"TERM":16,"TERM_PROGRAM":9,"TERM_PROGRAM_VERSION":26,"THREAD_SUBPROCS":3,"USER":5,"USERNAME":5,"WAYLAND_DISPLAY":11,"WEZTERM_CONFIG_DIR":31,"WEZTERM_CONFIG_FILE":44,"WEZTERM_EXECUTABLE":25,"WEZTERM_EXECUTABLE_DIR":12,"WEZTERM_PANE":4,"WEZTERM_UNIX_SOCKET":45,"XAUTHORITY":48,"XDG_CONFIG_DIRS":35,"XDG_CURRENT_DESKTOP":14,"XDG_DATA_DIRS":86,"XDG_MENU_PREFIX":8,"XDG_RUNTIME_DIR":19,"XDG_SESSION_CLASS":6,"XDG_SESSION_DESKTOP":8,"XDG_SESSION_TYPE":9,"XMODIFIERS":10,"XONSHRC":81,"XONSHRC_DIR":54,"XONSH_CAPTURE_ALWAYS":2,"XONSH_CONFIG_DIR":29,"XONSH_DATA_DIR":35,"XONSH_INTERACTIVE":3,"XONSH_LOGIN":3,"XONSH_VERSION":8,"__total__":3533},"locked":5,"sessionid":38,"ts":[18,18,41]}},
- "data": {"cmds": [{"cwd": "\/home\/user\/Documents\/code\/atuin", "inp": "echo hello world!\n", "rtn": 0, "ts": [1707193079.4782722, 1707193079.4829233]
-}
-, {"cwd": "\/home\/user\/Documents\/code\/atuin", "inp": "ls -l\n", "rtn": 0, "ts": [1707193081.7063284, 1707193081.727617]
-}
-]
-, "env": {"ATUIN_SESSION": "018d7ca2e953742e9826012f30115040", "BASH_COMPLETIONS": "\/usr\/share\/bash-completion\/bash_completion", "COLORTERM": "truecolor", "DBUS_SESSION_BUS_ADDRESS": "unix:path=\/run\/user\/1000\/bus", "DESKTOP_SESSION": "ubuntu", "DISPLAY": ":0", "GDMSESSION": "ubuntu", "GIO_LAUNCHED_DESKTOP_FILE": "\/usr\/share\/applications\/org.wezfurlong.wezterm.desktop", "GIO_LAUNCHED_DESKTOP_FILE_PID": "196859", "GJS_DEBUG_OUTPUT": "stderr", "GJS_DEBUG_TOPICS": "JS ERROR;JS LOG", "GNOME_DESKTOP_SESSION_ID": "this-is-deprecated", "GNOME_SETUP_DISPLAY": ":1", "GNOME_SHELL_SESSION_MODE": "ubuntu", "GTK_MODULES": "gail:atk-bridge", "HOME": "\/home\/user", "IM_CONFIG_PHASE": "1", "INVOCATION_ID": "4f121e7ad56c41a6b84aa3cbe1ad61fa", "JOURNAL_STREAM": "8:37187", "LANG": "en_US.UTF-8", "LOGNAME": "user", "MANAGERPID": "2118", "MOZ_ENABLE_WAYLAND": "1", "PATH": "\/home\/user\/.pyenv\/versions\/3.12.0\/bin:\/home\/user\/.pyenv\/libexec:\/home\/user\/.pyenv\/plugins\/python-build\/bin:\/home\/user\/.pyenv\/plugins\/pyenv-virtualenv\/bin:\/home\/user\/.pyenv\/plugins\/pyenv-update\/bin:\/home\/user\/.pyenv\/plugins\/pyenv-doctor\/bin:\/home\/user\/.cargo\/bin:\/home\/user\/.pyenv\/shims:\/home\/user\/.pyenv\/bin:\/home\/user\/bin:\/home\/user\/bin:\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin:\/usr\/games:\/usr\/local\/games:\/snap\/bin:\/snap\/bin:\/home\/user\/.local\/share\/JetBrains\/Toolbox\/scripts", "PWD": "\/home\/user\/Documents\/code\/atuin", "PYENV_DIR": "\/home\/user\/Documents\/code\/atuin", "PYENV_HOOK_PATH": "\/home\/user\/.pyenv\/pyenv.d:\/usr\/local\/etc\/pyenv.d:\/etc\/pyenv.d:\/usr\/lib\/pyenv\/hooks:\/home\/user\/.pyenv\/plugins\/pyenv-virtualenv\/etc\/pyenv.d", "PYENV_ROOT": "\/home\/user\/.pyenv", "PYENV_SHELL": "bash", "PYENV_VERSION": "3.12.0", "QT_ACCESSIBILITY": "1", "QT_IM_MODULE": "ibus", "SESSION_MANAGER": "local\/box:@\/tmp\/.ICE-unix\/2452,unix\/box:\/tmp\/.ICE-unix\/2452", "SHELL": "\/bin\/bash", "SHLVL": "1", "SSH_AGENT_LAUNCHER": "gnome-keyring", "SSH_AUTH_SOCK": "\/run\/user\/1000\/keyring\/ssh", "SSL_CERT_DIR": "\/usr\/lib\/ssl\/certs", "SSL_CERT_FILE": "\/usr\/lib\/ssl\/certs\/ca-certificates.crt", "SYSTEMD_EXEC_PID": "2470", "TERM": "xterm-256color", "TERM_PROGRAM": "WezTerm", "TERM_PROGRAM_VERSION": "20240127-113634-bbcac864", "THREAD_SUBPROCS": "1", "USER": "user", "USERNAME": "user", "WAYLAND_DISPLAY": "wayland-0", "WEZTERM_CONFIG_DIR": "\/home\/user\/.config\/wezterm", "WEZTERM_CONFIG_FILE": "\/home\/user\/.config\/wezterm\/wezterm.lua", "WEZTERM_EXECUTABLE": "\/usr\/bin\/wezterm-gui", "WEZTERM_EXECUTABLE_DIR": "\/usr\/bin", "WEZTERM_PANE": "38", "WEZTERM_UNIX_SOCKET": "\/run\/user\/1000\/wezterm\/gui-sock-196859", "XAUTHORITY": "\/run\/user\/1000\/.mutter-Xwaylandauth.T986H2", "XDG_CONFIG_DIRS": "\/etc\/xdg\/xdg-ubuntu:\/etc\/xdg", "XDG_CURRENT_DESKTOP": "ubuntu:GNOME", "XDG_DATA_DIRS": "\/usr\/share\/ubuntu:\/usr\/local\/share\/:\/usr\/share\/:\/var\/lib\/snapd\/desktop", "XDG_MENU_PREFIX": "gnome-", "XDG_RUNTIME_DIR": "\/run\/user\/1000", "XDG_SESSION_CLASS": "user", "XDG_SESSION_DESKTOP": "ubuntu", "XDG_SESSION_TYPE": "wayland", "XMODIFIERS": "@im=ibus", "XONSHRC": "\/etc\/xonsh\/xonshrc:\/home\/user\/.config\/xonsh\/rc.xsh:\/home\/user\/.xonshrc", "XONSHRC_DIR": "\/etc\/xonsh\/rc.d:\/home\/user\/.config\/xonsh\/rc.d", "XONSH_CAPTURE_ALWAYS": "", "XONSH_CONFIG_DIR": "\/home\/user\/.config\/xonsh", "XONSH_DATA_DIR": "\/home\/user\/.local\/share\/xonsh", "XONSH_INTERACTIVE": "1", "XONSH_LOGIN": "1", "XONSH_VERSION": "0.14.2"}
-, "locked": false, "sessionid": "de16af90-9148-4461-8df3-5b5659c6420d", "ts": [1707193067.8615997, 1707193089.2513068]
-}
-
-}
diff --git a/crates/atuin-common/Cargo.toml b/crates/atuin-common/Cargo.toml
deleted file mode 100644
index 811b0bdb..00000000
--- a/crates/atuin-common/Cargo.toml
+++ /dev/null
@@ -1,31 +0,0 @@
-[package]
-name = "atuin-common"
-edition = "2024"
-description = "common library for atuin"
-
-rust-version = { workspace = true }
-version = { workspace = true }
-authors = { workspace = true }
-license = { workspace = true }
-homepage = { workspace = true }
-repository = { workspace = true }
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-time = { workspace = true }
-serde = { workspace = true }
-uuid = { workspace = true }
-typed-builder = { workspace = true }
-eyre = { workspace = true }
-sqlx = { workspace = true }
-semver = { workspace = true }
-thiserror = { workspace = true }
-directories = { workspace = true }
-sysinfo = "0.30.7"
-base64 = { workspace = true }
-getrandom = "0.2"
-rustls = { workspace = true }
-
-[dev-dependencies]
-pretty_assertions = { workspace = true }
diff --git a/crates/atuin-daemon/Cargo.toml b/crates/atuin-daemon/Cargo.toml
deleted file mode 100644
index e767d3c9..00000000
--- a/crates/atuin-daemon/Cargo.toml
+++ /dev/null
@@ -1,52 +0,0 @@
-[package]
-name = "atuin-daemon"
-edition = "2024"
-version = { workspace = true }
-description = "The daemon crate for Atuin"
-
-authors.workspace = true
-rust-version.workspace = true
-license.workspace = true
-homepage.workspace = true
-repository.workspace = true
-readme.workspace = true
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-atuin-client = { path = "../atuin-client", version = "18.16.1" }
-atuin-common = { path = "../atuin-common", version = "18.16.1" }
-atuin-history = { path = "../atuin-history", version = "18.16.1" }
-
-time = { workspace = true }
-uuid = { workspace = true }
-tokio = { workspace = true }
-tower = { workspace = true }
-eyre = { workspace = true }
-tracing = { workspace = true }
-tracing-subscriber = { workspace = true }
-
-dashmap = "6.1.0"
-lasso = { version = "0.7", features = ["multi-threaded"] }
-tonic-types = "0.14"
-tonic = "0.14"
-tonic-prost = "0.14"
-prost = "0.14"
-prost-types = "0.14"
-tokio-stream = { version = "0.1.14", features = ["net"] }
-hyper-util = "0.1"
-
-rand.workspace = true
-atuin-nucleo = { workspace = true }
-
-
-[target.'cfg(target_os = "linux")'.dependencies]
-listenfd = "1.0.1"
-
-[dev-dependencies]
-tempfile = { workspace = true }
-
-[build-dependencies]
-protox = "0.9"
-tonic-build = "0.14"
-tonic-prost-build = "0.14"
diff --git a/crates/atuin-daemon/build.rs b/crates/atuin-daemon/build.rs
deleted file mode 100644
index 7808a07b..00000000
--- a/crates/atuin-daemon/build.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use std::{env, fs, path::PathBuf};
-
-use protox::prost::Message;
-
-fn main() -> std::io::Result<()> {
- let proto_paths = [
- "proto/history.proto",
- "proto/search.proto",
- "proto/control.proto",
- "proto/semantic.proto",
- ];
- let proto_include_dirs = ["proto"];
-
- let file_descriptors = protox::compile(proto_paths, proto_include_dirs).unwrap();
-
- let file_descriptor_path = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR not set"))
- .join("file_descriptor_set.bin");
- fs::write(&file_descriptor_path, file_descriptors.encode_to_vec()).unwrap();
-
- tonic_prost_build::configure()
- .build_server(true)
- .file_descriptor_set_path(&file_descriptor_path)
- .skip_protoc_run()
- .compile_protos(&proto_paths, &proto_include_dirs)
-}
diff --git a/crates/atuin-daemon/tests/lifecycle.rs b/crates/atuin-daemon/tests/lifecycle.rs
deleted file mode 100644
index 4a91e5cb..00000000
--- a/crates/atuin-daemon/tests/lifecycle.rs
+++ /dev/null
@@ -1,222 +0,0 @@
-//! Integration tests for the daemon server lifecycle.
-//!
-//! Each test spins up a real gRPC server on a temporary unix socket,
-//! connects a client, and exercises the daemon RPCs.
-
-#[cfg(unix)]
-mod unix {
- use std::time::Duration;
-
- use atuin_client::database::Sqlite;
- use atuin_client::record::sqlite_store::SqliteStore;
- use atuin_client::settings::{Settings, init_meta_config_for_testing};
- use atuin_daemon::client::HistoryClient;
- use atuin_daemon::components::HistoryComponent;
- use atuin_daemon::{Daemon, DaemonHandle};
- use tempfile::TempDir;
- use tokio::net::UnixListener;
- use tokio_stream::wrappers::UnixListenerStream;
- use tonic::transport::Server;
-
- /// Spins up a daemon server on a temp socket and returns a connected client,
- /// the daemon handle (for shutdown), and the temp dir (must be held to keep paths alive).
- async fn start_test_daemon() -> (HistoryClient, DaemonHandle, TempDir) {
- let tmp = tempfile::tempdir().unwrap();
-
- let db_path = tmp.path().join("history.db");
- let record_path = tmp.path().join("records.db");
- let key_path = tmp.path().join("key");
- let socket_path = tmp.path().join("test.sock");
- let meta_path = tmp.path().join("meta.db");
-
- // Initialize the meta store config for testing (required for Settings::host_id())
- init_meta_config_for_testing(meta_path.to_str().unwrap(), 5.0);
-
- // Build settings with test paths
- let settings: Settings = Settings::builder()
- .expect("could not build settings builder")
- .set_override("db_path", db_path.to_str().unwrap())
- .expect("failed to set db_path")
- .set_override("record_store_path", record_path.to_str().unwrap())
- .expect("failed to set record_store_path")
- .set_override("key_path", key_path.to_str().unwrap())
- .expect("failed to set key_path")
- .set_override("daemon.socket_path", socket_path.to_str().unwrap())
- .expect("failed to set socket_path")
- .set_override("meta.db_path", meta_path.to_str().unwrap())
- .expect("failed to set meta.db_path")
- .build()
- .expect("could not build settings")
- .try_deserialize()
- .expect("could not deserialize settings");
-
- // Create databases
- let history_db = Sqlite::new(&db_path, 5.0).await.unwrap();
- let store = SqliteStore::new(&record_path, 5.0).await.unwrap();
-
- // Create the history component and get its gRPC service
- let history_component = HistoryComponent::new();
- let history_service = history_component.grpc_service();
-
- // Build and start the daemon
- let mut daemon = Daemon::builder(settings)
- .store(store)
- .history_db(history_db)
- .component(history_component)
- .build()
- .await
- .unwrap();
-
- let handle = daemon.handle();
-
- // Start components (this initializes the history component with the handle)
- daemon.start_components().await.unwrap();
-
- // Start the gRPC server
- let uds = UnixListener::bind(&socket_path).unwrap();
- let stream = UnixListenerStream::new(uds);
-
- let server_handle = handle.clone();
- tokio::spawn(async move {
- let mut rx = server_handle.subscribe();
- Server::builder()
- .add_service(history_service)
- .serve_with_incoming_shutdown(stream, async move {
- loop {
- match rx.recv().await {
- Ok(atuin_daemon::DaemonEvent::ShutdownRequested) => break,
- Ok(_) => continue,
- Err(_) => break,
- }
- }
- })
- .await
- .unwrap();
- });
-
- // Spawn the daemon event loop in the background
- tokio::spawn(async move {
- daemon.run_event_loop().await.unwrap();
- });
-
- // Give the server a moment to bind.
- tokio::time::sleep(Duration::from_millis(50)).await;
-
- let client = HistoryClient::new(socket_path.to_string_lossy().to_string())
- .await
- .unwrap();
-
- (client, handle, tmp)
- }
-
- #[tokio::test]
- async fn test_status() {
- let (mut client, _handle, _tmp) = start_test_daemon().await;
-
- let status = client.status().await.unwrap();
- assert!(status.healthy);
- assert_eq!(status.version, env!("CARGO_PKG_VERSION"));
- assert_eq!(status.protocol, 1);
- assert!(status.pid > 0);
- }
-
- #[tokio::test]
- async fn test_start_end_history() {
- use atuin_client::history::History;
-
- let (mut client, _handle, _tmp) = start_test_daemon().await;
-
- let history = History::daemon()
- .timestamp(time::OffsetDateTime::now_utc())
- .command("echo hello".to_string())
- .cwd("/tmp".to_string())
- .session("test-session".to_string())
- .hostname("test-host".to_string())
- .build()
- .into();
-
- let start_reply = client.start_history(history).await.unwrap();
- assert!(!start_reply.id.is_empty());
-
- let end_reply = client
- .end_history(start_reply.id, 1_000_000, 0)
- .await
- .unwrap();
- assert!(!end_reply.id.is_empty());
- }
-
- #[tokio::test]
- async fn test_tail_history_streams_started_and_ended_events() {
- use atuin_client::history::History;
- use atuin_daemon::history::HistoryEventKind;
-
- let (mut client, _handle, _tmp) = start_test_daemon().await;
- let mut stream = client.tail_history().await.unwrap();
-
- let history = History::daemon()
- .timestamp(time::OffsetDateTime::now_utc())
- .command("git status".to_string())
- .cwd("/tmp/repo".to_string())
- .session("tail-session".to_string())
- .hostname("test-host:ellie".to_string())
- .author("claude".to_string())
- .intent("inspect repository state".to_string())
- .build()
- .into();
-
- let start_reply = client.start_history(history).await.unwrap();
-
- let started = stream.message().await.unwrap().unwrap();
- assert_eq!(
- HistoryEventKind::try_from(started.kind).unwrap(),
- HistoryEventKind::Started
- );
- let started_history = started.history.unwrap();
- assert_eq!(started_history.id, start_reply.id);
- assert_eq!(started_history.command, "git status");
- assert_eq!(started_history.cwd, "/tmp/repo");
- assert_eq!(started_history.hostname, "test-host:ellie");
- assert_eq!(started_history.author, "claude");
- assert_eq!(started_history.intent, "inspect repository state");
-
- client
- .end_history(start_reply.id.clone(), 1_000_000, 0)
- .await
- .unwrap();
-
- let ended = stream.message().await.unwrap().unwrap();
- assert_eq!(
- HistoryEventKind::try_from(ended.kind).unwrap(),
- HistoryEventKind::Ended
- );
- let ended_history = ended.history.unwrap();
- assert_eq!(ended_history.id, start_reply.id);
- assert_eq!(ended_history.exit, 0);
- assert_eq!(ended_history.duration, 1_000_000);
- }
-
- #[tokio::test]
- async fn test_end_unknown_history_fails() {
- let (mut client, _handle, _tmp) = start_test_daemon().await;
-
- let result = client
- .end_history("nonexistent-id".to_string(), 1000, 0)
- .await;
- assert!(result.is_err());
- }
-
- #[tokio::test]
- async fn test_shutdown() {
- let (mut client, _handle, _tmp) = start_test_daemon().await;
-
- let accepted = client.shutdown().await.unwrap();
- assert!(accepted);
-
- // Give server time to shut down.
- tokio::time::sleep(Duration::from_millis(100)).await;
-
- // Subsequent calls should fail since the server is gone.
- let result = client.status().await;
- assert!(result.is_err());
- }
-}
diff --git a/crates/atuin-history/Cargo.toml b/crates/atuin-history/Cargo.toml
deleted file mode 100644
index 50831a0b..00000000
--- a/crates/atuin-history/Cargo.toml
+++ /dev/null
@@ -1,30 +0,0 @@
-[package]
-name = "atuin-history"
-description = "The history crate for Atuin"
-edition = "2024"
-version = { workspace = true }
-
-authors.workspace = true
-rust-version.workspace = true
-license.workspace = true
-homepage.workspace = true
-repository.workspace = true
-readme.workspace = true
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-atuin-client = { path = "../atuin-client", version = "18.16.1" }
-
-time = { workspace = true }
-serde = { workspace = true }
-crossterm = { workspace = true, features = ["use-dev-tty"] }
-unicode-segmentation = "1.11.0"
-
-[dev-dependencies]
-divan = "0.1.14"
-rand = { workspace = true }
-
-[[bench]]
-name = "smart_sort"
-harness = false
diff --git a/crates/atuin-history/benches/smart_sort.rs b/crates/atuin-history/benches/smart_sort.rs
deleted file mode 100644
index a78064de..00000000
--- a/crates/atuin-history/benches/smart_sort.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-use atuin_client::history::History;
-use atuin_history::sort::sort;
-
-use rand::Rng;
-
-fn main() {
- // Run registered benchmarks.
- divan::main();
-}
-
-// Smart sort usually runs on 200 entries, test on a few sizes
-#[divan::bench(args=[100, 200, 400, 800, 1600, 10000])]
-fn smart_sort(lines: usize) {
- // benchmark a few different sizes of "history"
- // first we need to generate some history. This will use a whole bunch of memory, sorry
- let mut rng = rand::thread_rng();
- let now = time::OffsetDateTime::now_utc().unix_timestamp();
-
- let possible_commands = ["echo", "ls", "cd", "grep", "atuin", "curl"];
- let mut commands = Vec::<History>::with_capacity(lines);
-
- for _ in 0..lines {
- let command = possible_commands[rng.gen_range(0..possible_commands.len())];
-
- let command = History::import()
- .command(command)
- .timestamp(time::OffsetDateTime::from_unix_timestamp(rng.gen_range(0..now)).unwrap())
- .build()
- .into();
-
- commands.push(command);
- }
-
- let _ = sort("curl", commands);
-}
diff --git a/crates/atuin-pty-proxy/Cargo.toml b/crates/atuin-pty-proxy/Cargo.toml
deleted file mode 100644
index baacf776..00000000
--- a/crates/atuin-pty-proxy/Cargo.toml
+++ /dev/null
@@ -1,21 +0,0 @@
-[package]
-name = "atuin-pty-proxy"
-edition = "2024"
-description = "a PTY proxy for atuin"
-
-version = { workspace = true }
-authors = { workspace = true }
-rust-version = { workspace = true }
-license = { workspace = true }
-homepage = { workspace = true }
-repository = { workspace = true }
-
-[dependencies]
-clap = { workspace = true }
-
-[target.'cfg(unix)'.dependencies]
-crossterm = { workspace = true }
-eyre = { workspace = true }
-portable-pty = "0.9"
-signal-hook = "0.3"
-vt100 = { workspace = true }
diff --git a/crates/atuin-pty-proxy/src/lib.rs b/crates/atuin-pty-proxy/src/lib.rs
deleted file mode 100644
index d1571079..00000000
--- a/crates/atuin-pty-proxy/src/lib.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-#[cfg(unix)]
-mod capture;
-#[cfg(unix)]
-mod debug;
-#[cfg(unix)]
-mod osc133;
-#[cfg(unix)]
-mod pty_proxy;
-#[cfg(unix)]
-mod runtime;
-#[cfg(unix)]
-mod screen;
-
-#[cfg(unix)]
-pub use capture::{CommandCapture, CommandCaptureSink};
-#[cfg(unix)]
-pub use pty_proxy::PtyProxy;
-
-#[cfg(not(unix))]
-#[expect(dead_code)]
-mod unsupported {
- use clap::{Args, Subcommand};
-
- #[derive(Args, Debug)]
- pub struct PtyProxy {
- /// Highlight OSC 133 prompt, input, output, and exit-code regions
- #[arg(long)]
- debug_osc133: bool,
-
- #[command(subcommand)]
- cmd: Option<Cmd>,
- }
-
- #[derive(Subcommand, Debug)]
- enum Cmd {
- /// Print shell code to initialize atuin pty-proxy on shell startup
- Init(Init),
- }
-
- #[derive(Args, Debug)]
- struct Init {
- /// Shell to generate init for. If omitted, attempt auto-detection
- shell: Option<String>,
- }
-}
-
-#[cfg(not(unix))]
-pub use unsupported::PtyProxy;
diff --git a/crates/atuin-server-database/Cargo.toml b/crates/atuin-server-database/Cargo.toml
deleted file mode 100644
index 52ccbf97..00000000
--- a/crates/atuin-server-database/Cargo.toml
+++ /dev/null
@@ -1,21 +0,0 @@
-[package]
-name = "atuin-server-database"
-edition = "2024"
-description = "server database library for atuin"
-
-version = { workspace = true }
-authors = { workspace = true }
-license = { workspace = true }
-homepage = { workspace = true }
-repository = { workspace = true }
-
-[dependencies]
-atuin-common = { path = "../atuin-common", version = "18.16.1" }
-
-async-trait = { workspace = true }
-eyre = { workspace = true }
-serde = { workspace = true }
-sqlx = { workspace = true }
-time = { workspace = true }
-tracing = { workspace = true }
-url = "2.5.2"
diff --git a/crates/atuin-server-postgres/Cargo.toml b/crates/atuin-server-postgres/Cargo.toml
deleted file mode 100644
index ea19899e..00000000
--- a/crates/atuin-server-postgres/Cargo.toml
+++ /dev/null
@@ -1,25 +0,0 @@
-[package]
-name = "atuin-server-postgres"
-edition = "2024"
-description = "server postgres database library for atuin"
-
-version = { workspace = true }
-authors = { workspace = true }
-license = { workspace = true }
-homepage = { workspace = true }
-repository = { workspace = true }
-
-[dependencies]
-atuin-common = { path = "../atuin-common", version = "18.16.1" }
-atuin-server-database = { path = "../atuin-server-database", version = "18.16.1" }
-
-eyre = { workspace = true }
-tracing = { workspace = true }
-time = { workspace = true }
-serde = { workspace = true }
-sqlx = { workspace = true }
-async-trait = { workspace = true }
-uuid = { workspace = true }
-metrics = "0.24"
-futures-util = "0.3"
-rand.workspace = true \ No newline at end of file
diff --git a/crates/atuin-server-postgres/build.rs b/crates/atuin-server-postgres/build.rs
deleted file mode 100644
index d5068697..00000000
--- a/crates/atuin-server-postgres/build.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-// generated by `sqlx migrate build-script`
-fn main() {
- // trigger recompilation when a new migration is added
- println!("cargo:rerun-if-changed=migrations");
-}
diff --git a/crates/atuin-server-postgres/migrations/20210425153745_create_history.sql b/crates/atuin-server-postgres/migrations/20210425153745_create_history.sql
deleted file mode 100644
index 2c2d17b0..00000000
--- a/crates/atuin-server-postgres/migrations/20210425153745_create_history.sql
+++ /dev/null
@@ -1,11 +0,0 @@
-create table history (
- id bigserial primary key,
- client_id text not null unique, -- the client-generated ID
- user_id bigserial not null, -- allow multiple users
- hostname text not null, -- a unique identifier from the client (can be hashed, random, whatever)
- timestamp timestamp not null, -- one of the few non-encrypted metadatas
-
- data varchar(8192) not null, -- store the actual history data, encrypted. I don't wanna know!
-
- created_at timestamp not null default current_timestamp
-);
diff --git a/crates/atuin-server-postgres/migrations/20210425153757_create_users.sql b/crates/atuin-server-postgres/migrations/20210425153757_create_users.sql
deleted file mode 100644
index a25dcced..00000000
--- a/crates/atuin-server-postgres/migrations/20210425153757_create_users.sql
+++ /dev/null
@@ -1,10 +0,0 @@
-create table users (
- id bigserial primary key, -- also store our own ID
- username varchar(32) not null unique, -- being able to contact users is useful
- email varchar(128) not null unique, -- being able to contact users is useful
- password varchar(128) not null unique
-);
-
--- the prior index is case sensitive :(
-CREATE UNIQUE INDEX email_unique_idx on users (LOWER(email));
-CREATE UNIQUE INDEX username_unique_idx on users (LOWER(username));
diff --git a/crates/atuin-server-postgres/migrations/20210425153800_create_sessions.sql b/crates/atuin-server-postgres/migrations/20210425153800_create_sessions.sql
deleted file mode 100644
index c2fb6559..00000000
--- a/crates/atuin-server-postgres/migrations/20210425153800_create_sessions.sql
+++ /dev/null
@@ -1,6 +0,0 @@
--- Add migration script here
-create table sessions (
- id bigserial primary key,
- user_id bigserial,
- token varchar(128) unique not null
-);
diff --git a/crates/atuin-server-postgres/migrations/20220419082412_add_count_trigger.sql b/crates/atuin-server-postgres/migrations/20220419082412_add_count_trigger.sql
deleted file mode 100644
index dd1afa88..00000000
--- a/crates/atuin-server-postgres/migrations/20220419082412_add_count_trigger.sql
+++ /dev/null
@@ -1,51 +0,0 @@
--- Prior to this, the count endpoint was super naive and just ran COUNT(1).
--- This is slow asf. Now that we have an amount of actual traffic,
--- stop doing that!
--- This basically maintains a count, so we can read ONE row, instead of ALL the
--- rows. Much better.
--- Future optimisation could use some sort of cache so we don't even need to hit
--- postgres at all.
-
-create table total_history_count_user(
- id bigserial primary key,
- user_id bigserial,
- total integer -- try and avoid using keywords - hence total, not count
-);
-
-create or replace function user_history_count()
-returns trigger as
-$func$
-begin
- if (TG_OP='INSERT') then
- update total_history_count_user set total = total + 1 where user_id = new.user_id;
-
- if not found then
- insert into total_history_count_user(user_id, total)
- values (
- new.user_id,
- (select count(1) from history where user_id = new.user_id)
- );
- end if;
-
- elsif (TG_OP='DELETE') then
- update total_history_count_user set total = total - 1 where user_id = new.user_id;
-
- if not found then
- insert into total_history_count_user(user_id, total)
- values (
- new.user_id,
- (select count(1) from history where user_id = new.user_id)
- );
- end if;
- end if;
-
- return NEW; -- this is actually ignored for an after trigger, but oh well
-end;
-$func$
-language plpgsql volatile -- pldfplplpflh
-cost 100; -- default value
-
-create trigger tg_user_history_count
- after insert or delete on history
- for each row
- execute procedure user_history_count();
diff --git a/crates/atuin-server-postgres/migrations/20220421073605_fix_count_trigger_delete.sql b/crates/atuin-server-postgres/migrations/20220421073605_fix_count_trigger_delete.sql
deleted file mode 100644
index 6198f300..00000000
--- a/crates/atuin-server-postgres/migrations/20220421073605_fix_count_trigger_delete.sql
+++ /dev/null
@@ -1,35 +0,0 @@
--- the old version of this function used NEW in the delete part when it should
--- use OLD
-
-create or replace function user_history_count()
-returns trigger as
-$func$
-begin
- if (TG_OP='INSERT') then
- update total_history_count_user set total = total + 1 where user_id = new.user_id;
-
- if not found then
- insert into total_history_count_user(user_id, total)
- values (
- new.user_id,
- (select count(1) from history where user_id = new.user_id)
- );
- end if;
-
- elsif (TG_OP='DELETE') then
- update total_history_count_user set total = total - 1 where user_id = old.user_id;
-
- if not found then
- insert into total_history_count_user(user_id, total)
- values (
- old.user_id,
- (select count(1) from history where user_id = old.user_id)
- );
- end if;
- end if;
-
- return NEW; -- this is actually ignored for an after trigger, but oh well
-end;
-$func$
-language plpgsql volatile -- pldfplplpflh
-cost 100; -- default value
diff --git a/crates/atuin-server-postgres/migrations/20220421174016_larger-commands.sql b/crates/atuin-server-postgres/migrations/20220421174016_larger-commands.sql
deleted file mode 100644
index 0ac43433..00000000
--- a/crates/atuin-server-postgres/migrations/20220421174016_larger-commands.sql
+++ /dev/null
@@ -1,3 +0,0 @@
--- Make it 4x larger. Most commands are less than this, but as it's base64
--- SOME are more than 8192. Should be enough for now.
-ALTER TABLE history ALTER COLUMN data TYPE varchar(32768);
diff --git a/crates/atuin-server-postgres/migrations/20220426172813_user-created-at.sql b/crates/atuin-server-postgres/migrations/20220426172813_user-created-at.sql
deleted file mode 100644
index a9138194..00000000
--- a/crates/atuin-server-postgres/migrations/20220426172813_user-created-at.sql
+++ /dev/null
@@ -1 +0,0 @@
-alter table users add column created_at timestamp not null default now();
diff --git a/crates/atuin-server-postgres/migrations/20220505082442_create-events.sql b/crates/atuin-server-postgres/migrations/20220505082442_create-events.sql
deleted file mode 100644
index 57e16ec7..00000000
--- a/crates/atuin-server-postgres/migrations/20220505082442_create-events.sql
+++ /dev/null
@@ -1,14 +0,0 @@
-create type event_type as enum ('create', 'delete');
-
-create table events (
- id bigserial primary key,
- client_id text not null unique, -- the client-generated ID
- user_id bigserial not null, -- allow multiple users
- hostname text not null, -- a unique identifier from the client (can be hashed, random, whatever)
- timestamp timestamp not null, -- one of the few non-encrypted metadatas
-
- event_type event_type,
- data text not null, -- store the actual history data, encrypted. I don't wanna know!
-
- created_at timestamp not null default current_timestamp
-);
diff --git a/crates/atuin-server-postgres/migrations/20220610074049_history-length.sql b/crates/atuin-server-postgres/migrations/20220610074049_history-length.sql
deleted file mode 100644
index b1c23016..00000000
--- a/crates/atuin-server-postgres/migrations/20220610074049_history-length.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Add migration script here
-alter table history alter column data type text;
diff --git a/crates/atuin-server-postgres/migrations/20230315220537_drop-events.sql b/crates/atuin-server-postgres/migrations/20230315220537_drop-events.sql
deleted file mode 100644
index fe3cae17..00000000
--- a/crates/atuin-server-postgres/migrations/20230315220537_drop-events.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Add migration script here
-drop table events;
diff --git a/crates/atuin-server-postgres/migrations/20230315224203_create-deleted.sql b/crates/atuin-server-postgres/migrations/20230315224203_create-deleted.sql
deleted file mode 100644
index 9a9e6263..00000000
--- a/crates/atuin-server-postgres/migrations/20230315224203_create-deleted.sql
+++ /dev/null
@@ -1,5 +0,0 @@
--- Add migration script here
-alter table history add column if not exists deleted_at timestamp;
-
--- queries will all be selecting the ids of history for a user, that has been deleted
-create index if not exists history_deleted_index on history(client_id, user_id, deleted_at);
diff --git a/crates/atuin-server-postgres/migrations/20230515221038_trigger-delete-only.sql b/crates/atuin-server-postgres/migrations/20230515221038_trigger-delete-only.sql
deleted file mode 100644
index 3d0bba52..00000000
--- a/crates/atuin-server-postgres/migrations/20230515221038_trigger-delete-only.sql
+++ /dev/null
@@ -1,30 +0,0 @@
--- We do not need to run the trigger on deletes, as the only time we are deleting history is when the user
--- has already been deleted
--- This actually slows down deleting all the history a good bit!
-
-create or replace function user_history_count()
-returns trigger as
-$func$
-begin
- if (TG_OP='INSERT') then
- update total_history_count_user set total = total + 1 where user_id = new.user_id;
-
- if not found then
- insert into total_history_count_user(user_id, total)
- values (
- new.user_id,
- (select count(1) from history where user_id = new.user_id)
- );
- end if;
- end if;
-
- return NEW; -- this is actually ignored for an after trigger, but oh well
-end;
-$func$
-language plpgsql volatile -- pldfplplpflh
-cost 100; -- default value
-
-create or replace trigger tg_user_history_count
- after insert on history
- for each row
- execute procedure user_history_count();
diff --git a/crates/atuin-server-postgres/migrations/20230623070418_records.sql b/crates/atuin-server-postgres/migrations/20230623070418_records.sql
deleted file mode 100644
index 22437595..00000000
--- a/crates/atuin-server-postgres/migrations/20230623070418_records.sql
+++ /dev/null
@@ -1,15 +0,0 @@
--- Add migration script here
-create table records (
- id uuid primary key, -- remember to use uuidv7 for happy indices <3
- client_id uuid not null, -- I am too uncomfortable with the idea of a client-generated primary key
- host uuid not null, -- a unique identifier for the host
- parent uuid default null, -- the ID of the parent record, bearing in mind this is a linked list
- timestamp bigint not null, -- not a timestamp type, as those do not have nanosecond precision
- version text not null,
- tag text not null, -- what is this? history, kv, whatever. Remember clients get a log per tag per host
- data text not null, -- store the actual history data, encrypted. I don't wanna know!
- cek text not null,
-
- user_id bigint not null, -- allow multiple users
- created_at timestamp not null default current_timestamp
-);
diff --git a/crates/atuin-server-postgres/migrations/20231202170508_create-store.sql b/crates/atuin-server-postgres/migrations/20231202170508_create-store.sql
deleted file mode 100644
index ffb57966..00000000
--- a/crates/atuin-server-postgres/migrations/20231202170508_create-store.sql
+++ /dev/null
@@ -1,15 +0,0 @@
--- Add migration script here
-create table store (
- id uuid primary key, -- remember to use uuidv7 for happy indices <3
- client_id uuid not null, -- I am too uncomfortable with the idea of a client-generated primary key, even though it's fine mathematically
- host uuid not null, -- a unique identifier for the host
- idx bigint not null, -- the index of the record in this store, identified by (host, tag)
- timestamp bigint not null, -- not a timestamp type, as those do not have nanosecond precision
- version text not null,
- tag text not null, -- what is this? history, kv, whatever. Remember clients get a log per tag per host
- data text not null, -- store the actual history data, encrypted. I don't wanna know!
- cek text not null,
-
- user_id bigint not null, -- allow multiple users
- created_at timestamp not null default current_timestamp
-);
diff --git a/crates/atuin-server-postgres/migrations/20231203124112_create-store-idx.sql b/crates/atuin-server-postgres/migrations/20231203124112_create-store-idx.sql
deleted file mode 100644
index 56d67145..00000000
--- a/crates/atuin-server-postgres/migrations/20231203124112_create-store-idx.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Add migration script here
-create unique index record_uniq ON store(user_id, host, tag, idx);
diff --git a/crates/atuin-server-postgres/migrations/20240108124837_drop-some-defaults.sql b/crates/atuin-server-postgres/migrations/20240108124837_drop-some-defaults.sql
deleted file mode 100644
index ad2af5a1..00000000
--- a/crates/atuin-server-postgres/migrations/20240108124837_drop-some-defaults.sql
+++ /dev/null
@@ -1,4 +0,0 @@
--- Add migration script here
-alter table history alter column user_id drop default;
-alter table sessions alter column user_id drop default;
-alter table total_history_count_user alter column user_id drop default;
diff --git a/crates/atuin-server-postgres/migrations/20240614104159_idx-cache.sql b/crates/atuin-server-postgres/migrations/20240614104159_idx-cache.sql
deleted file mode 100644
index 76425ed7..00000000
--- a/crates/atuin-server-postgres/migrations/20240614104159_idx-cache.sql
+++ /dev/null
@@ -1,8 +0,0 @@
-create table store_idx_cache(
- id bigserial primary key,
- user_id bigint,
-
- host uuid,
- tag text,
- idx bigint
-);
diff --git a/crates/atuin-server-postgres/migrations/20240621110731_user-verified.sql b/crates/atuin-server-postgres/migrations/20240621110731_user-verified.sql
deleted file mode 100644
index 6eba02ec..00000000
--- a/crates/atuin-server-postgres/migrations/20240621110731_user-verified.sql
+++ /dev/null
@@ -1,8 +0,0 @@
-alter table users add verified_at timestamp with time zone default null;
-
-create table user_verification_token(
- id bigserial primary key,
- user_id bigint unique references users(id),
- token text,
- valid_until timestamp with time zone
-);
diff --git a/crates/atuin-server-postgres/migrations/20240702094825_idx_cache_index.sql b/crates/atuin-server-postgres/migrations/20240702094825_idx_cache_index.sql
deleted file mode 100644
index d1a7b194..00000000
--- a/crates/atuin-server-postgres/migrations/20240702094825_idx_cache_index.sql
+++ /dev/null
@@ -1 +0,0 @@
-create unique index store_idx_cache_uniq on store_idx_cache(user_id, host, tag);
diff --git a/crates/atuin-server-postgres/migrations/20260127000000_remove-email-verification.sql b/crates/atuin-server-postgres/migrations/20260127000000_remove-email-verification.sql
deleted file mode 100644
index 15309920..00000000
--- a/crates/atuin-server-postgres/migrations/20260127000000_remove-email-verification.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-drop table if exists user_verification_token;
-alter table users drop column if exists verified_at;
diff --git a/crates/atuin-server-sqlite/Cargo.toml b/crates/atuin-server-sqlite/Cargo.toml
deleted file mode 100644
index 579a5e7e..00000000
--- a/crates/atuin-server-sqlite/Cargo.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-[package]
-name = "atuin-server-sqlite"
-edition = "2024"
-description = "server sqlite database library for atuin"
-
-version = { workspace = true }
-authors = { workspace = true }
-license = { workspace = true }
-homepage = { workspace = true }
-repository = { workspace = true }
-
-[dependencies]
-atuin-common = { path = "../atuin-common", version = "18.16.1" }
-atuin-server-database = { path = "../atuin-server-database", version = "18.16.1" }
-
-eyre = { workspace = true }
-tracing = { workspace = true }
-time = { workspace = true }
-serde = { workspace = true }
-sqlx = { workspace = true, features = ["sqlite", "regexp"] }
-async-trait = { workspace = true }
-uuid = { workspace = true }
-metrics = "0.24"
-futures-util = "0.3"
diff --git a/crates/atuin-server-sqlite/build.rs b/crates/atuin-server-sqlite/build.rs
deleted file mode 100644
index d5068697..00000000
--- a/crates/atuin-server-sqlite/build.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-// generated by `sqlx migrate build-script`
-fn main() {
- // trigger recompilation when a new migration is added
- println!("cargo:rerun-if-changed=migrations");
-}
diff --git a/crates/atuin-server-sqlite/migrations/20231203124112_create-store.sql b/crates/atuin-server-sqlite/migrations/20231203124112_create-store.sql
deleted file mode 100644
index ca19ed62..00000000
--- a/crates/atuin-server-sqlite/migrations/20231203124112_create-store.sql
+++ /dev/null
@@ -1,17 +0,0 @@
-create table store (
- id text primary key, -- remember to use uuidv7 for happy indices <3
- client_id text not null, -- I am too uncomfortable with the idea of a client-generated primary key, even though it's fine mathematically
- host text not null, -- a unique identifier for the host
- idx bigint not null, -- the index of the record in this store, identified by (host, tag)
- timestamp bigint not null, -- not a timestamp type, as those do not have nanosecond precision
- version text not null,
- tag text not null, -- what is this? history, kv, whatever. Remember clients get a log per tag per host
- data text not null, -- store the actual history data, encrypted. I don't wanna know!
- cek text not null,
-
- user_id bigint not null, -- allow multiple users
- created_at timestamp not null default current_timestamp
-);
-
-create unique index record_uniq ON store(user_id, host, tag, idx);
-
diff --git a/crates/atuin-server-sqlite/migrations/20240108124830_create-history.sql b/crates/atuin-server-sqlite/migrations/20240108124830_create-history.sql
deleted file mode 100644
index 7bd653ba..00000000
--- a/crates/atuin-server-sqlite/migrations/20240108124830_create-history.sql
+++ /dev/null
@@ -1,15 +0,0 @@
-create table history (
- id integer primary key autoincrement,
- client_id text not null unique, -- the client-generated ID
- user_id bigserial not null, -- allow multiple users
- hostname text not null, -- a unique identifier from the client (can be hashed, random, whatever)
- timestamp timestamp not null, -- one of the few non-encrypted metadatas
-
- data text not null, -- store the actual history data, encrypted. I don't wanna know!
-
- created_at timestamp not null default current_timestamp,
- deleted_at timestamp
-);
-
-create unique index history_deleted_index on history(client_id, user_id, deleted_at);
-
diff --git a/crates/atuin-server-sqlite/migrations/20240108124831_create-sessions.sql b/crates/atuin-server-sqlite/migrations/20240108124831_create-sessions.sql
deleted file mode 100644
index 3120c35d..00000000
--- a/crates/atuin-server-sqlite/migrations/20240108124831_create-sessions.sql
+++ /dev/null
@@ -1,6 +0,0 @@
-create table sessions (
- id integer primary key autoincrement,
- user_id integer,
- token text unique not null
-);
-
diff --git a/crates/atuin-server-sqlite/migrations/20240621110730_create-users.sql b/crates/atuin-server-sqlite/migrations/20240621110730_create-users.sql
deleted file mode 100644
index 852c159d..00000000
--- a/crates/atuin-server-sqlite/migrations/20240621110730_create-users.sql
+++ /dev/null
@@ -1,12 +0,0 @@
-create table users (
- id integer primary key autoincrement, -- also store our own ID
- username text not null unique, -- being able to contact users is useful
- email text not null unique, -- being able to contact users is useful
- password text not null unique,
- created_at timestamp not null default (datetime('now','localtime')),
- verified_at timestamp with time zone default null
-);
-
--- the prior index is case sensitive :(
-CREATE UNIQUE INDEX email_unique_idx on users (LOWER(email));
-CREATE UNIQUE INDEX username_unique_idx on users (LOWER(username));
diff --git a/crates/atuin-server-sqlite/migrations/20240621110731_create-user-verification-token.sql b/crates/atuin-server-sqlite/migrations/20240621110731_create-user-verification-token.sql
deleted file mode 100644
index 36eb14de..00000000
--- a/crates/atuin-server-sqlite/migrations/20240621110731_create-user-verification-token.sql
+++ /dev/null
@@ -1,6 +0,0 @@
-create table user_verification_token(
- id integer primary key autoincrement,
- user_id bigint unique references users(id),
- token text,
- valid_until timestamp with time zone
-);
diff --git a/crates/atuin-server-sqlite/migrations/20240702094825_create-store-idx-cache.sql b/crates/atuin-server-sqlite/migrations/20240702094825_create-store-idx-cache.sql
deleted file mode 100644
index cd54cb18..00000000
--- a/crates/atuin-server-sqlite/migrations/20240702094825_create-store-idx-cache.sql
+++ /dev/null
@@ -1,10 +0,0 @@
-create table store_idx_cache(
- id integer primary key autoincrement,
- user_id bigint,
-
- host uuid,
- tag text,
- idx bigint
-);
-
-create unique index store_idx_cache_uniq on store_idx_cache(user_id, host, tag);
diff --git a/crates/atuin-server-sqlite/migrations/20260127000000_remove-email-verification.sql b/crates/atuin-server-sqlite/migrations/20260127000000_remove-email-verification.sql
deleted file mode 100644
index 0bde89d7..00000000
--- a/crates/atuin-server-sqlite/migrations/20260127000000_remove-email-verification.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-drop table if exists user_verification_token;
-alter table users drop column verified_at;
diff --git a/crates/atuin-server/CHANGELOG.md b/crates/atuin-server/CHANGELOG.md
deleted file mode 120000
index 699cc9e7..00000000
--- a/crates/atuin-server/CHANGELOG.md
+++ /dev/null
@@ -1 +0,0 @@
-../../CHANGELOG.md \ No newline at end of file
diff --git a/crates/atuin-server/Cargo.toml b/crates/atuin-server/Cargo.toml
deleted file mode 100644
index b7779899..00000000
--- a/crates/atuin-server/Cargo.toml
+++ /dev/null
@@ -1,45 +0,0 @@
-[package]
-name = "atuin-server"
-edition = "2024"
-description = "server library for atuin"
-
-rust-version = { workspace = true }
-version = { workspace = true }
-authors = { workspace = true }
-license = { workspace = true }
-homepage = { workspace = true }
-repository = { workspace = true }
-
-[lib]
-name = "atuin_server"
-path = "src/lib.rs"
-
-[[bin]]
-name = "atuin-server"
-path = "src/bin/main.rs"
-
-[dependencies]
-atuin-common = { workspace = true }
-atuin-server-database = { workspace = true }
-atuin-server-postgres = { workspace = true }
-atuin-server-sqlite = { workspace = true }
-
-tracing = { workspace = true }
-time = { workspace = true }
-eyre = { workspace = true }
-config = { workspace = true }
-serde = { workspace = true }
-serde_json = { workspace = true }
-rand = { workspace = true }
-tokio = { workspace = true }
-axum = "0.8"
-fs-err = { workspace = true }
-tower = { workspace = true }
-tower-http = { version = "0.6", features = ["trace"] }
-reqwest = { workspace = true }
-argon2 = "0.5"
-semver = { workspace = true }
-metrics-exporter-prometheus = { version = "0.18", default-features = false }
-metrics = "0.24"
-clap = { workspace = true }
-tracing-subscriber = { workspace = true }
diff --git a/crates/atuin-server/server.toml b/crates/atuin-server/server.toml
deleted file mode 100644
index 9ff95890..00000000
--- a/crates/atuin-server/server.toml
+++ /dev/null
@@ -1,38 +0,0 @@
-## host to bind, can also be passed via CLI args
-# host = "127.0.0.1"
-
-## port to bind, can also be passed via CLI args
-# port = 8888
-
-## whether to allow anyone to register an account
-# open_registration = false
-
-## URI for postgres (using development creds here)
-# db_uri="postgres://username:password@localhost/atuin"
-# db_uri="sqlite:///config/atuin-server.db"
-
-## Optional: URI for read replica database
-## If set, read-only queries will be routed to this database
-# read_db_uri="postgres://username:password@localhost-replica/atuin"
-
-## Maximum size for one history entry
-# max_history_length = 8192
-
-## Maximum size for one record entry
-## 1024 * 1024 * 1024
-# max_record_size = 1073741824
-
-## Webhook to be called when user registers on the servers
-# register_webhook_username = ""
-
-## Default page size for requests
-# page_size = 1100
-
-# [metrics]
-# enable = false
-# host = 127.0.0.1
-# port = 9001
-
-## Enable legacy sync v1 routes (history-based sync)
-## Set to false to disable and use only the newer record-based sync
-# sync_v1_enabled = true
diff --git a/crates/atuin-server/src/bin/main.rs b/crates/atuin-server/src/bin/main.rs
deleted file mode 100644
index 960bdf6e..00000000
--- a/crates/atuin-server/src/bin/main.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-#![forbid(unsafe_code)]
-
-use std::net::SocketAddr;
-
-use atuin_server::{Settings, example_config, launch, launch_metrics_server};
-use atuin_server_database::DbType;
-use atuin_server_postgres::Postgres;
-use atuin_server_sqlite::Sqlite;
-
-use clap::Parser;
-use eyre::{Context, Result, eyre};
-use tracing_subscriber::{EnvFilter, fmt, prelude::*};
-
-#[derive(Parser, Debug)]
-#[clap(
- name = "atuin-server",
- about = "Atuin sync server",
- version,
- infer_subcommands = true
-)]
-enum Cmd {
- /// Start the server
- Start {
- /// The host address to bind
- #[clap(long)]
- host: Option<String>,
-
- /// The port to bind
- #[clap(long, short)]
- port: Option<u16>,
- },
-
- /// Print server example configuration
- DefaultConfig,
-}
-
-#[tokio::main]
-async fn main() -> Result<()> {
- let cmd = Cmd::parse();
-
- tracing_subscriber::registry()
- .with(fmt::layer())
- .with(EnvFilter::from_default_env())
- .init();
-
- tracing::trace!(command = ?cmd, "server command");
-
- match cmd {
- Cmd::Start { host, port } => {
- let settings = Settings::new().wrap_err("could not load server settings")?;
- let host = host.as_ref().unwrap_or(&settings.host).clone();
- let port = port.unwrap_or(settings.port);
- let addr = SocketAddr::new(host.parse()?, port);
-
- if settings.metrics.enable {
- tokio::spawn(launch_metrics_server(
- settings.metrics.host.clone(),
- settings.metrics.port,
- ));
- }
-
- match settings.db_settings.db_type() {
- DbType::Postgres => launch::<Postgres>(settings, addr).await,
- DbType::Sqlite => launch::<Sqlite>(settings, addr).await,
- DbType::Unknown => Err(eyre!("db_uri must start with postgres:// or sqlite://")),
- }
- }
- Cmd::DefaultConfig => {
- println!("{}", example_config());
- Ok(())
- }
- }
-}
diff --git a/crates/atuin/CHANGELOG.md b/crates/atuin/CHANGELOG.md
deleted file mode 120000
index 699cc9e7..00000000
--- a/crates/atuin/CHANGELOG.md
+++ /dev/null
@@ -1 +0,0 @@
-../../CHANGELOG.md \ No newline at end of file
diff --git a/crates/atuin/Cargo.toml b/crates/atuin/Cargo.toml
deleted file mode 100644
index 6cdc57fa..00000000
--- a/crates/atuin/Cargo.toml
+++ /dev/null
@@ -1,87 +0,0 @@
-[package]
-name = "atuin"
-edition = "2024"
-description = "atuin - magical shell history"
-readme = "./README.md"
-
-rust-version = { workspace = true }
-version = { workspace = true }
-authors = { workspace = true }
-license = { workspace = true }
-homepage = { workspace = true }
-repository = { workspace = true }
-
-[features]
-default = [
- "client", "sync", "clipboard", "daemon", "pty-proxy"
-]
-client = ["atuin-client"]
-sync = ["atuin-client/sync"]
-daemon = ["atuin-client/daemon", "atuin-daemon"]
-pty-proxy = ["dep:atuin-pty-proxy"]
-hex = ["pty-proxy"]
-clipboard = ["arboard"]
-
-[dependencies]
-atuin-client = { path = "../atuin-client", version = "18.16.1", optional = true, default-features = false }
-atuin-common = { workspace = true }
-atuin-history = { workspace = true }
-atuin-daemon = { path = "../atuin-daemon", version = "18.16.1", optional = true, default-features = false }
-atuin-pty-proxy = { path = "../atuin-pty-proxy", version = "18.16.1", optional = true, default-features = false }
-
-log = { workspace = true }
-time = { workspace = true }
-eyre = { workspace = true }
-indicatif = "0.18.0"
-serde = { workspace = true }
-serde_json = { workspace = true }
-crossterm = { workspace = true, features = ["use-dev-tty"] }
-unicode-width = "0.2"
-itertools = { workspace = true }
-tokio = { workspace = true }
-async-trait = { workspace = true }
-interim = { workspace = true }
-clap = { workspace = true }
-clap_complete = "4.5.8"
-clap_complete_nushell = "4.5.4"
-fs-err = { workspace = true }
-fs4 = "0.13.1"
-rpassword = "7.0"
-semver = { workspace = true }
-rustix = { workspace = true }
-runtime-format = "0.1.3"
-futures-util = "0.3"
-fuzzy-matcher = "0.3.7"
-colored = "2.0.4"
-open = "5"
-ratatui = { workspace = true }
-tracing = "0.1"
-tracing-subscriber = { workspace = true }
-tracing-appender = "0.2"
-uuid = { workspace = true }
-sysinfo = "0.30.7"
-regex = "1.10.5"
-norm = { version = "0.1.1", features = ["fzf-v2"] }
-atuin-nucleo-matcher = { workspace = true }
-tempfile = { workspace = true }
-shlex = "1.3.0"
-
-# settings editor with comment and relative ordering preservation
-toml_edit = { workspace = true }
-
-[target.'cfg(target_os = "linux")'.dependencies]
-arboard = { version = "3.4", optional = true, default-features = false, features = [
- "wayland-data-control",
-] }
-
-[target.'cfg(unix)'.dependencies]
-daemonize = "0.5.0"
-
-[dev-dependencies]
-tracing-tree = "0.4"
-
-# Integration tests in tests/ spin up a test server to verify sync functionality.
-# TODO: Consider moving these tests to atuin-server crate instead (client would become a dev dep there)
-atuin-server = { workspace = true }
-atuin-server-database = { workspace = true }
-atuin-server-postgres = { workspace = true }
diff --git a/crates/atuin/LICENSE b/crates/atuin/LICENSE
deleted file mode 100644
index 7dfc9b58..00000000
--- a/crates/atuin/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2021 Ellie Huxtable
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/crates/atuin/README.md b/crates/atuin/README.md
deleted file mode 120000
index fe840054..00000000
--- a/crates/atuin/README.md
+++ /dev/null
@@ -1 +0,0 @@
-../../README.md \ No newline at end of file
diff --git a/crates/atuin/build.rs b/crates/atuin/build.rs
deleted file mode 100644
index 75d53ee0..00000000
--- a/crates/atuin/build.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-use std::process::Command;
-fn main() {
- let output = Command::new("git").args(["rev-parse", "HEAD"]).output();
-
- let sha = match output {
- Ok(sha) => String::from_utf8(sha.stdout).unwrap(),
- Err(_) => String::from("NO_GIT"),
- };
-
- println!("cargo:rustc-env=GIT_HASH={sha}");
-}
diff --git a/crates/atuin/src/command/client/default_config.rs b/crates/atuin/src/command/client/default_config.rs
deleted file mode 100644
index f51e45c2..00000000
--- a/crates/atuin/src/command/client/default_config.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-use atuin_client::settings::Settings;
-
-pub fn run() {
- println!("{}", Settings::example_config());
-}
diff --git a/crates/atuin/tests/common/mod.rs b/crates/atuin/tests/common/mod.rs
deleted file mode 100644
index 228c0d17..00000000
--- a/crates/atuin/tests/common/mod.rs
+++ /dev/null
@@ -1,117 +0,0 @@
-use std::{env, time::Duration};
-
-use atuin_client::api_client;
-use atuin_common::utils::uuid_v7;
-use atuin_server::{Settings as ServerSettings, launch_with_tcp_listener};
-use atuin_server_database::DbSettings;
-use atuin_server_postgres::Postgres;
-use futures_util::TryFutureExt;
-use tokio::{net::TcpListener, sync::oneshot, task::JoinHandle};
-use tracing::{Dispatch, dispatcher};
-use tracing_subscriber::{EnvFilter, layer::SubscriberExt};
-
-pub async fn start_server(path: &str) -> (String, oneshot::Sender<()>, JoinHandle<()>) {
- let formatting_layer = tracing_tree::HierarchicalLayer::default()
- .with_writer(tracing_subscriber::fmt::TestWriter::new())
- .with_indent_lines(true)
- .with_ansi(true)
- .with_targets(true)
- .with_indent_amount(2);
-
- let dispatch: Dispatch = tracing_subscriber::registry()
- .with(formatting_layer)
- .with(EnvFilter::new("atuin_server=debug,atuin_client=debug,info"))
- .into();
-
- let db_uri = env::var("ATUIN_DB_URI")
- .unwrap_or_else(|_| "postgres://atuin:pass@localhost:5432/atuin".to_owned());
-
- let server_settings = ServerSettings {
- host: "127.0.0.1".to_owned(),
- port: 0,
- path: path.to_owned(),
- sync_v1_enabled: true,
- open_registration: true,
- max_history_length: 8192,
- max_record_size: 1024 * 1024 * 1024,
- page_size: 1100,
- register_webhook_url: None,
- register_webhook_username: String::new(),
- db_settings: DbSettings {
- db_uri: db_uri,
- read_db_uri: None,
- },
- metrics: atuin_server::settings::Metrics::default(),
- fake_version: None,
- };
-
- let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel();
- let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
- let addr = listener.local_addr().unwrap();
- let server = tokio::spawn(async move {
- let _tracing_guard = dispatcher::set_default(&dispatch);
-
- if let Err(e) = launch_with_tcp_listener::<Postgres>(
- server_settings,
- listener,
- shutdown_rx.unwrap_or_else(|_| ()),
- )
- .await
- {
- tracing::error!(error=?e, "server error");
- panic!("error running server: {e:?}");
- }
- });
-
- // let the server come online
- tokio::time::sleep(Duration::from_millis(200)).await;
-
- (format!("http://{addr}{path}"), shutdown_tx, server)
-}
-
-pub async fn register_inner<'a>(
- address: &'a str,
- username: &str,
- password: &str,
-) -> api_client::Client<'a> {
- let email = format!("{}@example.com", uuid_v7().as_simple());
-
- // registration works
- let registration_response = api_client::register(address, username, &email, password)
- .await
- .unwrap();
-
- api_client::Client::new(
- address,
- api_client::AuthToken::Token(registration_response.session),
- 5,
- 30,
- )
- .unwrap()
-}
-
-#[expect(dead_code)]
-pub async fn login(address: &str, username: String, password: String) -> api_client::Client<'_> {
- // registration works
- let login_response = api_client::login(
- address,
- atuin_common::api::LoginRequest { username, password },
- )
- .await
- .unwrap();
-
- api_client::Client::new(
- address,
- api_client::AuthToken::Token(login_response.session),
- 5,
- 30,
- )
- .unwrap()
-}
-
-#[expect(dead_code)]
-pub async fn register(address: &str) -> api_client::Client<'_> {
- let username = uuid_v7().as_simple().to_string();
- let password = uuid_v7().as_simple().to_string();
- register_inner(address, &username, &password).await
-}
diff --git a/crates/atuin/tests/sync.rs b/crates/atuin/tests/sync.rs
deleted file mode 100644
index 7e25d1c2..00000000
--- a/crates/atuin/tests/sync.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use atuin_common::{api::AddHistoryRequest, utils::uuid_v7};
-use time::OffsetDateTime;
-
-mod common;
-
-#[tokio::test]
-async fn sync() {
- let path = format!("/{}", uuid_v7().as_simple());
- let (address, shutdown, server) = common::start_server(&path).await;
-
- let client = common::register(&address).await;
- let hostname = uuid_v7().as_simple().to_string();
- let now = OffsetDateTime::now_utc();
-
- let data1 = uuid_v7().as_simple().to_string();
- let data2 = uuid_v7().as_simple().to_string();
-
- client
- .post_history(&[
- AddHistoryRequest {
- id: uuid_v7().as_simple().to_string(),
- timestamp: now,
- data: data1.clone(),
- hostname: hostname.clone(),
- },
- AddHistoryRequest {
- id: uuid_v7().as_simple().to_string(),
- timestamp: now,
- data: data2.clone(),
- hostname: hostname.clone(),
- },
- ])
- .await
- .unwrap();
-
- let history = client
- .get_history(OffsetDateTime::UNIX_EPOCH, OffsetDateTime::UNIX_EPOCH, None)
- .await
- .unwrap();
-
- assert_eq!(history.history, vec![data1, data2]);
-
- shutdown.send(()).unwrap();
- server.await.unwrap();
-}
diff --git a/crates/atuin/tests/users.rs b/crates/atuin/tests/users.rs
deleted file mode 100644
index 95fb533b..00000000
--- a/crates/atuin/tests/users.rs
+++ /dev/null
@@ -1,121 +0,0 @@
-use atuin_common::utils::uuid_v7;
-
-mod common;
-
-#[tokio::test]
-async fn registration() {
- let path = format!("/{}", uuid_v7().as_simple());
- let (address, shutdown, server) = common::start_server(&path).await;
- dbg!(&address);
-
- // -- REGISTRATION --
-
- let username = uuid_v7().as_simple().to_string();
- let password = uuid_v7().as_simple().to_string();
- let client = common::register_inner(&address, &username, &password).await;
-
- // the session token works
- let status = client.status().await.unwrap();
- assert_eq!(status.username, username);
-
- // -- LOGIN --
-
- let client = common::login(&address, username.clone(), password).await;
-
- // the session token works
- let status = client.status().await.unwrap();
- assert_eq!(status.username, username);
-
- shutdown.send(()).unwrap();
- server.await.unwrap();
-}
-
-#[tokio::test]
-async fn change_password() {
- let path = format!("/{}", uuid_v7().as_simple());
- let (address, shutdown, server) = common::start_server(&path).await;
-
- // -- REGISTRATION --
-
- let username = uuid_v7().as_simple().to_string();
- let password = uuid_v7().as_simple().to_string();
- let client = common::register_inner(&address, &username, &password).await;
-
- // the session token works
- let status = client.status().await.unwrap();
- assert_eq!(status.username, username);
-
- // -- PASSWORD CHANGE --
-
- let current_password = password;
- let new_password = uuid_v7().as_simple().to_string();
- let result = client
- .change_password(current_password, new_password.clone())
- .await;
-
- // the password change request succeeded
- assert!(result.is_ok());
-
- // -- LOGIN --
-
- let client = common::login(&address, username.clone(), new_password).await;
-
- // login with new password yields a working token
- let status = client.status().await.unwrap();
- assert_eq!(status.username, username);
-
- shutdown.send(()).unwrap();
- server.await.unwrap();
-}
-
-#[tokio::test]
-async fn multi_user_test() {
- let path = format!("/{}", uuid_v7().as_simple());
- let (address, shutdown, server) = common::start_server(&path).await;
- dbg!(&address);
-
- // -- REGISTRATION --
-
- let user_one = uuid_v7().as_simple().to_string();
- let password_one = uuid_v7().as_simple().to_string();
- let client_one = common::register_inner(&address, &user_one, &password_one).await;
-
- // the session token works
- let status = client_one.status().await.unwrap();
- assert_eq!(status.username, user_one);
-
- let user_two = uuid_v7().as_simple().to_string();
- let password_two = uuid_v7().as_simple().to_string();
- let client_two = common::register_inner(&address, &user_two, &password_two).await;
-
- // the session token works
- let status = client_two.status().await.unwrap();
- assert_eq!(status.username, user_two);
-
- // check that we can change user one's password, and _this does not affect user two_
-
- let current_password = password_one;
- let new_password = uuid_v7().as_simple().to_string();
- let result = client_one
- .change_password(current_password, new_password.clone())
- .await;
-
- // the password change request succeeded
- assert!(result.is_ok());
-
- // -- LOGIN --
-
- let client_one = common::login(&address, user_one.clone(), new_password).await;
- let client_two = common::login(&address, user_two.clone(), password_two).await;
-
- // login with new password yields a working token
- let status = client_one.status().await.unwrap();
- assert_eq!(status.username, user_one);
- assert_ne!(status.username, user_two);
-
- let status = client_two.status().await.unwrap();
- assert_eq!(status.username, user_two);
-
- shutdown.send(()).unwrap();
- server.await.unwrap();
-}
diff --git a/crates/turtle/Cargo.toml b/crates/turtle/Cargo.toml
new file mode 100644
index 00000000..87557905
--- /dev/null
+++ b/crates/turtle/Cargo.toml
@@ -0,0 +1,142 @@
+[package]
+name = "atuin"
+edition = "2024"
+description = "atuin - magical shell history"
+readme = "./README.md"
+
+rust-version = { workspace = true }
+version = { workspace = true }
+authors = { workspace = true }
+license = { workspace = true }
+homepage = { workspace = true }
+repository = { workspace = true }
+
+[features]
+default = [
+ "clipboard",
+ "daemon",
+ "hex",
+ "sync",
+ "client",
+]
+
+clipboard = ["arboard"]
+daemon = ["pty-proxy"]
+pty-proxy = []
+client = []
+hex = ["dep:hex"]
+sync = ["urlencoding", "reqwest", "sha2", "hex"]
+
+[dependencies]
+argon2 = "0.5"
+async-trait = "0.1.58"
+atuin-nucleo-matcher = { workspace = true }
+atuin-nucleo = { workspace = true }
+axum = "0.8"
+base64 = "0.22"
+clap = { version = "4.5.7", features = ["derive"] }
+clap_complete = "4.5.8"
+clap_complete_nushell = "4.5.4"
+colored = "2.0.4"
+config = { version = "0.15.8", default-features = false, features = ["toml"] }
+crossterm = {version = "0.29.0", features = ["use-dev-tty", "serde"] }
+crypto_secretbox = "0.1.1"
+dashmap = "6.1.0"
+directories = "6.0.0"
+eyre = "0.6"
+fs-err = "3.1"
+fs4 = "0.13.1"
+futures = "0.3"
+futures-util = "0.3"
+fuzzy-matcher = "0.3.7"
+generic-array = { version = "0.14", features = ["serde"] }
+getrandom = "0.2"
+glob-match = "0.2.1"
+hex = { version = "0.4", optional = true }
+humantime = "2.1.0"
+hyper-util = "0.1"
+imara-diff = "0.2"
+indicatif = "0.18.0"
+interim = { version = "0.2.0", features = ["time_0_3"] }
+itertools = "0.14.0"
+lasso = { version = "0.7", features = ["multi-threaded"] }
+log = "0.4"
+memchr = "2.7"
+metrics = "0.24"
+metrics-exporter-prometheus = { version = "0.18", default-features = false }
+minijinja = "2.9.0"
+minspan = "0.1.5"
+norm = { version = "0.1.1", features = ["fzf-v2"] }
+notify = "7"
+open = "5"
+palette = { version = "0.7.5", features = ["serializing"] }
+pretty_assertions = "1.3.0"
+prost = "0.14"
+prost-types = "0.14"
+rand = { version = "0.8.5", features = ["std"] }
+ratatui = "0.30.0"
+regex = "1.10.5"
+reqwest = { version = "0.13", optional = true, features = ["json", "rustls-no-provider", "stream"], default-features = false }
+rmp = { version = "0.8.14" }
+rpassword = "7.0"
+runtime-format = "0.1.3"
+rustix = { version = "1.1.4", features = ["process", "fs"] }
+rustls = { version = "0.23", default-features = false, features = [ "ring", "std", "tls12", ] }
+rusty_paserk = { version = "0.5.0", default-features = false, features = [ "v4", "serde", ] }
+rusty_paseto = { version = "0.8.0", default-features = false }
+semver = "1.0.20"
+serde = { version = "1.0.202", features = ["derive"] }
+serde_json = "1.0.119"
+serde_regex = "1.1.0"
+serde_with = "3.8.1"
+sha2 = { version = "0.10", optional = true }
+shellexpand = "3"
+shlex = "1.3.0"
+sql-builder = "3"
+sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "time", "postgres", "uuid", "sqlite", "regexp"] }
+strum = { version = "0.27", features = ["strum_macros"] }
+strum_macros = "0.27"
+sysinfo = "0.30.7"
+tempfile = { version = "3.19" }
+thiserror = "2"
+time = { version = "0.3.47", features = [ "serde-human-readable", "macros", "local-offset", "macros", "formatting", "parsing"] }
+tokio = { version = "1", features = ["full"] }
+tokio-stream = { version = "0.1.14", features = ["net"] }
+toml_edit = "0.25.4"
+tonic = "0.14"
+tonic-prost = "0.14"
+tonic-types = "0.14"
+tower = "0.5"
+tower-http = { version = "0.6", features = ["trace"] }
+tracing = "0.1"
+tracing-appender = "0.2"
+tracing-subscriber = { version = "0.3", features = ["ansi", "fmt", "registry", "env-filter", "json"] }
+typed-builder = "0.18.2"
+unicode-segmentation = "1.11.0"
+unicode-width = "0.2"
+url = "2.5.2"
+urlencoding = { version = "2.1.0", optional = true }
+uuid = { version = "1.9", features = ["v4", "v7", "serde"] }
+vt100 = "0.16"
+whoami = "2.1.0"
+xxhash-rust = { version = "0.8", features = ["xxh3"] }
+
+[target.'cfg(target_os = "linux")'.dependencies]
+arboard = { version = "3.4", optional = true, default-features = false, features = [ "wayland-data-control", ] }
+listenfd = "1.0.1"
+
+[target.'cfg(unix)'.dependencies]
+daemonize = "0.5.0"
+portable-pty = "0.9"
+signal-hook = "0.3"
+
+[dev-dependencies]
+tracing-tree = "0.4"
+divan = "0.1.14"
+tokio = { version = "1", features = ["full"] }
+testing_logger = "0.1.1"
+
+[build-dependencies]
+protox = "0.9"
+tonic-build = "0.14"
+tonic-prost-build = "0.14"
diff --git a/crates/turtle/build.rs b/crates/turtle/build.rs
new file mode 100644
index 00000000..5f26e26c
--- /dev/null
+++ b/crates/turtle/build.rs
@@ -0,0 +1,39 @@
+use std::process::Command;
+use std::{env, fs, path::PathBuf};
+
+use protox::prost::Message;
+
+fn main() -> Result<(), std::io::Error> {
+ {
+ let output = Command::new("git").args(["rev-parse", "HEAD"]).output();
+
+ let sha = match output {
+ Ok(sha) => String::from_utf8(sha.stdout).unwrap(),
+ Err(_) => String::from("NO_GIT"),
+ };
+
+ println!("cargo:rustc-env=GIT_HASH={sha}");
+ }
+
+ {
+ let proto_paths = [
+ "proto/history.proto",
+ "proto/search.proto",
+ "proto/control.proto",
+ "proto/semantic.proto",
+ ];
+ let proto_include_dirs = ["proto"];
+
+ let file_descriptors = protox::compile(proto_paths, proto_include_dirs).unwrap();
+
+ let file_descriptor_path = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR not set"))
+ .join("file_descriptor_set.bin");
+ fs::write(&file_descriptor_path, file_descriptors.encode_to_vec()).unwrap();
+
+ tonic_prost_build::configure()
+ .build_server(true)
+ .file_descriptor_set_path(&file_descriptor_path)
+ .skip_protoc_run()
+ .compile_protos(&proto_paths, &proto_include_dirs)
+ }
+}
diff --git a/crates/atuin-daemon/proto/control.proto b/crates/turtle/proto/control.proto
index 06347902..06347902 100644
--- a/crates/atuin-daemon/proto/control.proto
+++ b/crates/turtle/proto/control.proto
diff --git a/crates/atuin-daemon/proto/history.proto b/crates/turtle/proto/history.proto
index 59c12471..59c12471 100644
--- a/crates/atuin-daemon/proto/history.proto
+++ b/crates/turtle/proto/history.proto
diff --git a/crates/atuin-daemon/proto/search.proto b/crates/turtle/proto/search.proto
index 6b84acbd..6b84acbd 100644
--- a/crates/atuin-daemon/proto/search.proto
+++ b/crates/turtle/proto/search.proto
diff --git a/crates/atuin-daemon/proto/semantic.proto b/crates/turtle/proto/semantic.proto
index 07e550c8..07e550c8 100644
--- a/crates/atuin-daemon/proto/semantic.proto
+++ b/crates/turtle/proto/semantic.proto
diff --git a/crates/atuin-client/src/api_client.rs b/crates/turtle/src/atuin_client/api_client.rs
index ca2fc661..7955c2da 100644
--- a/crates/atuin-client/src/api_client.rs
+++ b/crates/turtle/src/atuin_client/api_client.rs
@@ -7,13 +7,14 @@ use reqwest::{
Response, StatusCode, Url,
header::{AUTHORIZATION, HeaderMap, USER_AGENT},
};
+use tracing::debug;
-use atuin_common::{
+use crate::atuin_common::{
api::{ATUIN_CARGO_VERSION, ATUIN_HEADER_VERSION, ATUIN_VERSION},
record::{EncryptedData, HostId, Record, RecordIdx},
tls::ensure_crypto_provider,
};
-use atuin_common::{
+use crate::atuin_common::{
api::{
AddHistoryRequest, ChangePasswordRequest, CountResponse, DeleteHistoryRequest,
ErrorResponse, LoginRequest, LoginResponse, MeResponse, RegisterResponse, StatusResponse,
@@ -26,7 +27,7 @@ use semver::Version;
use time::OffsetDateTime;
use time::format_description::well_known::Rfc3339;
-use crate::{history::History, sync::hash_str, utils::get_host_user};
+use crate::atuin_client::{history::History, sync::hash_str, utils::get_host_user};
static APP_USER_AGENT: &str = concat!("atuin/", env!("CARGO_PKG_VERSION"),);
diff --git a/crates/atuin-client/src/auth.rs b/crates/turtle/src/atuin_client/auth.rs
index 1031c11f..b770c488 100644
--- a/crates/atuin-client/src/auth.rs
+++ b/crates/turtle/src/atuin_client/auth.rs
@@ -2,12 +2,15 @@ use async_trait::async_trait;
use eyre::{Context, Result, bail};
use reqwest::{Url, header::USER_AGENT};
-use atuin_common::{
- api::{ATUIN_CARGO_VERSION, ATUIN_HEADER_VERSION, ChangePasswordRequest, LoginRequest},
- tls::ensure_crypto_provider,
+use crate::{
+ atuin_client::api_client,
+ atuin_common::{
+ api::{ATUIN_CARGO_VERSION, ATUIN_HEADER_VERSION, ChangePasswordRequest, LoginRequest},
+ tls::ensure_crypto_provider,
+ },
};
-use crate::settings::Settings;
+use crate::atuin_client::settings::Settings;
static APP_USER_AGENT: &str = concat!("atuin/", env!("CARGO_PKG_VERSION"));
@@ -42,12 +45,7 @@ pub enum MutateResponse {
#[async_trait]
pub trait AuthClient: Send + Sync {
/// Log in with username + password, optionally providing a TOTP code.
- async fn login(
- &self,
- username: &str,
- password: &str,
- totp_code: Option<&str>,
- ) -> Result<AuthResponse>;
+ async fn login(&self, username: &str, password: &str) -> Result<AuthResponse>;
/// Register a new account.
async fn register(&self, username: &str, email: &str, password: &str) -> Result<AuthResponse>;
@@ -129,14 +127,9 @@ impl LegacyAuthClient {
#[async_trait]
impl AuthClient for LegacyAuthClient {
- async fn login(
- &self,
- username: &str,
- password: &str,
- _totp_code: Option<&str>,
- ) -> Result<AuthResponse> {
+ async fn login(&self, username: &str, password: &str) -> Result<AuthResponse> {
// The legacy server has no 2FA support; totp_code is ignored.
- let resp = crate::api_client::login(
+ let resp = api_client::login(
&self.address,
LoginRequest {
username: username.to_string(),
@@ -152,7 +145,7 @@ impl AuthClient for LegacyAuthClient {
}
async fn register(&self, username: &str, email: &str, password: &str) -> Result<AuthResponse> {
- let resp = crate::api_client::register(&self.address, username, email, password).await?;
+ let resp = api_client::register(&self.address, username, email, password).await?;
Ok(AuthResponse::Success {
session: resp.session,
auth_type: resp.auth.or(Some("cli".into())),
diff --git a/crates/atuin-client/src/database.rs b/crates/turtle/src/atuin_client/database.rs
index 946c1eb0..75b1200c 100644
--- a/crates/atuin-client/src/database.rs
+++ b/crates/turtle/src/atuin_client/database.rs
@@ -5,9 +5,9 @@ use std::{
time::Duration,
};
-use crate::history::{AUTHOR_FILTER_ALL_AGENT, AUTHOR_FILTER_ALL_USER, KNOWN_AGENTS};
+use crate::atuin_client::history::{AUTHOR_FILTER_ALL_AGENT, AUTHOR_FILTER_ALL_USER, KNOWN_AGENTS};
+use crate::atuin_common::utils;
use async_trait::async_trait;
-use atuin_common::utils;
use fs_err as fs;
use itertools::Itertools;
use rand::{Rng, distributions::Alphanumeric};
@@ -20,9 +20,10 @@ use sqlx::{
},
};
use time::OffsetDateTime;
+use tracing::debug;
use uuid::Uuid;
-use crate::{
+use crate::atuin_client::{
history::{HistoryId, HistoryStats},
utils::get_host_user,
};
@@ -969,7 +970,7 @@ impl SqlBuilderExt for SqlBuilder {
#[cfg(test)]
mod test {
- use crate::settings::test_local_timeout;
+ use crate::atuin_client::settings::test_local_timeout;
use super::*;
use std::time::{Duration, Instant};
diff --git a/crates/atuin-client/src/distro.rs b/crates/turtle/src/atuin_client/distro.rs
index dead8355..dead8355 100644
--- a/crates/atuin-client/src/distro.rs
+++ b/crates/turtle/src/atuin_client/distro.rs
diff --git a/crates/atuin-client/src/encryption.rs b/crates/turtle/src/atuin_client/encryption.rs
index f2032482..20a0cd90 100644
--- a/crates/atuin-client/src/encryption.rs
+++ b/crates/turtle/src/atuin_client/encryption.rs
@@ -22,7 +22,7 @@ use rmp::{Marker, decode::Bytes};
use serde::{Deserialize, Serialize};
use time::{OffsetDateTime, format_description::well_known::Rfc3339, macros::format_description};
-use crate::{history::History, settings::Settings};
+use crate::atuin_client::{history::History, settings::Settings};
#[derive(Debug, Serialize, Deserialize)]
pub struct EncryptedHistory {
diff --git a/crates/atuin-client/src/history.rs b/crates/turtle/src/atuin_client/history.rs
index aa0d84d5..cef65115 100644
--- a/crates/atuin-client/src/history.rs
+++ b/crates/turtle/src/atuin_client/history.rs
@@ -5,14 +5,14 @@ use rmp::{Marker, decode::Bytes};
use std::env;
use std::fmt::Display;
-use atuin_common::record::DecryptedData;
-use atuin_common::utils::uuid_v7;
+use crate::atuin_common::record::DecryptedData;
+use crate::atuin_common::utils::uuid_v7;
use eyre::{Result, bail, eyre};
-use crate::secrets::SECRET_PATTERNS_RE;
-use crate::settings::Settings;
-use crate::utils::get_host_user;
+use crate::atuin_client::secrets::SECRET_PATTERNS_RE;
+use crate::atuin_client::settings::Settings;
+use crate::atuin_client::utils::get_host_user;
use time::OffsetDateTime;
mod builder;
@@ -381,7 +381,7 @@ impl History {
///
/// ## Examples
/// ```
- /// use atuin_client::history::History;
+ /// use crate::atuin_client::history::History;
///
/// let history: History = History::import()
/// .timestamp(time::OffsetDateTime::now_utc())
@@ -392,7 +392,7 @@ impl History {
///
/// If shell history contains more information, it can be added to the builder:
/// ```
- /// use atuin_client::history::History;
+ /// use crate::atuin_client::history::History;
///
/// let history: History = History::import()
/// .timestamp(time::OffsetDateTime::now_utc())
@@ -408,7 +408,7 @@ impl History {
/// is forced at compile time:
///
/// ```compile_fail
- /// use atuin_client::history::History;
+ /// use crate::atuin_client::history::History;
///
/// // this will not compile because timestamp is missing
/// let history: History = History::import()
@@ -428,7 +428,7 @@ impl History {
///
/// ## Examples
/// ```rust
- /// use atuin_client::history::History;
+ /// use crate::atuin_client::history::History;
///
/// let history: History = History::capture()
/// .timestamp(time::OffsetDateTime::now_utc())
@@ -441,7 +441,7 @@ impl History {
/// Command without any required info cannot be captured, which is forced at compile time:
///
/// ```compile_fail
- /// use atuin_client::history::History;
+ /// use crate::atuin_client::history::History;
///
/// // this will not compile because `cwd` is missing
/// let history: History = History::capture()
@@ -466,7 +466,7 @@ impl History {
///
/// ## Examples
/// ```rust
- /// use atuin_client::history::History;
+ /// use crate::atuin_client::history::History;
///
/// let history: History = History::daemon()
/// .timestamp(time::OffsetDateTime::now_utc())
@@ -481,7 +481,7 @@ impl History {
/// Command without any required info cannot be captured, which is forced at compile time:
///
/// ```compile_fail
- /// use atuin_client::history::History;
+ /// use crate::atuin_client::history::History;
///
/// // this will not compile because `hostname` is missing
/// let history: History = History::daemon()
@@ -501,7 +501,7 @@ impl History {
/// All fields are required, as they are all present in the database.
///
/// ```compile_fail
- /// use atuin_client::history::History;
+ /// use crate::atuin_client::history::History;
///
/// // this will not compile because `id` field is missing
/// let history: History = History::from_db()
diff --git a/crates/atuin-client/src/history/builder.rs b/crates/turtle/src/atuin_client/history/builder.rs
index 72a505fd..72a505fd 100644
--- a/crates/atuin-client/src/history/builder.rs
+++ b/crates/turtle/src/atuin_client/history/builder.rs
diff --git a/crates/atuin-client/src/history/store.rs b/crates/turtle/src/atuin_client/history/store.rs
index ce7b43a1..66d9db47 100644
--- a/crates/atuin-client/src/history/store.rs
+++ b/crates/turtle/src/atuin_client/history/store.rs
@@ -3,12 +3,13 @@ use std::{collections::HashSet, fmt::Write, time::Duration};
use eyre::{Result, bail, eyre};
use indicatif::{ProgressBar, ProgressState, ProgressStyle};
use rmp::decode::Bytes;
+use tracing::debug;
-use crate::{
+use crate::atuin_client::{
database::{Database, current_context},
record::{encryption::PASETO_V4, sqlite_store::SqliteStore, store::Store},
};
-use atuin_common::record::{DecryptedData, Host, HostId, Record, RecordId, RecordIdx};
+use crate::atuin_common::record::{DecryptedData, Host, HostId, Record, RecordId, RecordIdx};
use super::{HISTORY_TAG, HISTORY_VERSION, HISTORY_VERSION_V0, History, HistoryId};
@@ -361,10 +362,10 @@ impl HistoryStore {
#[cfg(test)]
mod tests {
- use atuin_common::record::DecryptedData;
+ use crate::atuin_common::record::DecryptedData;
use time::macros::datetime;
- use crate::history::{HISTORY_VERSION, store::HistoryRecord};
+ use crate::atuin_client::history::{HISTORY_VERSION, store::HistoryRecord};
use super::History;
diff --git a/crates/atuin-client/src/import/bash.rs b/crates/turtle/src/atuin_client/import/bash.rs
index 99a44a58..d92fdfa0 100644
--- a/crates/atuin-client/src/import/bash.rs
+++ b/crates/turtle/src/atuin_client/import/bash.rs
@@ -5,10 +5,11 @@ use directories::UserDirs;
use eyre::{Result, eyre};
use itertools::Itertools;
use time::{Duration, OffsetDateTime};
+use tracing::warn;
use super::{Importer, Loader, get_histfile_path, unix_byte_lines};
-use crate::history::History;
-use crate::import::read_to_end;
+use crate::atuin_client::history::History;
+use crate::atuin_client::import::read_to_end;
#[derive(Debug)]
pub struct Bash {
@@ -130,7 +131,7 @@ mod test {
use itertools::{Itertools, assert_equal};
- use crate::import::{Importer, tests::TestLoader};
+ use crate::atuin_client::import::{Importer, tests::TestLoader};
use super::Bash;
@@ -183,7 +184,7 @@ cd ../
);
assert_equal(
loader.buf.iter().map(|h| h.timestamp.unix_timestamp()),
- [1672918999, 1672919006, 1672919020],
+ [1_672_918_999, 1_672_919_006, 1_672_919_020],
)
}
diff --git a/crates/atuin-client/src/import/fish.rs b/crates/turtle/src/atuin_client/import/fish.rs
index 9fcf624c..1375bdd6 100644
--- a/crates/atuin-client/src/import/fish.rs
+++ b/crates/turtle/src/atuin_client/import/fish.rs
@@ -9,8 +9,8 @@ use eyre::{Result, eyre};
use time::OffsetDateTime;
use super::{Importer, Loader, unix_byte_lines};
-use crate::history::History;
-use crate::import::read_to_end;
+use crate::atuin_client::history::History;
+use crate::atuin_client::import::read_to_end;
#[derive(Debug)]
pub struct Fish {
diff --git a/crates/atuin-client/src/import/mod.rs b/crates/turtle/src/atuin_client/import/mod.rs
index 4a1c6af6..7726ead7 100644
--- a/crates/atuin-client/src/import/mod.rs
+++ b/crates/turtle/src/atuin_client/import/mod.rs
@@ -6,7 +6,7 @@ use async_trait::async_trait;
use eyre::{Result, bail};
use memchr::Memchr;
-use crate::history::History;
+use crate::atuin_client::history::History;
pub mod bash;
pub mod fish;
diff --git a/crates/atuin-client/src/import/nu.rs b/crates/turtle/src/atuin_client/import/nu.rs
index cae90ac4..c93789b8 100644
--- a/crates/atuin-client/src/import/nu.rs
+++ b/crates/turtle/src/atuin_client/import/nu.rs
@@ -9,8 +9,8 @@ use eyre::{Result, eyre};
use time::OffsetDateTime;
use super::{Importer, Loader, unix_byte_lines};
-use crate::history::History;
-use crate::import::read_to_end;
+use crate::atuin_client::history::History;
+use crate::atuin_client::import::read_to_end;
#[derive(Debug)]
pub struct Nu {
diff --git a/crates/atuin-client/src/import/nu_histdb.rs b/crates/turtle/src/atuin_client/import/nu_histdb.rs
index a13cb2b4..7de18369 100644
--- a/crates/atuin-client/src/import/nu_histdb.rs
+++ b/crates/turtle/src/atuin_client/import/nu_histdb.rs
@@ -10,8 +10,8 @@ use sqlx::{Pool, sqlite::SqlitePool};
use time::{Duration, OffsetDateTime};
use super::Importer;
-use crate::history::History;
-use crate::import::Loader;
+use crate::atuin_client::history::History;
+use crate::atuin_client::import::Loader;
#[derive(sqlx::FromRow, Debug)]
pub struct HistDbEntry {
diff --git a/crates/atuin-client/src/import/powershell.rs b/crates/turtle/src/atuin_client/import/powershell.rs
index 86fd007d..8adcc850 100644
--- a/crates/atuin-client/src/import/powershell.rs
+++ b/crates/turtle/src/atuin_client/import/powershell.rs
@@ -5,8 +5,8 @@ use std::path::PathBuf;
use time::{Duration, OffsetDateTime};
use super::{Importer, Loader, count_lines, unix_byte_lines};
-use crate::history::History;
-use crate::import::read_to_end;
+use crate::atuin_client::history::History;
+use crate::atuin_client::import::read_to_end;
#[derive(Debug)]
pub struct PowerShell {
diff --git a/crates/atuin-client/src/import/replxx.rs b/crates/turtle/src/atuin_client/import/replxx.rs
index 47d566cf..42f84df5 100644
--- a/crates/atuin-client/src/import/replxx.rs
+++ b/crates/turtle/src/atuin_client/import/replxx.rs
@@ -6,8 +6,8 @@ use eyre::{Result, eyre};
use time::{OffsetDateTime, PrimitiveDateTime, macros::format_description};
use super::{Importer, Loader, get_histfile_path, unix_byte_lines};
-use crate::history::History;
-use crate::import::read_to_end;
+use crate::atuin_client::history::History;
+use crate::atuin_client::import::read_to_end;
#[derive(Debug)]
pub struct Replxx {
diff --git a/crates/atuin-client/src/import/resh.rs b/crates/turtle/src/atuin_client/import/resh.rs
index df15f5b4..c5980c44 100644
--- a/crates/atuin-client/src/import/resh.rs
+++ b/crates/turtle/src/atuin_client/import/resh.rs
@@ -5,12 +5,12 @@ use directories::UserDirs;
use eyre::{Result, eyre};
use serde::Deserialize;
-use atuin_common::utils::uuid_v7;
+use crate::atuin_common::utils::uuid_v7;
use time::OffsetDateTime;
use super::{Importer, Loader, get_histfile_path, unix_byte_lines};
-use crate::history::History;
-use crate::import::read_to_end;
+use crate::atuin_client::history::History;
+use crate::atuin_client::import::read_to_end;
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
diff --git a/crates/atuin-client/src/import/xonsh.rs b/crates/turtle/src/atuin_client/import/xonsh.rs
index 6f38de68..a7217826 100644
--- a/crates/atuin-client/src/import/xonsh.rs
+++ b/crates/turtle/src/atuin_client/import/xonsh.rs
@@ -11,8 +11,8 @@ use uuid::Uuid;
use uuid::timestamp::{Timestamp, context::NoContext};
use super::{Importer, Loader, get_histdir_path};
-use crate::history::History;
-use crate::utils::get_host_user;
+use crate::atuin_client::history::History;
+use crate::atuin_client::utils::get_host_user;
// Note: both HistoryFile and HistoryData have other keys present in the JSON, we don't
// care about them so we leave them unspecified so as to avoid deserializing unnecessarily.
diff --git a/crates/atuin-client/src/import/xonsh_sqlite.rs b/crates/turtle/src/atuin_client/import/xonsh_sqlite.rs
index 7d50ac84..ceedf7e9 100644
--- a/crates/atuin-client/src/import/xonsh_sqlite.rs
+++ b/crates/turtle/src/atuin_client/import/xonsh_sqlite.rs
@@ -11,8 +11,8 @@ use uuid::Uuid;
use uuid::timestamp::{Timestamp, context::NoContext};
use super::{Importer, Loader, get_histfile_path};
-use crate::history::History;
-use crate::utils::get_host_user;
+use crate::atuin_client::history::History;
+use crate::atuin_client::utils::get_host_user;
#[derive(Debug, FromRow)]
struct HistDbEntry {
diff --git a/crates/atuin-client/src/import/zsh.rs b/crates/turtle/src/atuin_client/import/zsh.rs
index 11e2f371..e1fd813a 100644
--- a/crates/atuin-client/src/import/zsh.rs
+++ b/crates/turtle/src/atuin_client/import/zsh.rs
@@ -10,8 +10,8 @@ use eyre::{Result, eyre};
use time::OffsetDateTime;
use super::{Importer, Loader, get_histfile_path, unix_byte_lines};
-use crate::history::History;
-use crate::import::read_to_end;
+use crate::atuin_client::history::History;
+use crate::atuin_client::import::read_to_end;
#[derive(Debug)]
pub struct Zsh {
diff --git a/crates/atuin-client/src/import/zsh_histdb.rs b/crates/turtle/src/atuin_client/import/zsh_histdb.rs
index bf44c3ad..f61bb74f 100644
--- a/crates/atuin-client/src/import/zsh_histdb.rs
+++ b/crates/turtle/src/atuin_client/import/zsh_histdb.rs
@@ -36,16 +36,16 @@ use std::collections::HashMap;
use std::path::{Path, PathBuf};
use async_trait::async_trait;
-use atuin_common::utils::uuid_v7;
+use crate::atuin_common::utils::uuid_v7;
use directories::UserDirs;
use eyre::{Result, eyre};
use sqlx::{Pool, sqlite::SqlitePool};
use time::PrimitiveDateTime;
use super::Importer;
-use crate::history::History;
-use crate::import::Loader;
-use crate::utils::{get_hostname, get_username};
+use crate::atuin_client::history::History;
+use crate::atuin_client::import::Loader;
+use crate::atuin_client::utils::{get_hostname, get_username};
#[derive(sqlx::FromRow, Debug)]
pub struct HistDbEntryCount {
diff --git a/crates/atuin-client/src/login.rs b/crates/turtle/src/atuin_client/login.rs
index 2545e890..ca4e16fe 100644
--- a/crates/atuin-client/src/login.rs
+++ b/crates/turtle/src/atuin_client/login.rs
@@ -1,11 +1,11 @@
use std::path::PathBuf;
-use atuin_common::api::LoginRequest;
+use crate::atuin_common::api::LoginRequest;
use eyre::{Context, Result, bail};
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
-use crate::{
+use crate::atuin_client::{
api_client,
encryption::{decode_key, load_key},
record::{sqlite_store::SqliteStore, store::Store},
diff --git a/crates/atuin-client/src/logout.rs b/crates/turtle/src/atuin_client/logout.rs
index f720b302..343934b9 100644
--- a/crates/atuin-client/src/logout.rs
+++ b/crates/turtle/src/atuin_client/logout.rs
@@ -1,6 +1,6 @@
use eyre::Result;
-use crate::settings::Settings;
+use crate::atuin_client::settings::Settings;
pub async fn logout() -> Result<()> {
let meta = Settings::meta_store().await?;
diff --git a/crates/atuin-client/src/meta.rs b/crates/turtle/src/atuin_client/meta.rs
index 870f36d0..1eea7061 100644
--- a/crates/atuin-client/src/meta.rs
+++ b/crates/turtle/src/atuin_client/meta.rs
@@ -2,11 +2,12 @@ use std::path::Path;
use std::str::FromStr;
use std::time::Duration;
-use atuin_common::record::HostId;
+use crate::atuin_common::record::HostId;
use eyre::{Result, eyre};
use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode, SqlitePool, SqlitePoolOptions};
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
use tokio::sync::OnceCell;
+use tracing::{debug, warn};
use uuid::Uuid;
// Filenames for the legacy plain-text files that we migrate from.
@@ -125,7 +126,7 @@ impl MetaStore {
return Ok(HostId(parsed));
}
- let uuid = atuin_common::utils::uuid_v7();
+ let uuid = crate::atuin_common::utils::uuid_v7();
self.set(KEY_HOST_ID, uuid.as_simple().to_string().as_ref())
.await?;
@@ -197,7 +198,7 @@ impl MetaStore {
return Ok(());
}
- let data_dir = crate::settings::Settings::effective_data_dir();
+ let data_dir = crate::atuin_client::settings::Settings::effective_data_dir();
// host_id — validate as UUID
let host_id_path = data_dir.join(LEGACY_HOST_ID_FILENAME);
diff --git a/crates/atuin-client/src/lib.rs b/crates/turtle/src/atuin_client/mod.rs
index cd7785e1..7f07f2e2 100644
--- a/crates/atuin-client/src/lib.rs
+++ b/crates/turtle/src/atuin_client/mod.rs
@@ -1,8 +1,3 @@
-#![deny(unsafe_code)]
-
-#[macro_use]
-extern crate log;
-
#[cfg(feature = "sync")]
pub mod api_client;
#[cfg(feature = "sync")]
diff --git a/crates/atuin-client/src/ordering.rs b/crates/turtle/src/atuin_client/ordering.rs
index 4e5ec84c..4e5ec84c 100644
--- a/crates/atuin-client/src/ordering.rs
+++ b/crates/turtle/src/atuin_client/ordering.rs
diff --git a/crates/atuin-client/src/plugin.rs b/crates/turtle/src/atuin_client/plugin.rs
index 6f351bf1..6f351bf1 100644
--- a/crates/atuin-client/src/plugin.rs
+++ b/crates/turtle/src/atuin_client/plugin.rs
diff --git a/crates/atuin-client/src/record/encryption.rs b/crates/turtle/src/atuin_client/record/encryption.rs
index 1e94d967..22dcdec3 100644
--- a/crates/atuin-client/src/record/encryption.rs
+++ b/crates/turtle/src/atuin_client/record/encryption.rs
@@ -1,4 +1,4 @@
-use atuin_common::record::{
+use crate::atuin_common::record::{
AdditionalData, DecryptedData, EncryptedData, Encryption, HostId, RecordId, RecordIdx,
};
use base64::{Engine, engine::general_purpose};
@@ -197,7 +197,7 @@ impl Assertions<'_> {
#[cfg(test)]
mod tests {
- use atuin_common::{
+ use crate::atuin_common::{
record::{Host, Record},
utils::uuid_v7,
};
diff --git a/crates/atuin-client/src/record/mod.rs b/crates/turtle/src/atuin_client/record/mod.rs
index c40fd395..c40fd395 100644
--- a/crates/atuin-client/src/record/mod.rs
+++ b/crates/turtle/src/atuin_client/record/mod.rs
diff --git a/crates/atuin-client/src/record/sqlite_store.rs b/crates/turtle/src/atuin_client/record/sqlite_store.rs
index ed51f3fd..5fab999d 100644
--- a/crates/atuin-client/src/record/sqlite_store.rs
+++ b/crates/turtle/src/atuin_client/record/sqlite_store.rs
@@ -13,11 +13,12 @@ use sqlx::{
Row,
sqlite::{SqliteConnectOptions, SqliteJournalMode, SqlitePool, SqlitePoolOptions, SqliteRow},
};
+use tracing::debug;
-use atuin_common::record::{
+use crate::atuin_common::record::{
EncryptedData, Host, HostId, Record, RecordId, RecordIdx, RecordStatus,
};
-use atuin_common::utils;
+use crate::atuin_common::utils;
use uuid::Uuid;
use super::encryption::PASETO_V4;
@@ -371,7 +372,7 @@ impl Store for SqliteStore {
#[cfg(test)]
mod tests {
- use atuin_common::{
+ use crate::atuin_common::{
record::{DecryptedData, EncryptedData, Host, HostId, Record},
utils::uuid_v7,
};
diff --git a/crates/atuin-client/src/record/store.rs b/crates/turtle/src/atuin_client/record/store.rs
index 49ca4968..f99085d0 100644
--- a/crates/atuin-client/src/record/store.rs
+++ b/crates/turtle/src/atuin_client/record/store.rs
@@ -1,7 +1,7 @@
use async_trait::async_trait;
use eyre::Result;
-use atuin_common::record::{EncryptedData, HostId, Record, RecordId, RecordIdx, RecordStatus};
+use crate::atuin_common::record::{EncryptedData, HostId, Record, RecordId, RecordIdx, RecordStatus};
/// A record store stores records
/// In more detail - we tend to need to process this into _another_ format to actually query it.
diff --git a/crates/atuin-client/src/record/sync.rs b/crates/turtle/src/atuin_client/record/sync.rs
index b785b5dc..f831570b 100644
--- a/crates/atuin-client/src/record/sync.rs
+++ b/crates/turtle/src/atuin_client/record/sync.rs
@@ -3,11 +3,12 @@ use std::{cmp::Ordering, fmt::Write};
use eyre::Result;
use thiserror::Error;
+use tracing::error;
use super::{encryption::PASETO_V4, store::Store};
-use crate::{api_client::Client, settings::Settings};
+use crate::atuin_client::{api_client::Client, settings::Settings};
-use atuin_common::record::{Diff, HostId, RecordId, RecordIdx, RecordStatus};
+use crate::atuin_common::record::{Diff, HostId, RecordId, RecordIdx, RecordStatus};
use indicatif::{ProgressBar, ProgressState, ProgressStyle};
#[derive(Error, Debug)]
@@ -372,10 +373,10 @@ pub async fn sync(
#[cfg(test)]
mod tests {
- use atuin_common::record::{Diff, EncryptedData, HostId, Record};
+ use crate::atuin_common::record::{Diff, EncryptedData, HostId, Record};
use pretty_assertions::assert_eq;
- use crate::{
+ use crate::atuin_client::{
record::{
encryption::PASETO_V4,
sqlite_store::SqliteStore,
@@ -387,11 +388,11 @@ mod tests {
fn test_record() -> Record<EncryptedData> {
Record::builder()
- .host(atuin_common::record::Host::new(HostId(
- atuin_common::utils::uuid_v7(),
+ .host(crate::atuin_common::record::Host::new(HostId(
+ crate::atuin_common::utils::uuid_v7(),
)))
.version("v1".into())
- .tag(atuin_common::utils::uuid_v7().simple().to_string())
+ .tag(crate::atuin_common::utils::uuid_v7().simple().to_string())
.data(EncryptedData {
data: String::new(),
content_encryption_key: String::new(),
diff --git a/crates/atuin-client/src/register.rs b/crates/turtle/src/atuin_client/register.rs
index ad077dd1..4b14c233 100644
--- a/crates/atuin-client/src/register.rs
+++ b/crates/turtle/src/atuin_client/register.rs
@@ -1,6 +1,6 @@
use eyre::Result;
-use crate::{api_client, settings::Settings};
+use crate::atuin_client::{api_client, settings::Settings};
pub async fn register_classic(
settings: &Settings,
@@ -14,7 +14,7 @@ pub async fn register_classic(
let meta = Settings::meta_store().await?;
meta.save_session(&session.session).await?;
- let _key = crate::encryption::load_key(settings)?;
+ let _key = crate::atuin_client::encryption::load_key(settings)?;
Ok(session.session)
}
diff --git a/crates/atuin-client/src/secrets.rs b/crates/turtle/src/atuin_client/secrets.rs
index e8a6ab62..e8a6ab62 100644
--- a/crates/atuin-client/src/secrets.rs
+++ b/crates/turtle/src/atuin_client/secrets.rs
diff --git a/crates/atuin-client/src/settings.rs b/crates/turtle/src/atuin_client/settings.rs
index 5fb65c17..b0ffc7c1 100644
--- a/crates/atuin-client/src/settings.rs
+++ b/crates/turtle/src/atuin_client/settings.rs
@@ -1,8 +1,8 @@
use std::{collections::HashMap, fmt, io::prelude::*, path::PathBuf, str::FromStr, sync::OnceLock};
use tokio::sync::OnceCell;
-use atuin_common::record::HostId;
-use atuin_common::utils;
+use crate::atuin_common::record::HostId;
+use crate::atuin_common::utils;
use clap::ValueEnum;
use config::{
Config, ConfigBuilder, Environment, File as ConfigFile, FileFormat, builder::DefaultState,
@@ -16,11 +16,10 @@ use serde_with::DeserializeFromStr;
use time::{OffsetDateTime, UtcOffset, format_description::FormatItem, macros::format_description};
pub const HISTORY_PAGE_SIZE: i64 = 100;
-static EXAMPLE_CONFIG: &str = include_str!("../config.toml");
static DATA_DIR: OnceLock<PathBuf> = OnceLock::new();
static META_CONFIG: OnceLock<(String, f64)> = OnceLock::new();
-static META_STORE: OnceCell<crate::meta::MetaStore> = OnceCell::const_new();
+static META_STORE: OnceCell<crate::atuin_client::meta::MetaStore> = OnceCell::const_new();
pub(crate) mod meta;
pub mod watcher;
@@ -374,8 +373,8 @@ impl SyncAuth {
/// Convert into the auth token type used by the API client.
///
/// Returns an error with an actionable message for `NotLoggedIn`.
- pub fn into_auth_token(self) -> Result<crate::api_client::AuthToken> {
- use crate::api_client::AuthToken;
+ pub fn into_auth_token(self) -> Result<crate::atuin_client::api_client::AuthToken> {
+ use crate::atuin_client::api_client::AuthToken;
match self {
SyncAuth::Legacy { token } => Ok(AuthToken::Token(token)),
SyncAuth::NotLoggedIn { reason } => Err(eyre!(reason)),
@@ -1038,7 +1037,6 @@ pub struct Settings {
pub timezone: Timezone,
pub style: Style,
pub auto_sync: bool,
- pub update_check: bool,
/// The sync address for atuin.
pub sync_address: String,
@@ -1144,18 +1142,18 @@ impl Settings {
DATA_DIR
.get()
.cloned()
- .unwrap_or_else(atuin_common::utils::data_dir)
+ .unwrap_or_else(crate::atuin_common::utils::data_dir)
}
// -- Meta store: lazily initialized on first access --
- pub async fn meta_store() -> Result<&'static crate::meta::MetaStore> {
+ pub async fn meta_store() -> Result<&'static crate::atuin_client::meta::MetaStore> {
META_STORE
.get_or_try_init(|| async {
let (db_path, timeout) = META_CONFIG.get().ok_or_else(|| {
eyre!("meta store config not set — Settings::new() has not been called")
})?;
- crate::meta::MetaStore::new(db_path, *timeout).await
+ crate::atuin_client::meta::MetaStore::new(db_path, *timeout).await
})
.await
}
@@ -1240,7 +1238,7 @@ impl Settings {
/// `AuthToken`. Callers that need to distinguish between auth states
/// (e.g. to show different UI) should call `resolve_sync_auth` directly.
#[cfg(feature = "sync")]
- pub async fn sync_auth_token(&self) -> Result<crate::api_client::AuthToken> {
+ pub async fn sync_auth_token(&self) -> Result<crate::atuin_client::api_client::AuthToken> {
self.resolve_sync_auth().await.into_auth_token()
}
@@ -1262,7 +1260,7 @@ impl Settings {
}
pub fn builder() -> Result<ConfigBuilder<DefaultState>> {
- Self::builder_with_data_dir(&atuin_common::utils::data_dir())
+ Self::builder_with_data_dir(&crate::atuin_common::utils::data_dir())
}
fn builder_with_data_dir(data_dir: &std::path::Path) -> Result<ConfigBuilder<DefaultState>> {
@@ -1271,9 +1269,9 @@ impl Settings {
let kv_path = data_dir.join("kv.db");
let scripts_path = data_dir.join("scripts.db");
let ai_sessions_path = data_dir.join("ai_sessions.db");
- let socket_path = atuin_common::utils::runtime_dir().join("atuin.sock");
+ let socket_path = crate::atuin_common::utils::runtime_dir().join("atuin.sock");
let pidfile_path = data_dir.join("atuin-daemon.pid");
- let logs_dir = atuin_common::utils::logs_dir();
+ let logs_dir = crate::atuin_common::utils::logs_dir();
let key_path = data_dir.join("key");
let meta_path = data_dir.join("meta.db");
@@ -1286,7 +1284,6 @@ impl Settings {
.set_default("dialect", "us")?
.set_default("timezone", "local")?
.set_default("auto_sync", true)?
- .set_default("update_check", cfg!(feature = "check-update"))?
.set_default("sync_address", "https://api.atuin.sh")?
.set_default("sync_frequency", "5m")?
.set_default("search_mode", "fuzzy")?
@@ -1390,7 +1387,7 @@ impl Settings {
}
pub fn get_config_path() -> Result<PathBuf> {
- let config_dir = atuin_common::utils::config_dir();
+ let config_dir = crate::atuin_common::utils::config_dir();
create_dir_all(&config_dir)
.wrap_err_with(|| format!("could not create dir {config_dir:?}"))?;
@@ -1447,10 +1444,10 @@ impl Settings {
.map_err(|e| eyre!("failed to expand data_dir path: {}", e))?;
PathBuf::from(expanded.as_ref())
}
- None => atuin_common::utils::data_dir(),
+ None => crate::atuin_common::utils::data_dir(),
}
} else {
- atuin_common::utils::data_dir()
+ crate::atuin_common::utils::data_dir()
};
DATA_DIR.set(effective_data_dir.clone()).ok();
@@ -1467,7 +1464,10 @@ impl Settings {
config_builder.add_source(ConfigFile::new(config_file_str, FileFormat::Toml))
} else {
let mut file = File::create(config_file).wrap_err("could not create config file")?;
- file.write_all(EXAMPLE_CONFIG.as_bytes())
+
+ let config = config_builder.build_cloned()?;
+ // TODO(@bpeetz): Not so sure about this <2026-06-10>
+ file.write_all(config.cache.to_string().as_bytes())
.wrap_err("could not write default config file")?;
config_builder
@@ -1590,10 +1590,6 @@ impl Settings {
.map_err(|e| eyre!("failed to expand path: {}", e))
}
- pub fn example_config() -> &'static str {
- EXAMPLE_CONFIG
- }
-
pub fn paths_ok(&self) -> bool {
let paths = [
&self.db_path,
@@ -1766,7 +1762,7 @@ mod tests {
assert_eq!(meta_db_path, custom_dir.join("meta.db").to_str().unwrap());
assert_eq!(
daemon_socket_path,
- atuin_common::utils::runtime_dir()
+ crate::atuin_common::utils::runtime_dir()
.join("atuin.sock")
.to_str()
.unwrap()
@@ -1783,7 +1779,7 @@ mod tests {
#[test]
fn effective_data_dir_returns_default_when_not_set() {
let effective = super::Settings::effective_data_dir();
- let default = atuin_common::utils::data_dir();
+ let default = crate::atuin_common::utils::data_dir();
assert!(effective.to_str().is_some());
assert!(effective.ends_with("atuin") || effective == default);
diff --git a/crates/atuin-client/src/settings/meta.rs b/crates/turtle/src/atuin_client/settings/meta.rs
index 108d74ec..450d0432 100644
--- a/crates/atuin-client/src/settings/meta.rs
+++ b/crates/turtle/src/atuin_client/settings/meta.rs
@@ -7,7 +7,7 @@ pub struct Settings {
impl Default for Settings {
fn default() -> Self {
- let dir = atuin_common::utils::data_dir();
+ let dir = crate::atuin_common::utils::data_dir();
let path = dir.join("meta.db");
Self {
diff --git a/crates/atuin-client/src/settings/watcher.rs b/crates/turtle/src/atuin_client/settings/watcher.rs
index 740b8d12..7548573e 100644
--- a/crates/atuin-client/src/settings/watcher.rs
+++ b/crates/turtle/src/atuin_client/settings/watcher.rs
@@ -6,7 +6,7 @@
//! # Example
//!
//! ```no_run
-//! use atuin_client::settings::watcher::global_settings_watcher;
+//! use crate::atuin_client::settings::watcher::global_settings_watcher;
//!
//! async fn example() -> eyre::Result<()> {
//! let watcher = global_settings_watcher()?;
@@ -103,7 +103,7 @@ impl SettingsWatcher {
let config_dir = if let Ok(p) = std::env::var("ATUIN_CONFIG_DIR") {
PathBuf::from(p)
} else {
- atuin_common::utils::config_dir()
+ crate::atuin_common::utils::config_dir()
};
config_dir.join("config.toml")
}
diff --git a/crates/atuin-client/src/sync.rs b/crates/turtle/src/atuin_client/sync.rs
index 2c902794..361b6636 100644
--- a/crates/atuin-client/src/sync.rs
+++ b/crates/turtle/src/atuin_client/sync.rs
@@ -2,12 +2,13 @@ use std::collections::HashSet;
use std::iter::FromIterator;
use eyre::Result;
+use tracing::{debug, info};
-use atuin_common::api::AddHistoryRequest;
+use crate::atuin_common::api::AddHistoryRequest;
use crypto_secretbox::Key;
use time::OffsetDateTime;
-use crate::{
+use crate::atuin_client::{
api_client,
database::Database,
encryption::{decrypt, encrypt, load_key},
diff --git a/crates/atuin-client/src/theme.rs b/crates/turtle/src/atuin_client/theme.rs
index a277ac13..1d9c0b9e 100644
--- a/crates/atuin-client/src/theme.rs
+++ b/crates/turtle/src/atuin_client/theme.rs
@@ -395,7 +395,7 @@ impl ThemeManager {
}
PathBuf::from(p)
} else {
- let config_dir = atuin_common::utils::config_dir();
+ let config_dir = crate::atuin_common::utils::config_dir();
let mut theme_file = if let Ok(p) = std::env::var("ATUIN_CONFIG_DIR") {
PathBuf::from(p)
} else {
@@ -407,7 +407,7 @@ impl ThemeManager {
theme_file
};
- let theme_toml = format!["{name}.toml"];
+ let theme_toml = format!("{name}.toml");
theme_file.push(theme_toml);
let mut config_builder = Config::builder();
diff --git a/crates/atuin-client/src/utils.rs b/crates/turtle/src/atuin_client/utils.rs
index 35d7db26..35d7db26 100644
--- a/crates/atuin-client/src/utils.rs
+++ b/crates/turtle/src/atuin_client/utils.rs
diff --git a/crates/atuin-common/src/api.rs b/crates/turtle/src/atuin_common/api.rs
index 1a9f348c..1a9f348c 100644
--- a/crates/atuin-common/src/api.rs
+++ b/crates/turtle/src/atuin_common/api.rs
diff --git a/crates/atuin-common/src/calendar.rs b/crates/turtle/src/atuin_common/calendar.rs
index d3b1d921..d3b1d921 100644
--- a/crates/atuin-common/src/calendar.rs
+++ b/crates/turtle/src/atuin_common/calendar.rs
diff --git a/crates/atuin-common/src/lib.rs b/crates/turtle/src/atuin_common/mod.rs
index 91164a82..d886520d 100644
--- a/crates/atuin-common/src/lib.rs
+++ b/crates/turtle/src/atuin_common/mod.rs
@@ -1,5 +1,3 @@
-#![deny(unsafe_code)]
-
/// Defines a new UUID type wrapper
macro_rules! new_uuid {
($name:ident) => {
diff --git a/crates/atuin-common/src/record.rs b/crates/turtle/src/atuin_common/record.rs
index e6ce2647..05c29338 100644
--- a/crates/atuin-common/src/record.rs
+++ b/crates/turtle/src/atuin_common/record.rs
@@ -46,7 +46,7 @@ pub type RecordIdx = u64;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, TypedBuilder)]
pub struct Record<Data> {
/// a unique ID
- #[builder(default = RecordId(crate::utils::uuid_v7()))]
+ #[builder(default = RecordId(crate::atuin_common::utils::uuid_v7()))]
pub id: RecordId,
/// The integer record ID. This is only unique per (host, tag).
@@ -280,16 +280,16 @@ impl Record<EncryptedData> {
#[cfg(test)]
mod tests {
- use crate::record::{Host, HostId};
+ use crate::atuin_common::record::{Host, HostId};
use super::{DecryptedData, Diff, Record, RecordStatus};
use pretty_assertions::assert_eq;
fn test_record() -> Record<DecryptedData> {
Record::builder()
- .host(Host::new(HostId(crate::utils::uuid_v7())))
+ .host(Host::new(HostId(crate::atuin_common::utils::uuid_v7())))
.version("v1".into())
- .tag(crate::utils::uuid_v7().simple().to_string())
+ .tag(crate::atuin_common::utils::uuid_v7().simple().to_string())
.data(DecryptedData(vec![0, 1, 2, 3]))
.idx(0)
.build()
diff --git a/crates/atuin-common/src/shell.rs b/crates/turtle/src/atuin_common/shell.rs
index 7f9a7b8f..7f9a7b8f 100644
--- a/crates/atuin-common/src/shell.rs
+++ b/crates/turtle/src/atuin_common/shell.rs
diff --git a/crates/atuin-common/src/tls.rs b/crates/turtle/src/atuin_common/tls.rs
index e8c840e0..e8c840e0 100644
--- a/crates/atuin-common/src/tls.rs
+++ b/crates/turtle/src/atuin_common/tls.rs
diff --git a/crates/atuin-common/src/utils.rs b/crates/turtle/src/atuin_common/utils.rs
index d7382fb2..d7382fb2 100644
--- a/crates/atuin-common/src/utils.rs
+++ b/crates/turtle/src/atuin_common/utils.rs
diff --git a/crates/atuin-daemon/src/client.rs b/crates/turtle/src/atuin_daemon/client.rs
index c18e0e46..45ef19e9 100644
--- a/crates/atuin-daemon/src/client.rs
+++ b/crates/turtle/src/atuin_daemon/client.rs
@@ -1,8 +1,6 @@
-use atuin_client::database::Context;
-use atuin_client::settings::{FilterMode, Settings};
+use crate::atuin_client::database::Context;
+use crate::atuin_client::settings::{FilterMode, Settings};
use eyre::{Context as EyreContext, Result};
-#[cfg(windows)]
-use tokio::net::TcpStream;
use tonic::Code;
use tonic::transport::{Channel, Endpoint, Uri};
use tower::service_fn;
@@ -12,25 +10,25 @@ use hyper_util::rt::TokioIo;
#[cfg(unix)]
use tokio::net::UnixStream;
-use atuin_client::history::History;
+use crate::atuin_client::history::History;
use tracing::{Level, instrument, span};
-use crate::control::HistoryRebuiltEvent;
-use crate::control::{
+use crate::atuin_daemon::control::HistoryRebuiltEvent;
+use crate::atuin_daemon::control::{
ForceSyncEvent, HistoryDeletedEvent, HistoryPrunedEvent, SendEventRequest,
SettingsReloadedEvent, ShutdownEvent, control_client::ControlClient as ControlServiceClient,
};
-use crate::events::DaemonEvent;
-use crate::history::{
+use crate::atuin_daemon::events::DaemonEvent;
+use crate::atuin_daemon::history::{
EndHistoryReply, EndHistoryRequest, ShutdownRequest, StartHistoryReply, StartHistoryRequest,
StatusReply, StatusRequest, TailHistoryReply, TailHistoryRequest,
history_client::HistoryClient as HistoryServiceClient,
};
-use crate::search::{
+use crate::atuin_daemon::search::{
FilterMode as RpcFilterMode, SearchContext as RpcSearchContext, SearchRequest, SearchResponse,
search_client::SearchClient as SearchServiceClient,
};
-use crate::semantic::{
+use crate::atuin_daemon::semantic::{
CommandCapture, CommandOutputReply, CommandOutputRequest, OutputRange, RecordCommandsReply,
semantic_client::SemanticClient as SemanticServiceClient,
};
@@ -94,28 +92,6 @@ impl HistoryClient {
Ok(HistoryClient { client })
}
- #[cfg(not(unix))]
- pub async fn new(port: u64) -> Result<Self> {
- let channel = Endpoint::try_from("http://atuin_local_daemon:0")?
- .connect_with_connector(service_fn(move |_: Uri| {
- let url = format!("127.0.0.1:{port}");
-
- async move {
- Ok::<_, std::io::Error>(TokioIo::new(TcpStream::connect(url.clone()).await?))
- }
- }))
- .await
- .wrap_err_with(|| {
- format!(
- "failed to connect to local atuin daemon at 127.0.0.1:{port}. Is it running?"
- )
- })?;
-
- let client = HistoryServiceClient::new(channel);
-
- Ok(HistoryClient { client })
- }
-
pub async fn start_history(&mut self, h: History) -> Result<StartHistoryReply> {
let req = StartHistoryRequest {
command: h.command,
@@ -188,28 +164,6 @@ impl SearchClient {
Ok(SearchClient { client })
}
- #[cfg(not(unix))]
- pub async fn new(port: u64) -> Result<Self> {
- let channel = Endpoint::try_from("http://atuin_local_daemon:0")?
- .connect_with_connector(service_fn(move |_: Uri| {
- let url = format!("127.0.0.1:{port}");
-
- async move {
- Ok::<_, std::io::Error>(TokioIo::new(TcpStream::connect(url.clone()).await?))
- }
- }))
- .await
- .wrap_err_with(|| {
- format!(
- "failed to connect to local atuin daemon at 127.0.0.1:{port}. Is it running?"
- )
- })?;
-
- let client = SearchServiceClient::new(channel);
-
- Ok(SearchClient { client })
- }
-
#[instrument(skip_all, level = Level::TRACE, name = "daemon_client_search", fields(query = %query, query_id = query_id))]
pub async fn search(
&mut self,
@@ -289,38 +243,11 @@ impl SemanticClient {
Ok(SemanticClient { client })
}
- #[cfg(not(unix))]
- pub async fn new(port: u64) -> Result<Self> {
- let channel = Endpoint::try_from("http://atuin_local_daemon:0")?
- .connect_with_connector(service_fn(move |_: Uri| {
- let url = format!("127.0.0.1:{port}");
-
- async move {
- Ok::<_, std::io::Error>(TokioIo::new(TcpStream::connect(url.clone()).await?))
- }
- }))
- .await
- .wrap_err_with(|| {
- format!(
- "failed to connect to local atuin daemon at 127.0.0.1:{port}. Is it running?"
- )
- })?;
-
- let client = SemanticServiceClient::new(channel);
-
- Ok(SemanticClient { client })
- }
-
#[cfg(unix)]
pub async fn from_settings(settings: &Settings) -> Result<Self> {
Self::new(settings.daemon.socket_path.clone()).await
}
- #[cfg(not(unix))]
- pub async fn from_settings(settings: &Settings) -> Result<Self> {
- Self::new(settings.daemon.tcp_port).await
- }
-
pub async fn record_commands(
&mut self,
captures: Vec<CommandCapture>,
@@ -383,41 +310,12 @@ impl ControlClient {
Ok(ControlClient { client })
}
- /// Connect to the daemon's control service.
- #[cfg(not(unix))]
- pub async fn new(port: u64) -> Result<Self> {
- let channel = Endpoint::try_from("http://atuin_local_daemon:0")?
- .connect_with_connector(service_fn(move |_: Uri| {
- let url = format!("127.0.0.1:{port}");
-
- async move {
- Ok::<_, std::io::Error>(TokioIo::new(TcpStream::connect(url.clone()).await?))
- }
- }))
- .await
- .wrap_err_with(|| {
- format!(
- "failed to connect to local atuin daemon at 127.0.0.1:{port}. Is it running?"
- )
- })?;
-
- let client = ControlServiceClient::new(channel);
-
- Ok(ControlClient { client })
- }
-
/// Connect using settings.
#[cfg(unix)]
pub async fn from_settings(settings: &Settings) -> Result<Self> {
Self::new(settings.daemon.socket_path.clone()).await
}
- /// Connect using settings.
- #[cfg(not(unix))]
- pub async fn from_settings(settings: &Settings) -> Result<Self> {
- Self::new(settings.daemon.tcp_port).await
- }
-
/// Send an event to the daemon.
pub async fn send_event(&mut self, event: DaemonEvent) -> Result<()> {
let proto_event = daemon_event_to_proto(event);
@@ -430,8 +328,10 @@ impl ControlClient {
}
/// Convert a daemon event to its proto representation.
-fn daemon_event_to_proto(event: DaemonEvent) -> crate::control::send_event_request::Event {
- use crate::control::send_event_request::Event;
+fn daemon_event_to_proto(
+ event: DaemonEvent,
+) -> crate::atuin_daemon::control::send_event_request::Event {
+ use crate::atuin_daemon::control::send_event_request::Event;
match event {
DaemonEvent::HistoryPruned => Event::HistoryPruned(HistoryPrunedEvent {}),
diff --git a/crates/atuin-daemon/src/components/history.rs b/crates/turtle/src/atuin_daemon/components/history.rs
index c82c8f94..95d34b69 100644
--- a/crates/atuin-daemon/src/components/history.rs
+++ b/crates/turtle/src/atuin_daemon/components/history.rs
@@ -4,7 +4,7 @@
use std::{pin::Pin, sync::Arc};
-use atuin_client::{
+use crate::atuin_client::{
database::Database,
history::{History, HistoryId, store::HistoryStore},
settings::Settings,
@@ -16,7 +16,7 @@ use tokio_stream::Stream;
use tonic::{Request, Response, Status};
use tracing::{Level, instrument};
-use crate::{
+use crate::atuin_daemon::{
daemon::{Component, DaemonHandle},
events::DaemonEvent,
history::{
diff --git a/crates/atuin-daemon/src/components/mod.rs b/crates/turtle/src/atuin_daemon/components/mod.rs
index 447e31df..447e31df 100644
--- a/crates/atuin-daemon/src/components/mod.rs
+++ b/crates/turtle/src/atuin_daemon/components/mod.rs
diff --git a/crates/atuin-daemon/src/components/search.rs b/crates/turtle/src/atuin_daemon/components/search.rs
index 9fc87fae..85191cff 100644
--- a/crates/atuin-daemon/src/components/search.rs
+++ b/crates/turtle/src/atuin_daemon/components/search.rs
@@ -5,7 +5,7 @@
use std::{pin::Pin, sync::Arc};
-use atuin_client::database::Database;
+use crate::atuin_client::database::Database;
use eyre::Result;
use tokio::sync::RwLock;
use tokio_stream::Stream;
@@ -13,7 +13,7 @@ use tonic::{Request, Response, Status, Streaming};
use tracing::{Level, debug, info, instrument, span, trace};
use uuid::Uuid;
-use crate::{
+use crate::atuin_daemon::{
daemon::{Component, DaemonHandle},
events::DaemonEvent,
search::{
@@ -368,7 +368,7 @@ impl SearchSvc for SearchGrpcService {
/// Convert proto FilterMode and context to IndexFilterMode.
fn convert_filter_mode(
mode: FilterMode,
- context: &Option<crate::search::SearchContext>,
+ context: &Option<crate::atuin_daemon::search::SearchContext>,
) -> IndexFilterMode {
match (mode, context) {
(FilterMode::Global, _) => IndexFilterMode::Global,
diff --git a/crates/atuin-daemon/src/components/semantic.rs b/crates/turtle/src/atuin_daemon/components/semantic.rs
index dff38fd3..a42fd5cb 100644
--- a/crates/atuin-daemon/src/components/semantic.rs
+++ b/crates/turtle/src/atuin_daemon/components/semantic.rs
@@ -8,13 +8,13 @@ use std::collections::{HashMap, VecDeque};
use std::fmt::{Display, Formatter};
use std::sync::Arc;
-use atuin_client::history::{History, HistoryId};
+use crate::atuin_client::history::{History, HistoryId};
use eyre::Result;
use tokio::sync::Mutex;
use tonic::{Request, Response, Status, Streaming};
use tracing::{Level, instrument};
-use crate::{
+use crate::atuin_daemon::{
daemon::{Component, DaemonHandle},
events::DaemonEvent,
semantic::{
@@ -244,7 +244,7 @@ impl SemanticState {
fn command_output_for_ref(
&self,
capture_ref: &CaptureRef,
- ranges: &[crate::semantic::OutputRange],
+ ranges: &[crate::atuin_daemon::semantic::OutputRange],
) -> Option<CommandOutputReply> {
let stored = self
.sessions
@@ -534,14 +534,17 @@ fn command_output_not_found() -> CommandOutputReply {
}
}
-fn select_output_ranges(output: &str, ranges: &[crate::semantic::OutputRange]) -> Vec<OutputLine> {
+fn select_output_ranges(
+ output: &str,
+ ranges: &[crate::atuin_daemon::semantic::OutputRange],
+) -> Vec<OutputLine> {
let lines: Vec<&str> = output.lines().collect();
if lines.is_empty() {
return Vec::new();
}
let ranges = if ranges.is_empty() {
- vec![crate::semantic::OutputRange { start: 0, end: 999 }]
+ vec![crate::atuin_daemon::semantic::OutputRange { start: 0, end: 999 }]
} else {
ranges.to_vec()
};
@@ -816,8 +819,8 @@ mod tests {
fn output_ranges_are_line_based_inclusive_and_support_negative_offsets() {
let output = "zero\none\ntwo\nthree\nfour";
let ranges = vec![
- crate::semantic::OutputRange { start: 1, end: 2 },
- crate::semantic::OutputRange { start: -2, end: -1 },
+ crate::atuin_daemon::semantic::OutputRange { start: 1, end: 2 },
+ crate::atuin_daemon::semantic::OutputRange { start: -2, end: -1 },
];
assert_eq!(
@@ -838,8 +841,8 @@ mod tests {
.collect::<Vec<_>>()
.join("\n");
let ranges = vec![
- crate::semantic::OutputRange { start: 0, end: 100 },
- crate::semantic::OutputRange {
+ crate::atuin_daemon::semantic::OutputRange { start: 0, end: 100 },
+ crate::atuin_daemon::semantic::OutputRange {
start: -100,
end: -1,
},
@@ -856,8 +859,8 @@ mod tests {
fn output_ranges_can_leave_gaps_for_client_formatting() {
let output = "zero\none\ntwo\nthree\nfour";
let ranges = vec![
- crate::semantic::OutputRange { start: 0, end: 1 },
- crate::semantic::OutputRange { start: 4, end: 4 },
+ crate::atuin_daemon::semantic::OutputRange { start: 0, end: 1 },
+ crate::atuin_daemon::semantic::OutputRange { start: 4, end: 4 },
];
assert_eq!(
@@ -888,8 +891,8 @@ mod tests {
fn output_ranges_skip_ranges_fully_outside_output() {
let output = "zero\none\ntwo";
let ranges = vec![
- crate::semantic::OutputRange { start: 10, end: 20 },
- crate::semantic::OutputRange {
+ crate::atuin_daemon::semantic::OutputRange { start: 10, end: 20 },
+ crate::atuin_daemon::semantic::OutputRange {
start: -20,
end: -10,
},
diff --git a/crates/atuin-daemon/src/components/sync.rs b/crates/turtle/src/atuin_daemon/components/sync.rs
index 6e486250..c76fb71b 100644
--- a/crates/atuin-daemon/src/components/sync.rs
+++ b/crates/turtle/src/atuin_daemon/components/sync.rs
@@ -9,9 +9,9 @@ use rand::Rng;
use tokio::sync::mpsc;
use tokio::time::{self, MissedTickBehavior};
-use atuin_client::{history::store::HistoryStore, record::sync, settings::Settings};
+use crate::atuin_client::{history::store::HistoryStore, record::sync, settings::Settings};
-use crate::{
+use crate::atuin_daemon::{
daemon::{Component, DaemonHandle},
events::DaemonEvent,
};
diff --git a/crates/atuin-daemon/src/control/mod.rs b/crates/turtle/src/atuin_daemon/control/mod.rs
index afb29c57..afb29c57 100644
--- a/crates/atuin-daemon/src/control/mod.rs
+++ b/crates/turtle/src/atuin_daemon/control/mod.rs
diff --git a/crates/atuin-daemon/src/control/service.rs b/crates/turtle/src/atuin_daemon/control/service.rs
index 2e7403ce..cb2ff74e 100644
--- a/crates/atuin-daemon/src/control/service.rs
+++ b/crates/turtle/src/atuin_daemon/control/service.rs
@@ -3,7 +3,7 @@
//! This gRPC service allows external processes (like CLI commands) to inject
//! events into the daemon's event bus.
-use atuin_client::history::HistoryId;
+use crate::atuin_client::history::HistoryId;
use tonic::{Request, Response, Status};
use tracing::{Level, info, instrument};
@@ -12,7 +12,7 @@ use super::{
control_server::{Control, ControlServer},
send_event_request::Event,
};
-use crate::{daemon::DaemonHandle, events::DaemonEvent};
+use crate::atuin_daemon::{daemon::DaemonHandle, events::DaemonEvent};
/// The Control gRPC service.
///
diff --git a/crates/atuin-daemon/src/daemon.rs b/crates/turtle/src/atuin_daemon/daemon.rs
index 625ca205..77c0d8a5 100644
--- a/crates/atuin-daemon/src/daemon.rs
+++ b/crates/turtle/src/atuin_daemon/daemon.rs
@@ -10,14 +10,14 @@
use std::sync::Arc;
-use atuin_client::{
+use crate::atuin_client::{
database::Sqlite as HistoryDatabase, encryption, record::sqlite_store::SqliteStore,
settings::Settings,
};
use eyre::{Context, Result};
use tokio::sync::{RwLock, broadcast};
-use crate::events::DaemonEvent;
+use crate::atuin_daemon::events::DaemonEvent;
// ============================================================================
// DaemonState
diff --git a/crates/atuin-daemon/src/events.rs b/crates/turtle/src/atuin_daemon/events.rs
index 4e6c6ff3..9a398925 100644
--- a/crates/atuin-daemon/src/events.rs
+++ b/crates/turtle/src/atuin_daemon/events.rs
@@ -7,8 +7,8 @@
//! External processes (like CLI commands) can also inject events via the
//! Control gRPC service.
-use atuin_client::history::{History, HistoryId};
-use atuin_common::record::RecordId;
+use crate::atuin_client::history::{History, HistoryId};
+use crate::atuin_common::record::RecordId;
/// Events that flow through the daemon's event bus.
///
diff --git a/crates/atuin-daemon/src/history/mod.rs b/crates/turtle/src/atuin_daemon/history/mod.rs
index b71853df..b71853df 100644
--- a/crates/atuin-daemon/src/history/mod.rs
+++ b/crates/turtle/src/atuin_daemon/history/mod.rs
diff --git a/crates/atuin-daemon/src/lib.rs b/crates/turtle/src/atuin_daemon/mod.rs
index 27d3932b..b05eb95c 100644
--- a/crates/atuin-daemon/src/lib.rs
+++ b/crates/turtle/src/atuin_daemon/mod.rs
@@ -1,6 +1,6 @@
-use atuin_client::database::Sqlite as HistoryDatabase;
-use atuin_client::record::sqlite_store::SqliteStore;
-use atuin_client::settings::{Settings, watcher::global_settings_watcher};
+use crate::atuin_client::database::Sqlite as HistoryDatabase;
+use crate::atuin_client::record::sqlite_store::SqliteStore;
+use crate::atuin_client::settings::{Settings, watcher::global_settings_watcher};
use eyre::Result;
pub mod client;
@@ -126,11 +126,3 @@ async fn shutdown_signal() {
_ = int.recv() => {},
}
}
-
-/// Wait for a shutdown signal (Ctrl+C).
-#[cfg(not(unix))]
-async fn shutdown_signal() {
- tokio::signal::ctrl_c()
- .await
- .expect("failed to listen for ctrl+c");
-}
diff --git a/crates/atuin-daemon/src/search/index.rs b/crates/turtle/src/atuin_daemon/search/index.rs
index bb155979..df627e1b 100644
--- a/crates/atuin-daemon/src/search/index.rs
+++ b/crates/turtle/src/atuin_daemon/search/index.rs
@@ -12,8 +12,11 @@ use std::{
sync::Arc,
};
-use atuin_client::history::{History, is_known_agent};
-use atuin_client::settings::Search;
+use crate::atuin_client::settings::Search;
+use crate::{
+ atuin_client::history::{History, is_known_agent},
+ atuin_daemon::components::search::with_trailing_slash,
+};
use atuin_nucleo::{Injector, Nucleo, pattern};
use dashmap::DashMap;
use lasso::{Spur, ThreadedRodeo};
@@ -22,8 +25,6 @@ use tokio::sync::RwLock;
use tracing::{Level, instrument};
use uuid::Uuid;
-use crate::components::search::with_trailing_slash;
-
/// Parse a UUID string into a 16-byte array.
/// Returns None if the string is not a valid UUID.
fn parse_uuid_bytes(s: &str) -> Option<[u8; 16]> {
@@ -491,7 +492,7 @@ mod tests {
#[test]
fn frecency_data_compute() {
- let now = 1000000i64;
+ let now = 1_000_000i64;
// Recent command (with default multipliers of 1.0)
let recent = FrecencyData {
@@ -518,7 +519,7 @@ mod tests {
#[test]
fn frecency_data_compute_with_multipliers() {
- let now = 1000000i64;
+ let now = 1_000_000_i64;
let data = FrecencyData {
count: 5,
diff --git a/crates/atuin-daemon/src/search/mod.rs b/crates/turtle/src/atuin_daemon/search/mod.rs
index 4d261956..4d261956 100644
--- a/crates/atuin-daemon/src/search/mod.rs
+++ b/crates/turtle/src/atuin_daemon/search/mod.rs
diff --git a/crates/atuin-daemon/src/semantic/mod.rs b/crates/turtle/src/atuin_daemon/semantic/mod.rs
index c3511676..c3511676 100644
--- a/crates/atuin-daemon/src/semantic/mod.rs
+++ b/crates/turtle/src/atuin_daemon/semantic/mod.rs
diff --git a/crates/atuin-daemon/src/server.rs b/crates/turtle/src/atuin_daemon/server.rs
index b823cff2..23b04342 100644
--- a/crates/atuin-daemon/src/server.rs
+++ b/crates/turtle/src/atuin_daemon/server.rs
@@ -1,15 +1,15 @@
use eyre::Result;
-use crate::components::history::HistoryGrpcService;
-use crate::components::search::SearchGrpcService;
-use crate::components::semantic::SemanticGrpcService;
-use crate::control::{ControlService, control_server::ControlServer};
-use crate::daemon::DaemonHandle;
-use crate::history::history_server::HistoryServer;
-use crate::search::search_server::SearchServer;
-use crate::semantic::semantic_server::SemanticServer;
+use crate::atuin_daemon::components::history::HistoryGrpcService;
+use crate::atuin_daemon::components::search::SearchGrpcService;
+use crate::atuin_daemon::components::semantic::SemanticGrpcService;
+use crate::atuin_daemon::control::{ControlService, control_server::ControlServer};
+use crate::atuin_daemon::daemon::DaemonHandle;
+use crate::atuin_daemon::history::history_server::HistoryServer;
+use crate::atuin_daemon::search::search_server::SearchServer;
+use crate::atuin_daemon::semantic::semantic_server::SemanticServer;
-use atuin_client::settings::Settings;
+use crate::atuin_client::settings::Settings;
/// Run the gRPC server with the given services.
///
@@ -65,8 +65,6 @@ pub async fn run_grpc_server(
}
(UnixListener::from_std(listener)?, false)
}
- #[cfg(not(target_os = "linux"))]
- unreachable!()
} else {
tracing::info!("listening on unix socket {socket_path:?}");
(UnixListener::bind(socket_path.clone())?, true)
@@ -78,7 +76,7 @@ pub async fn run_grpc_server(
let shutdown_signal = async move {
let mut rx = handle.subscribe();
loop {
- use crate::DaemonEvent;
+ use crate::atuin_daemon::DaemonEvent;
match rx.recv().await {
Ok(DaemonEvent::ShutdownRequested) => break,
@@ -115,56 +113,3 @@ pub async fn run_grpc_server(
Ok(())
}
-
-/// Run the gRPC server with the given services (Windows/TCP version).
-#[cfg(not(unix))]
-pub async fn run_grpc_server(
- settings: Settings,
- history_service: HistoryServer<HistoryGrpcService>,
- search_service: SearchServer<SearchGrpcService>,
- semantic_service: SemanticServer<SemanticGrpcService>,
- control_service: ControlServer<ControlService>,
- handle: DaemonHandle,
-) -> Result<()> {
- use tokio::net::TcpListener;
- use tokio_stream::wrappers::TcpListenerStream;
- use tonic::transport::Server;
-
- let port = settings.daemon.tcp_port;
- let url = format!("127.0.0.1:{port}");
- let tcp = TcpListener::bind(&url).await?;
- let tcp_stream = TcpListenerStream::new(tcp);
-
- tracing::info!("listening on tcp port {:?}", port);
-
- // Create shutdown signal from daemon handle
- let shutdown_signal = async move {
- use crate::DaemonEvent;
-
- let mut rx = handle.subscribe();
- loop {
- match rx.recv().await {
- Ok(DaemonEvent::ShutdownRequested) => break,
- Ok(_) => continue,
- Err(_) => break, // Channel closed
- }
- }
- eprintln!("Shutting down gRPC server...");
- };
-
- // Spawn the server in the background
- tokio::spawn(async move {
- if let Err(e) = Server::builder()
- .add_service(history_service)
- .add_service(search_service)
- .add_service(semantic_service)
- .add_service(control_service)
- .serve_with_incoming_shutdown(tcp_stream, shutdown_signal)
- .await
- {
- tracing::error!("gRPC server error: {e}");
- }
- });
-
- Ok(())
-}
diff --git a/crates/atuin-history/src/lib.rs b/crates/turtle/src/atuin_history/mod.rs
index e7b33916..e7b33916 100644
--- a/crates/atuin-history/src/lib.rs
+++ b/crates/turtle/src/atuin_history/mod.rs
diff --git a/crates/atuin-history/src/sort.rs b/crates/turtle/src/atuin_history/sort.rs
index 022865a2..b162c810 100644
--- a/crates/atuin-history/src/sort.rs
+++ b/crates/turtle/src/atuin_history/sort.rs
@@ -1,4 +1,4 @@
-use atuin_client::history::History;
+use crate::atuin_client::history::History;
type ScoredHistory = (f64, History);
diff --git a/crates/atuin-history/src/stats.rs b/crates/turtle/src/atuin_history/stats.rs
index fedb1487..e47d6c8e 100644
--- a/crates/atuin-history/src/stats.rs
+++ b/crates/turtle/src/atuin_history/stats.rs
@@ -4,7 +4,7 @@ use crossterm::style::{Color, ResetColor, SetAttribute, SetForegroundColor};
use serde::{Deserialize, Serialize};
use unicode_segmentation::UnicodeSegmentation;
-use atuin_client::{history::History, settings::Settings, theme::Meaning, theme::Theme};
+use crate::atuin_client::{history::History, settings::Settings, theme::Meaning, theme::Theme};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Stats {
@@ -299,8 +299,8 @@ pub fn compute(
#[cfg(test)]
mod tests {
- use atuin_client::history::History;
- use atuin_client::settings::Settings;
+ use crate::atuin_client::history::History;
+ use crate::atuin_client::settings::Settings;
use time::OffsetDateTime;
use super::compute;
diff --git a/crates/atuin-pty-proxy/src/capture.rs b/crates/turtle/src/atuin_pty_proxy/capture.rs
index 6426035b..97ac9b8f 100644
--- a/crates/atuin-pty-proxy/src/capture.rs
+++ b/crates/turtle/src/atuin_pty_proxy/capture.rs
@@ -1,7 +1,7 @@
use std::sync::Arc;
use std::sync::atomic::{AtomicU16, Ordering};
-use crate::osc133::{Event, Params, Parser, Zone};
+use crate::atuin_pty_proxy::osc133::{Event, Params, Parser, Zone};
const HISTORY_ID_PARAM: &str = "history_id";
const SESSION_ID_PARAM: &str = "session_id";
diff --git a/crates/atuin-pty-proxy/src/debug.rs b/crates/turtle/src/atuin_pty_proxy/debug.rs
index 806bde90..bf311281 100644
--- a/crates/atuin-pty-proxy/src/debug.rs
+++ b/crates/turtle/src/atuin_pty_proxy/debug.rs
@@ -1,4 +1,4 @@
-use crate::osc133::{Event, Parser};
+use crate::atuin_pty_proxy::osc133::{Event, Parser};
pub(crate) const RESET: &[u8] = b"\x1b[0m";
diff --git a/crates/turtle/src/atuin_pty_proxy/mod.rs b/crates/turtle/src/atuin_pty_proxy/mod.rs
new file mode 100644
index 00000000..612943fa
--- /dev/null
+++ b/crates/turtle/src/atuin_pty_proxy/mod.rs
@@ -0,0 +1,17 @@
+#[cfg(unix)]
+mod capture;
+#[cfg(unix)]
+mod debug;
+#[cfg(unix)]
+mod osc133;
+#[cfg(unix)]
+mod pty_proxy;
+#[cfg(unix)]
+mod runtime;
+#[cfg(unix)]
+mod screen;
+
+#[cfg(unix)]
+pub use capture::{CommandCapture, CommandCaptureSink};
+#[cfg(unix)]
+pub use pty_proxy::PtyProxy;
diff --git a/crates/atuin-pty-proxy/src/osc133.rs b/crates/turtle/src/atuin_pty_proxy/osc133.rs
index 5b70f0aa..5b70f0aa 100644
--- a/crates/atuin-pty-proxy/src/osc133.rs
+++ b/crates/turtle/src/atuin_pty_proxy/osc133.rs
diff --git a/crates/atuin-pty-proxy/src/pty_proxy.rs b/crates/turtle/src/atuin_pty_proxy/pty_proxy.rs
index 19ccd274..8dde6f53 100644
--- a/crates/atuin-pty-proxy/src/pty_proxy.rs
+++ b/crates/turtle/src/atuin_pty_proxy/pty_proxy.rs
@@ -1,6 +1,6 @@
use clap::{Args, Subcommand, ValueEnum};
-use crate::{CommandCaptureSink, runtime};
+use crate::atuin_pty_proxy::{CommandCaptureSink, runtime};
#[derive(Args, Debug)]
pub struct PtyProxy {
diff --git a/crates/atuin-pty-proxy/src/runtime.rs b/crates/turtle/src/atuin_pty_proxy/runtime.rs
index 2b34fbb7..37c77eef 100644
--- a/crates/atuin-pty-proxy/src/runtime.rs
+++ b/crates/turtle/src/atuin_pty_proxy/runtime.rs
@@ -6,10 +6,10 @@ use std::sync::mpsc;
use crossterm::terminal;
use portable_pty::{CommandBuilder, PtySize, native_pty_system};
-use crate::capture::CommandCaptureTracker;
-use crate::debug::{Osc133DebugHighlighter, RESET};
-use crate::pty_proxy::RuntimeOptions;
-use crate::screen::{self, Msg};
+use crate::atuin_pty_proxy::capture::CommandCaptureTracker;
+use crate::atuin_pty_proxy::debug::{Osc133DebugHighlighter, RESET};
+use crate::atuin_pty_proxy::pty_proxy::RuntimeOptions;
+use crate::atuin_pty_proxy::screen::{self, Msg};
pub(crate) fn main(options: RuntimeOptions) {
if let Err(e) = run(options) {
diff --git a/crates/atuin-pty-proxy/src/screen.rs b/crates/turtle/src/atuin_pty_proxy/screen.rs
index 5b892e21..5b892e21 100644
--- a/crates/atuin-pty-proxy/src/screen.rs
+++ b/crates/turtle/src/atuin_pty_proxy/screen.rs
diff --git a/crates/atuin-server/src/handlers/health.rs b/crates/turtle/src/atuin_server/handlers/health.rs
index aebd1e8f..aebd1e8f 100644
--- a/crates/atuin-server/src/handlers/health.rs
+++ b/crates/turtle/src/atuin_server/handlers/health.rs
diff --git a/crates/atuin-server/src/handlers/history.rs b/crates/turtle/src/atuin_server/handlers/history.rs
index bdafcc60..7f09161b 100644
--- a/crates/atuin-server/src/handlers/history.rs
+++ b/crates/turtle/src/atuin_server/handlers/history.rs
@@ -10,17 +10,17 @@ use time::{Month, UtcOffset};
use tracing::{debug, error, instrument};
use super::{ErrorResponse, ErrorResponseStatus, RespExt};
-use crate::{
+use crate::atuin_server::{
router::{AppState, UserAuth},
utils::client_version_min,
};
-use atuin_server_database::{
+use crate::atuin_server_database::{
Database,
calendar::{TimePeriod, TimePeriodInfo},
models::NewHistory,
};
-use atuin_common::api::*;
+use crate::atuin_common::api::*;
#[instrument(skip_all, fields(user.id = user.id))]
pub async fn count<DB: Database>(
diff --git a/crates/atuin-server/src/handlers/mod.rs b/crates/turtle/src/atuin_server/handlers/mod.rs
index 2176ac5e..7722d03e 100644
--- a/crates/atuin-server/src/handlers/mod.rs
+++ b/crates/turtle/src/atuin_server/handlers/mod.rs
@@ -1,8 +1,8 @@
-use atuin_common::api::{ErrorResponse, IndexResponse};
-use atuin_server_database::Database;
+use crate::atuin_common::api::{ErrorResponse, IndexResponse};
+use crate::atuin_server_database::Database;
use axum::{Json, extract::State, http, response::IntoResponse};
-use crate::router::AppState;
+use crate::atuin_server::router::AppState;
pub mod health;
pub mod history;
diff --git a/crates/atuin-server/src/handlers/record.rs b/crates/turtle/src/atuin_server/handlers/record.rs
index 410c54bd..63325606 100644
--- a/crates/atuin-server/src/handlers/record.rs
+++ b/crates/turtle/src/atuin_server/handlers/record.rs
@@ -3,9 +3,9 @@ use serde_json::json;
use tracing::instrument;
use super::{ErrorResponse, ErrorResponseStatus, RespExt};
-use crate::router::UserAuth;
+use crate::atuin_server::router::UserAuth;
-use atuin_common::record::{EncryptedData, Record};
+use crate::atuin_common::record::{EncryptedData, Record};
#[instrument(skip_all, fields(user.id = user.id))]
pub async fn post(UserAuth(user): UserAuth) -> Result<(), ErrorResponseStatus<'static>> {
diff --git a/crates/atuin-server/src/handlers/status.rs b/crates/turtle/src/atuin_server/handlers/status.rs
index 9c152d51..0cf2ca1e 100644
--- a/crates/atuin-server/src/handlers/status.rs
+++ b/crates/turtle/src/atuin_server/handlers/status.rs
@@ -2,10 +2,10 @@ use axum::{Json, extract::State, http::StatusCode};
use tracing::instrument;
use super::{ErrorResponse, ErrorResponseStatus, RespExt};
-use crate::router::{AppState, UserAuth};
-use atuin_server_database::Database;
+use crate::atuin_server::router::{AppState, UserAuth};
+use crate::atuin_server_database::Database;
-use atuin_common::api::*;
+use crate::atuin_common::api::*;
const VERSION: &str = env!("CARGO_PKG_VERSION");
diff --git a/crates/atuin-server/src/handlers/user.rs b/crates/turtle/src/atuin_server/handlers/user.rs
index dda7a381..01b72202 100644
--- a/crates/atuin-server/src/handlers/user.rs
+++ b/crates/turtle/src/atuin_server/handlers/user.rs
@@ -16,18 +16,18 @@ use metrics::counter;
use rand::rngs::OsRng;
use tracing::{debug, error, info, instrument};
-use atuin_common::tls::ensure_crypto_provider;
+use crate::atuin_common::tls::ensure_crypto_provider;
use super::{ErrorResponse, ErrorResponseStatus, RespExt};
-use crate::router::{AppState, UserAuth};
-use atuin_server_database::{
+use crate::atuin_server::router::{AppState, UserAuth};
+use crate::atuin_server_database::{
Database, DbError,
models::{NewSession, NewUser},
};
use reqwest::header::CONTENT_TYPE;
-use atuin_common::{api::*, utils::crypto_random_string};
+use crate::atuin_common::{api::*, utils::crypto_random_string};
pub fn verify_str(hash: &str, password: &str) -> bool {
let arg2 = Argon2::new(Algorithm::Argon2id, Version::V0x13, Params::default());
diff --git a/crates/atuin-server/src/handlers/v0/me.rs b/crates/turtle/src/atuin_server/handlers/v0/me.rs
index 7960b479..a1e2db46 100644
--- a/crates/atuin-server/src/handlers/v0/me.rs
+++ b/crates/turtle/src/atuin_server/handlers/v0/me.rs
@@ -1,10 +1,10 @@
use axum::Json;
use tracing::instrument;
-use crate::handlers::ErrorResponseStatus;
-use crate::router::UserAuth;
+use crate::atuin_server::handlers::ErrorResponseStatus;
+use crate::atuin_server::router::UserAuth;
-use atuin_common::api::*;
+use crate::atuin_common::api::*;
#[instrument(skip_all, fields(user.id = user.id))]
pub async fn get(
diff --git a/crates/atuin-server/src/handlers/v0/mod.rs b/crates/turtle/src/atuin_server/handlers/v0/mod.rs
index d6f880f2..d6f880f2 100644
--- a/crates/atuin-server/src/handlers/v0/mod.rs
+++ b/crates/turtle/src/atuin_server/handlers/v0/mod.rs
diff --git a/crates/atuin-server/src/handlers/v0/record.rs b/crates/turtle/src/atuin_server/handlers/v0/record.rs
index 5c57910b..9b147a52 100644
--- a/crates/atuin-server/src/handlers/v0/record.rs
+++ b/crates/turtle/src/atuin_server/handlers/v0/record.rs
@@ -3,13 +3,13 @@ use metrics::counter;
use serde::Deserialize;
use tracing::{error, instrument};
-use crate::{
+use crate::atuin_server::{
handlers::{ErrorResponse, ErrorResponseStatus, RespExt},
router::{AppState, UserAuth},
};
-use atuin_server_database::Database;
+use crate::atuin_server_database::Database;
-use atuin_common::record::{EncryptedData, HostId, Record, RecordIdx, RecordStatus};
+use crate::atuin_common::record::{EncryptedData, HostId, Record, RecordIdx, RecordStatus};
#[instrument(skip_all, fields(user.id = user.id))]
pub async fn post<DB: Database>(
diff --git a/crates/atuin-server/src/handlers/v0/store.rs b/crates/turtle/src/atuin_server/handlers/v0/store.rs
index 6ca455d7..cd184546 100644
--- a/crates/atuin-server/src/handlers/v0/store.rs
+++ b/crates/turtle/src/atuin_server/handlers/v0/store.rs
@@ -3,11 +3,11 @@ use metrics::counter;
use serde::Deserialize;
use tracing::{error, instrument};
-use crate::{
+use crate::atuin_server::{
handlers::{ErrorResponse, ErrorResponseStatus, RespExt},
router::{AppState, UserAuth},
};
-use atuin_server_database::Database;
+use crate::atuin_server_database::Database;
#[derive(Deserialize)]
pub struct DeleteParams {}
diff --git a/crates/atuin-server/src/metrics.rs b/crates/turtle/src/atuin_server/metrics.rs
index ebd0dd2d..ebd0dd2d 100644
--- a/crates/atuin-server/src/metrics.rs
+++ b/crates/turtle/src/atuin_server/metrics.rs
diff --git a/crates/atuin-server/src/lib.rs b/crates/turtle/src/atuin_server/mod.rs
index 02e50e1e..bd0f2168 100644
--- a/crates/atuin-server/src/lib.rs
+++ b/crates/turtle/src/atuin_server/mod.rs
@@ -1,9 +1,7 @@
-#![forbid(unsafe_code)]
-
use std::future::Future;
use std::net::SocketAddr;
-use atuin_server_database::Database;
+use crate::atuin_server_database::Database;
use axum::{Router, serve};
use eyre::{Context, Result};
@@ -13,7 +11,6 @@ mod router;
mod utils;
pub use settings::Settings;
-pub use settings::example_config;
pub mod settings;
diff --git a/crates/atuin-server/src/router.rs b/crates/turtle/src/atuin_server/router.rs
index 2d679759..11a16148 100644
--- a/crates/atuin-server/src/router.rs
+++ b/crates/turtle/src/atuin_server/router.rs
@@ -1,4 +1,4 @@
-use atuin_common::api::{ATUIN_CARGO_VERSION, ATUIN_HEADER_VERSION, ErrorResponse};
+use crate::atuin_common::api::{ATUIN_CARGO_VERSION, ATUIN_HEADER_VERSION, ErrorResponse};
use axum::{
Router,
extract::{FromRequestParts, Request},
@@ -12,12 +12,12 @@ use tower::ServiceBuilder;
use tower_http::trace::TraceLayer;
use super::handlers;
-use crate::{
+use crate::atuin_server::{
handlers::{ErrorResponseStatus, RespExt},
metrics,
settings::Settings,
};
-use atuin_server_database::{Database, DbError, models::User};
+use crate::atuin_server_database::{Database, DbError, models::User};
pub struct UserAuth(pub User);
diff --git a/crates/atuin-server/src/settings.rs b/crates/turtle/src/atuin_server/settings.rs
index 3a612be9..f6650af0 100644
--- a/crates/atuin-server/src/settings.rs
+++ b/crates/turtle/src/atuin_server/settings.rs
@@ -1,13 +1,11 @@
use std::{io::prelude::*, path::PathBuf};
-use atuin_server_database::DbSettings;
+use crate::atuin_server_database::DbSettings;
use config::{Config, Environment, File as ConfigFile, FileFormat};
use eyre::{Result, eyre};
use fs_err::{File, create_dir_all};
use serde::{Deserialize, Serialize};
-static EXAMPLE_CONFIG: &str = include_str!("../server.toml");
-
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Metrics {
#[serde(alias = "enabled")]
@@ -60,7 +58,7 @@ impl Settings {
PathBuf::from(p)
} else {
let mut config_file = PathBuf::new();
- let config_dir = atuin_common::utils::config_dir();
+ let config_dir = crate::atuin_common::utils::config_dir();
config_file.push(config_dir);
config_file
};
@@ -87,27 +85,26 @@ impl Settings {
.separator("__"),
);
- config_builder = if config_file.exists() {
- config_builder.add_source(ConfigFile::new(
- config_file.to_str().unwrap(),
- FileFormat::Toml,
- ))
+ let config = if config_file.exists() {
+ config_builder
+ .add_source(ConfigFile::new(
+ config_file.to_str().unwrap(),
+ FileFormat::Toml,
+ ))
+ .build()?
} else {
create_dir_all(config_file.parent().unwrap())?;
let mut file = File::create(config_file)?;
- file.write_all(EXAMPLE_CONFIG.as_bytes())?;
- config_builder
- };
+ let config = config_builder.build()?;
+ // TODO(@bpeetz): I'm quiet unsure, if this will work <2026-06-10>
+ file.write_all(config.cache.to_string().as_bytes())?;
- let config = config_builder.build()?;
+ config
+ };
config
.try_deserialize()
.map_err(|e| eyre!("failed to deserialize: {}", e))
}
}
-
-pub fn example_config() -> &'static str {
- EXAMPLE_CONFIG
-}
diff --git a/crates/atuin-server/src/utils.rs b/crates/turtle/src/atuin_server/utils.rs
index 12e9ac1b..12e9ac1b 100644
--- a/crates/atuin-server/src/utils.rs
+++ b/crates/turtle/src/atuin_server/utils.rs
diff --git a/crates/atuin-server-database/src/calendar.rs b/crates/turtle/src/atuin_server_database/calendar.rs
index 2229667b..2229667b 100644
--- a/crates/atuin-server-database/src/calendar.rs
+++ b/crates/turtle/src/atuin_server_database/calendar.rs
diff --git a/crates/atuin-server-database/src/lib.rs b/crates/turtle/src/atuin_server_database/mod.rs
index 5437fc15..91077b84 100644
--- a/crates/atuin-server-database/src/lib.rs
+++ b/crates/turtle/src/atuin_server_database/mod.rs
@@ -1,5 +1,3 @@
-#![forbid(unsafe_code)]
-
pub mod calendar;
pub mod models;
@@ -14,7 +12,7 @@ use self::{
models::{History, NewHistory, NewSession, NewUser, Session, User},
};
use async_trait::async_trait;
-use atuin_common::record::{EncryptedData, HostId, Record, RecordIdx, RecordStatus};
+use crate::atuin_common::record::{EncryptedData, HostId, Record, RecordIdx, RecordStatus};
use serde::{Deserialize, Serialize};
use time::{Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset};
use tracing::instrument;
diff --git a/crates/atuin-server-database/src/models.rs b/crates/turtle/src/atuin_server_database/models.rs
index b71a9bc9..b71a9bc9 100644
--- a/crates/atuin-server-database/src/models.rs
+++ b/crates/turtle/src/atuin_server_database/models.rs
diff --git a/crates/atuin-server-postgres/src/lib.rs b/crates/turtle/src/atuin_server_postgres/mod.rs
index 2e69c7f2..f506cf25 100644
--- a/crates/atuin-server-postgres/src/lib.rs
+++ b/crates/turtle/src/atuin_server_postgres/mod.rs
@@ -3,10 +3,12 @@ use std::ops::Range;
use rand::Rng;
+use crate::atuin_common::record::{EncryptedData, HostId, Record, RecordIdx, RecordStatus};
+use crate::atuin_server_database::models::{
+ History, NewHistory, NewSession, NewUser, Session, User,
+};
+use crate::atuin_server_database::{Database, DbError, DbResult, DbSettings, into_utc};
use async_trait::async_trait;
-use atuin_common::record::{EncryptedData, HostId, Record, RecordIdx, RecordStatus};
-use atuin_server_database::models::{History, NewHistory, NewSession, NewUser, Session, User};
-use atuin_server_database::{Database, DbError, DbResult, DbSettings, into_utc};
use futures_util::TryStreamExt;
use sqlx::Row;
use sqlx::postgres::PgPoolOptions;
@@ -289,7 +291,7 @@ impl Database for Postgres {
sqlx::query(
"insert into history
- (client_id, user_id, hostname, timestamp, data)
+ (client_id, user_id, hostname, timestamp, data)
values ($1, $2, $3, $4, $5)
on conflict do nothing
",
@@ -430,11 +432,11 @@ impl Database for Postgres {
let mut heads = HashMap::<(HostId, &str), u64>::new();
for i in records {
- let id = atuin_common::utils::uuid_v7();
+ let id = crate::atuin_common::utils::uuid_v7();
let result = sqlx::query(
"insert into store
- (id, client_id, host, idx, timestamp, version, tag, data, cek, user_id)
+ (id, client_id, host, idx, timestamp, version, tag, data, cek, user_id)
values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
on conflict do nothing
",
@@ -469,7 +471,7 @@ impl Database for Postgres {
for ((host, tag), idx) in heads {
sqlx::query(
"insert into store_idx_cache
- (user_id, host, tag, idx)
+ (user_id, host, tag, idx)
values ($1, $2, $3, $4)
on conflict(user_id, host, tag) do update set idx = greatest(store_idx_cache.idx, $4)
",
diff --git a/crates/atuin-server-postgres/src/wrappers.rs b/crates/turtle/src/atuin_server_postgres/wrappers.rs
index cde4134c..214b255d 100644
--- a/crates/atuin-server-postgres/src/wrappers.rs
+++ b/crates/turtle/src/atuin_server_postgres/wrappers.rs
@@ -1,6 +1,6 @@
use ::sqlx::{FromRow, Result};
-use atuin_common::record::{EncryptedData, Host, Record};
-use atuin_server_database::models::{History, Session, User};
+use crate::atuin_common::record::{EncryptedData, Host, Record};
+use crate::atuin_server_database::models::{History, Session, User};
use sqlx::{Row, postgres::PgRow};
use time::PrimitiveDateTime;
diff --git a/crates/atuin-server-sqlite/src/lib.rs b/crates/turtle/src/atuin_server_sqlite/mod.rs
index 56ed9b6c..3470a2f1 100644
--- a/crates/atuin-server-sqlite/src/lib.rs
+++ b/crates/turtle/src/atuin_server_sqlite/mod.rs
@@ -1,11 +1,11 @@
use std::str::FromStr;
-use async_trait::async_trait;
-use atuin_common::record::{EncryptedData, HostId, Record, RecordIdx, RecordStatus};
-use atuin_server_database::{
+use crate::atuin_common::record::{EncryptedData, HostId, Record, RecordIdx, RecordStatus};
+use crate::atuin_server_database::{
Database, DbError, DbResult, DbSettings, into_utc,
models::{History, NewHistory, NewSession, NewUser, Session, User},
};
+use async_trait::async_trait;
use futures_util::TryStreamExt;
use sqlx::{
Row,
@@ -203,7 +203,7 @@ impl Database for Sqlite {
// edge case.
let res = sqlx::query(
- "select client_id from history
+ "select client_id from history
where user_id = $1
and deleted_at is not null",
)
@@ -233,11 +233,11 @@ impl Database for Sqlite {
let mut tx = self.pool.begin().await?;
for i in records {
- let id = atuin_common::utils::uuid_v7();
+ let id = crate::atuin_common::utils::uuid_v7();
sqlx::query(
"insert into store
- (id, client_id, host, idx, timestamp, version, tag, data, cek, user_id)
+ (id, client_id, host, idx, timestamp, version, tag, data, cek, user_id)
values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
on conflict do nothing
",
@@ -394,7 +394,7 @@ impl Database for Sqlite {
sqlx::query(
"insert into history
- (client_id, user_id, hostname, timestamp, data)
+ (client_id, user_id, hostname, timestamp, data)
values ($1, $2, $3, $4, $5)
on conflict do nothing
",
@@ -416,7 +416,7 @@ impl Database for Sqlite {
#[instrument(skip_all)]
async fn oldest_history(&self, user: &User) -> DbResult<History> {
sqlx::query_as(
- "select id, client_id, user_id, hostname, timestamp, data, created_at from history
+ "select id, client_id, user_id, hostname, timestamp, data, created_at from history
where user_id = $1
order by timestamp asc
limit 1",
diff --git a/crates/atuin-server-sqlite/src/wrappers.rs b/crates/turtle/src/atuin_server_sqlite/wrappers.rs
index 2f1230c2..5aa7a982 100644
--- a/crates/atuin-server-sqlite/src/wrappers.rs
+++ b/crates/turtle/src/atuin_server_sqlite/wrappers.rs
@@ -1,6 +1,6 @@
use ::sqlx::{FromRow, Result};
-use atuin_common::record::{EncryptedData, Host, Record};
-use atuin_server_database::models::{History, Session, User};
+use crate::atuin_common::record::{EncryptedData, Host, Record};
+use crate::atuin_server_database::models::{History, Session, User};
use sqlx::{Row, sqlite::SqliteRow};
pub struct DbUser(pub User);
diff --git a/crates/atuin/src/command/CONTRIBUTORS b/crates/turtle/src/command/CONTRIBUTORS
index 1ca4115a..1ca4115a 120000
--- a/crates/atuin/src/command/CONTRIBUTORS
+++ b/crates/turtle/src/command/CONTRIBUTORS
diff --git a/crates/atuin/src/command/client.rs b/crates/turtle/src/command/client.rs
index 6c1bac29..20d85303 100644
--- a/crates/atuin/src/command/client.rs
+++ b/crates/turtle/src/command/client.rs
@@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
use clap::Subcommand;
use eyre::{Result, WrapErr};
-use atuin_client::{
+use crate::atuin_client::{
database::Sqlite, record::sqlite_store::SqliteStore, settings::Settings, theme,
};
use tracing_appender::rolling::{RollingFileAppender, Rotation};
@@ -57,6 +57,7 @@ mod import;
mod info;
mod init;
mod search;
+mod server;
mod setup;
mod stats;
mod store;
@@ -87,6 +88,10 @@ pub enum Cmd {
#[command(flatten)]
Sync(sync::Cmd),
+ /// Manage the atuin server
+ #[command(subcommand)]
+ Server(server::Cmd),
+
/// Manage your sync account
#[cfg(feature = "sync")]
Account(account::Cmd),
@@ -341,6 +346,8 @@ impl Cmd {
Self::Store(store) => store.run(&settings, &db, sqlite_store).await,
+ Self::Server(server) => server.run().await,
+
Self::Info => {
info::run(&settings);
Ok(())
diff --git a/crates/atuin/src/command/client/account.rs b/crates/turtle/src/command/client/account.rs
index fc1c9343..898f1ac4 100644
--- a/crates/atuin/src/command/client/account.rs
+++ b/crates/turtle/src/command/client/account.rs
@@ -1,8 +1,8 @@
use clap::{Args, Subcommand};
use eyre::Result;
-use atuin_client::record::sqlite_store::SqliteStore;
-use atuin_client::settings::Settings;
+use crate::atuin_client::record::sqlite_store::SqliteStore;
+use crate::atuin_client::settings::Settings;
pub mod change_password;
pub mod delete;
diff --git a/crates/atuin/src/command/client/account/change_password.rs b/crates/turtle/src/command/client/account/change_password.rs
index 234d4dc0..6112b0df 100644
--- a/crates/atuin/src/command/client/account/change_password.rs
+++ b/crates/turtle/src/command/client/account/change_password.rs
@@ -1,7 +1,7 @@
use clap::Parser;
use eyre::{Result, bail};
-use atuin_client::{
+use crate::atuin_client::{
auth::{self, MutateResponse},
settings::Settings,
};
diff --git a/crates/atuin/src/command/client/account/delete.rs b/crates/turtle/src/command/client/account/delete.rs
index a5e7f0dd..bcb40bc3 100644
--- a/crates/atuin/src/command/client/account/delete.rs
+++ b/crates/turtle/src/command/client/account/delete.rs
@@ -1,4 +1,4 @@
-use atuin_client::{
+use crate::atuin_client::{
auth::{self, MutateResponse},
settings::Settings,
};
diff --git a/crates/atuin/src/command/client/account/login.rs b/crates/turtle/src/command/client/account/login.rs
index e320e80b..0c5b66f5 100644
--- a/crates/atuin/src/command/client/account/login.rs
+++ b/crates/turtle/src/command/client/account/login.rs
@@ -4,7 +4,7 @@ use clap::Parser;
use eyre::{Context, Result, bail};
use tokio::{fs::File, io::AsyncWriteExt};
-use atuin_client::{
+use crate::atuin_client::{
auth::{self, AuthResponse},
encryption::{decode_key, load_key},
record::sqlite_store::SqliteStore,
@@ -65,7 +65,7 @@ impl Cmd {
self.prompt_and_store_key(settings, store).await?;
let client = auth::auth_client(settings).await;
- let response = client.login(&username, &password, None).await?;
+ let response = client.login(&username, &password).await?;
match response {
AuthResponse::Success { session, .. } => {
diff --git a/crates/atuin/src/command/client/account/logout.rs b/crates/turtle/src/command/client/account/logout.rs
index b958e65a..6150a52b 100644
--- a/crates/atuin/src/command/client/account/logout.rs
+++ b/crates/turtle/src/command/client/account/logout.rs
@@ -1,5 +1,5 @@
use eyre::Result;
pub async fn run() -> Result<()> {
- atuin_client::logout::logout().await
+ crate::atuin_client::logout::logout().await
}
diff --git a/crates/atuin/src/command/client/account/register.rs b/crates/turtle/src/command/client/account/register.rs
index bd836e7b..548c2739 100644
--- a/crates/atuin/src/command/client/account/register.rs
+++ b/crates/turtle/src/command/client/account/register.rs
@@ -2,7 +2,7 @@ use clap::Parser;
use eyre::{Result, bail};
use super::login::or_user_input;
-use atuin_client::settings::{Settings, SyncAuth};
+use crate::atuin_client::settings::{Settings, SyncAuth};
#[derive(Parser, Debug)]
pub struct Cmd {
@@ -42,7 +42,7 @@ impl Cmd {
bail!("please provide a password");
}
- let session = atuin_client::api_client::register(
+ let session = crate::atuin_client::api_client::register(
settings.sync_address.as_str(),
&username,
&email,
@@ -53,7 +53,7 @@ impl Cmd {
let meta = Settings::meta_store().await?;
meta.save_session(&session.session).await?;
- let _key = atuin_client::encryption::load_key(settings)?;
+ let _key = crate::atuin_client::encryption::load_key(settings)?;
println!(
"Registration successful! Please make a note of your key (run 'atuin key') and keep it safe."
diff --git a/crates/atuin/src/command/client/config.rs b/crates/turtle/src/command/client/config.rs
index 5ec5f7f3..1597a8d6 100644
--- a/crates/atuin/src/command/client/config.rs
+++ b/crates/turtle/src/command/client/config.rs
@@ -1,4 +1,4 @@
-use atuin_client::settings::Settings;
+use crate::atuin_client::settings::Settings;
use clap::{Args, Subcommand, ValueEnum};
use eyre::Result;
use toml_edit::{Document, DocumentMut, Item, Table, TableLike, Value};
diff --git a/crates/atuin/src/command/client/daemon.rs b/crates/turtle/src/command/client/daemon.rs
index c3dcf9d0..2ee9b759 100644
--- a/crates/atuin/src/command/client/daemon.rs
+++ b/crates/turtle/src/command/client/daemon.rs
@@ -6,11 +6,13 @@ use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::time::{Duration, Instant};
-use atuin_client::{
+use crate::atuin_client::{
database::Sqlite, history::History, record::sqlite_store::SqliteStore, settings::Settings,
};
-use atuin_daemon::DaemonEvent;
-use atuin_daemon::client::{ControlClient, DaemonClientErrorKind, HistoryClient, classify_error};
+use crate::atuin_daemon::DaemonEvent;
+use crate::atuin_daemon::client::{
+ ControlClient, DaemonClientErrorKind, HistoryClient, classify_error,
+};
use clap::Subcommand;
#[cfg(unix)]
use daemonize::Daemonize;
@@ -218,8 +220,6 @@ async fn wait_for_pidfile_available(path: &Path, timeout: Duration) -> Result<()
async fn connect_client(settings: &Settings) -> Result<HistoryClient> {
HistoryClient::new(
- #[cfg(not(unix))]
- settings.daemon.tcp_port,
#[cfg(unix)]
settings.daemon.socket_path.clone(),
)
@@ -339,8 +339,6 @@ fn ensure_autostart_supported(settings: &Settings) -> Result<()> {
"daemon autostart is incompatible with `daemon.systemd_socket = true`; use systemd to manage the daemon"
);
}
- #[cfg(not(unix))]
- let _ = settings;
Ok(())
}
@@ -546,8 +544,6 @@ async fn status_cmd(settings: &Settings) -> Result<()> {
println!(" Healthy: {}", status.healthy);
#[cfg(unix)]
println!(" Socket: {}", settings.daemon.socket_path);
- #[cfg(not(unix))]
- println!(" Port: {}", settings.daemon.tcp_port);
}
Probe::NeedsRestart(reason) => {
println!("Daemon running (needs restart)");
@@ -648,7 +644,7 @@ async fn run(
let pidfile_path = PathBuf::from(&settings.daemon.pidfile_path);
let _pidfile_guard = PidfileGuard::acquire(&pidfile_path)?;
- atuin_daemon::boot(settings, store, history_db).await?;
+ crate::atuin_daemon::boot(settings, store, history_db).await?;
Ok(())
}
@@ -700,17 +696,6 @@ fn kill_process(pid: u32) {
.status();
}
-/// Kill a process by PID.
-#[cfg(not(unix))]
-fn kill_process(pid: u32) {
- // On Windows, use taskkill
- let _ = Command::new("taskkill")
- .args(["/PID", &pid.to_string(), "/F"])
- .stdout(Stdio::null())
- .stderr(Stdio::null())
- .status();
-}
-
#[cfg(test)]
mod tests {
use super::*;
diff --git a/crates/turtle/src/command/client/default_config.rs b/crates/turtle/src/command/client/default_config.rs
new file mode 100644
index 00000000..e8cc15f9
--- /dev/null
+++ b/crates/turtle/src/command/client/default_config.rs
@@ -0,0 +1,4 @@
+pub fn run() {
+ // TODO(@bpeetz): Re-add the default settings option back (Settings::example_config()) <2026-06-11>
+ println!("TODO");
+}
diff --git a/crates/atuin/src/command/client/doctor.rs b/crates/turtle/src/command/client/doctor.rs
index 1bf003db..09fa6e77 100644
--- a/crates/atuin/src/command/client/doctor.rs
+++ b/crates/turtle/src/command/client/doctor.rs
@@ -1,10 +1,10 @@
use std::process::Command;
use std::{env, str::FromStr};
-use atuin_client::database::Sqlite;
-use atuin_client::settings::Settings;
-use atuin_common::shell::{Shell, shell_name};
-use atuin_common::utils;
+use crate::atuin_client::database::Sqlite;
+use crate::atuin_client::settings::Settings;
+use crate::atuin_common::shell::{Shell, shell_name};
+use crate::atuin_common::utils;
use colored::Colorize;
use eyre::Result;
use serde::Serialize;
@@ -168,7 +168,7 @@ impl ShellInfo {
}
pub fn new() -> Self {
- // TODO: rework to use atuin_common::Shell
+ // TODO: rework to use crate::atuin_common::Shell
let sys = System::new_all();
diff --git a/crates/atuin/src/command/client/history.rs b/crates/turtle/src/command/client/history.rs
index abf39cc2..0c61392c 100644
--- a/crates/atuin/src/command/client/history.rs
+++ b/crates/turtle/src/command/client/history.rs
@@ -5,7 +5,7 @@ use std::{
time::Duration,
};
-use atuin_common::utils::{self, Escapable as _};
+use crate::atuin_common::utils::{self, Escapable as _};
use clap::Subcommand;
use eyre::{Context, Result, bail};
use runtime_format::{FormatKey, FormatKeyError, ParseSegment, ParsedFmt};
@@ -18,9 +18,9 @@ use colored::Colorize;
use serde::Serialize;
#[cfg(feature = "daemon")]
-use atuin_daemon::history::{HistoryEventKind, TailHistoryReply};
+use crate::atuin_daemon::history::{HistoryEventKind, TailHistoryReply};
-use atuin_client::{
+use crate::atuin_client::{
database::{Database, Sqlite, current_context},
encryption,
history::{History, store::HistoryStore},
@@ -32,7 +32,7 @@ use atuin_client::{
};
#[cfg(feature = "sync")]
-use atuin_client::{record, sync};
+use crate::atuin_client::record;
use log::{debug, warn};
use time::{OffsetDateTime, macros::format_description};
@@ -924,7 +924,7 @@ impl Cmd {
async fn handle_list(
db: &impl Database,
settings: &Settings,
- context: atuin_client::database::Context,
+ context: crate::atuin_client::database::Context,
session: bool,
cwd: bool,
mode: ListMode,
@@ -967,7 +967,7 @@ impl Cmd {
db: &impl Database,
settings: &Settings,
store: SqliteStore,
- context: atuin_client::database::Context,
+ context: crate::atuin_client::database::Context,
dry_run: bool,
) -> Result<()> {
// Grab all executed commands and filter them using History::should_save.
@@ -1011,7 +1011,7 @@ impl Cmd {
}
#[cfg(feature = "daemon")]
- daemon_cmd::emit_event(settings, atuin_daemon::DaemonEvent::HistoryPruned).await;
+ daemon_cmd::emit_event(settings, crate::atuin_daemon::DaemonEvent::HistoryPruned).await;
}
Ok(())
}
@@ -1068,8 +1068,11 @@ impl Cmd {
}
#[cfg(feature = "daemon")]
- daemon_cmd::emit_event(settings, atuin_daemon::DaemonEvent::HistoryDeleted { ids })
- .await;
+ daemon_cmd::emit_event(
+ settings,
+ crate::atuin_daemon::DaemonEvent::HistoryDeleted { ids },
+ )
+ .await;
}
Ok(())
}
diff --git a/crates/atuin/src/command/client/import.rs b/crates/turtle/src/command/client/import.rs
index 21ac76b4..363e6405 100644
--- a/crates/atuin/src/command/client/import.rs
+++ b/crates/turtle/src/command/client/import.rs
@@ -5,7 +5,7 @@ use clap::Parser;
use eyre::Result;
use indicatif::ProgressBar;
-use atuin_client::{
+use crate::atuin_client::{
database::Database,
history::History,
import::{
diff --git a/crates/atuin/src/command/client/info.rs b/crates/turtle/src/command/client/info.rs
index a69f9b2f..ee24c419 100644
--- a/crates/atuin/src/command/client/info.rs
+++ b/crates/turtle/src/command/client/info.rs
@@ -1,9 +1,9 @@
-use atuin_client::settings::Settings;
+use crate::atuin_client::settings::Settings;
use crate::{SHA, VERSION};
pub fn run(settings: &Settings) {
- let config = atuin_common::utils::config_dir();
+ let config = crate::atuin_common::utils::config_dir();
let mut config_file = config.clone();
config_file.push("config.toml");
let mut sever_config = config;
diff --git a/crates/atuin/src/command/client/init.rs b/crates/turtle/src/command/client/init.rs
index 39cd1247..bf9747bb 100644
--- a/crates/atuin/src/command/client/init.rs
+++ b/crates/turtle/src/command/client/init.rs
@@ -1,4 +1,4 @@
-use atuin_client::settings::{Settings, Tmux};
+use crate::atuin_client::settings::{Settings, Tmux};
use clap::{Parser, ValueEnum};
mod bash;
diff --git a/crates/atuin/src/command/client/init/bash.rs b/crates/turtle/src/command/client/init/bash.rs
index 2280dc3d..fd17e37e 100644
--- a/crates/atuin/src/command/client/init/bash.rs
+++ b/crates/turtle/src/command/client/init/bash.rs
@@ -1,4 +1,4 @@
-use atuin_client::settings::Tmux;
+use crate::atuin_client::settings::Tmux;
fn print_tmux_config(tmux: &Tmux) {
if tmux.enabled {
diff --git a/crates/atuin/src/command/client/init/fish.rs b/crates/turtle/src/command/client/init/fish.rs
index 07c6a5ba..8a046bfa 100644
--- a/crates/atuin/src/command/client/init/fish.rs
+++ b/crates/turtle/src/command/client/init/fish.rs
@@ -1,4 +1,4 @@
-use atuin_client::settings::Tmux;
+use crate::atuin_client::settings::Tmux;
fn print_tmux_config(tmux: &Tmux) {
if tmux.enabled {
diff --git a/crates/atuin/src/command/client/init/powershell.rs b/crates/turtle/src/command/client/init/powershell.rs
index f92f1cbe..10c0c461 100644
--- a/crates/atuin/src/command/client/init/powershell.rs
+++ b/crates/turtle/src/command/client/init/powershell.rs
@@ -1,4 +1,4 @@
-use atuin_client::settings::Tmux;
+use crate::atuin_client::settings::Tmux;
pub fn init_static(disable_up_arrow: bool, disable_ctrl_r: bool, _tmux: &Tmux) {
let base = include_str!("../../../shell/atuin.ps1");
diff --git a/crates/atuin/src/command/client/init/xonsh.rs b/crates/turtle/src/command/client/init/xonsh.rs
index 9fb5730d..a17d85d8 100644
--- a/crates/atuin/src/command/client/init/xonsh.rs
+++ b/crates/turtle/src/command/client/init/xonsh.rs
@@ -1,4 +1,4 @@
-use atuin_client::settings::Tmux;
+use crate::atuin_client::settings::Tmux;
pub fn init_static(disable_up_arrow: bool, disable_ctrl_r: bool, _tmux: &Tmux) {
let base = include_str!("../../../shell/atuin.xsh");
diff --git a/crates/atuin/src/command/client/init/zsh.rs b/crates/turtle/src/command/client/init/zsh.rs
index 3f325167..38c3086b 100644
--- a/crates/atuin/src/command/client/init/zsh.rs
+++ b/crates/turtle/src/command/client/init/zsh.rs
@@ -1,4 +1,4 @@
-use atuin_client::settings::Tmux;
+use crate::atuin_client::settings::Tmux;
fn print_tmux_config(tmux: &Tmux) {
if tmux.enabled {
diff --git a/crates/atuin/src/command/client/search.rs b/crates/turtle/src/command/client/search.rs
index a9dc9a68..4a2114d5 100644
--- a/crates/atuin/src/command/client/search.rs
+++ b/crates/turtle/src/command/client/search.rs
@@ -1,11 +1,11 @@
use std::fs::File;
use std::io::{IsTerminal as _, Write, stderr, stdout};
-use atuin_common::utils::{self, Escapable as _};
+use crate::atuin_common::utils::{self, Escapable as _};
use clap::Parser;
use eyre::Result;
-use atuin_client::{
+use crate::atuin_client::{
database::Database,
database::{OptFilters, current_context},
encryption,
diff --git a/crates/atuin/src/command/client/search/cursor.rs b/crates/turtle/src/command/client/search/cursor.rs
index c1cdfee4..84f94082 100644
--- a/crates/atuin/src/command/client/search/cursor.rs
+++ b/crates/turtle/src/command/client/search/cursor.rs
@@ -1,4 +1,4 @@
-use atuin_client::settings::WordJumpMode;
+use crate::atuin_client::settings::WordJumpMode;
pub struct Cursor {
source: String,
diff --git a/crates/atuin/src/command/client/search/duration.rs b/crates/turtle/src/command/client/search/duration.rs
index 54856c87..54856c87 100644
--- a/crates/atuin/src/command/client/search/duration.rs
+++ b/crates/turtle/src/command/client/search/duration.rs
diff --git a/crates/atuin/src/command/client/search/engines.rs b/crates/turtle/src/command/client/search/engines.rs
index 886f0171..0f92b4c7 100644
--- a/crates/atuin/src/command/client/search/engines.rs
+++ b/crates/turtle/src/command/client/search/engines.rs
@@ -1,5 +1,5 @@
use async_trait::async_trait;
-use atuin_client::{
+use crate::atuin_client::{
database::{Context, Database, OptFilters},
history::{AUTHOR_FILTER_ALL_USER, History, HistoryId},
settings::{FilterMode, SearchMode, Settings},
diff --git a/crates/atuin/src/command/client/search/engines/daemon.rs b/crates/turtle/src/command/client/search/engines/daemon.rs
index 8b15c180..b1299c02 100644
--- a/crates/atuin/src/command/client/search/engines/daemon.rs
+++ b/crates/turtle/src/command/client/search/engines/daemon.rs
@@ -1,10 +1,10 @@
-use async_trait::async_trait;
-use atuin_client::{
+use crate::atuin_client::{
database::{Database, OptFilters},
history::{AUTHOR_FILTER_ALL_USER, History},
settings::{SearchMode, Settings},
};
-use atuin_daemon::client::{DaemonClientErrorKind, SearchClient, classify_error};
+use crate::atuin_daemon::client::{DaemonClientErrorKind, SearchClient, classify_error};
+use async_trait::async_trait;
use atuin_nucleo_matcher::{
Config, Matcher, Utf32Str,
pattern::{CaseMatching, Normalization, Pattern},
@@ -22,8 +22,6 @@ pub struct Search {
settings: Settings,
#[cfg(unix)]
socket_path: String,
- #[cfg(not(unix))]
- tcp_port: u64,
}
impl Search {
@@ -34,8 +32,6 @@ impl Search {
settings: settings.clone(),
#[cfg(unix)]
socket_path: settings.daemon.socket_path.clone(),
- #[cfg(not(unix))]
- tcp_port: settings.daemon.tcp_port,
}
}
@@ -51,9 +47,6 @@ impl Search {
#[cfg(unix)]
let client = SearchClient::new(self.socket_path.clone()).await?;
- #[cfg(not(unix))]
- let client = SearchClient::new(self.tcp_port).await?;
-
self.client = Some(client);
Ok(())
}
diff --git a/crates/atuin/src/command/client/search/engines/db.rs b/crates/turtle/src/command/client/search/engines/db.rs
index b15aabd8..2765faf5 100644
--- a/crates/atuin/src/command/client/search/engines/db.rs
+++ b/crates/turtle/src/command/client/search/engines/db.rs
@@ -1,6 +1,6 @@
use super::{SearchEngine, SearchState};
use async_trait::async_trait;
-use atuin_client::{
+use crate::atuin_client::{
database::Database,
database::OptFilters,
database::{QueryToken, QueryTokenizer},
diff --git a/crates/atuin/src/command/client/search/engines/skim.rs b/crates/turtle/src/command/client/search/engines/skim.rs
index fe05fd09..96a6574d 100644
--- a/crates/atuin/src/command/client/search/engines/skim.rs
+++ b/crates/turtle/src/command/client/search/engines/skim.rs
@@ -1,7 +1,7 @@
use std::path::Path;
use async_trait::async_trait;
-use atuin_client::{
+use crate::atuin_client::{
database::Database,
history::{History, is_known_agent},
settings::FilterMode,
diff --git a/crates/atuin/src/command/client/search/history_list.rs b/crates/turtle/src/command/client/search/history_list.rs
index 7af324b4..4c83d7eb 100644
--- a/crates/atuin/src/command/client/search/history_list.rs
+++ b/crates/turtle/src/command/client/search/history_list.rs
@@ -2,12 +2,12 @@ use std::time::Duration;
use super::duration::format_duration;
use super::engines::SearchEngine;
-use atuin_client::{
+use crate::atuin_client::{
history::History,
settings::{UiColumn, UiColumnType},
theme::{Meaning, Theme},
};
-use atuin_common::utils::Escapable as _;
+use crate::atuin_common::utils::Escapable as _;
use itertools::Itertools;
use ratatui::{
backend::FromCrossterm,
diff --git a/crates/atuin/src/command/client/search/inspector.rs b/crates/turtle/src/command/client/search/inspector.rs
index e2cdabe5..1ebc4383 100644
--- a/crates/atuin/src/command/client/search/inspector.rs
+++ b/crates/turtle/src/command/client/search/inspector.rs
@@ -1,7 +1,7 @@
use std::time::Duration;
use time::macros::format_description;
-use atuin_client::{
+use crate::atuin_client::{
history::{History, HistoryStats},
settings::{Settings, Timezone},
};
@@ -338,7 +338,7 @@ pub fn draw_full(
#[cfg(test)]
mod tests {
use super::draw_ultracompact;
- use atuin_client::{
+ use crate::atuin_client::{
history::{History, HistoryId, HistoryStats},
theme::ThemeManager,
};
diff --git a/crates/atuin/src/command/client/search/interactive.rs b/crates/turtle/src/command/client/search/interactive.rs
index 4efba803..a3d2cb79 100644
--- a/crates/atuin/src/command/client/search/interactive.rs
+++ b/crates/turtle/src/command/client/search/interactive.rs
@@ -6,7 +6,7 @@ use std::{
#[cfg(unix)]
use std::io::Read as _;
-use atuin_common::{shell::Shell, utils::Escapable as _};
+use crate::atuin_common::{shell::Shell, utils::Escapable as _};
use eyre::Result;
use time::OffsetDateTime;
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
@@ -16,7 +16,7 @@ use super::{
engines::{SearchEngine, SearchState},
history_list::{HistoryList, ListState},
};
-use atuin_client::{
+use crate::atuin_client::{
database::{Context, Database, current_context},
history::{History, HistoryId, HistoryStats, store::HistoryStore},
settings::{
@@ -50,9 +50,6 @@ use ratatui::crossterm::event::{
KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags,
};
-#[cfg(windows)]
-use windows_sys::Win32::System::Console::{GetConsoleOutputCP, SetConsoleOutputCP};
-
const TAB_TITLES: [&str; 2] = ["Search", "Inspect"];
pub enum InputAction {
@@ -97,9 +94,9 @@ impl InspectingState {
pub fn to_compactness(f: &Frame, settings: &Settings) -> Compactness {
if match settings.style {
- atuin_client::settings::Style::Auto => f.area().height < 14,
- atuin_client::settings::Style::Compact => true,
- atuin_client::settings::Style::Full => false,
+ crate::atuin_client::settings::Style::Auto => f.area().height < 14,
+ crate::atuin_client::settings::Style::Compact => true,
+ crate::atuin_client::settings::Style::Full => false,
} {
if settings.auto_hide_height != 0 && f.area().height <= settings.auto_hide_height {
Compactness::Ultracompact
@@ -166,7 +163,7 @@ impl State {
self.results_len = results.len();
if smart_sort {
- Ok(atuin_history::sort::sort(
+ Ok(crate::atuin_history::sort::sort(
self.search.input.as_str(),
results,
))
@@ -1275,14 +1272,9 @@ enum TerminalWriter {
Stdout(std::io::Stdout),
#[cfg(unix)]
Tty(std::fs::File),
- #[cfg(windows)]
- ConOut(std::io::LineWriter<std::fs::File>, u32),
}
impl TerminalWriter {
- #[cfg(windows)]
- const CP_UTF8: u32 = 65001;
-
fn new() -> std::io::Result<Self> {
let stdout = stdout();
if stdout.is_terminal() {
@@ -1301,35 +1293,6 @@ impl TerminalWriter {
.open("/dev/tty")?,
))
}
-
- // On Windows, use CONOUT$ which is the equivalent of /dev/tty, but this
- // requires setting the current console output code page to UTF-8 for the
- // TUI to render properly. We'll set it back to its previous value upon exit.
- #[cfg(windows)]
- {
- let file = std::fs::File::options()
- .read(true)
- .write(true)
- .open("CONOUT$")?;
-
- let initial_console_output_cp = unsafe { GetConsoleOutputCP() };
- if initial_console_output_cp != Self::CP_UTF8 {
- unsafe {
- SetConsoleOutputCP(Self::CP_UTF8);
- }
- }
-
- Ok(TerminalWriter::ConOut(
- std::io::LineWriter::new(file),
- initial_console_output_cp,
- ))
- }
-
- #[cfg(not(any(unix, windows)))]
- Err(std::io::Error::new(
- std::io::ErrorKind::Unsupported,
- "Interactive mode requires a terminal",
- ))
}
}
@@ -1339,8 +1302,6 @@ impl Write for TerminalWriter {
TerminalWriter::Stdout(stdout) => stdout.write(buf),
#[cfg(unix)]
TerminalWriter::Tty(file) => file.write(buf),
- #[cfg(windows)]
- TerminalWriter::ConOut(writer, _) => writer.write(buf),
}
}
@@ -1349,21 +1310,6 @@ impl Write for TerminalWriter {
TerminalWriter::Stdout(stdout) => stdout.flush(),
#[cfg(unix)]
TerminalWriter::Tty(file) => file.flush(),
- #[cfg(windows)]
- TerminalWriter::ConOut(writer, _) => writer.flush(),
- }
- }
-}
-
-impl Drop for TerminalWriter {
- fn drop(&mut self) {
- #[cfg(windows)]
- if let TerminalWriter::ConOut(_, initial_console_output_cp) = self
- && *initial_console_output_cp != Self::CP_UTF8
- {
- unsafe {
- SetConsoleOutputCP(*initial_console_output_cp);
- }
}
}
}
@@ -1668,10 +1614,6 @@ pub async fn history(
}
};
- #[cfg(not(unix))]
- let (saved_screen, popup_rect, _popup_scroll_offset): (Option<()>, Rect, u16) =
- (None, Rect::default(), 0);
-
let popup_mode = saved_screen.is_some();
let stdout = Stdout::new(inline_height > 0, settings.no_mouse)?;
@@ -2053,9 +1995,9 @@ fn set_clipboard(_s: String) {}
#[cfg(test)]
mod tests {
- use atuin_client::database::Context;
- use atuin_client::history::History;
- use atuin_client::settings::{
+ use crate::atuin_client::database::Context;
+ use crate::atuin_client::history::History;
+ use crate::atuin_client::settings::{
FilterMode, KeymapMode, Preview, PreviewStrategy, SearchMode, Settings,
};
use time::OffsetDateTime;
@@ -2264,7 +2206,7 @@ mod tests {
#[test]
fn test_accept_keybindings() {
- use atuin_client::settings::Keys;
+ use crate::atuin_client::settings::Keys;
use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
let mut settings = Settings::utc();
@@ -2870,8 +2812,8 @@ mod tests {
#[test]
fn execute_exit_returns_based_on_exit_mode() {
+ use crate::atuin_client::settings::ExitMode;
use crate::command::client::search::keybindings::Action;
- use atuin_client::settings::ExitMode;
let mut state = make_executor_state(100, 0);
let mut settings = Settings::utc();
@@ -3043,7 +2985,7 @@ mod tests {
#[test]
fn keymap_config_return_query() {
- use atuin_client::settings::KeyBindingConfig;
+ use crate::atuin_client::settings::KeyBindingConfig;
use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use std::collections::HashMap;
diff --git a/crates/atuin/src/command/client/search/keybindings/actions.rs b/crates/turtle/src/command/client/search/keybindings/actions.rs
index ff2ef7de..ff2ef7de 100644
--- a/crates/atuin/src/command/client/search/keybindings/actions.rs
+++ b/crates/turtle/src/command/client/search/keybindings/actions.rs
diff --git a/crates/atuin/src/command/client/search/keybindings/conditions.rs b/crates/turtle/src/command/client/search/keybindings/conditions.rs
index 055ae905..055ae905 100644
--- a/crates/atuin/src/command/client/search/keybindings/conditions.rs
+++ b/crates/turtle/src/command/client/search/keybindings/conditions.rs
diff --git a/crates/atuin/src/command/client/search/keybindings/defaults.rs b/crates/turtle/src/command/client/search/keybindings/defaults.rs
index a76cd4a9..c8401e37 100644
--- a/crates/atuin/src/command/client/search/keybindings/defaults.rs
+++ b/crates/turtle/src/command/client/search/keybindings/defaults.rs
@@ -1,6 +1,6 @@
use std::collections::HashMap;
-use atuin_client::settings::{KeyBindingConfig, Settings};
+use crate::atuin_client::settings::{KeyBindingConfig, Settings};
use tracing::warn;
use super::actions::Action;
@@ -354,7 +354,7 @@ pub fn default_vim_insert_keymap(settings: &Settings) -> Keymap {
/// bindings. We respect the user's `keymap_mode` to provide vim-style j/k
/// navigation for vim users.
pub fn default_inspector_keymap(settings: &Settings) -> Keymap {
- use atuin_client::settings::KeymapMode;
+ use crate::atuin_client::settings::KeymapMode;
let mut km = Keymap::new();
@@ -495,7 +495,7 @@ impl KeymapSet {
/// - If `[keymap]` is empty/absent, `[keys]` customizes the defaults
/// (current behavior for backward compatibility).
pub fn from_settings(settings: &Settings) -> Self {
- use atuin_client::settings::Keys;
+ use crate::atuin_client::settings::Keys;
if settings.keymap.is_empty() {
// No [keymap] section → use [keys] to customize defaults
@@ -975,7 +975,7 @@ mod tests {
#[test]
fn parse_simple_binding_config() {
- use atuin_client::settings::KeyBindingConfig;
+ use crate::atuin_client::settings::KeyBindingConfig;
let cfg = KeyBindingConfig::Simple("accept".to_string());
let binding = super::parse_binding_config(&cfg).unwrap();
assert_eq!(binding.rules.len(), 1);
@@ -985,7 +985,7 @@ mod tests {
#[test]
fn parse_conditional_binding_config() {
- use atuin_client::settings::{KeyBindingConfig, KeyRuleConfig};
+ use crate::atuin_client::settings::{KeyBindingConfig, KeyRuleConfig};
let cfg = KeyBindingConfig::Rules(vec![
KeyRuleConfig {
when: Some("cursor-at-start".to_string()),
@@ -1006,14 +1006,14 @@ mod tests {
#[test]
fn parse_binding_config_invalid_action() {
- use atuin_client::settings::KeyBindingConfig;
+ use crate::atuin_client::settings::KeyBindingConfig;
let cfg = KeyBindingConfig::Simple("not-a-real-action".to_string());
assert!(super::parse_binding_config(&cfg).is_err());
}
#[test]
fn parse_binding_config_invalid_condition() {
- use atuin_client::settings::{KeyBindingConfig, KeyRuleConfig};
+ use crate::atuin_client::settings::{KeyBindingConfig, KeyRuleConfig};
let cfg = KeyBindingConfig::Rules(vec![KeyRuleConfig {
when: Some("not-a-real-condition".to_string()),
action: "exit".to_string(),
@@ -1023,7 +1023,7 @@ mod tests {
#[test]
fn config_override_replaces_key() {
- use atuin_client::settings::KeyBindingConfig;
+ use crate::atuin_client::settings::KeyBindingConfig;
use std::collections::HashMap;
let mut settings = default_settings();
@@ -1048,7 +1048,7 @@ mod tests {
#[test]
fn config_override_preserves_unoverridden_keys() {
- use atuin_client::settings::KeyBindingConfig;
+ use crate::atuin_client::settings::KeyBindingConfig;
use std::collections::HashMap;
let mut settings = default_settings();
@@ -1072,7 +1072,7 @@ mod tests {
#[test]
fn config_conditional_override() {
- use atuin_client::settings::{KeyBindingConfig, KeyRuleConfig};
+ use crate::atuin_client::settings::{KeyBindingConfig, KeyRuleConfig};
use std::collections::HashMap;
let mut settings = default_settings();
@@ -1131,7 +1131,7 @@ mod tests {
#[test]
fn keymap_overrides_ignore_keys_section() {
- use atuin_client::settings::KeyBindingConfig;
+ use crate::atuin_client::settings::KeyBindingConfig;
// Set up: [keys] disables scroll_exits, but [keymap] is present
let mut settings = default_settings();
@@ -1172,7 +1172,7 @@ mod tests {
#[test]
fn keymap_present_resets_to_standard_keys_defaults() {
- use atuin_client::settings::KeyBindingConfig;
+ use crate::atuin_client::settings::KeyBindingConfig;
let mut settings = default_settings();
// Disable all [keys] behaviors
@@ -1214,7 +1214,7 @@ mod tests {
#[test]
fn keys_has_non_default_values_detection() {
- use atuin_client::settings::Keys;
+ use crate::atuin_client::settings::Keys;
let standard = Keys::standard_defaults();
assert!(!standard.has_non_default_values());
@@ -1230,7 +1230,7 @@ mod tests {
#[test]
fn original_input_empty_condition_in_config() {
- use atuin_client::settings::{KeyBindingConfig, KeyRuleConfig};
+ use crate::atuin_client::settings::{KeyBindingConfig, KeyRuleConfig};
use std::collections::HashMap;
let mut settings = default_settings();
diff --git a/crates/atuin/src/command/client/search/keybindings/key.rs b/crates/turtle/src/command/client/search/keybindings/key.rs
index c2eb31c6..c2eb31c6 100644
--- a/crates/atuin/src/command/client/search/keybindings/key.rs
+++ b/crates/turtle/src/command/client/search/keybindings/key.rs
diff --git a/crates/atuin/src/command/client/search/keybindings/keymap.rs b/crates/turtle/src/command/client/search/keybindings/keymap.rs
index 0d362863..0d362863 100644
--- a/crates/atuin/src/command/client/search/keybindings/keymap.rs
+++ b/crates/turtle/src/command/client/search/keybindings/keymap.rs
diff --git a/crates/atuin/src/command/client/search/keybindings/mod.rs b/crates/turtle/src/command/client/search/keybindings/mod.rs
index 3b6eb2b2..3b6eb2b2 100644
--- a/crates/atuin/src/command/client/search/keybindings/mod.rs
+++ b/crates/turtle/src/command/client/search/keybindings/mod.rs
diff --git a/crates/turtle/src/command/client/server.rs b/crates/turtle/src/command/client/server.rs
new file mode 100644
index 00000000..7de27551
--- /dev/null
+++ b/crates/turtle/src/command/client/server.rs
@@ -0,0 +1,61 @@
+use std::net::SocketAddr;
+
+use crate::atuin_server::{Settings, launch, launch_metrics_server};
+use crate::atuin_server_database::DbType;
+use crate::atuin_server_postgres::Postgres;
+use crate::atuin_server_sqlite::Sqlite;
+
+use clap::Subcommand;
+use eyre::{Context, Result, eyre};
+
+#[derive(Subcommand, Clone, Debug)]
+#[command(infer_subcommands = true)]
+pub enum Cmd {
+ /// Start the server
+ Start {
+ /// The host address to bind
+ #[clap(long)]
+ host: Option<String>,
+
+ /// The port to bind
+ #[clap(long, short)]
+ port: Option<u16>,
+ },
+
+ /// Print server example configuration
+ DefaultConfig,
+}
+
+impl Cmd {
+ #[expect(clippy::too_many_lines)]
+ pub async fn run(self) -> Result<()> {
+ match self {
+ Cmd::Start { host, port } => {
+ let settings = Settings::new().wrap_err("could not load server settings")?;
+ let host = host.as_ref().unwrap_or(&settings.host).clone();
+ let port = port.unwrap_or(settings.port);
+ let addr = SocketAddr::new(host.parse()?, port);
+
+ if settings.metrics.enable {
+ tokio::spawn(launch_metrics_server(
+ settings.metrics.host.clone(),
+ settings.metrics.port,
+ ));
+ }
+
+ match settings.db_settings.db_type() {
+ DbType::Postgres => launch::<Postgres>(settings, addr).await,
+ DbType::Sqlite => launch::<Sqlite>(settings, addr).await,
+ DbType::Unknown => {
+ Err(eyre!("db_uri must start with postgres:// or sqlite://"))
+ }
+ }
+ }
+ Cmd::DefaultConfig => {
+ // TODO(@bpeetz): Add this back <2026-06-11>
+ println!("TODO");
+ Ok(())
+ }
+ }
+ }
+}
diff --git a/crates/atuin/src/command/client/setup.rs b/crates/turtle/src/command/client/setup.rs
index 8de73d62..b32ceb97 100644
--- a/crates/atuin/src/command/client/setup.rs
+++ b/crates/turtle/src/command/client/setup.rs
@@ -1,4 +1,4 @@
-use atuin_client::settings::Settings;
+use crate::atuin_client::settings::Settings;
use colored::Colorize;
use eyre::Result;
diff --git a/crates/atuin/src/command/client/stats.rs b/crates/turtle/src/command/client/stats.rs
index a7fc00ac..fc10e949 100644
--- a/crates/atuin/src/command/client/stats.rs
+++ b/crates/turtle/src/command/client/stats.rs
@@ -3,13 +3,13 @@ use eyre::Result;
use interim::parse_date_string;
use time::{Duration, OffsetDateTime, Time};
-use atuin_client::{
+use crate::atuin_client::{
database::{Database, current_context},
settings::Settings,
theme::Theme,
};
-use atuin_history::stats::{compute, pretty_print};
+use crate::atuin_history::stats::{compute, pretty_print};
fn parse_ngram_size(s: &str) -> Result<usize, String> {
let value = s
diff --git a/crates/atuin/src/command/client/store.rs b/crates/turtle/src/command/client/store.rs
index 513c404a..dfa3b66c 100644
--- a/crates/atuin/src/command/client/store.rs
+++ b/crates/turtle/src/command/client/store.rs
@@ -1,7 +1,7 @@
use clap::Subcommand;
use eyre::Result;
-use atuin_client::{
+use crate::atuin_client::{
database::Database,
record::{sqlite_store::SqliteStore, store::Store},
settings::Settings,
diff --git a/crates/atuin/src/command/client/store/pull.rs b/crates/turtle/src/command/client/store/pull.rs
index 25b925c7..c9c9c379 100644
--- a/crates/atuin/src/command/client/store/pull.rs
+++ b/crates/turtle/src/command/client/store/pull.rs
@@ -1,7 +1,7 @@
use clap::Args;
use eyre::Result;
-use atuin_client::{
+use crate::atuin_client::{
database::Database,
encryption::load_key,
record::store::Store,
diff --git a/crates/atuin/src/command/client/store/purge.rs b/crates/turtle/src/command/client/store/purge.rs
index ad2369ce..f7996c4b 100644
--- a/crates/atuin/src/command/client/store/purge.rs
+++ b/crates/turtle/src/command/client/store/purge.rs
@@ -1,7 +1,7 @@
use clap::Args;
use eyre::Result;
-use atuin_client::{
+use crate::atuin_client::{
encryption::load_key,
record::{sqlite_store::SqliteStore, store::Store},
settings::Settings,
diff --git a/crates/atuin/src/command/client/store/push.rs b/crates/turtle/src/command/client/store/push.rs
index d8569e1e..724dfbef 100644
--- a/crates/atuin/src/command/client/store/push.rs
+++ b/crates/turtle/src/command/client/store/push.rs
@@ -1,9 +1,9 @@
-use atuin_common::record::HostId;
+use crate::atuin_common::record::HostId;
use clap::Args;
use eyre::Result;
use uuid::Uuid;
-use atuin_client::{
+use crate::atuin_client::{
api_client::Client,
encryption::load_key,
record::sync::Operation,
diff --git a/crates/atuin/src/command/client/store/rebuild.rs b/crates/turtle/src/command/client/store/rebuild.rs
index b9f2837b..80e201c2 100644
--- a/crates/atuin/src/command/client/store/rebuild.rs
+++ b/crates/turtle/src/command/client/store/rebuild.rs
@@ -4,7 +4,7 @@ use eyre::{Result, bail};
#[cfg(feature = "daemon")]
use crate::command::client::daemon as daemon_cmd;
-use atuin_client::{
+use crate::atuin_client::{
database::Database, encryption, history::store::HistoryStore,
record::sqlite_store::SqliteStore, settings::Settings,
};
@@ -51,7 +51,7 @@ impl Rebuild {
history_store.build(database).await?;
#[cfg(feature = "daemon")]
- daemon_cmd::emit_event(settings, atuin_daemon::DaemonEvent::HistoryRebuilt).await;
+ daemon_cmd::emit_event(settings, crate::atuin_daemon::DaemonEvent::HistoryRebuilt).await;
Ok(())
}
diff --git a/crates/atuin/src/command/client/store/rekey.rs b/crates/turtle/src/command/client/store/rekey.rs
index c92d2555..e63be447 100644
--- a/crates/atuin/src/command/client/store/rekey.rs
+++ b/crates/turtle/src/command/client/store/rekey.rs
@@ -2,7 +2,7 @@ use clap::Args;
use eyre::Result;
use tokio::{fs::File, io::AsyncWriteExt};
-use atuin_client::{
+use crate::atuin_client::{
encryption::{decode_key, generate_encoded_key, load_key},
record::sqlite_store::SqliteStore,
record::store::Store,
diff --git a/crates/atuin/src/command/client/store/verify.rs b/crates/turtle/src/command/client/store/verify.rs
index 84bec96a..5aa1dc70 100644
--- a/crates/atuin/src/command/client/store/verify.rs
+++ b/crates/turtle/src/command/client/store/verify.rs
@@ -1,7 +1,7 @@
use clap::Args;
use eyre::Result;
-use atuin_client::{
+use crate::atuin_client::{
encryption::load_key,
record::{sqlite_store::SqliteStore, store::Store},
settings::Settings,
diff --git a/crates/atuin/src/command/client/sync.rs b/crates/turtle/src/command/client/sync.rs
index 5b8c2cb7..a4839b5f 100644
--- a/crates/atuin/src/command/client/sync.rs
+++ b/crates/turtle/src/command/client/sync.rs
@@ -1,7 +1,7 @@
use clap::Subcommand;
use eyre::{Result, WrapErr};
-use atuin_client::{
+use crate::atuin_client::{
database::Database,
encryption,
history::store::HistoryStore,
@@ -53,7 +53,7 @@ impl Cmd {
Self::Register(r) => r.run(&settings).await,
Self::Status => status::run(&settings).await,
Self::Key {} => {
- use atuin_client::encryption::{encode_key, load_key};
+ use crate::atuin_client::encryption::{encode_key, load_key};
let key = load_key(&settings).wrap_err("could not load encryption key")?;
let encode = encode_key(&key).wrap_err("could not encode encryption key")?;
diff --git a/crates/atuin/src/command/client/sync/status.rs b/crates/turtle/src/command/client/sync/status.rs
index c992eb3e..00088b59 100644
--- a/crates/atuin/src/command/client/sync/status.rs
+++ b/crates/turtle/src/command/client/sync/status.rs
@@ -1,5 +1,5 @@
use crate::{SHA, VERSION};
-use atuin_client::{api_client, settings::Settings};
+use crate::atuin_client::{api_client, settings::Settings};
use colored::Colorize;
use eyre::{Result, bail};
diff --git a/crates/atuin/src/command/client/wrapped.rs b/crates/turtle/src/command/client/wrapped.rs
index 0e0c9f14..694157c2 100644
--- a/crates/atuin/src/command/client/wrapped.rs
+++ b/crates/turtle/src/command/client/wrapped.rs
@@ -3,9 +3,9 @@ use eyre::Result;
use std::collections::{HashMap, HashSet};
use time::{Date, Duration, Month, OffsetDateTime, Time};
-use atuin_client::{database::Database, settings::Settings, theme::Theme};
+use crate::atuin_client::{database::Database, settings::Settings, theme::Theme};
-use atuin_history::stats::{Stats, compute};
+use crate::atuin_history::stats::{Stats, compute};
#[derive(Debug)]
struct WrappedStats {
@@ -20,7 +20,11 @@ struct WrappedStats {
impl WrappedStats {
#[expect(clippy::too_many_lines, clippy::cast_precision_loss)]
- fn new(settings: &Settings, stats: &Stats, history: &[atuin_client::history::History]) -> Self {
+ fn new(
+ settings: &Settings,
+ stats: &Stats,
+ history: &[crate::atuin_client::history::History],
+ ) -> Self {
let nav_commands = stats
.top
.iter()
@@ -313,7 +317,7 @@ pub async fn run(
);
println!("Your Top Commands:");
- atuin_history::stats::pretty_print(stats.clone(), 1, theme);
+ crate::atuin_history::stats::pretty_print(stats.clone(), 1, theme);
println!();
print_fun_facts(&wrapped_stats, &stats, year);
diff --git a/crates/atuin/src/command/contributors.rs b/crates/turtle/src/command/contributors.rs
index 452fd335..452fd335 100644
--- a/crates/atuin/src/command/contributors.rs
+++ b/crates/turtle/src/command/contributors.rs
diff --git a/crates/atuin/src/command/external.rs b/crates/turtle/src/command/external.rs
index 5d875e9d..e1f0cddd 100644
--- a/crates/atuin/src/command/external.rs
+++ b/crates/turtle/src/command/external.rs
@@ -3,7 +3,7 @@ use std::process::Command;
use std::{io, process};
#[cfg(feature = "client")]
-use atuin_client::plugin::{OfficialPluginRegistry, PluginContext};
+use crate::atuin_client::plugin::{OfficialPluginRegistry, PluginContext};
use clap::CommandFactory;
use clap::builder::{StyledStr, Styles};
use eyre::Result;
diff --git a/crates/atuin/src/command/gen_completions.rs b/crates/turtle/src/command/gen_completions.rs
index 10d4f689..10d4f689 100644
--- a/crates/atuin/src/command/gen_completions.rs
+++ b/crates/turtle/src/command/gen_completions.rs
diff --git a/crates/atuin/src/command/mod.rs b/crates/turtle/src/command/mod.rs
index 8aac4062..e58bfe72 100644
--- a/crates/atuin/src/command/mod.rs
+++ b/crates/turtle/src/command/mod.rs
@@ -24,7 +24,7 @@ pub enum AtuinCmd {
/// PTY proxy for atuin
#[cfg(feature = "pty-proxy")]
#[command(alias = "hex")]
- PtyProxy(atuin_pty_proxy::PtyProxy),
+ PtyProxy(crate::atuin_pty_proxy::PtyProxy),
/// Generate a UUID
Uuid,
@@ -63,7 +63,7 @@ impl AtuinCmd {
Ok(())
}
Self::Uuid => {
- println!("{}", atuin_common::utils::uuid_v7().as_simple());
+ println!("{}", crate::atuin_common::utils::uuid_v7().as_simple());
Ok(())
}
Self::GenCompletions(gen_completions) => gen_completions.run(),
@@ -73,7 +73,7 @@ impl AtuinCmd {
}
#[cfg(all(feature = "pty-proxy", unix))]
-fn run_pty_proxy(proxy: atuin_pty_proxy::PtyProxy) {
+fn run_pty_proxy(proxy: crate::atuin_pty_proxy::PtyProxy) {
#[cfg(feature = "daemon")]
proxy.run(semantic_command_capture_sink());
@@ -81,14 +81,8 @@ fn run_pty_proxy(proxy: atuin_pty_proxy::PtyProxy) {
proxy.run(None);
}
-#[cfg(all(feature = "pty-proxy", not(unix)))]
-fn run_pty_proxy(_proxy: atuin_pty_proxy::PtyProxy) {
- eprintln!("atuin pty-proxy currently supports unix platforms");
- std::process::exit(1);
-}
-
#[cfg(all(feature = "daemon", feature = "pty-proxy", unix))]
-fn semantic_command_capture_sink() -> Option<atuin_pty_proxy::CommandCaptureSink> {
+fn semantic_command_capture_sink() -> Option<crate::atuin_pty_proxy::CommandCaptureSink> {
use std::sync::mpsc;
use std::time::Duration;
@@ -96,8 +90,8 @@ fn semantic_command_capture_sink() -> Option<atuin_pty_proxy::CommandCaptureSink
return None;
}
- let settings = atuin_client::settings::Settings::new().ok()?;
- let (tx, rx) = mpsc::sync_channel::<atuin_pty_proxy::CommandCapture>(128);
+ let settings = crate::atuin_client::settings::Settings::new().ok()?;
+ let (tx, rx) = mpsc::sync_channel::<crate::atuin_pty_proxy::CommandCapture>(128);
std::thread::spawn(move || {
let Ok(runtime) = tokio::runtime::Builder::new_current_thread()
@@ -139,12 +133,12 @@ fn is_truthy_env(name: &str) -> bool {
#[cfg(all(feature = "daemon", feature = "pty-proxy", unix))]
async fn send_semantic_command_captures(
- settings: &atuin_client::settings::Settings,
- batch: Vec<atuin_pty_proxy::CommandCapture>,
+ settings: &crate::atuin_client::settings::Settings,
+ batch: Vec<crate::atuin_pty_proxy::CommandCapture>,
) {
let captures = batch
.into_iter()
- .map(|capture| atuin_daemon::semantic::CommandCapture {
+ .map(|capture| crate::atuin_daemon::semantic::CommandCapture {
prompt: capture.prompt,
command: capture.command,
output: capture.output,
@@ -156,7 +150,7 @@ async fn send_semantic_command_captures(
})
.collect();
- if let Ok(mut client) = atuin_daemon::SemanticClient::from_settings(settings).await {
+ if let Ok(mut client) = crate::atuin_daemon::SemanticClient::from_settings(settings).await {
let _ = client.record_commands(captures).await;
}
}
diff --git a/crates/atuin/src/main.rs b/crates/turtle/src/main.rs
index 255db36a..e5b80ee8 100644
--- a/crates/atuin/src/main.rs
+++ b/crates/turtle/src/main.rs
@@ -1,5 +1,7 @@
#![warn(clippy::pedantic, clippy::nursery)]
#![allow(clippy::use_self, clippy::missing_const_for_fn)] // not 100% reliable
+// #![deny(unsafe_code)]
+#![forbid(unsafe_code)]
use clap::Parser;
use clap::builder::Styles;
@@ -10,6 +12,16 @@ use command::AtuinCmd;
mod command;
+mod atuin_client;
+mod atuin_common;
+mod atuin_daemon;
+mod atuin_history;
+mod atuin_pty_proxy;
+mod atuin_server;
+mod atuin_server_database;
+mod atuin_server_postgres;
+mod atuin_server_sqlite;
+
#[cfg(feature = "sync")]
mod print_error;
#[cfg(feature = "sync")]
diff --git a/crates/atuin/src/print_error.rs b/crates/turtle/src/print_error.rs
index a6da283d..4d4724bc 100644
--- a/crates/atuin/src/print_error.rs
+++ b/crates/turtle/src/print_error.rs
@@ -1,6 +1,6 @@
use std::io::IsTerminal;
-use atuin_client::record::sync::SyncError;
+use crate::atuin_client::record::sync::SyncError;
use colored::Colorize;
use crossterm::terminal;
diff --git a/crates/atuin/src/shell/.gitattributes b/crates/turtle/src/shell/.gitattributes
index fae8897c..fae8897c 100644
--- a/crates/atuin/src/shell/.gitattributes
+++ b/crates/turtle/src/shell/.gitattributes
diff --git a/crates/atuin/src/shell/atuin.bash b/crates/turtle/src/shell/atuin.bash
index 8b540bd7..8b540bd7 100644
--- a/crates/atuin/src/shell/atuin.bash
+++ b/crates/turtle/src/shell/atuin.bash
diff --git a/crates/atuin/src/shell/atuin.fish b/crates/turtle/src/shell/atuin.fish
index 15b33451..15b33451 100644
--- a/crates/atuin/src/shell/atuin.fish
+++ b/crates/turtle/src/shell/atuin.fish
diff --git a/crates/atuin/src/shell/atuin.nu b/crates/turtle/src/shell/atuin.nu
index d37457e4..d37457e4 100644
--- a/crates/atuin/src/shell/atuin.nu
+++ b/crates/turtle/src/shell/atuin.nu
diff --git a/crates/atuin/src/shell/atuin.ps1 b/crates/turtle/src/shell/atuin.ps1
index 431ee2c3..431ee2c3 100644
--- a/crates/atuin/src/shell/atuin.ps1
+++ b/crates/turtle/src/shell/atuin.ps1
diff --git a/crates/atuin/src/shell/atuin.xsh b/crates/turtle/src/shell/atuin.xsh
index a0283402..a0283402 100644
--- a/crates/atuin/src/shell/atuin.xsh
+++ b/crates/turtle/src/shell/atuin.xsh
diff --git a/crates/atuin/src/shell/atuin.zsh b/crates/turtle/src/shell/atuin.zsh
index 7a7375aa..7a7375aa 100644
--- a/crates/atuin/src/shell/atuin.zsh
+++ b/crates/turtle/src/shell/atuin.zsh
diff --git a/crates/atuin/src/sync.rs b/crates/turtle/src/sync.rs
index 02e4db69..56aef615 100644
--- a/crates/atuin/src/sync.rs
+++ b/crates/turtle/src/sync.rs
@@ -1,10 +1,10 @@
use eyre::{Context, Result};
-use atuin_client::{
+use crate::atuin_client::{
database::Database, history::store::HistoryStore, record::sqlite_store::SqliteStore,
settings::Settings,
};
-use atuin_common::record::RecordId;
+use crate::atuin_common::record::RecordId;
// This is the only crate that ties together all other crates.
// Therefore, it's the only crate where functions tying together all stores can live
@@ -18,7 +18,7 @@ pub async fn build(
db: &dyn Database,
downloaded: Option<&[RecordId]>,
) -> Result<()> {
- let encryption_key: [u8; 32] = atuin_client::encryption::load_key(settings)
+ let encryption_key: [u8; 32] = crate::atuin_client::encryption::load_key(settings)
.context("could not load encryption key")?
.into();