aboutsummaryrefslogtreecommitdiffstats
path: root/crates/atuin-client/src/history
diff options
context:
space:
mode:
authorEllie Huxtable <ellie@atuin.sh>2026-02-25 19:10:58 -0800
committerGitHub <noreply@github.com>2026-02-25 19:10:58 -0800
commit9fe7d10fcf73570767ba7b4eabaa95f65958821b (patch)
treeed9705225db8e5bbe2f3c689ba5d1c9908b75eb1 /crates/atuin-client/src/history
parentfeat: Generate commands or ask questions with `atuin ai` (#3199) (diff)
downloadatuin-9fe7d10fcf73570767ba7b4eabaa95f65958821b.zip
feat: Add history author/intent metadata and v1 record version (#3205)
<!-- Thank you for making a PR! Bug fixes are always welcome, but if you're adding a new feature or changing an existing one, we'd really appreciate if you open an issue, post on the forum, or drop in on Discord --> ## Checks - [x] I am happy for maintainers to push small adjustments to this PR, to speed up the review cycle - [x] I have checked that there are no existing pull requests for the same thing Adds `author` and `intent` to client history records and DB persistence, including migration/backfill and CLI/daemon propagation. Introduces V2 record-store history version `v1` while retaining read compatibility for legacy `v0` records. Adds `--author` and `--intent` flags to `atuin history start`, plus `{author}` and `{intent}` format keys for listing/history output. Updates shell-integration docs for `ATUIN_HISTORY_AUTHOR` and `ATUIN_HISTORY_INTENT`, and updates related tests/fixtures. Validated with `cargo test -p atuin-client --lib`, `cargo test -p atuin-daemon --tests`, `cargo test -p atuin search::inspector`, and `cargo fmt --check`.
Diffstat (limited to 'crates/atuin-client/src/history')
-rw-r--r--crates/atuin-client/src/history/builder.rs22
-rw-r--r--crates/atuin-client/src/history/store.rs21
2 files changed, 37 insertions, 6 deletions
diff --git a/crates/atuin-client/src/history/builder.rs b/crates/atuin-client/src/history/builder.rs
index 2b28339f..72a505fd 100644
--- a/crates/atuin-client/src/history/builder.rs
+++ b/crates/atuin-client/src/history/builder.rs
@@ -20,6 +20,10 @@ pub struct HistoryImported {
session: Option<String>,
#[builder(default, setter(strip_option, into))]
hostname: Option<String>,
+ #[builder(default, setter(strip_option, into))]
+ author: Option<String>,
+ #[builder(default, setter(strip_option, into))]
+ intent: Option<String>,
}
impl From<HistoryImported> for History {
@@ -32,6 +36,8 @@ impl From<HistoryImported> for History {
imported.duration,
imported.session,
imported.hostname,
+ imported.author,
+ imported.intent,
None,
)
}
@@ -49,6 +55,10 @@ pub struct HistoryCaptured {
command: String,
#[builder(setter(into))]
cwd: String,
+ #[builder(default, setter(strip_option, into))]
+ author: Option<String>,
+ #[builder(default, setter(strip_option, into))]
+ intent: Option<String>,
}
impl From<HistoryCaptured> for History {
@@ -61,6 +71,8 @@ impl From<HistoryCaptured> for History {
-1,
None,
None,
+ captured.author,
+ captured.intent,
None,
)
}
@@ -79,6 +91,8 @@ pub struct HistoryFromDb {
duration: i64,
session: String,
hostname: String,
+ author: String,
+ intent: Option<String>,
deleted_at: Option<time::OffsetDateTime>,
}
@@ -93,6 +107,8 @@ impl From<HistoryFromDb> for History {
duration: from_db.duration,
session: from_db.session,
hostname: from_db.hostname,
+ author: from_db.author,
+ intent: from_db.intent,
deleted_at: from_db.deleted_at,
}
}
@@ -114,6 +130,10 @@ pub struct HistoryDaemonCapture {
session: String,
#[builder(setter(into))]
hostname: String,
+ #[builder(default, setter(strip_option, into))]
+ author: Option<String>,
+ #[builder(default, setter(strip_option, into))]
+ intent: Option<String>,
}
impl From<HistoryDaemonCapture> for History {
@@ -126,6 +146,8 @@ impl From<HistoryDaemonCapture> for History {
-1,
Some(captured.session),
Some(captured.hostname),
+ captured.author,
+ captured.intent,
None,
)
}
diff --git a/crates/atuin-client/src/history/store.rs b/crates/atuin-client/src/history/store.rs
index 041d90ce..d166564f 100644
--- a/crates/atuin-client/src/history/store.rs
+++ b/crates/atuin-client/src/history/store.rs
@@ -10,7 +10,7 @@ use crate::{
};
use atuin_common::record::{DecryptedData, Host, HostId, Record, RecordId, RecordIdx};
-use super::{HISTORY_TAG, HISTORY_VERSION, History, HistoryId};
+use super::{HISTORY_TAG, HISTORY_VERSION, HISTORY_VERSION_V0, History, HistoryId};
#[derive(Debug, Clone)]
pub struct HistoryStore {
@@ -196,10 +196,11 @@ impl HistoryStore {
for record in records.into_iter() {
let hist = match record.version.as_str() {
- HISTORY_VERSION => {
+ HISTORY_VERSION_V0 | HISTORY_VERSION => {
+ let version = record.version.clone();
let decrypted = record.decrypt::<PASETO_V4>(&self.encryption_key)?;
- HistoryRecord::deserialize(&decrypted.data, HISTORY_VERSION)
+ HistoryRecord::deserialize(&decrypted.data, version.as_str())
}
version => bail!("unknown history version {version:?}"),
}?;
@@ -257,8 +258,14 @@ impl HistoryStore {
continue;
}
+ let version = record.version.clone();
let decrypted = record.decrypt::<PASETO_V4>(&self.encryption_key)?;
- let record = HistoryRecord::deserialize(&decrypted.data, HISTORY_VERSION)?;
+ let record = match version.as_str() {
+ HISTORY_VERSION_V0 | HISTORY_VERSION => {
+ HistoryRecord::deserialize(&decrypted.data, version.as_str())?
+ }
+ version => bail!("unknown history version {version:?}"),
+ };
match record {
HistoryRecord::Create(h) => {
@@ -350,14 +357,14 @@ mod tests {
#[test]
fn test_serialize_deserialize_create() {
let bytes = [
- 204, 0, 196, 141, 205, 0, 0, 153, 217, 32, 48, 49, 56, 99, 100, 52, 102, 101, 56, 49,
+ 204, 0, 196, 147, 205, 0, 1, 154, 217, 32, 48, 49, 56, 99, 100, 52, 102, 101, 56, 49,
55, 53, 55, 99, 100, 50, 97, 101, 101, 54, 53, 99, 100, 55, 56, 54, 49, 102, 57, 99,
56, 49, 207, 23, 166, 251, 212, 181, 82, 0, 0, 100, 0, 162, 108, 115, 217, 41, 47, 85,
115, 101, 114, 115, 47, 101, 108, 108, 105, 101, 47, 115, 114, 99, 47, 103, 105, 116,
104, 117, 98, 46, 99, 111, 109, 47, 97, 116, 117, 105, 110, 115, 104, 47, 97, 116, 117,
105, 110, 217, 32, 48, 49, 56, 99, 100, 52, 102, 101, 97, 100, 56, 57, 55, 53, 57, 55,
56, 53, 50, 53, 50, 55, 97, 51, 49, 99, 57, 57, 56, 48, 53, 57, 170, 98, 111, 111, 112,
- 58, 101, 108, 108, 105, 101, 192,
+ 58, 101, 108, 108, 105, 101, 192, 165, 101, 108, 108, 105, 101,
];
let history = History {
@@ -369,6 +376,8 @@ mod tests {
cwd: "/Users/ellie/src/github.com/atuinsh/atuin".to_owned(),
session: "018cd4fead897597852527a31c998059".to_owned(),
hostname: "boop:ellie".to_owned(),
+ author: "ellie".to_owned(),
+ intent: None,
deleted_at: None,
};