aboutsummaryrefslogtreecommitdiffstats
path: root/ui/backend
diff options
context:
space:
mode:
authorEllie Huxtable <ellie@atuin.sh>2024-07-08 11:17:47 +0100
committerGitHub <noreply@github.com>2024-07-08 11:17:47 +0100
commit5b384487331eaf08031dfe438bb2affa31aafcbb (patch)
tree51904c3df8c54cbc5b7aa5832a5bae49d57f7141 /ui/backend
parentfeat(bash/blesh): hook into BLE_ONLOAD to resolve loading order issue (#2234) (diff)
downloadatuin-5b384487331eaf08031dfe438bb2affa31aafcbb.zip
feat(gui): runbooks that run (#2233)
* add initial runbooks frontend * fix buttons, scroll, add shell support to editor * work * some tweaks * wip - run crate * functioning executable blocks * handle resizing, killing ptys * clear properly on stop * move terminal to its own component, handle lifecycle better * fix all build issues * ffs codespelll * update lockfile * clippy is needy once more * only build pty stuff on mac/linux * vendor pty handling into desktop * update lockfile
Diffstat (limited to '')
-rw-r--r--ui/backend/Cargo.lock471
-rw-r--r--ui/backend/Cargo.toml6
-rw-r--r--ui/backend/capabilities/migrated.json1
-rw-r--r--ui/backend/rust-toolchain.toml2
-rw-r--r--ui/backend/src/db.rs35
-rw-r--r--ui/backend/src/install.rs3
-rw-r--r--ui/backend/src/main.rs27
-rw-r--r--ui/backend/src/pty.rs112
-rw-r--r--ui/backend/src/run/mod.rs1
-rw-r--r--ui/backend/src/run/pty.rs93
-rw-r--r--ui/backend/src/state.rs10
11 files changed, 733 insertions, 28 deletions
diff --git a/ui/backend/Cargo.lock b/ui/backend/Cargo.lock
index 90b5c8c4..827fd09b 100644
--- a/ui/backend/Cargo.lock
+++ b/ui/backend/Cargo.lock
@@ -153,6 +153,12 @@ dependencies = [
]
[[package]]
+name = "arrayvec"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
+
+[[package]]
name = "async-broadcast"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -329,12 +335,6 @@ dependencies = [
]
[[package]]
-name = "atomic"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba"
-
-[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -342,7 +342,7 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "atuin-client"
-version = "18.3.0"
+version = "18.4.0-beta.1"
dependencies = [
"async-trait",
"atuin-common",
@@ -390,10 +390,12 @@ dependencies = [
[[package]]
name = "atuin-common"
-version = "18.3.0"
+version = "18.4.0-beta.1"
dependencies = [
+ "base64 0.22.1",
"directories",
"eyre",
+ "getrandom 0.2.15",
"lazy_static",
"rand 0.8.5",
"semver",
@@ -408,7 +410,7 @@ dependencies = [
[[package]]
name = "atuin-dotfiles"
-version = "0.3.0"
+version = "0.4.0"
dependencies = [
"atuin-client",
"atuin-common",
@@ -422,7 +424,7 @@ dependencies = [
[[package]]
name = "atuin-history"
-version = "0.2.0"
+version = "0.3.0"
dependencies = [
"async-trait",
"atuin-client",
@@ -505,6 +507,21 @@ dependencies = [
]
[[package]]
+name = "bit-set"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
+dependencies = [
+ "bit-vec",
+]
+
+[[package]]
+name = "bit-vec"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
+
+[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -779,7 +796,8 @@ dependencies = [
"anstream",
"anstyle",
"clap_lex",
- "strsim",
+ "strsim 0.11.1",
+ "terminal_size",
]
[[package]]
@@ -847,6 +865,26 @@ dependencies = [
]
[[package]]
+name = "comrak"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0436149c9f6a1935b13306206c739b1ba84fa81f551b5eb87fc2ca7a13700af"
+dependencies = [
+ "clap",
+ "derive_builder",
+ "entities",
+ "memchr",
+ "once_cell",
+ "regex",
+ "shell-words",
+ "slug",
+ "syntect",
+ "typed-arena",
+ "unicode_categories",
+ "xdg",
+]
+
+[[package]]
name = "concurrent-queue"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1157,12 +1195,36 @@ dependencies = [
[[package]]
name = "darling"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
+dependencies = [
+ "darling_core 0.14.4",
+ "darling_macro 0.14.4",
+]
+
+[[package]]
+name = "darling"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
dependencies = [
- "darling_core",
- "darling_macro",
+ "darling_core 0.20.9",
+ "darling_macro 0.20.9",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim 0.10.0",
+ "syn 1.0.109",
]
[[package]]
@@ -1175,17 +1237,28 @@ dependencies = [
"ident_case",
"proc-macro2",
"quote",
- "strsim",
+ "strsim 0.11.1",
"syn 2.0.66",
]
[[package]]
name = "darling_macro"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
+dependencies = [
+ "darling_core 0.14.4",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "darling_macro"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
dependencies = [
- "darling_core",
+ "darling_core 0.20.9",
"quote",
"syn 2.0.66",
]
@@ -1229,6 +1302,37 @@ dependencies = [
]
[[package]]
+name = "derive_builder"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
+dependencies = [
+ "derive_builder_macro",
+]
+
+[[package]]
+name = "derive_builder_core"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
+dependencies = [
+ "darling 0.14.4",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "derive_builder_macro"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
+dependencies = [
+ "derive_builder_core",
+ "syn 1.0.109",
+]
+
+[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1242,6 +1346,12 @@ dependencies = [
]
[[package]]
+name = "deunicode"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00"
+
+[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1360,6 +1470,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
+name = "downcast-rs"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
+
+[[package]]
name = "dpi"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1470,6 +1586,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"
[[package]]
+name = "entities"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca"
+
+[[package]]
name = "enumflags2"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1555,6 +1677,16 @@ dependencies = [
]
[[package]]
+name = "fancy-regex"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2"
+dependencies = [
+ "bit-set",
+ "regex",
+]
+
+[[package]]
name = "fastrand"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1581,7 +1713,7 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f"
dependencies = [
- "memoffset",
+ "memoffset 0.9.1",
"rustc_version",
]
@@ -2658,12 +2790,40 @@ dependencies = [
]
[[package]]
+name = "ioctl-rs"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7970510895cee30b3e9128319f2cefd4bde883a39f38baa279567ba3a7eb97d"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "ipnet"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
+name = "is-docker"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "is-wsl"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5"
+dependencies = [
+ "is-docker",
+ "once_cell",
+]
+
+[[package]]
name = "is_terminal_polyfill"
version = "1.70.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3024,6 +3184,15 @@ checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
[[package]]
name = "memoffset"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "memoffset"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
@@ -3127,6 +3296,20 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "nix"
+version = "0.25.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4"
+dependencies = [
+ "autocfg",
+ "bitflags 1.3.2",
+ "cfg-if",
+ "libc",
+ "memoffset 0.6.5",
+ "pin-utils",
+]
+
+[[package]]
+name = "nix"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
@@ -3134,7 +3317,19 @@ dependencies = [
"bitflags 2.5.0",
"cfg-if",
"libc",
- "memoffset",
+ "memoffset 0.9.1",
+]
+
+[[package]]
+name = "nix"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
+dependencies = [
+ "bitflags 2.5.0",
+ "cfg-if",
+ "cfg_aliases",
+ "libc",
]
[[package]]
@@ -3443,6 +3638,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
+name = "open"
+version = "5.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5ca541f22b1c46d4bb9801014f234758ab4297e7870b904b6a8415b980a7388"
+dependencies = [
+ "is-wsl",
+ "libc",
+ "pathdiff",
+]
+
+[[package]]
name = "openssl-probe"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3465,6 +3671,16 @@ dependencies = [
]
[[package]]
+name = "os_pipe"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29d73ba8daf8fac13b0501d1abeddcfe21ba7401ada61a819144b6c2a4f32209"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3841,6 +4057,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
[[package]]
+name = "portable-pty"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "806ee80c2a03dbe1a9fb9534f8d19e4c0546b790cde8fd1fea9d6390644cb0be"
+dependencies = [
+ "anyhow",
+ "bitflags 1.3.2",
+ "downcast-rs",
+ "filedescriptor",
+ "lazy_static",
+ "libc",
+ "log",
+ "nix 0.25.1",
+ "serial",
+ "shared_library",
+ "shell-words",
+ "winapi",
+ "winreg 0.10.1",
+]
+
+[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4605,9 +4842,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.117"
+version = "1.0.120"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
+checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
dependencies = [
"itoa 1.0.11",
"ryu",
@@ -4680,13 +4917,55 @@ version = "3.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2"
dependencies = [
- "darling",
+ "darling 0.20.9",
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
+name = "serial"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1237a96570fc377c13baa1b88c7589ab66edced652e43ffb17088f003db3e86"
+dependencies = [
+ "serial-core",
+ "serial-unix",
+ "serial-windows",
+]
+
+[[package]]
+name = "serial-core"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f46209b345401737ae2125fe5b19a77acce90cd53e1658cda928e4fe9a64581"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "serial-unix"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f03fbca4c9d866e24a459cbca71283f545a37f8e3e002ad8c70593871453cab7"
+dependencies = [
+ "ioctl-rs",
+ "libc",
+ "serial-core",
+ "termios",
+]
+
+[[package]]
+name = "serial-windows"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15c6d3b776267a75d31bbdfd5d36c0ca051251caafc285827052bc53bcdc8162"
+dependencies = [
+ "libc",
+ "serial-core",
+]
+
+[[package]]
name = "serialize-to-javascript"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4750,6 +5029,32 @@ dependencies = [
]
[[package]]
+name = "shared_child"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "shared_library"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
+dependencies = [
+ "lazy_static",
+ "libc",
+]
+
+[[package]]
+name = "shell-words"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
+
+[[package]]
name = "shellexpand"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4820,6 +5125,16 @@ dependencies = [
]
[[package]]
+name = "slug"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4"
+dependencies = [
+ "deunicode",
+ "wasm-bindgen",
+]
+
+[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5196,6 +5511,12 @@ dependencies = [
[[package]]
name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
@@ -5264,6 +5585,7 @@ checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1"
dependencies = [
"bincode",
"bitflags 1.3.2",
+ "fancy-regex",
"flate2",
"fnv",
"once_cell",
@@ -5553,6 +5875,27 @@ dependencies = [
]
[[package]]
+name = "tauri-plugin-shell"
+version = "2.0.0-beta.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8675bf7ab71f571a99192d0685ae870eb7af1264bdbbb66a1d655609f6c7ebd"
+dependencies = [
+ "encoding_rs",
+ "log",
+ "open",
+ "os_pipe",
+ "regex",
+ "schemars",
+ "serde",
+ "serde_json",
+ "shared_child",
+ "tauri",
+ "tauri-plugin",
+ "thiserror",
+ "tokio",
+]
+
+[[package]]
name = "tauri-plugin-single-instance"
version = "2.0.0-beta.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5697,6 +6040,25 @@ dependencies = [
]
[[package]]
+name = "terminal_size"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
+dependencies = [
+ "rustix",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "termios"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "thin-slice"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6068,6 +6430,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
+name = "typed-arena"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
+
+[[package]]
name = "typed-builder"
version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6099,7 +6467,7 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
dependencies = [
- "memoffset",
+ "memoffset 0.9.1",
"tempfile",
"winapi",
]
@@ -6112,7 +6480,11 @@ dependencies = [
"atuin-common",
"atuin-dotfiles",
"atuin-history",
+ "bytes",
+ "comrak",
"eyre",
+ "nix 0.29.0",
+ "portable-pty",
"serde",
"serde_json",
"sqlx",
@@ -6120,11 +6492,13 @@ dependencies = [
"tauri",
"tauri-build",
"tauri-plugin-http",
+ "tauri-plugin-shell",
"tauri-plugin-single-instance",
"tauri-plugin-sql",
"time",
"tokio",
"uuid",
+ "vt100",
]
[[package]]
@@ -6286,11 +6660,10 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
-version = "1.8.0"
+version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
+checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439"
dependencies = [
- "atomic",
"getrandom 0.2.15",
"serde",
]
@@ -6340,6 +6713,39 @@ dependencies = [
]
[[package]]
+name = "vt100"
+version = "0.15.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84cd863bf0db7e392ba3bd04994be3473491b31e66340672af5d11943c6274de"
+dependencies = [
+ "itoa 1.0.11",
+ "log",
+ "unicode-width",
+ "vte",
+]
+
+[[package]]
+name = "vte"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197"
+dependencies = [
+ "arrayvec",
+ "utf8parse",
+ "vte_generate_state_changes",
+]
+
+[[package]]
+name = "vte_generate_state_changes"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6976,6 +7382,15 @@ dependencies = [
[[package]]
name = "winreg"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winreg"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
@@ -7070,6 +7485,12 @@ dependencies = [
]
[[package]]
+name = "xdg"
+version = "2.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546"
+
+[[package]]
name = "xdg-home"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -7135,7 +7556,7 @@ dependencies = [
"futures-sink",
"futures-util",
"hex",
- "nix",
+ "nix 0.27.1",
"ordered-stream",
"rand 0.8.5",
"serde",
diff --git a/ui/backend/Cargo.toml b/ui/backend/Cargo.toml
index ed8ca070..d027e152 100644
--- a/ui/backend/Cargo.toml
+++ b/ui/backend/Cargo.toml
@@ -27,6 +27,12 @@ syntect = "5.2.0"
tauri-plugin-http = "2.0.0-beta"
tauri-plugin-single-instance = "2.0.0-beta"
tokio = "1.38.0"
+tauri-plugin-shell = "2.0.0-beta.7"
+comrak = "0.22"
+portable-pty = "0.8.1"
+vt100 = "0.15.2"
+bytes = "1.6.0"
+nix = "0.29.0"
[dependencies.sqlx]
version = "0.7"
diff --git a/ui/backend/capabilities/migrated.json b/ui/backend/capabilities/migrated.json
index d6d8889c..e740ab1e 100644
--- a/ui/backend/capabilities/migrated.json
+++ b/ui/backend/capabilities/migrated.json
@@ -11,6 +11,7 @@
"resources:default",
"menu:default",
"tray:default",
+ "shell:allow-open",
"sql:allow-load",
"sql:allow-execute",
"sql:allow-select",
diff --git a/ui/backend/rust-toolchain.toml b/ui/backend/rust-toolchain.toml
index fcc85b9e..c6e4d7d5 100644
--- a/ui/backend/rust-toolchain.toml
+++ b/ui/backend/rust-toolchain.toml
@@ -1,2 +1,2 @@
[toolchain]
-channel = "1.77"
+channel = "1.79"
diff --git a/ui/backend/src/db.rs b/ui/backend/src/db.rs
index 1015ebf1..56d422ab 100644
--- a/ui/backend/src/db.rs
+++ b/ui/backend/src/db.rs
@@ -174,6 +174,41 @@ impl HistoryDB {
Ok(history)
}
+ pub async fn prefix_search(&self, query: &str) -> Result<Vec<UIHistory>, String> {
+ let context = Context {
+ session: "".to_string(),
+ cwd: "".to_string(),
+ host_id: "".to_string(),
+ hostname: "".to_string(),
+ git_root: None,
+ };
+
+ let filters = OptFilters {
+ limit: Some(5),
+ ..OptFilters::default()
+ };
+
+ let history = self
+ .0
+ .search(
+ SearchMode::Prefix,
+ FilterMode::Global,
+ &context,
+ query,
+ filters,
+ )
+ .await
+ .map_err(|e| e.to_string())?;
+
+ let history = history
+ .into_iter()
+ .filter(|h| h.duration > 0)
+ .map(|h| h.into())
+ .collect();
+
+ Ok(history)
+ }
+
pub async fn calendar(&self) -> Result<Vec<(String, u64)>, String> {
let query = "select count(1) as count, strftime('%F', datetime(timestamp / 1000000000, 'unixepoch')) as day from history where timestamp > ((unixepoch() - 31536000) * 1000000000) group by day;";
diff --git a/ui/backend/src/install.rs b/ui/backend/src/install.rs
index 43ad0c54..17896e3a 100644
--- a/ui/backend/src/install.rs
+++ b/ui/backend/src/install.rs
@@ -24,7 +24,8 @@ pub(crate) async fn install_cli() -> Result<(), String> {
pub(crate) async fn is_cli_installed() -> Result<bool, String> {
let shell = Shell::default_shell().map_err(|e| format!("Failed to get default shell: {e}"))?;
let output = if shell == Shell::Powershell {
- shell.run_interactive(&["atuin --version; if ($?) {echo 'ATUIN FOUND'}"])
+ shell
+ .run_interactive(&["atuin --version; if ($?) {echo 'ATUIN FOUND'}"])
.map_err(|e| format!("Failed to run interactive command"))?
} else {
shell
diff --git a/ui/backend/src/main.rs b/ui/backend/src/main.rs
index 2ba67e50..7adbbbe5 100644
--- a/ui/backend/src/main.rs
+++ b/ui/backend/src/main.rs
@@ -1,6 +1,8 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
+use tauri::State;
+
use std::path::PathBuf;
use tauri::{AppHandle, Manager};
@@ -9,6 +11,9 @@ use time::format_description::well_known::Rfc3339;
mod db;
mod dotfiles;
mod install;
+mod pty;
+mod run;
+mod state;
mod store;
use atuin_client::settings::Settings;
@@ -168,7 +173,7 @@ async fn home_info() -> Result<HomeInfo, String> {
}
// Match the format that the frontend library we use expects
-// All the processing in Rust, not JS.
+// All the processing in Rust, not JSunwrap.
// Faaaassssssst af ⚡️🦀
#[derive(Debug, serde::Serialize)]
pub struct HistoryCalendarDay {
@@ -215,6 +220,19 @@ async fn history_calendar() -> Result<Vec<HistoryCalendarDay>, String> {
Ok(ret)
}
+#[tauri::command]
+async fn prefix_search(query: &str) -> Result<Vec<String>, String> {
+ let settings = Settings::new().map_err(|e| e.to_string())?;
+
+ let db_path = PathBuf::from(settings.db_path.as_str());
+ let db = HistoryDB::new(db_path, settings.local_timeout).await?;
+
+ let history = db.prefix_search(query).await?;
+ let commands = history.into_iter().map(|h| h.command).collect();
+
+ Ok(commands)
+}
+
fn show_window(app: &AppHandle) {
let windows = app.webview_windows();
@@ -228,9 +246,11 @@ fn show_window(app: &AppHandle) {
fn main() {
tauri::Builder::default()
+ .plugin(tauri_plugin_shell::init())
.invoke_handler(tauri::generate_handler![
list,
search,
+ prefix_search,
global_stats,
aliases,
home_info,
@@ -239,6 +259,10 @@ fn main() {
login,
register,
history_calendar,
+ run::pty::pty_open,
+ run::pty::pty_write,
+ run::pty::pty_resize,
+ run::pty::pty_kill,
install::install_cli,
install::is_cli_installed,
install::setup_cli,
@@ -254,6 +278,7 @@ fn main() {
.plugin(tauri_plugin_single_instance::init(|app, args, cwd| {
let _ = show_window(app);
}))
+ .manage(state::AtuinState::default())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
diff --git a/ui/backend/src/pty.rs b/ui/backend/src/pty.rs
new file mode 100644
index 00000000..07857824
--- /dev/null
+++ b/ui/backend/src/pty.rs
@@ -0,0 +1,112 @@
+use std::{
+ io::Write,
+ sync::{Arc, Mutex},
+};
+
+use bytes::Bytes;
+use eyre::{eyre, Result};
+use portable_pty::{CommandBuilder, MasterPty, PtySize};
+
+pub struct Pty {
+ tx: tokio::sync::mpsc::Sender<Bytes>,
+
+ pub master: Arc<Mutex<Box<dyn MasterPty + Send>>>,
+ pub reader: Arc<Mutex<Box<dyn std::io::Read + Send>>>,
+}
+
+impl Pty {
+ pub async fn open<'a>(rows: u16, cols: u16) -> Result<Self> {
+ let sys = portable_pty::native_pty_system();
+
+ let pair = sys
+ .openpty(PtySize {
+ rows,
+ cols,
+ pixel_width: 0,
+ pixel_height: 0,
+ })
+ .map_err(|e| eyre!("Failed to open pty: {}", e))?;
+
+ let cmd = CommandBuilder::new_default_prog();
+
+ tokio::task::spawn_blocking(move || {
+ let mut child = pair.slave.spawn_command(cmd).unwrap();
+ // Wait for the child to exit
+ let _ = child.wait().unwrap();
+
+ // Ensure slave is dropped
+ // This closes file handles, we can deadlock if this is not done correctly.
+ drop(pair.slave);
+ });
+
+ // Handle input -> write to master writer
+ let (master_tx, mut master_rx) = tokio::sync::mpsc::channel::<Bytes>(32);
+
+ let mut writer = pair.master.take_writer().unwrap();
+ let reader = pair
+ .master
+ .try_clone_reader()
+ .map_err(|e| e.to_string())
+ .expect("Failed to clone reader");
+
+ tokio::spawn(async move {
+ while let Some(bytes) = master_rx.recv().await {
+ writer.write_all(&bytes).unwrap();
+ writer.flush().unwrap();
+ }
+
+ // When the channel has been closed, we won't be getting any more input. Close the
+ // writer and the master.
+ // This will also close the writer, which sends EOF to the underlying shell. Ensuring
+ // that is also closed.
+ drop(writer);
+ });
+
+ Ok(Pty {
+ tx: master_tx,
+ master: Arc::new(Mutex::new(pair.master)),
+ reader: Arc::new(Mutex::new(reader)),
+ })
+ }
+
+ pub async fn resize(&self, rows: u16, cols: u16) -> Result<()> {
+ let master = self
+ .master
+ .lock()
+ .map_err(|e| eyre!("Failed to lock pty master: {e}"))?;
+
+ master
+ .resize(PtySize {
+ rows,
+ cols,
+ pixel_width: 0,
+ pixel_height: 0,
+ })
+ .map_err(|e| eyre!("Failed to resize terminal: {e}"))?;
+
+ Ok(())
+ }
+
+ pub async fn send_bytes(&self, bytes: Bytes) -> Result<()> {
+ self.tx
+ .send(bytes)
+ .await
+ .map_err(|e| eyre!("Failed to write to master tx: {}", e))
+ }
+
+ pub async fn send_string(&self, cmd: &str) -> Result<()> {
+ let bytes: Vec<u8> = cmd.bytes().collect();
+ let bytes = Bytes::from(bytes);
+
+ self.send_bytes(bytes).await
+ }
+
+ pub async fn send_single_string(&self, cmd: &str) -> Result<()> {
+ let mut bytes: Vec<u8> = cmd.bytes().collect();
+ bytes.push(0x04);
+
+ let bytes = Bytes::from(bytes);
+
+ self.send_bytes(bytes).await
+ }
+}
diff --git a/ui/backend/src/run/mod.rs b/ui/backend/src/run/mod.rs
new file mode 100644
index 00000000..5ece0912
--- /dev/null
+++ b/ui/backend/src/run/mod.rs
@@ -0,0 +1 @@
+pub mod pty;
diff --git a/ui/backend/src/run/pty.rs b/ui/backend/src/run/pty.rs
new file mode 100644
index 00000000..382b45dd
--- /dev/null
+++ b/ui/backend/src/run/pty.rs
@@ -0,0 +1,93 @@
+use eyre::{Result, WrapErr};
+use std::io::BufRead;
+use std::path::PathBuf;
+
+use crate::state::AtuinState;
+use tauri::{Manager, State};
+
+use atuin_client::{database::Sqlite, record::sqlite_store::SqliteStore, settings::Settings};
+
+#[tauri::command]
+pub async fn pty_open<'a>(
+ app: tauri::AppHandle,
+ state: State<'a, AtuinState>,
+) -> Result<uuid::Uuid, String> {
+ let id = uuid::Uuid::new_v4();
+ let pty = crate::pty::Pty::open(24, 80).await.unwrap();
+
+ let reader = pty.reader.clone();
+
+ tauri::async_runtime::spawn_blocking(move || loop {
+ let mut buf = [0u8; 512];
+
+ match reader.lock().unwrap().read(&mut buf) {
+ // EOF
+ Ok(0) => {
+ println!("reader loop hit eof");
+ break;
+ }
+
+ Ok(n) => {
+ println!("read {n} bytes");
+
+ // TODO: sort inevitable encoding issues
+ let out = String::from_utf8_lossy(&buf).to_string();
+ let out = out.trim_matches(char::from(0));
+ let channel = format!("pty-{id}");
+
+ app.emit(channel.as_str(), out).unwrap();
+ }
+
+ Err(e) => {
+ println!("failed to read: {e}");
+ break;
+ }
+ }
+ });
+
+ state.pty_sessions.write().await.insert(id, pty);
+
+ Ok(id)
+}
+
+#[tauri::command]
+pub(crate) async fn pty_write(
+ pid: uuid::Uuid,
+ data: String,
+ state: tauri::State<'_, AtuinState>,
+) -> Result<(), String> {
+ let sessions = state.pty_sessions.read().await;
+ let pty = sessions.get(&pid).ok_or("Pty not found")?;
+
+ let bytes = data.as_bytes().to_vec();
+ pty.send_bytes(bytes.into())
+ .await
+ .map_err(|e| e.to_string())?;
+ Ok(())
+}
+
+#[tauri::command]
+pub(crate) async fn pty_resize(
+ pid: uuid::Uuid,
+ rows: u16,
+ cols: u16,
+ state: tauri::State<'_, AtuinState>,
+) -> Result<(), String> {
+ let sessions = state.pty_sessions.read().await;
+ let pty = sessions.get(&pid).ok_or("Pty not found")?;
+
+ pty.resize(rows, cols).await.map_err(|e| e.to_string())?;
+
+ Ok(())
+}
+
+#[tauri::command]
+pub(crate) async fn pty_kill(
+ pid: uuid::Uuid,
+ state: tauri::State<'_, AtuinState>,
+) -> Result<(), String> {
+ let pty = state.pty_sessions.write().await.remove(&pid).unwrap();
+ println!("RIP {pid:?}");
+
+ Ok(())
+}
diff --git a/ui/backend/src/state.rs b/ui/backend/src/state.rs
new file mode 100644
index 00000000..de53b4c5
--- /dev/null
+++ b/ui/backend/src/state.rs
@@ -0,0 +1,10 @@
+use std::collections::HashMap;
+use std::sync::Mutex;
+use tauri::async_runtime::RwLock;
+
+use crate::pty::Pty;
+
+#[derive(Default)]
+pub(crate) struct AtuinState {
+ pub pty_sessions: RwLock<HashMap<uuid::Uuid, Pty>>,
+}