Skip to content

Commit 9fe7d10

Browse files
authored
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`.
1 parent 6ea760b commit 9fe7d10

File tree

12 files changed

+339
-59
lines changed

12 files changed

+339
-59
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
alter table history add column author text;
2+
alter table history add column intent text;

crates/atuin-client/src/database.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ impl Sqlite {
200200

201201
async fn save_raw(tx: &mut sqlx::Transaction<'_, sqlx::Sqlite>, h: &History) -> Result<()> {
202202
sqlx::query(
203-
"insert or ignore into history(id, timestamp, duration, exit, command, cwd, session, hostname, deleted_at)
204-
values(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)",
203+
"insert or ignore into history(id, timestamp, duration, exit, command, cwd, session, hostname, author, intent, deleted_at)
204+
values(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)",
205205
)
206206
.bind(h.id.0.as_str())
207207
.bind(h.timestamp.unix_timestamp_nanos() as i64)
@@ -211,6 +211,8 @@ impl Sqlite {
211211
.bind(h.cwd.as_str())
212212
.bind(h.session.as_str())
213213
.bind(h.hostname.as_str())
214+
.bind(h.author.as_str())
215+
.bind(h.intent.as_deref())
214216
.bind(h.deleted_at.map(|t|t.unix_timestamp_nanos() as i64))
215217
.execute(&mut **tx)
216218
.await?;
@@ -232,6 +234,13 @@ impl Sqlite {
232234

233235
fn query_history(row: SqliteRow) -> History {
234236
let deleted_at: Option<i64> = row.get("deleted_at");
237+
let hostname: String = row.get("hostname");
238+
let author: Option<String> = row.try_get("author").ok().flatten();
239+
let author = author
240+
.filter(|author| !author.trim().is_empty())
241+
.unwrap_or_else(|| History::author_from_hostname(hostname.as_str()));
242+
let intent: Option<String> = row.try_get("intent").ok().flatten();
243+
let intent = intent.filter(|intent| !intent.trim().is_empty());
235244

236245
History::from_db()
237246
.id(row.get("id"))
@@ -244,7 +253,9 @@ impl Sqlite {
244253
.command(row.get("command"))
245254
.cwd(row.get("cwd"))
246255
.session(row.get("session"))
247-
.hostname(row.get("hostname"))
256+
.hostname(hostname)
257+
.author(author)
258+
.intent(intent)
248259
.deleted_at(
249260
deleted_at.and_then(|t| OffsetDateTime::from_unix_timestamp_nanos(t as i128).ok()),
250261
)
@@ -295,7 +306,7 @@ impl Database for Sqlite {
295306

296307
sqlx::query(
297308
"update history
298-
set timestamp = ?2, duration = ?3, exit = ?4, command = ?5, cwd = ?6, session = ?7, hostname = ?8, deleted_at = ?9
309+
set timestamp = ?2, duration = ?3, exit = ?4, command = ?5, cwd = ?6, session = ?7, hostname = ?8, author = ?9, intent = ?10, deleted_at = ?11
299310
where id = ?1",
300311
)
301312
.bind(h.id.0.as_str())
@@ -306,6 +317,8 @@ impl Database for Sqlite {
306317
.bind(h.cwd.as_str())
307318
.bind(h.session.as_str())
308319
.bind(h.hostname.as_str())
320+
.bind(h.author.as_str())
321+
.bind(h.intent.as_deref())
309322
.bind(h.deleted_at.map(|t|t.unix_timestamp_nanos() as i64))
310323
.execute(&self.pool)
311324
.await?;
@@ -612,6 +625,8 @@ impl Database for Sqlite {
612625
"exit",
613626
"command",
614627
"deleted_at",
628+
"null as author",
629+
"null as intent",
615630
"group_concat(cwd, ':') as cwd",
616631
"group_concat(session) as session",
617632
"group_concat(hostname, ',') as hostname",

crates/atuin-client/src/encryption.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ fn decode(bytes: &[u8]) -> Result<History> {
253253
cwd: cwd.to_owned(),
254254
session: session.to_owned(),
255255
hostname: hostname.to_owned(),
256+
author: History::author_from_hostname(hostname),
257+
intent: None,
256258
deleted_at: deleted_at
257259
.map(|t| OffsetDateTime::parse(t, &Rfc3339))
258260
.transpose()?,
@@ -287,6 +289,8 @@ mod test {
287289
.duration(1)
288290
.session("beep boop".into())
289291
.hostname("booop".into())
292+
.author("booop".into())
293+
.intent(None)
290294
.deleted_at(None)
291295
.build()
292296
.into();
@@ -331,6 +335,8 @@ mod test {
331335
cwd: "/Users/conrad.ludgate/Documents/code/atuin".to_owned(),
332336
session: "b97d9a306f274473a203d2eba41f9457".to_owned(),
333337
hostname: "fvfg936c0kpf:conrad.ludgate".to_owned(),
338+
author: "conrad.ludgate".to_owned(),
339+
intent: None,
334340
deleted_at: None,
335341
};
336342

@@ -352,6 +358,8 @@ mod test {
352358
cwd: "/Users/conrad.ludgate/Documents/code/atuin".to_owned(),
353359
session: "b97d9a306f274473a203d2eba41f9457".to_owned(),
354360
hostname: "fvfg936c0kpf:conrad.ludgate".to_owned(),
361+
author: "conrad.ludgate".to_owned(),
362+
intent: None,
355363
deleted_at: Some(datetime!(2023-05-28 18:35:40.633872 +00:00)),
356364
};
357365

@@ -383,6 +391,8 @@ mod test {
383391
cwd: "/Users/conrad.ludgate/Documents/code/atuin".to_owned(),
384392
session: "b97d9a306f274473a203d2eba41f9457".to_owned(),
385393
hostname: "fvfg936c0kpf:conrad.ludgate".to_owned(),
394+
author: "conrad.ludgate".to_owned(),
395+
intent: None,
386396
deleted_at: None,
387397
};
388398

0 commit comments

Comments
 (0)