From b838d000dba683a7afd21108f5ce5ecb9895ccf4 Mon Sep 17 00:00:00 2001 From: Kartios Date: Mon, 31 Aug 2026 17:05:49 -0700 Subject: [PATCH] feat: add interactive VT and workspace command plane --- Cargo.lock | 351 ++++++- Cargo.toml | 1 + README.md | 12 +- assets/brand/app-icons/lumbridge-app-1024.png | Bin 0 -> 41595 bytes assets/brand/app-icons/lumbridge-app-128.png | Bin 0 -> 4018 bytes assets/brand/app-icons/lumbridge-app-16.png | Bin 0 -> 627 bytes assets/brand/app-icons/lumbridge-app-256.png | Bin 0 -> 13892 bytes assets/brand/app-icons/lumbridge-app-32.png | Bin 0 -> 1183 bytes assets/brand/app-icons/lumbridge-app-48.png | Bin 0 -> 1645 bytes assets/brand/app-icons/lumbridge-app-512.png | Bin 0 -> 33953 bytes assets/brand/app-icons/lumbridge-app-64.png | Bin 0 -> 2104 bytes .../brand/dark/lumbridge-mark-dark-1024.png | Bin 0 -> 41595 bytes assets/brand/dark/lumbridge-mark-dark-128.png | Bin 0 -> 4018 bytes assets/brand/dark/lumbridge-mark-dark-16.png | Bin 0 -> 627 bytes assets/brand/dark/lumbridge-mark-dark-256.png | Bin 0 -> 13889 bytes assets/brand/dark/lumbridge-mark-dark-32.png | Bin 0 -> 1183 bytes assets/brand/dark/lumbridge-mark-dark-48.png | Bin 0 -> 1645 bytes assets/brand/dark/lumbridge-mark-dark-512.png | Bin 0 -> 33935 bytes assets/brand/dark/lumbridge-mark-dark-64.png | Bin 0 -> 2104 bytes .../brand/light/lumbridge-mark-light-1024.png | Bin 0 -> 41595 bytes .../brand/light/lumbridge-mark-light-128.png | Bin 0 -> 4018 bytes .../brand/light/lumbridge-mark-light-16.png | Bin 0 -> 627 bytes .../brand/light/lumbridge-mark-light-256.png | Bin 0 -> 13850 bytes .../brand/light/lumbridge-mark-light-32.png | Bin 0 -> 1183 bytes .../brand/light/lumbridge-mark-light-48.png | Bin 0 -> 1645 bytes .../brand/light/lumbridge-mark-light-512.png | Bin 0 -> 33796 bytes .../brand/light/lumbridge-mark-light-64.png | Bin 0 -> 2104 bytes .../master/lumbridge-mark-master-1024.png | Bin 0 -> 41595 bytes crates/lumbridge-core/Cargo.toml | 4 +- crates/lumbridge-core/src/lib.rs | 9 + crates/lumbridge-core/src/workspace.rs | 861 +++++++++++++++ crates/lumbridge-runtime/Cargo.toml | 3 + .../tests/terminal_pipeline.rs | 78 ++ crates/lumbridge-terminal/Cargo.toml | 15 + crates/lumbridge-terminal/src/lib.rs | 994 ++++++++++++++++++ docs/ARCHITECTURE.md | 51 +- docs/BRAND.md | 92 ++ docs/DISTRIBUTION.md | 8 +- docs/PRODUCT_SPEC.md | 38 + docs/RESEARCH.md | 11 +- docs/RESEARCH_SNAPSHOTS.md | 4 + docs/ROADMAP.md | 7 + docs/TESTING.md | 13 +- docs/UI_SPIKE_SCORECARD.md | 10 +- docs/UX_VERTICAL_SLICE.md | 11 +- .../0004-runtime-actor-owns-each-pty.md | 7 +- .../0005-terminal-engine-boundary.md | 24 + .../decisions/0006-workspace-command-plane.md | 20 + .../0007-optional-lumbridge-harness.md | 27 + spikes/README.md | 5 +- spikes/gpui-shell/Cargo.lock | 82 ++ spikes/gpui-shell/Cargo.toml | 1 + spikes/gpui-shell/src/main.rs | 353 +++++-- spikes/ui-shell-model/src/lib.rs | 25 + 54 files changed, 3004 insertions(+), 113 deletions(-) create mode 100644 assets/brand/app-icons/lumbridge-app-1024.png create mode 100644 assets/brand/app-icons/lumbridge-app-128.png create mode 100644 assets/brand/app-icons/lumbridge-app-16.png create mode 100644 assets/brand/app-icons/lumbridge-app-256.png create mode 100644 assets/brand/app-icons/lumbridge-app-32.png create mode 100644 assets/brand/app-icons/lumbridge-app-48.png create mode 100644 assets/brand/app-icons/lumbridge-app-512.png create mode 100644 assets/brand/app-icons/lumbridge-app-64.png create mode 100644 assets/brand/dark/lumbridge-mark-dark-1024.png create mode 100644 assets/brand/dark/lumbridge-mark-dark-128.png create mode 100644 assets/brand/dark/lumbridge-mark-dark-16.png create mode 100644 assets/brand/dark/lumbridge-mark-dark-256.png create mode 100644 assets/brand/dark/lumbridge-mark-dark-32.png create mode 100644 assets/brand/dark/lumbridge-mark-dark-48.png create mode 100644 assets/brand/dark/lumbridge-mark-dark-512.png create mode 100644 assets/brand/dark/lumbridge-mark-dark-64.png create mode 100644 assets/brand/light/lumbridge-mark-light-1024.png create mode 100644 assets/brand/light/lumbridge-mark-light-128.png create mode 100644 assets/brand/light/lumbridge-mark-light-16.png create mode 100644 assets/brand/light/lumbridge-mark-light-256.png create mode 100644 assets/brand/light/lumbridge-mark-light-32.png create mode 100644 assets/brand/light/lumbridge-mark-light-48.png create mode 100644 assets/brand/light/lumbridge-mark-light-512.png create mode 100644 assets/brand/light/lumbridge-mark-light-64.png create mode 100644 assets/brand/master/lumbridge-mark-master-1024.png create mode 100644 crates/lumbridge-core/src/workspace.rs create mode 100644 crates/lumbridge-runtime/tests/terminal_pipeline.rs create mode 100644 crates/lumbridge-terminal/Cargo.toml create mode 100644 crates/lumbridge-terminal/src/lib.rs create mode 100644 docs/BRAND.md create mode 100644 docs/decisions/0005-terminal-engine-boundary.md create mode 100644 docs/decisions/0006-workspace-command-plane.md create mode 100644 docs/decisions/0007-optional-lumbridge-harness.md diff --git a/Cargo.lock b/Cargo.lock index 9753810..6b504b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,6 +12,39 @@ dependencies = [ "generic-array", ] +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + +[[package]] +name = "alacritty_terminal" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda177466b9524d59f1b12f0dd30b68696788e9992a7e959021c4a0ed96fcf59" +dependencies = [ + "base64", + "bitflags 2.13.1", + "home", + "libc", + "log", + "miow", + "parking_lot", + "piper", + "polling", + "regex-automata", + "rustix", + "rustix-openpty", + "signal-hook", + "unicode-width", + "vte", + "windows-sys 0.59.0", +] + [[package]] name = "android_system_properties" version = "0.1.6" @@ -33,6 +66,12 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.5.1" @@ -282,6 +321,15 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "const-oid" version = "0.10.2" @@ -312,6 +360,12 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + [[package]] name = "crypto-common" version = "0.1.7" @@ -341,6 +395,12 @@ dependencies = [ "cmov", ] +[[package]] +name = "cursor-icon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" + [[package]] name = "digest" version = "0.10.7" @@ -381,6 +441,16 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "fallible-iterator" version = "0.3.0" @@ -393,6 +463,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + [[package]] name = "filedescriptor" version = "0.8.3" @@ -425,6 +501,12 @@ version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + [[package]] name = "futures-task" version = "0.3.34" @@ -478,6 +560,12 @@ dependencies = [ "rand_core 0.10.1", ] +[[package]] +name = "hermit-abi" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284" + [[package]] name = "hex" version = "0.4.3" @@ -520,6 +608,15 @@ dependencies = [ "digest 0.11.3", ] +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "hybrid-array" version = "0.4.14" @@ -719,12 +816,27 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + [[package]] name = "litemap" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.34" @@ -751,6 +863,9 @@ dependencies = [ [[package]] name = "lumbridge-core" version = "0.0.1" +dependencies = [ + "thiserror 2.0.20", +] [[package]] name = "lumbridge-pty" @@ -766,6 +881,7 @@ name = "lumbridge-runtime" version = "0.0.1" dependencies = [ "lumbridge-pty", + "lumbridge-terminal", "thiserror 2.0.20", ] @@ -777,12 +893,29 @@ dependencies = [ "rusqlite", ] +[[package]] +name = "lumbridge-terminal" +version = "0.0.1" +dependencies = [ + "alacritty_terminal", + "thiserror 2.0.20", +] + [[package]] name = "memchr" version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" +[[package]] +name = "miow" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "536bfad37a309d62069485248eeaba1e8d9853aaf951caaeaed0585a95346f08" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "nix" version = "0.28.0" @@ -840,6 +973,29 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + [[package]] name = "password-hash" version = "0.5.0" @@ -873,12 +1029,37 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "piper" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + [[package]] name = "pkg-config" version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "windows-sys 0.61.2", +] + [[package]] name = "poly1305" version = "0.8.0" @@ -1000,6 +1181,32 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.1", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + [[package]] name = "rusqlite" version = "0.40.2" @@ -1013,6 +1220,30 @@ dependencies = [ "smallvec", ] +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags 2.13.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustix-openpty" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de16c7c59892b870a6336f185dc10943517f1327447096bbb7bb32cd85e2393" +dependencies = [ + "errno", + "libc", + "rustix", +] + [[package]] name = "rustversion" version = "1.0.23" @@ -1028,6 +1259,12 @@ dependencies = [ "cipher", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "scrypt" version = "0.11.0" @@ -1111,7 +1348,7 @@ checksum = "b16809bc35793b19ce4e0c53924bc0dce3937f15487997cfdaed936004180730" dependencies = [ "cfg-if", "libc", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -1158,6 +1395,26 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" +[[package]] +name = "signal-hook" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a0c28ca5908dbdbcd52e6fdaa00358ab88637f8ab33e1f188dd510eb44b53d" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + [[package]] name = "slab" version = "0.4.12" @@ -1301,6 +1558,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + [[package]] name = "universal-hash" version = "0.5.1" @@ -1354,6 +1617,19 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vte" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5924018406ce0063cd67f8e008104968b74b563ee1b85dde3ed1f7cb87d3dbd" +dependencies = [ + "arrayvec", + "bitflags 2.13.1", + "cursor-icon", + "log", + "memchr", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -1496,6 +1772,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -1505,6 +1790,70 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "winreg" version = "0.10.1" diff --git a/Cargo.toml b/Cargo.toml index da2d268..10f2c6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "crates/lumbridge-pty", "crates/lumbridge-runtime", "crates/lumbridge-storage", + "crates/lumbridge-terminal", ] exclude = ["spikes"] resolver = "2" diff --git a/README.md b/README.md index eda3464..5245ac8 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,10 @@ as installable binaries; building from source will remain supported. This repository is in architecture and vertical-slice phase. The installable binary is still a scaffold, while the isolated native UI spikes now exercise an interactive six-surface workspace and the root workspace contains the first -bounded local PTY and runtime-actor boundaries. The GPUI slice renders one real -actor-owned PTY beside five deterministic surfaces. We are still validating -terminal emulation, standalone runtime IPC/durability, ACP integration, +bounded local PTY, runtime-actor, VT engine, and capability-gated workspace +command boundaries. The GPUI slice renders one real actor-owned VT session beside +five deterministic surfaces. We are still validating the dedicated styled +terminal renderer, standalone runtime IPC/durability, ACP integration, packaging, and usage-data contracts before a large implementation. ## Product shape @@ -39,6 +40,9 @@ packaging, and usage-data contracts before a large implementation. provenance instead of invented precision. - Optional first-class Buzz channels, messages, agents, and confirmed redacted pane sharing without making Buzz a requirement. +- An optional Lumbridge Harness that can suggest, coordinate, and—with explicit + execution capability—manage agents through the same audited command plane as + the human UI. Lumbridge remains useful without it. Start with [the product spec](docs/PRODUCT_SPEC.md), [architecture](docs/ARCHITECTURE.md), [research map](docs/RESEARCH.md), and @@ -63,3 +67,5 @@ native shell candidates live in [`spikes/`](spikes/), with results tracked in [the UI scorecard](docs/UI_SPIKE_SCORECARD.md). The signed-protocol and pane-sharing boundary is in [the Buzz integration design](docs/BUZZ_INTEGRATION.md). +Brand masters, platform-ready raster exports, and usage rules are in +[`assets/brand/`](assets/brand/) and [the brand guide](docs/BRAND.md). diff --git a/assets/brand/app-icons/lumbridge-app-1024.png b/assets/brand/app-icons/lumbridge-app-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..50652115122442b09fcb59bb37b097e731697a9e GIT binary patch literal 41595 zcmeGD^;=Zm_dgErGeLJthXNucNY@}DDAFyhB1m@%96-Q8LPS7n01*U{?ix`ENs%5> zl$1`%@4TMxU+#b5zOK()b6qpDW}UtE*=y~!A1lr?Jsk~7GFCDG0Oc*s8wLQN2wzcv z1WEYN{DLnhd~n~_G|&bhh#vs>2>?d~61)U}uQ&iJwgAYd0>JE%(V(vg0HQ2)7O0)6%%{m#4mxjqrom=a#lQ@d^nSvovMNw{}m02LQKjs2T-KtYto% z=lD6^5$RZZN#i$7-#1w&8ikjcV~mtem(~B}yb}_7SyWwJ^(NtUyGi+w!Ewur5*f= z^}Q&`)rJIM&p*~QI9^M?;ry}w&6*Yjb~E!GBWSc^9QTY}ZO8z2Njsj)tQdT`L zC@ZmcA;>Xa3xm6-E;bwhTl-g+ zN~Rf1T$;TAy{b{b?f-#5P?taJ)=h3|VbDxvOH~qpU0Ws0=T)SpBRysfNjI7p-Xb=j zG`7D-VD04j!O9(r+;jz;(M06(ON}+9G+;oID)aV_lY@sU|88O)(2J+E^T`4DN4H%L zDGdwAp`}?QuD7(k0C0tWf^UNp{}z=U#&BAiBLqhZl}g*bIsycJd7qxNc^}+|o=PJh z+u2geZy(o`(t!cCxa~V|70}Dz`+Hi-ld0`ua|vJt*p=vn0R_a}*DI`QEV;{qPay?M zq{lSfwE%&p(U#wr#g7swkjmx(WPqTNMdTU-=RwX6e2X5yoMsFR)Z<9$xevPqm9V!Y zX=njX@BuPRK(FR4kRT)83}rMp8`w`q0H?(p!-Cf?gU}G1CIW#}B{@o5(?Wxx-dmFM zmLLg(xMu^rmmc6p$v|PcYs72ZYw#rTvu6$vO|R;WceN1)SnGYNZ75&@MIwWm_fZ{r z*PF;mf?N85!& zJtvBL4(v%_bDk&1!`H*yj^9E+YKvq1K{TRD7@|WXPReHaPYF6hf|a>RK4W2;esgFE z#^l|6N=80Cyl+gP+bLAjriuYO@dW*gH!kBUYD!sw9{HlW4$Ka5XIUZx?hU-lo@j9a z7>*3C5mcu!ytF}A43oRq$N(%+=(vyBCwg%ol)>aR!3rqU{39VK$!2R3 zWZhwYS?8~fK>I@OZ5HsQSN`kCP41>Vpr;i@BfT+NBgO^vqPlM_$+pH_0TN##l&*UG zsnT+>Q2|&4n-GNUY!?#+x1qOHNA)%C01PNyIc9=w80vnWxR(Q?R``m`3;@{RH>QYz z@uT=A_%a(d{3|zzPW8Rj$-59HM9002l3tRjafiTwh{_`g^EQ-bGD*@aspT8^0|1s@ z{i}>Tv$Z0HOTqQWGy4Qo+%W%L$%q@HN{<~z=<$SmosiaSAiw~lsg-u z6iShv>D_lFaL>JMehdlPBW|2ua7DY=9!mpY<@u2b=9PxCsc_oN@Od}Mn*0CAQyz5_ z#1wbW8SbJk3WM|3i}xuTM)pGpW6YY-p(~-l1R92DN&`I!#Z5BVd*9t%X9&(+aWsnZ zx&jmG2N_Ka1^pv7jJ#L;yvqzJz+S^IQ+-y?3pdbFoguQVP$lQbw=e>X`KMA|5M+Tf z1yz)2+oeK&5RNEBmJ!{HfLP>LXuu3T_t+CQml+CxWyc#a!Z@&bwmA4wkQ#yW@Kl$A zo;HD^8!S@~j@wj7!=Y(d?TDi{90<5_6R1q3$ChRdn2iKJ|;@m4k zv;drIS&b}rLL}^>B;M`?;}1|kuu~@m%@|%pib-H*7$I($+E;=AnODahQD+*E=Uu3! zQWatd;CqvDZLxIOQ{?b8x6Es|VHCqK z&@71{THO94j(w$pZ}Y>6j2Ah!r0@r5Ac#|vXT%mU511hfn{dIdGb{irDRT*peML$` z3cC#U{~v|?WCRXJVqeh@jFA{cwH5qzKJEh`)6AK=uWF-D@X%%$H7oiS4T&F4%0xb@ z%rw0Vo*;06Mx0Bb_yfXuglo`_(dZ5URs*f>Gdi+3Q-wQVknM10uNtca&CyBmvkZYx4^nbP1?hZzk2a(}9Fu!%!BQy@#Z; z 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 U65Q8K&U6@{sivb^L9`D04JN`m}=p~J{5 z#O5=RiNz(5<=FL{q$<_f(v_=Hs7{1 z+mu-&EmM`T*`)KtqLUrl*01B|`K&k(XeMKlx4VmHJL{7gAcwug)7O>#6^FdI8K23S z>8F808$4YcLnJP{_C04hq`=cseNZd!b==zO_j}7j@BQy=3Cpe%*ijJgcR56`QPAVJ zD2JVF(ARrB{}^_t3p8ba6#d;clCkC0gNFvDi%xo6#~GnCg{oBcMg-eTUl2kV{| z?Pc8l`*8EDZ^9Kfm-)P3qw1IcKzBCt)Pt76FD0gjzh&;W=e>6PpX@H6+ZjAv{an^L HB{Ts5v+flH literal 0 HcmV?d00001 diff --git a/assets/brand/app-icons/lumbridge-app-256.png b/assets/brand/app-icons/lumbridge-app-256.png new file mode 100644 index 0000000000000000000000000000000000000000..a45e8e307e0a11a3b3b28e695bb66cb2e7489938 GIT binary patch literal 13892 zcmcJ$^;?wB7dO7UEX&f}xs;TYgmlBAv~-trC`i{X(jlRMAWDdIO2@*Af~cfQNDC6O zz=Fim`|SJk{r(BhbKO78ea*S%%-nOI^ExqSQcaBXD9PB!0001`K3v-j000tRfdD9k z(AWo6dk`8PH@KN001zn%03Z?ofD1wwVjBPmkpuvCoB;sEmjD3sqv9S@WdZ@>dS6c) zfdB6)MO8f~^pHH!H`F27fpRm;QOS%Jd;&9?#ejJ1i7BAE z@!Is&P?2#SMZrH>Lt@TUd^;Hw9(t3;w2VWhO~4Q^BmMSEqO@4upLM(+5Wnw8^NP68 zBt&UWaJOUX=cj$K%S*SOlq{d9PDF&3y#81lHeK7sLjwhakm~=poBF$oZ~KwxujNsr zH=L#E(RSAj_%J1Q`OFI@BDVw{1Zg5HzGf{D$rF#zqCqEofZk9%y0xn5O!ZPc)P_HW z$Hdv^r#y`{qXE$onh1$yzE5*oT{d2PQW(lNY4+)Ji8{+|XZF=(G#7dnQ2<=wPa;Nw z%76wei!`fjtL;OTPZ3Q-+~816nS{S<5^czQUez=3AT)@1j%*IR2y7u91;y#KA;Xw1 z4e96AMQPd4?&Wr3o(K%0v&cUfeTrT{N)YvCw*h_GSx)YNX8;7=Ld8tYDvyAVL@TOD z4k4o;E8v7?5@bi%nnwm{$s>dKk~j@&1dNN_IBA1pnEsvzLW_aLWPV5}p2CIMi#Q%2 z$WXau$$RG2Qe0+0<=}38AhT+R-iJz!?i^}>o~QF5zI=9Vxe`Ah(r%x1=ArR-hQN^5 zh+yO;BYuM6l7!Sih`@urzY3pVvm&*iG^BcjHbhJSvu^3oK>j}>OQ8$eDt#ljy(H-U zB!#f;0TKE!Kea|S8q5oI{#OQ~dPMt(^xu-d5x|4npZ*AqL9Ub1y|e}c4epZNE=`9X zSfnVK%x-|Ywa6IX5E%g+wX)ILywFk=6J$GhGGw8_(3y<(Okq_AT}K#q7YuBpR%`s_ z;SVwqL>2%f-WhZX(NS3Gw_NjF-ReX)+ARqRuSPt@`|v#3{|cPY54+s!n{- zgg&VV#5%+;jkeq)BS*hNex#*qrhWQ0wjWIc1$hDOmGKtn=^^YsplYh)yM}#2*xP#2 zPbSWs|67mC0Ml8oO<;P;Ma*8L62lxI8akK5AWx(FAtZ&szwAC4bwDl9`om1~?*(9$ z=?ujnSMxXxcv7`G-8c@XHG7TZCmRD&t5ZBJa$z||ge3j9sKgj@v&xmy&$e!5Nt6RD z;WXnycXyI0WwdD2FPnkFOgpCX90zhhi9dnFq3UpFGFPEyM*>d}!(cV2S49(`O7@7w zD|@mL&A!;JNp4L-_zY@uo-kekqI2z1!Gl9kk#02qBbMKc)>Z@(Nj=ZLg&2xWEv5Nl z{TNS=Y|xh_b`z4^B+$6`U1JLbsW?|T`tuRPB#Xei9doxp2{XX8b%VR3XHK`s6}ab; zWxy=vXSeG$ObV=kVZ^aIBFc2riJut=vZ`9Y5+~to+{%^2e8aJc@XtARiOSse8fMS{ z>>%0DVrY5H2J772IPhyz=5{ZvL#*_J%#p{ zY`N&c+;hyYFg1Wd&`a4F8rCXnq+&!G0D4H(g)bK0Z^jU`S?-Q)#)ymABtJPYR*+82d8 zXV8EpVUKDD$bON+Z}1!sKiJ*=J&VDZH3hGj4wR^K5oQE1W7RT``}Byi1TA)KS{I}S z+G9Ai)6^-H&@3>hv$S(!99Jq%ZOG5gf8A;Ndb|A;5GoO?_llkG(`V}~$@Lp5xZ*P`c0 zHp=;OR6_EGh(in86(fW1D0zP_-!g-<|Zyrzo8; zG5Bv2Srf=GSOb8eU*7H{k-k6Cwh(aZ$a=s1;vJ10&M9DpGbinn#b**-!nTJ%n0H$d zESKY&<$FK3J&%s8j{p6M3ab`mTiQw*LP3V11U}G01}6j_yq`irwA-aN8{G88|NDJN z`bdVh{ODqwa{?4(?bKY0=cU_>y4zgHf3=jh(X6=@btTviu036l++k)B;)6QBMjzj> zZ4HPXymx(V`0uZKzGxX`_$$rlHJ`4q>|Igh87zdUNF1A;p0P}CTK8h_!fA}3@sy)7 zS!bkmm7Alhe+N2M3}zYjHjv@kwGbPT;QXlQF2HAs45L$g|Y zdBYtXh?G+I0=Pj6gtu;CU+S&xP~X16ZJ>hU1N2>Pr=knUv7p)dsdget0{F9hFkIiu z3=0h{S&(95c6t#0){Uf#smqKzP7@_*0G)=TN7~!=xaAc1j;; z@5@r>CeTUkZ3CH8i+Yt%^buZ?nauBt<(kcYqbKbb4nDp6g&5FE0!(cVLl32f0pf$k z17Adu?1d+38e)I17eik|F1KT!@)PB8HCf-(TkHN$cvz^O5k|n@H}|oo!&sO4C(cl z!^HAY6S9N>!^HmPRx<<&Vu9IXS9HwrPt(T+MmWk>Fj_;>w+t+uV|M$qL=hh%W0dT- zXLi@C1n^vIkYdQT-=em&GC{c_y@Dp5q0{x_Lu!8M&DH=9C_Yuor9*Ah_#7-`oGmt; z8837gExS1eUi{)>AtG!eRJ@nEB7bEp=dqf{-^5_HGj?HmlPDYCpFi+>k-b!%{@G?u zPu+pzAS)uLP#hZzJz)%$$de}tNd z^t9dJ1Azkq79wOstN&?k+awMzR8djzdQh}LscG=7555)In&YDs9Kapt_gc?c*5?Eh z6TPVFn}PpK02n@mDL%viKjP{gwa+;Q;}jyzs@;2qOeWgm**W#t`MrL$7rBj<^14bH zy0!;KH(E3A;8_SZS7tJ0Kzt21z>Ii)(&oBfE{xMavw7t(Kvg_4%{uyJA(Y?lIF@ zoUHgtBBeC`8-V)rVdy*gRxJ9q{`$2**%SU|MD*tYK4ML^%<7eUpq@a7*8r>vOA@&L zRFcS^IQpZCuk$G353zY+QJjxRT8)w+M?)P^j0=^e_G0{RNvjQ4p{oNlhR$#Lm{ylU zRK2_uJ_6c(uK;I6F4x??U|_wJ{Z!U#TIN#RP+ha~{I%0g9syB-QX;V|FyJedmrBMC zhDbqML>T_>;TFTU=9?@jUTI(OHdpJw%u$pKZ?)pvEcxNv0Gu|R_Y-kMBeS5qRjI(q zkL(L%Y~^Y#TfB+Ca@)51v-TUj_bSb5UF6E^%vX>ZfHZyC6WEBm06}Tl-lpKKb}Q<} z6xn%Xo+gmkJ+WUx7YmkdDX@_;6}?mD7^%6i7}9CY(g@6I!c^rP;wQ#>ToTnh+cJ!N zi3!%hcJb%cX>C^}i5dkdgDp?@kD_b@+4>J;X2oxH@%@zrV67j(;`y`H@pBS0ajmdP zu3pWze?hNZWKs#PC_p#8VH8^%v<$e#H$SNSF$dj>oXyQmzUU@-<$hri!32oa;jKrm zCO9RlbZU60?}ujnQk&l;<8|B&|Dd;H$hVHOBdW?3+j(GK{g;)_T04nO0_13V)lr04 zikn-WUitiv5rg6G7rTlq=>?X+oVac`8xX{uY1Xp76IFL{%nj;$%>bO!i2M}GKdA%u zhTH|-?Z3MPis0j+kZ_NDCYq$YY^66(lq%3g{P2~gb0WcP3_o(4yI&Xjc9Cy_hyUP7 zg=;nyaXy?!o<@bDuev_z^+q9w5g z;O)@HkhFYWN7J9T{Ex&AL^w!IrhKik(WwMiQ+8pVc*h4EiHXaTblhrmBH!A7KzEms z^^)kS+nUPn0rV#Ut};z!LK)Lm7`_QtxA#QRg$qBTqm%)TI(*3%GdCW}Wjl_tQ-?1svbyqXuu3<~7WLFc+O14*|z zo(5_vgBA7uly~Q&N;qnjNwXtq%TD@xgT(*i1Jl8HU91z&@HhgH7W1-c$8VG!!X6uS@Sr8I6oqi`04>ICH>B z3?X<~+lPiny(K&ToyIvbNKcsf;6^r@BzqD3Dp|4`{fpG#gv0Q37Ngwhdie~_?^YwH z>3mKAU`oHK(Lg@SBby>)f+y!Gfb@JHO?Q`^RB0xG%jt1f+KayY<~!ajlYjY|=P$XT zizN(O&J$teQT@{wLjM2FS{i?Je-+f)`1i3~z)CLKoBso65?J+_Idji587tV&=Kzlq z;)?ta%N`B`Zh&WE`HsFXN#wFc_zh|Kn_USD02%~k%me#v#a|zZEJyJ|H zD9QyuQ%6B1#5dGtfhG+{7PyT}#03RTZXxPt=n-DIS@wV@cp$P^1s5aojQT$>?royn zz68^KcIwFlu<{G=GtJ@SuA`Y8gyRGK)o&@L`#WoWA^awa4lU7-TI?TT_G0I6_Md6r z{5=@DF)Tdt*ALwLgq9{im!h>28khYN@vfXZU_j6WIrVQfi%3RsG(DDL`B6$!~ZV=P<0n01w^+D+0-`58s%C)4* zAQ&*SnLP>IkAyBW9_Okvw#~-XFUbcRqLz_`!JA(TRN6i4oT2|&t3qB@MdWZ$?V;@l zlm7tIAh*DUh3+mh4Eas?IYNSGZTj?c&JN3;3?zAq?LgF6D@H|v33otUac^WPHYW)g z`RSXTpaIhYIs}vECVQ}HiO$NAv<*q5%&jVU@U1t6CJ_08TrHl#{q6dm-w+p{HCt|- zOHYXoC|Cx}8o7{jBGLyA&s5N>YJL2i>C{@=K3c6IB0!~+iA8~glqV`Y_+mM^fEt zZ}8*^(3l2AqXzbn{-ck({owG55T{lB8`k{uC0jxemzO9PBx;|R`QzC3f>TDsgc50( z{$%a+C=_^GBuJ>7)UVVyQzJO;4LCLd`kNarFnp!5eP;~VsZ*(%+=mW$IHPqUi4IUA zolC43BgA!ZFi?#9f{L2tCh>)Bugn+@ka^TQ^qu5FJvdO^!ezo+o4$+tKwo=2IMs{GV4QMr4$?#H8PJ%}Yn#G-zSd zbKh8t?x$0(MCC7uqDIo)N2{tMZEH#lv#)mi7R?o&HS!?Sb5>uA!gUo(hU-C5d=)}9 zF-~cV?v)`EwOU!pyhVvj3N`#K|DnGnl}H;NT%2sM;7|GR7zWI4IoUXVmY7^KTcA{V zpN)zGkv(mMcE!ECu41FG5+n6PvS7!BLTzMbTX0P|3CVnpz`76w!}ZJ7g7|u=A0@5i z#UKuQ4mGVgB8V;x`kyoVLT38LNs1}P4Q}0d`qE+B;(-G)`x{b?X#jIC;5M`3+k<}e zw>uNk(CCJKdkuPj&s#9dI3j4rCPkd}$kA1N3VN74&r zEM}SF1;H{a*PHBSKou&USnQp22-wu`wHP|rVX5BE*n({MN%8E+TdttM+BGH-P<*I{ zGz;#X{mZr$RCVZa5WkRjaLZoQCfn&R%ntQ-l&Qq0!<1L8sU3_$1k3>23yabWoXH*c zbhr7<644ON{7!i~=Z`C+E(4goVRQ4WkZO0cQ$PCnL^ zLx#;q}w`avG=RWmJ;n4|1OY{uy78)CbEN(v=~3?tLX1ysQX)z z+LOcq@R*HPf~fi|&X@8S?yTw++b6B52fjg5%5=nMlx8&J_1#84ijaz-D@>_+bCgqp zH`=O|r6pV1d%$3VLnoJ%LhVHe)_}hSTdctWSzYBkYE(0j0g3W*&0iCN`mVRkfTOXp zK$W1uCe?qKoE993urcHE;SGLY>T)X~j_R;CjtwSk(YmK{{$}Cx(IuJgQOe0p@ftph zdFzXzqb+WfEUIMU1F?dvG9h{bOWyS}XM-QFG& zpvndsJpeZx;XJMnoxTnedGTD;cK6X0)>L`!BS(WnMfa17PHNv>k$y3qOA2zyj%Cfc z>A4rZqAhbrsUoFbBY6_Q#(O8ufu!(L`3u{+-d8bFn1IZTh%)=dAg;gX+|C`ciCBSY zR49-x?{4*huS5@m=KBC&f-6zv?w#qAEB8|zUbJu@@e|Va=lk}Lt{98fyU;Vw;7k@W zLU=w2DCBvmqkW?G@?W?$?wf|bD|Kf{?9({)_*5pZ#($cD6KdqqT*9p79j2Oog4+4BU z{wm;zxO907dnTRYRM=O8$>;)07cNN$-Z&-38GjlJlh8i%+}_Ix_Ws)Kh?>HLV1=uQ zDL~wv%?K7p?)X$oirYLeXelIMv5E4Z3fx=FA~QHIJl`nCrZewX<(6{3d)Wl*_- zc=$6gtBeCUi!*=0{%2#zENY2_w{>mq?kPvKgzq}GB;(HlHT~+_oU{@>bC19uh{#;K z8DF`H4l_+}tc7fSFHnzp;p1(u$u`)->_>BFHQDpuXTva=OS zT9Kt^Hn#Wi6l+G&Vy?}i=Vy-xv2VVR5z=xG^!eqVcc0b{{IgIj5y)rena*hvltBn2 zK(do%FUI)tFMsII_>^4C|A`h^91zam@mNTfDIT%;h5BHah;M=lpFrcpd$NL>s)tA8 zw02o9?B$?Ue_Jy}qvsFaz>#JtsXF;I;MHuY3xA?$mcs`UI{BuYrMdKuX-5u;Kc|RN z8>8s-OO*d1`d>M5+(zrsMnDDCzU zqN`hU1#yBXRM664-%~bQ89ya_;F(_tz8Gi4A3F{-8mQ=6q~Z=syFB2W*>OGt*$Ml;AD{s=qvG zwp;9AKis|Fr)Tku3eeo<{d35~U#b&zr9l*Z3hIAmF!(n;{J0mpk&#zd&Z4)3nXmp< zd+A5W)Pv^%=0e82He1ONdXD~%+G&ph^nVHEeaoA@)&QTpgB$dd?Ue#maq1pi%ddmZ zcNdSMvb4l$s=0xir{BD(eD%Sq*fk)WQZMkSH>d6O!KB+siJo9@IMX?)A_U0@QW_s8 z9bil%KEnUV&iJ?iKHCQK%siVip8o7VaosWT>kG$vYQsvz42YACl*@ZX$1WMzKn4C< zeX{^)njJf4+lFvnZsms7f;B#0-a)s+5ffD`%4ofqD`Sl$sUnuQZmYFh)$jk!+TdeG z)g79!$#=~O8A_oVH9Gz6@90v~d12ioOL_pR@X>^x^mT29`%_+K;ce0(&!cNrsneKO zs*KUnTc+IjbQ+>c+a6C=4xgt7*l+laH}7^(77<`eyMyTP175S#ZRZNJTs8~4d$jllNnQEdA*vcdBqgcKPI`SRd~D=>cpL{HR%vKezY3KFWVoBJ_e?&#oQsSK)(|J%*ggMDWW}#WH=N9Py!G%z4(cV(+cv9Y%0ug4`@&N1}+_pvvT*TExsSnohiMg zG3n?531>8W@_>(0bSYYPBDZ(>`?a{I0Y(NwZpUpRN_P&ZK;<-VY2|=k+r3)f8jHBH zC-c<-?QCAFmIK9?;$H0n8u$QiR}U;M4dKX%y!Tg8b4N86F>Hr-iw)A`IIPc>?wn)J z@vj7ro`~kh_Ra>?!zS6Fy(8JbY1~!Ompr<<@IPfbdXKm4Z<{sa`dLY-Zz3L3r~C6F z(^r`S$Knsv$Npp?Y!Us1j{cPne^oPOVs7m?Q(DKq262UM3n<9KH9 zd84X_O>R@I;HH)~x;3T!oOYybJ~R5NP@Nlvf2I^i2&Ep(vhI4&`rd>txt*>ctZ{+X zS7Sv-;=G@pFg_xd&YL5gN!97A^k8#PWP$6D-AQ#E1{9~h7+A%tf}MiGmIpaJ>%?8g zop8$}*GBo0)S5mj9aIf$AopmzC*O0=vxq-Q-X^DULd?71FDq(vtie>$It5rHDsoA~ zK17M{@Mfp6S5|sr)sTj7DPIP^oDT0pPs2%D)nLLS%zQ)eSkkMw1j#;>`+PAUGi&uk z`9d!grb1UZvfj9PxgAy$^x>3Tc?Y+2e6H2+A4%9q2Ao>Wl@ypBk9HO@J z^qNIqT#^2-O~bpmFP}?jBlkA$p8~bBaS$r?4688R=p*^co2Yp%#e%J-W=Ow?81JV8 z-_iwpNZx5)n{iLb&Qp{4FlcY(15__NUJ-%$H%(hNNA@6$^ za+YRl0rq0{v!DaD_>T+?Bbi5@@Q1xd;Bobzz72g3-oNx5o>$cAcpdD_%sc6))}p!19B>7r#K3GJv#+5le; zqMRHl0W1NJSNUzXs>F$VZ7XY&&r#nk3un$(557b2wi_=(RZk+>^zk=6HY;f^>b`T0 zCN1p+znIQQUBmy~nVR`f_p-z5voi1TEgr_GcB>rzpS~)Xe#0cC*Vnk|?9+c%F_*TUwTyH|O1SJcRPr zX#`84PFhlj2v4>D3E=qc%A5BGIHh5_1lfPyO>yGoWNIWW#lBhlm~k5m>rP|X$DAy_ zietr3G?m_{qoJ6c$wA}qe{ zW37-Wlug=c{o9?#@MQa#bCo;i_wc)l-`dZ=m}A;FuTiZL!!xCZU}yH-*Xi%FoR2Os zkqg`HE)xL!(-*jYdDo>`uHMvDEP{da8hAj=PwT~=J6UIPRv59@`X^x^t-0^8-e_`9 z;rhlRG+rF_slq1d!e}#F?4uUanCD}B0jvdh@5x19B#QW}?lg{f|6?cff^6Ob?&dV+ z$sPP9Hu`=r>VNY;{_I+aA?-8yrG}Zm1WBvLuy2eE7C)RPyJ^UQqDy#0_FktQjhpV1 z*74%5Oa|qy?8`F)cW=6PR*46mpR0Ao?f1<;ue){y)>xdy(Ka~q<>u}YJCMa| zpofm?j_h8%$Dt*!VEf-K%lyHm>pxJU9b56*Jfuyv8xy)2DFXtmXF>A`)6h^&FkaJL z_syO@3UyMlfcb^5i?olzb|+;j87J?&>D}S{0~e~2{gXsI(^Z2p@3Ih`LqLzu;p*f2 z6>sK@i=+c*O48krUK@PpxT@ebw7A%#wes1IxW(kpkGKuraePf{z}{tXE}=er!LF~; zZh>o9#dN&l`w@y~p}nH4D2{e2aB7k@R4|)Z_8r*1i>3a|QSgIn7rQ7~ma5UR-{*6y z1=Ys&R*q6Dic_U35KRsr zUg#eAQzBpKctDUmo=~JGPeHC=GTHBRuiv&p@Ej(bE_2 z=GfX&0SxTfE(n~`rEXbLwG}UFQmm%s+|fz@_vQ$Ns*?s=U;E}Imks-oST4^ILj{Qv zW9kPhD_h1Lv4gaT+yVRP1LBI^IUTfM1;ei_nyBFu{@dD=p+|+6)&FGvOiImOOFok4 z-^btDM2WeN`zAwr`5HeGbV1$%-_VJM(4hdZN&5z*BBjUEUrmf&Zv3UOe|nPY){n4! z;8LK9YVHKtmz)%-olSm9nANqezB`lYp|P$X*eYkyL!^r=t`EP5dr&ruy%gn_!M#dp z#&f|~@5kHmx$UcD7bat=ckdUTRf;rXey`N+bu%McvwixEfzNJ@*{wb;_LF3UpKfZv zuZJHjDV+3%q(`YzvhKguY?oVaDURTo5ty$4ZYQslyGD&Co&s|vHxlB2v}eWute(C8 zd^U>x{zM(+F$NwO4&u$2v9Nwv9q&ljyx_k!3X*O@U+18!Jb6Pi(zDNq)l~Z-u(S!j z{&S*iLW$*7LDY(=gv4ziV539j6 zOeUmpro>8O;WTS<%JJHuZtwAxrPbKuqE~l58_UdV13H-Bk3;|z3u7$0+L@I}P2IwH z80p6>T1~6TuDL3hR>i)!O(vRgMT$pCY`Ix^WrYbGgs*;pO4*cIOU9)WPQZFjv))5~ zXC@ZFT*h(Q3F8oz^Qc2?@74Pa+nehEr1mN5*?U8tFe(AzX~?){My#COBv({TM83%O zwY}E2NnLjIO4>sU3dF@a?BS~Sgkn}g!yCwAL0{JV8&T#=oYqlqE$C66^EsF0^pXuf zB~A)no@rGTJS+6U4^uP`mUFQ3=f$ZDaz}`uG~~OZcHJBEdLeLsWKUQ%uKXkP#F`_S z#iT?#jo8G`PV8E{v^(rP%r;4m4lP@;e3xWlyF()XPKw&4BitqH^+*8?PQ}E6x^m&t zqNJuruWoFVw`k;TTGa8rEM&}2bfgrM_M*B7#ah^QO!o;Ln~ zs-pj?)dCupqPGrpx0TK0oLhFxSC$H+`91J{ja87zp96GNCVYA%>mnNs0Q_$MhcI&P0J8wCfvn zLi9%Bkg}PB&5;@rT2C@zxqr-G9Z3^)@q5?4YHpLv zdI#sLPGYYd>rq|Na(d8OQ!0O+t(I`4gn=Z2?ln_a*rKj&FF0e|B9{rU3dickTOn`G6X=?mp~D&an} zv9`dd2NRcY^5dO#`$_sR^c86j@_mbG)>JpKnpM4BLc7Ja%4oaAU3r+>UwhLDfwFxq zQ0B6o2TOTJVJGZOd~N+uv1PU|d4oDTsX9BxDhEx?*?KX^)PrUC-mI1)dSyfJb%zGn zm7+AJ+$ZZjXrQv$J2LsO*rVkn_6)x@vqDGuqkWmNX-_61PQ_n#z33;(RNw=HCKsy!o>S^rJ1Ro3?>C~WE z2Sv+R`ZHjI@mr-9zT9?KYQ!;7&AKB{JczF6g1F*IcbHpdUENn7J~er)K5>u|zmrSc zj(({TKy)BSA-QAgbB>RsC1=%T>`%ui4tU7zDG`vQ$;YW*DSGJIwAhSl?6y8!Yux5q zrAW@*&dnL9Z-34&Em11S{x>w+KurbTbwWta6~JhtA}84DnmOspdzCgy%PLP1u@67< z2;h}}*(((^R3kOEo+pWYOLemDBm}Z^QkWC?G`A4*^#RjvgnQER+w_wk6$Tv~J8ZrI zU1e-&R=7kBv9e$OqDO__%b27V1V*+=aASG_Hp}7q<4j_;vSRxlwuBoh_{t<1s>cUg z3_%Sz9?3)oE7>N_(5epy#jxc@5&2IPBmZ5oW{PswVb!!*>1iM-N ziTb&oH>oDo)~dD|g|2ma4=?WtTmAhqWcgs+=zfoetgIjwyKF3kYW|4I=s-d_R+o_~F zps#kj9EAY#V~(Vwo!W=~&SE`}o;Ae|oEnqVoKL8`_=a86Ar-%<`AQfjGR{jF=-!6t z6Q@oGtZ*|BCv~ zwVn6XgSJ9Iw9sGnY?eRRDKTVEf8M2Nn?U+K#=-%^5`DCC4j%1VLg6^PF=8Y!JM+Cs#RR#_yyR% zp3_?B*x+BAt2VU9H+kI#std;(1dmRDRJ9{I3ctf%M3wx=DSQ$wl_B^TFri&e-mrts z;_i4qe)mIxLu;eqYdrRRsHewA*^+4TF}@+2;!}gLp1}oX2NxqDT{iMvTf%?;x@-e% zf+k-&%1P^7=J8^GA&0i(`J&LtQ}gn=^axuc53?fe6nXBiA~Pd0Hbf8PANxxR|J&&6 zJMNq62Bf`cML7HwFjeyVf&EAB9vK?dcygd>#n^BQutob)BLQEM9-=BVa?`Xvx0L

ON)7oVPacLY)2>4|bJeb}yo-{enVMQP2VR6fPCGW+I= z_WZc?8G3b~)7s9DkuJ0KqdK$uAsmqs{1JM-lb1C${*qIw@E(!l&Eu_m-o}xE@35<; z@EM*z=!{O-tz{>wgOG_o{*&*UvhxigVHO}W16h4) zM+F(z@F?#df75U6Llg^gm7fH>)nHqT^lp3VBkE95i8rla@N3eqHr#w((aqAng?qSU zaTfCZ1^xEzSE@T!PCFEYQDaMZ`v!I#Ho~hQP~>aK8@qPS06B|C3Ja#5()Gti_`ep5S)}2fR&x`CN~@OAdqP4fajJ<)0}zuftfZ2jfai+;lV`{5lDC7M(&mxe zvNo>1vq_m=Z29iA@IK;_SBhQa%3*MAg;04*=?n+tQeQ;DYcSl|Vq>wf$PF3viBEgL z+9}7e%2`0D#hG51iAeK|oex?Hla@oWR@}p)a_ZHUtYQMhlnkB}<9O>ouQ7h( z>^VE^_i%la)OWdJ!j+aduLg(*KoGB<8+|T$m7_pZqMydttQB9o#+6s__}gN~W4-Zx zsoiV4yg0TmmC+EocQx2vpJ)H8tDs0RSVo+}vD&%u;=B)wH~PR9_^oC~GlUgc_bL~s z?HGU=gaaE1ynUS59`^_gq(G*n3b!x*T*~?9O1M%XkoN9@3Fq$nH+W-Lw>-T7+!!4bexs=?@|d{9(q(viRjNQ;(IvGzrWMHuKyNc zSh)3V??=exPH(XWMf8M*pziBRpXbIdgbUYJw8rh$7fuDO|H@B36wbefGq(rHL#y;8G=Om0`$PyY&||;E1m})1MD@TXF>@yrxo@mp(u51NctLXBHQ&1x5m{OncDCy zuH7*uV2M!hN0~DPC8WuHR~!&8U{S>c1F+ws>b^+Nrl& z=Y76St!Du+HCBc2yV54VCx3(Z<>wkl#D-_3l60l+IN+E@UTh5v^KWM-NtJD8(Z&OY zp~J!1d{0Ai)&o-1KcA{-Qk%Z>v?tUtBuRFFoI=9Cv`PkOuY%RA@RA9t|8H(P{r@+p d3`B02K~v8Bhhdz{go|AOeH|n1Mos7V{{zpRRpbBw literal 0 HcmV?d00001 diff --git a/assets/brand/app-icons/lumbridge-app-32.png b/assets/brand/app-icons/lumbridge-app-32.png new file mode 100644 index 0000000000000000000000000000000000000000..72376e697319c89f50489decde1e901263aba5c6 GIT binary patch literal 1183 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7e6l0AZa85pY67#JE_7#My5g&JNk zFq9fFFuY1&V6d9Oz#v{QXIG#N0|VoR0G|+7po0I|rlV+Rguws*J}I0rz&PtG3GxdD z#vwD0`RbWWEGZK*;%{;||NG-0_VDlT%%4$3hHrnVN!=GQ{d7`vkIAbIfp&+t>wdj{ zD%-8?fPTnD?icwzcW2l49&!KS;q%3kb@z_*H>8zal9wu4f3J|q-F5HU;vB1fzqEwQ zYgT<*c*Z;Z!<0uIFLl(PiBJBRq#5JeZPUfxYVRL=@Y2;K3zVKG#_>x?GOa!|ALug1 zByV?@{;y2UKY<+f5>H=O_E#M8;%0m%XQrP9N+0obaSX9IJ#}(tu&|-T(ceNxmvHTR zs<9$uV^>3lBcG!lzsMfZ6%`^b@0?v%DRG2+cpy+wznRnc%#ORU?#7#Eo~+xyN9Dch z!VCXR7!}Wo^EhxsFdgJ#=X;bd<)rjnU<${S2DcgQy>1OGEyo0n#H|tnZdUTVGFS3KQy$>o#PY9Z5`_W0XX zbhv;0c-+5g*NZD(oc=O;d@=mF<^Rpk;wNvMzH;EfYL51py6in^H5DqNzI}bY?rLg> zgXf%MI%J%GZ=d%3TK+Rj?M+1L{+PUHQn4#e{CN73QCQf7pS$+#I%XOE?AXzKVds_a z*Itk+wXa*Z&OB|dQ(|&)%H+>tCsMtOs}2|Ys9bt7jkRv#OP8=m8;+D6yQkW#tG+q+ z^*RgPg&Q_!JKwz9IB6btVx7j`@5_9aPrd)yxOnQJI{9DEze!)<3Tgl7;#UofVg^rF KKbLh*2~7ZOTr=$e literal 0 HcmV?d00001 diff --git a/assets/brand/app-icons/lumbridge-app-48.png b/assets/brand/app-icons/lumbridge-app-48.png new file mode 100644 index 0000000000000000000000000000000000000000..5d577fc74b935175a5ae761056a31dcb13a265e2 GIT binary patch literal 1645 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-s3dtTpz6=aiY77hwEes65fIu6j^(%n(Lb!x$g4i zD&KTxRk$yHMNU`v)hWpfAEopToU{7OS^51~_sOU%Z@073>PMdJd2jtAVe@W>4A<4g zcODxFy^+~^*npa&Bn2Tca?c;;>DL==J>bP%@&+HL!@tN%hGKdmpjdx z5FHs1k>1O{Gk(41vro2Wx5BtXL)PdRzI_y9Q}7^v)ydV|K*uvCdAqx8TAOtqm<1Tv zOFVsD*hj1UINGd~tAI)anHyS}k!Y`42hV7#Y7L z#y^viZRA+8gk$lW>+)6{txc_rW^*;zxm+hSEm>r<%de-osl;EB^=FS|-|>U27jCZa z7iinj7g^Gt#@_LoD^R6Nwz9RIl_7&i-f+^QnR4!tH*>YiOTNtb5wWWzMoe+Z=AX`s zZ^*TORBh@gWD<&$U12zJX{v;oXUdnkJU*S}M-;*@&#>yf%x$oE&bc#@Gh{Ey21+<^ z6rb3csxiawoO7V7kZeU5R~YA+bk)zrAk zaog+JwBp-kS6pUHN}FA`y!^*;C(Z=*y{BUD>}9X^J}O-j>%VWud3&)(ul|;}zHj`u z!ZM=z#fOO!N97-ViY=|%JE8ciYEP9-6#o^~$;X9OEj#^D#P<3_&XW)JHwdWBkTGBI zAm!f5%MXp0pO!u^CTBf8sp}`l&kVl@HkAi=RcNYR-LC(>=;Kt5%21yd>JO#XCoh3V{qUq6(NbT1b&71V literal 0 HcmV?d00001 diff --git a/assets/brand/app-icons/lumbridge-app-512.png b/assets/brand/app-icons/lumbridge-app-512.png new file mode 100644 index 0000000000000000000000000000000000000000..c2fcff85b63a5f902bbbbf6b1dc5d716bbcb9ddb GIT binary patch literal 33953 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 MU}cYOu=Gj&7gL-3EC2ui literal 0 HcmV?d00001 diff --git a/assets/brand/dark/lumbridge-mark-dark-1024.png b/assets/brand/dark/lumbridge-mark-dark-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..54473eb95b21696875235b4bf6d41229104fbf42 GIT binary patch literal 41595 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 U5Zu>HPIVZdsivb^L9`D44|i<0Qvd(} literal 0 HcmV?d00001 diff --git a/assets/brand/dark/lumbridge-mark-dark-16.png b/assets/brand/dark/lumbridge-mark-dark-16.png new file mode 100644 index 0000000000000000000000000000000000000000..7382e6ea9352e536d05ed525437012b2af69b243 GIT binary patch literal 627 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Lb6AYF9SoB8UsT^3j@P1pisjL z28L1t28LG&3=CE?7#PG0=Ijcz0ZQBp@Ck7R(*L`nhbQ{~|4xS98K4h6N`m}=p~J{5 z#O5=RiNz(5<=FL{q$<_f(v_=Hs7{1 z+mu-&EmM`T*`)KtqLUrl*01B|`K&k(XeMKlx4VmHJL{7gAcwug)7O>#6^FdI8K23S z>8F808$4YcLnJP{_C04hq`=cseNZd!b==zO_j}7j@BQy=3Cpe%*ijJgcR56`QPAVJ zD2JVF(ARrB{}^_t3p8ba6#d;clCkC0gNFvDi%xo6#~GnCg{oBcMg-eTUl2kV{| z?Pc8l`*8EDZ^9Kfm-)P3qw1IcKzBCt)Pt76FD0gjzh&;W=e>6PpX@H6+ZjAv{an^L HB{Ts5dU_~< literal 0 HcmV?d00001 diff --git a/assets/brand/dark/lumbridge-mark-dark-256.png b/assets/brand/dark/lumbridge-mark-dark-256.png new file mode 100644 index 0000000000000000000000000000000000000000..0a105c75b00073976215e78e7b2429eb665c662b GIT binary patch literal 13889 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 L{an^LB{Ts55pP>V literal 0 HcmV?d00001 diff --git a/assets/brand/dark/lumbridge-mark-dark-48.png b/assets/brand/dark/lumbridge-mark-dark-48.png new file mode 100644 index 0000000000000000000000000000000000000000..8b80dff96aab07924f2880423a213cabe452e093 GIT binary patch literal 1645 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-s3dtTpz6=aiY77hwEes65fIvhUY(F^!-9%9s59b3FU+J5duA_9?RVS~b@PV&Z=-<{ED2e@T*gj7d}eq9XMz8nX~fyvF?*mS>A4ErPYr-+4J7|N5baa4jHbi zi|;%(5_%)E^~O~t{l>JT)7H(~ahr`}1Me#H*u;x3zs&J(t(z@4cZNvc)Rv{&HZFIX zH6c1OAR@h&e`ox9&1au%&2EKphlZ@tF?{$*fg&mQqI)+^Ua@=AL{Zji7sDo5 zZ9&oMZdUD$;vpLn4&DU&Sc-r37u?R`|bB-Vf5j`Q|nk6!&Paed$T zZ-r$<^@|S^C63BJ`V?DQw|7GESJj>>n<)M(s*{fkty*^aqloSGhny!L>~9cIn;~Pq z;6cj0m6snHFF!4PUQEti{(E}lxOz&5_x-) zUFY%X0nkn)ME=K?R}cK-Tn3PEw)O{rY^3`;k88> z3~FmOA1b*t|EH?6(ycplUtcWy$8_UM(b>BDXEcpN;awKl=D~1_Jm2|?PFPg zqBFmkJHPtfUvYc0p8DZQJEEn&`s${2I~4}kZhNlJb8^1+Hu(~p6Fg6@Ki>S;J^i1+ dpXFbLo4Zf+pFcY#1DHt|JYD@<);T3K0RS@BPmurs literal 0 HcmV?d00001 diff --git a/assets/brand/dark/lumbridge-mark-dark-512.png b/assets/brand/dark/lumbridge-mark-dark-512.png new file mode 100644 index 0000000000000000000000000000000000000000..fa658e5353e4b9c1a97f64721969c3b23c9bce40 GIT binary patch literal 33935 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 C0o%<0 literal 0 HcmV?d00001 diff --git a/assets/brand/dark/lumbridge-mark-dark-64.png b/assets/brand/dark/lumbridge-mark-dark-64.png new file mode 100644 index 0000000000000000000000000000000000000000..73ea60fe383f2d8d4bd60836c2d84855e6978fcd GIT binary patch literal 2104 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 Wu|6hvt(u?cFhEz!K(mr)7xf>8IU#HS literal 0 HcmV?d00001 diff --git a/assets/brand/light/lumbridge-mark-light-16.png b/assets/brand/light/lumbridge-mark-light-16.png new file mode 100644 index 0000000000000000000000000000000000000000..7e487db42d855d8ba1bb29b7ab4a6093743c4dbf GIT binary patch literal 627 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 literal 0 HcmV?d00001 diff --git a/assets/brand/light/lumbridge-mark-light-32.png b/assets/brand/light/lumbridge-mark-light-32.png new file mode 100644 index 0000000000000000000000000000000000000000..bbaa6c658a82a93636113c343b013c36b8f9f387 GIT binary patch literal 1183 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7e6l0AZa85pY67#JE_7#My5g&JNk zFq9fFFuY1&V6d9Oz#v{QXIG#N0|VoR0G|+7pn{toDx+vfguws*{{^N@2gO-mNswPK zFbP3pdg>8F#TdrV$!2(&xAUH9wt zQ`v592lPWOa=*y$xjVbQ_lWxs51%iVth;xdzag#clDt&W`g?^;?yh^+7Ux*?`=upZ zUbE`k!ZY6KAErF&c&VfQOnmakB+VG#ZksOlR(t>0gO{!@S)lYhF^*qCl48X=DgM|$xj{X)px`b=j zQ;iiN8@n1Z9Qhpe_(k@JuBZ@kdFSl9N{J)n!vlee`puliXLj6;bvNET^JLxrJu2^2 z7hd>p!l-ywoX3G9g6SX^JKv*xDJP}p0#i7qG`P)Z?{#ZnX*ninByPnZ;HKDq#`@KM z&KtiBtpuMr|2iM8p^*|eB{3u3K|^G7OQ4*2&>?@v`4*8`uQmoxh+{}=yquc;C|!15 z^OZRBL@|y2x$ds2s|yz1`t|ap=R+lZ#lYb1)1~ubZ?wF+=wSAUYxbkhr$F8gZQ zvan-a7mt05Dogp9YrE^%Yx9cB5jQ1G)9xCzSRcEs^HS^WzT)YwOD>XjMjKabu{M@x?*D=fRXUC4_3p=lT zzxIMuseRqLb>?Yvof4CaQzm~FJCW*LTy?nEN9EF!X{>bem zuh&`VF5Iv=+xh0*#!2(I6YDhgeqZLZeCqwr#>G<))ye;Q{!RJwSCK?i8CjEOWF79xtPY!f8|Sl|2dxh_noMT3i}jUd##%5n;g0B z^5rVubZ1q#FMdT%SNPQ_$qOH)^bVY}`pjAR{aE+Os4Q={v(oBEp6q#V{Uc%XZiful z)x~!n8wtIU*?Qxul73^_(P``E?YPaxv4MA$d2HgvmtW@ix7N)ToI69LZ)(fZZ5x+6 z&6*G$84!`)%fB;zz2>t|wr01&xI;tM=or3z6k}8HAb-`#)!abGGbVYvyKGvUbsm@n z7}!fZeO=jKamb6C@tK^Newu-Sna$J1F~sBe(XjMz;Xsj;d(picC$HGOX`(1=wToes zthS(NbvLW_M)8mh2?y_q9&L+#bN6Taz4jL$Wz184KJm7^X`5g6?#B zuJ0FU+tC+U(w@fN@tP}8rAxN5wVjnAgGb(Q(xRDi?vXchwaZJs%=i(pt0YEDamnVN z&WmrzwSQD?>L_Fqij-YpIB{vJgqdf`m$^JXo#jUq!Y|LT>b=Zuuz1e7Gm$f7FUkf= zIB*o7*qN#^!|$APpsSEb+sgytApEI_o!t zuX(cSWYDrxApsn#uP3a1;k&k3Pf7XpNnWqif+;umUwnEitIF71ap%l=k6T&ys5)Ev8+htc=W=u+(UAMga$8jgl1ogeAV(;u_ul7DFT@vfRZ^wCiu}81|mbkue z{I|j~qWZ;$i4sTUAAO1~t=l`H_^WD9l}!}?71hbdg;p&){ZYjB`a{l>5B4_*sLhZu zU+^I1-pb1ljhCO6J})L`Jw2)GC&$kWzXvvz2X|Fys$Jc#|GwzsRF29}pBL&6rPe1e zn0&9K`Q6#VpW7GhxohH^_ewVITd;1!?lt#jCK;Q3mfLcy_Sz%H;KlNvCdxDWe2Kh0 z$*%MG^nmFeR~DYnvhj?s@e2E$wc$h0`NzLpMZMxqHSUSu`lz(^>oZICANN#WM(au! zJj+#9{k^Q$c*b|Vp0s`D&3Bd;O3A-D=Xhe=J490 z3z@8k d;Lq}}!p+?$`p=)8k^#&l44$rjF6*2UngDL^-`fBH literal 0 HcmV?d00001 diff --git a/assets/brand/light/lumbridge-mark-light-512.png b/assets/brand/light/lumbridge-mark-light-512.png new file mode 100644 index 0000000000000000000000000000000000000000..24163a4f9d9fa0fcdeee3dfeb277a047c34c31b9 GIT binary patch literal 33796 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 NK(MsOHCXth{0l?1w6OpH literal 0 HcmV?d00001 diff --git a/assets/brand/master/lumbridge-mark-master-1024.png b/assets/brand/master/lumbridge-mark-master-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..50652115122442b09fcb59bb37b097e731697a9e GIT binary patch literal 41595 zcmeGD^;=Zm_dgErGeLJthXNucNY@}DDAFyhB1m@%96-Q8LPS7n01*U{?ix`ENs%5> zl$1`%@4TMxU+#b5zOK()b6qpDW}UtE*=y~!A1lr?Jsk~7GFCDG0Oc*s8wLQN2wzcv z1WEYN{DLnhd~n~_G|&bhh#vs>2>?d~61)U}uQ&iJwgAYd0>JE%(V(vg0HQ2)7O0)6%%{m#4mxjqrom=a#lQ@d^nSvovMNw{}m02LQKjs2T-KtYto% z=lD6^5$RZZN#i$7-#1w&8ikjcV~mtem(~B}yb}_7SyWwJ^(NtUyGi+w!Ewur5*f= z^}Q&`)rJIM&p*~QI9^M?;ry}w&6*Yjb~E!GBWSc^9QTY}ZO8z2Njsj)tQdT`L zC@ZmcA;>Xa3xm6-E;bwhTl-g+ zN~Rf1T$;TAy{b{b?f-#5P?taJ)=h3|VbDxvOH~qpU0Ws0=T)SpBRysfNjI7p-Xb=j zG`7D-VD04j!O9(r+;jz;(M06(ON}+9G+;oID)aV_lY@sU|88O)(2J+E^T`4DN4H%L zDGdwAp`}?QuD7(k0C0tWf^UNp{}z=U#&BAiBLqhZl}g*bIsycJd7qxNc^}+|o=PJh z+u2geZy(o`(t!cCxa~V|70}Dz`+Hi-ld0`ua|vJt*p=vn0R_a}*DI`QEV;{qPay?M zq{lSfwE%&p(U#wr#g7swkjmx(WPqTNMdTU-=RwX6e2X5yoMsFR)Z<9$xevPqm9V!Y zX=njX@BuPRK(FR4kRT)83}rMp8`w`q0H?(p!-Cf?gU}G1CIW#}B{@o5(?Wxx-dmFM zmLLg(xMu^rmmc6p$v|PcYs72ZYw#rTvu6$vO|R;WceN1)SnGYNZ75&@MIwWm_fZ{r z*PF;mf?N85!& zJtvBL4(v%_bDk&1!`H*yj^9E+YKvq1K{TRD7@|WXPReHaPYF6hf|a>RK4W2;esgFE z#^l|6N=80Cyl+gP+bLAjriuYO@dW*gH!kBUYD!sw9{HlW4$Ka5XIUZx?hU-lo@j9a z7>*3C5mcu!ytF}A43oRq$N(%+=(vyBCwg%ol)>aR!3rqU{39VK$!2R3 zWZhwYS?8~fK>I@OZ5HsQSN`kCP41>Vpr;i@BfT+NBgO^vqPlM_$+pH_0TN##l&*UG zsnT+>Q2|&4n-GNUY!?#+x1qOHNA)%C01PNyIc9=w80vnWxR(Q?R``m`3;@{RH>QYz z@uT=A_%a(d{3|zzPW8Rj$-59HM9002l3tRjafiTwh{_`g^EQ-bGD*@aspT8^0|1s@ z{i}>Tv$Z0HOTqQWGy4Qo+%W%L$%q@HN{<~z=<$SmosiaSAiw~lsg-u z6iShv>D_lFaL>JMehdlPBW|2ua7DY=9!mpY<@u2b=9PxCsc_oN@Od}Mn*0CAQyz5_ z#1wbW8SbJk3WM|3i}xuTM)pGpW6YY-p(~-l1R92DN&`I!#Z5BVd*9t%X9&(+aWsnZ zx&jmG2N_Ka1^pv7jJ#L;yvqzJz+S^IQ+-y?3pdbFoguQVP$lQbw=e>X`KMA|5M+Tf z1yz)2+oeK&5RNEBmJ!{HfLP>LXuu3T_t+CQml+CxWyc#a!Z@&bwmA4wkQ#yW@Kl$A zo;HD^8!S@~j@wj7!=Y(d?TDi{90<5_6R1q3$ChRdn2iKJ|;@m4k zv;drIS&b}rLL}^>B;M`?;}1|kuu~@m%@|%pib-H*7$I($+E;=AnODahQD+*E=Uu3! zQWatd;CqvDZLxIOQ{?b8x6Es|VHCqK z&@71{THO94j(w$pZ}Y>6j2Ah!r0@r5Ac#|vXT%mU511hfn{dIdGb{irDRT*peML$` z3cC#U{~v|?WCRXJVqeh@jFA{cwH5qzKJEh`)6AK=uWF-D@X%%$H7oiS4T&F4%0xb@ z%rw0Vo*;06Mx0Bb_yfXuglo`_(dZ5URs*f>Gdi+3Q-wQVknM10uNtca&CyBmvkZYx4^nbP1?hZzk2a(}9Fu!%!BQy@#Z; z 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 { + #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + pub struct $name(String); + + impl $name { + /// Creates a stable, non-empty identifier. + /// + /// # Errors + /// + #[doc = concat!("Returns [`WorkspaceError::InvalidIdentifier`] for an empty ", $label, ".")] + pub fn new(value: impl Into) -> Result { + let value = value.into(); + if value.trim().is_empty() || value.chars().any(char::is_control) { + return Err(WorkspaceError::InvalidIdentifier($label)); + } + Ok(Self(value)) + } + + #[must_use] + pub fn as_str(&self) -> &str { + &self.0 + } + } + }; +} + +string_id!(WorkspaceId, "workspace ID"); +string_id!(PaneId, "pane ID"); +string_id!(CommandRequestId, "command request ID"); + +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum WorkspaceCapability { + Observe, + Configure, + Execute, +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum CommandOrigin { + Human, + Agent { identity: String }, + Automation { client: String }, +} + +impl CommandOrigin { + fn validate(&self) -> Result<(), WorkspaceError> { + let value = match self { + Self::Human => return Ok(()), + Self::Agent { identity } => identity, + Self::Automation { client } => client, + }; + if value.trim().is_empty() + || value.len() > MAX_IDENTITY_BYTES + || value.chars().any(char::is_control) + { + return Err(WorkspaceError::InvalidOrigin); + } + Ok(()) + } +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum PaneSurface { + Terminal, + Markdown, + Browser, + Tools, + Context, + Goal, + Review, +} + +/// A credential-free launch reference. Executable arguments and secret values +/// are deliberately absent from the workspace plan. +#[derive(Clone, Eq, PartialEq)] +pub enum PaneLaunchIntent { + UserShell { + working_directory: Option, + }, + HarnessProfile { + profile_id: String, + working_directory: Option, + }, +} + +/// Pane metadata suitable for persistence and automation. It intentionally has +/// no `Debug` implementation because titles and paths may be private. +#[derive(Clone, Eq, PartialEq)] +pub struct PaneDefinition { + pub id: PaneId, + pub title: String, + pub surface: PaneSurface, + pub execution_target: ExecutionTarget, + pub launch: Option, +} + +impl PaneDefinition { + /// Validates a pane definition before it reaches the layout state. + /// + /// # Errors + /// + /// Returns [`WorkspaceError::InvalidPane`] for an empty title or for a + /// launch intent on a non-terminal pane. + pub fn validate(&self) -> Result<(), WorkspaceError> { + if self.title.trim().is_empty() || self.title.chars().any(char::is_control) { + return Err(WorkspaceError::InvalidPane("pane title")); + } + if self.launch.is_some() && self.surface != PaneSurface::Terminal { + return Err(WorkspaceError::InvalidPane( + "only terminal panes may carry a launch intent", + )); + } + match &self.launch { + Some(PaneLaunchIntent::HarnessProfile { profile_id, .. }) + if profile_id.trim().is_empty() || profile_id.chars().any(char::is_control) => + { + Err(WorkspaceError::InvalidPane("harness profile ID")) + } + _ => Ok(()), + } + } +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum SplitAxis { + Horizontal, + Vertical, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum PanePlacement { + Before, + After, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum PaneCloseDisposition { + Detach, + Terminate, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct SplitRatio(u16); + +impl SplitRatio { + /// Creates the first child's share in permille. + /// + /// # Errors + /// + /// Returns [`WorkspaceError::InvalidSplitRatio`] outside 100..=900. + pub fn from_permille(value: u16) -> Result { + if !(MIN_SPLIT_PERMILLE..=MAX_SPLIT_PERMILLE).contains(&value) { + return Err(WorkspaceError::InvalidSplitRatio(value)); + } + Ok(Self(value)) + } + + #[must_use] + pub const fn permille(self) -> u16 { + self.0 + } +} + +impl Default for SplitRatio { + fn default() -> Self { + Self(500) + } +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum LayoutNode { + Pane(PaneId), + Split { + axis: SplitAxis, + ratio: SplitRatio, + first: Box, + second: Box, + }, +} + +impl LayoutNode { + fn contains(&self, pane: &PaneId) -> bool { + match self { + Self::Pane(candidate) => candidate == pane, + Self::Split { first, second, .. } => first.contains(pane) || second.contains(pane), + } + } + + fn split( + &mut self, + target: &PaneId, + new_pane: PaneId, + axis: SplitAxis, + ratio: SplitRatio, + placement: PanePlacement, + ) -> bool { + match self { + Self::Pane(candidate) if candidate == target => { + let existing = Self::Pane(candidate.clone()); + let inserted = Self::Pane(new_pane); + let (first, second) = match placement { + PanePlacement::Before => (inserted, existing), + PanePlacement::After => (existing, inserted), + }; + *self = Self::Split { + axis, + ratio, + first: Box::new(first), + second: Box::new(second), + }; + true + } + Self::Pane(_) => false, + Self::Split { first, second, .. } => { + first.split(target, new_pane.clone(), axis, ratio, placement) + || second.split(target, new_pane, axis, ratio, placement) + } + } + } + + fn remove(self, target: &PaneId) -> Option { + match self { + Self::Pane(pane) => (pane != *target).then_some(Self::Pane(pane)), + Self::Split { + axis, + ratio, + first, + second, + } => match (first.remove(target), second.remove(target)) { + (Some(first), Some(second)) => Some(Self::Split { + axis, + ratio, + first: Box::new(first), + second: Box::new(second), + }), + (Some(remaining), None) | (None, Some(remaining)) => Some(remaining), + (None, None) => None, + }, + } + } + + fn first_pane(&self) -> &PaneId { + match self { + Self::Pane(pane) => pane, + Self::Split { first, .. } => first.first_pane(), + } + } +} + +#[derive(Clone, Eq, PartialEq)] +pub enum WorkspaceCommand { + SplitPane { + target: PaneId, + pane: PaneDefinition, + axis: SplitAxis, + ratio: SplitRatio, + placement: PanePlacement, + }, + SelectPane { + pane: PaneId, + }, + RenamePane { + pane: PaneId, + title: String, + }, + ClosePane { + pane: PaneId, + disposition: PaneCloseDisposition, + }, +} + +impl WorkspaceCommand { + #[must_use] + pub const fn required_capability(&self) -> WorkspaceCapability { + match self { + Self::ClosePane { + disposition: PaneCloseDisposition::Terminate, + .. + } => WorkspaceCapability::Execute, + Self::SplitPane { pane, .. } if pane.launch.is_some() => WorkspaceCapability::Execute, + Self::SplitPane { .. } + | Self::SelectPane { .. } + | Self::RenamePane { .. } + | Self::ClosePane { + disposition: PaneCloseDisposition::Detach, + .. + } => WorkspaceCapability::Configure, + } + } +} + +#[derive(Clone, Eq, PartialEq)] +pub struct WorkspaceRequest { + pub request_id: CommandRequestId, + pub origin: CommandOrigin, + pub command: WorkspaceCommand, +} + +/// State transition emitted after an accepted command. Transcript or input +/// content never appears in these events. +#[derive(Clone, Eq, PartialEq)] +pub enum WorkspaceEvent { + PaneSplit { + target: PaneId, + pane: PaneId, + }, + PaneSelected { + pane: PaneId, + }, + PaneRenamed { + pane: PaneId, + }, + PaneClosed { + pane: PaneId, + disposition: PaneCloseDisposition, + }, +} + +pub struct WorkspaceApplyOutcome { + pub revision: u64, + pub duplicate: bool, + pub event: Option, +} + +#[derive(Debug, Error, Eq, PartialEq)] +pub enum WorkspaceError { + #[error("invalid {0}")] + InvalidIdentifier(&'static str), + #[error("invalid {0}")] + InvalidPane(&'static str), + #[error("split ratio {0} must be between 100 and 900 permille")] + InvalidSplitRatio(u16), + #[error("pane does not exist: {}", .0.as_str())] + PaneNotFound(PaneId), + #[error("pane already exists: {}", .0.as_str())] + PaneAlreadyExists(PaneId), + #[error("command origin identity is invalid")] + InvalidOrigin, + #[error("request ID was already used for a different request: {}", .0.as_str())] + RequestConflict(CommandRequestId), + #[error("the last pane cannot be closed")] + CannotCloseLastPane, + #[error("workspace command requires {required:?} capability but only {granted:?} was granted")] + CapabilityDenied { + required: WorkspaceCapability, + granted: WorkspaceCapability, + }, +} + +/// Deterministic layout state shared by all command-plane frontends. It has no +/// `Debug` implementation because pane metadata may contain local paths. +#[derive(Clone, Eq, PartialEq)] +pub struct WorkspaceState { + id: WorkspaceId, + name: String, + panes: BTreeMap, + layout: LayoutNode, + selected: PaneId, + applied_requests: BTreeMap, + revision: u64, +} + +impl WorkspaceState { + /// Creates a workspace with one root pane. + /// + /// # Errors + /// + /// Returns [`WorkspaceError::InvalidPane`] for invalid names or pane + /// definitions. + pub fn new( + id: WorkspaceId, + name: impl Into, + root: PaneDefinition, + ) -> Result { + let name = name.into(); + if name.trim().is_empty() || name.chars().any(char::is_control) { + return Err(WorkspaceError::InvalidPane("workspace name")); + } + root.validate()?; + let selected = root.id.clone(); + let layout = LayoutNode::Pane(root.id.clone()); + let panes = BTreeMap::from([(root.id.clone(), root)]); + Ok(Self { + id, + name, + panes, + layout, + selected, + applied_requests: BTreeMap::new(), + revision: 0, + }) + } + + #[must_use] + pub const fn id(&self) -> &WorkspaceId { + &self.id + } + + #[must_use] + pub fn name(&self) -> &str { + &self.name + } + + #[must_use] + pub const fn layout(&self) -> &LayoutNode { + &self.layout + } + + #[must_use] + pub const fn selected(&self) -> &PaneId { + &self.selected + } + + #[must_use] + pub const fn revision(&self) -> u64 { + self.revision + } + + #[must_use] + pub fn pane(&self, id: &PaneId) -> Option<&PaneDefinition> { + self.panes.get(id) + } + + #[must_use] + pub fn pane_count(&self) -> usize { + self.panes.len() + } + + /// Applies one idempotent command after checking its required capability. + /// + /// # Errors + /// + /// Rejects insufficient authority and invalid state transitions without + /// changing the workspace. + pub fn apply( + &mut self, + request: WorkspaceRequest, + granted: WorkspaceCapability, + ) -> Result { + if let Some(applied) = self.applied_requests.get(&request.request_id) { + if applied == &request { + return Ok(WorkspaceApplyOutcome { + revision: self.revision, + duplicate: true, + event: None, + }); + } + return Err(WorkspaceError::RequestConflict(request.request_id)); + } + request.origin.validate()?; + let required = request.command.required_capability(); + if granted < required { + return Err(WorkspaceError::CapabilityDenied { required, granted }); + } + + let event = self.apply_command(request.command.clone())?; + self.applied_requests + .insert(request.request_id.clone(), request); + self.revision = self.revision.saturating_add(1); + Ok(WorkspaceApplyOutcome { + revision: self.revision, + duplicate: false, + event: Some(event), + }) + } + + /// Applies a setup plan atomically. Any rejected command leaves the + /// original workspace unchanged. + /// + /// # Errors + /// + /// Returns the first command error without committing partial state. + pub fn apply_plan( + &mut self, + requests: impl IntoIterator, + granted: WorkspaceCapability, + ) -> Result, WorkspaceError> { + let mut candidate = self.clone(); + let mut outcomes = Vec::new(); + for request in requests { + outcomes.push(candidate.apply(request, granted)?); + } + *self = candidate; + Ok(outcomes) + } + + fn apply_command( + &mut self, + command: WorkspaceCommand, + ) -> Result { + match command { + WorkspaceCommand::SplitPane { + target, + pane, + axis, + ratio, + placement, + } => { + if !self.layout.contains(&target) { + return Err(WorkspaceError::PaneNotFound(target)); + } + if self.panes.contains_key(&pane.id) { + return Err(WorkspaceError::PaneAlreadyExists(pane.id)); + } + pane.validate()?; + let pane_id = pane.id.clone(); + let did_split = self + .layout + .split(&target, pane_id.clone(), axis, ratio, placement); + debug_assert!(did_split, "target presence was checked"); + self.panes.insert(pane_id.clone(), pane); + self.selected = pane_id.clone(); + Ok(WorkspaceEvent::PaneSplit { + target, + pane: pane_id, + }) + } + WorkspaceCommand::SelectPane { pane } => { + if !self.panes.contains_key(&pane) { + return Err(WorkspaceError::PaneNotFound(pane)); + } + self.selected = pane.clone(); + Ok(WorkspaceEvent::PaneSelected { pane }) + } + WorkspaceCommand::RenamePane { pane, title } => { + if title.trim().is_empty() || title.chars().any(char::is_control) { + return Err(WorkspaceError::InvalidPane("pane title")); + } + let definition = self + .panes + .get_mut(&pane) + .ok_or_else(|| WorkspaceError::PaneNotFound(pane.clone()))?; + definition.title = title; + Ok(WorkspaceEvent::PaneRenamed { pane }) + } + WorkspaceCommand::ClosePane { pane, disposition } => { + if self.panes.len() == 1 && self.panes.contains_key(&pane) { + return Err(WorkspaceError::CannotCloseLastPane); + } + if !self.panes.contains_key(&pane) { + return Err(WorkspaceError::PaneNotFound(pane)); + } + let layout = self + .layout + .clone() + .remove(&pane) + .ok_or(WorkspaceError::CannotCloseLastPane)?; + self.panes.remove(&pane); + self.layout = layout; + if self.selected == pane { + self.selected = self.layout.first_pane().clone(); + } + Ok(WorkspaceEvent::PaneClosed { pane, disposition }) + } + } + } +} + +impl fmt::Debug for WorkspaceEvent { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::PaneSplit { target, pane } => formatter + .debug_struct("PaneSplit") + .field("target", target) + .field("pane", pane) + .finish(), + Self::PaneSelected { pane } => formatter + .debug_struct("PaneSelected") + .field("pane", pane) + .finish(), + Self::PaneRenamed { pane } => formatter + .debug_struct("PaneRenamed") + .field("pane", pane) + .finish(), + Self::PaneClosed { pane, disposition } => formatter + .debug_struct("PaneClosed") + .field("pane", pane) + .field("disposition", disposition) + .finish(), + } + } +} + +#[cfg(test)] +mod tests { + use super::{ + CommandOrigin, CommandRequestId, LayoutNode, PaneCloseDisposition, PaneDefinition, PaneId, + PaneLaunchIntent, PanePlacement, PaneSurface, SplitAxis, SplitRatio, WorkspaceCapability, + WorkspaceCommand, WorkspaceError, WorkspaceId, WorkspaceRequest, WorkspaceState, + }; + use crate::ExecutionTarget; + + fn id(constructor: impl FnOnce(String) -> Result, value: &str) -> T { + constructor(value.to_owned()).unwrap() + } + + fn pane(value: &str, launch: bool) -> PaneDefinition { + PaneDefinition { + id: id(PaneId::new, value), + title: value.to_owned(), + surface: PaneSurface::Terminal, + execution_target: ExecutionTarget::Local, + launch: launch.then_some(PaneLaunchIntent::UserShell { + working_directory: None, + }), + } + } + + fn request(value: &str, command: WorkspaceCommand) -> WorkspaceRequest { + WorkspaceRequest { + request_id: id(CommandRequestId::new, value), + origin: CommandOrigin::Agent { + identity: "test-agent".into(), + }, + command, + } + } + + fn workspace() -> WorkspaceState { + WorkspaceState::new(id(WorkspaceId::new, "ws"), "Workspace", pane("root", false)).unwrap() + } + + #[test] + fn agent_plan_builds_a_deterministic_split_tree() { + let mut state = workspace(); + let requests = [ + request( + "split-1", + WorkspaceCommand::SplitPane { + target: id(PaneId::new, "root"), + pane: pane("agent", false), + axis: SplitAxis::Horizontal, + ratio: SplitRatio::default(), + placement: PanePlacement::After, + }, + ), + request( + "split-2", + WorkspaceCommand::SplitPane { + target: id(PaneId::new, "agent"), + pane: pane("tests", false), + axis: SplitAxis::Vertical, + ratio: SplitRatio::from_permille(600).unwrap(), + placement: PanePlacement::Before, + }, + ), + ]; + let outcomes = state + .apply_plan(requests, WorkspaceCapability::Configure) + .unwrap(); + assert_eq!(outcomes.len(), 2); + assert_eq!(state.pane_count(), 3); + assert_eq!(state.selected().as_str(), "tests"); + assert_eq!(state.revision(), 2); + assert!(matches!(state.layout(), LayoutNode::Split { .. })); + } + + #[test] + fn repeated_request_is_idempotent() { + let mut state = workspace(); + let command = request( + "select-root", + WorkspaceCommand::SelectPane { + pane: id(PaneId::new, "root"), + }, + ); + let first = state + .apply(command.clone(), WorkspaceCapability::Configure) + .unwrap(); + let second = state + .apply(command, WorkspaceCapability::Configure) + .unwrap(); + assert!(!first.duplicate); + assert!(second.duplicate); + assert_eq!(state.revision(), 1); + } + + #[test] + fn reused_request_id_must_match_origin_and_command() { + let mut state = workspace(); + state + .apply( + request( + "shared-id", + WorkspaceCommand::SelectPane { + pane: id(PaneId::new, "root"), + }, + ), + WorkspaceCapability::Configure, + ) + .unwrap(); + let conflicting = request( + "shared-id", + WorkspaceCommand::RenamePane { + pane: id(PaneId::new, "root"), + title: "Different".into(), + }, + ); + assert!(matches!( + state.apply(conflicting, WorkspaceCapability::Configure), + Err(WorkspaceError::RequestConflict(_)) + )); + assert_eq!(state.pane(&id(PaneId::new, "root")).unwrap().title, "root"); + assert_eq!(state.revision(), 1); + } + + #[test] + fn rejects_unattributed_agent_requests() { + let mut state = workspace(); + let request = WorkspaceRequest { + request_id: id(CommandRequestId::new, "origin"), + origin: CommandOrigin::Agent { + identity: "\n".into(), + }, + command: WorkspaceCommand::SelectPane { + pane: id(PaneId::new, "root"), + }, + }; + assert!(matches!( + state.apply(request, WorkspaceCapability::Configure), + Err(WorkspaceError::InvalidOrigin) + )); + assert_eq!(state.revision(), 0); + } + + #[test] + fn launch_and_termination_require_execute_capability() { + let mut state = workspace(); + let launch = request( + "launch", + WorkspaceCommand::SplitPane { + target: id(PaneId::new, "root"), + pane: pane("shell", true), + axis: SplitAxis::Horizontal, + ratio: SplitRatio::default(), + placement: PanePlacement::After, + }, + ); + assert!(matches!( + state.apply(launch.clone(), WorkspaceCapability::Configure), + Err(WorkspaceError::CapabilityDenied { .. }) + )); + state.apply(launch, WorkspaceCapability::Execute).unwrap(); + let terminate = request( + "terminate", + WorkspaceCommand::ClosePane { + pane: id(PaneId::new, "shell"), + disposition: PaneCloseDisposition::Terminate, + }, + ); + assert!(matches!( + state.apply(terminate, WorkspaceCapability::Configure), + Err(WorkspaceError::CapabilityDenied { .. }) + )); + } + + #[test] + fn failed_plan_is_atomic() { + let mut state = workspace(); + let before = state.clone(); + let requests = [ + request( + "good", + WorkspaceCommand::SplitPane { + target: id(PaneId::new, "root"), + pane: pane("new", false), + axis: SplitAxis::Horizontal, + ratio: SplitRatio::default(), + placement: PanePlacement::After, + }, + ), + request( + "bad", + WorkspaceCommand::SelectPane { + pane: id(PaneId::new, "missing"), + }, + ), + ]; + assert!( + state + .apply_plan(requests, WorkspaceCapability::Configure) + .is_err() + ); + assert!(state == before); + } + + #[test] + fn close_promotes_sibling_and_never_closes_last_pane() { + let mut state = workspace(); + state + .apply( + request( + "split", + WorkspaceCommand::SplitPane { + target: id(PaneId::new, "root"), + pane: pane("second", false), + axis: SplitAxis::Horizontal, + ratio: SplitRatio::default(), + placement: PanePlacement::After, + }, + ), + WorkspaceCapability::Configure, + ) + .unwrap(); + state + .apply( + request( + "close", + WorkspaceCommand::ClosePane { + pane: id(PaneId::new, "second"), + disposition: PaneCloseDisposition::Detach, + }, + ), + WorkspaceCapability::Configure, + ) + .unwrap(); + assert_eq!(state.selected().as_str(), "root"); + assert_eq!(state.pane_count(), 1); + assert!(matches!( + state.apply( + request( + "last", + WorkspaceCommand::ClosePane { + pane: id(PaneId::new, "root"), + disposition: PaneCloseDisposition::Detach, + }, + ), + WorkspaceCapability::Configure + ), + Err(WorkspaceError::CannotCloseLastPane) + )); + } + + #[test] + fn rejects_invalid_identifiers_ratios_and_launch_surfaces() { + assert!(PaneId::new(" ").is_err()); + assert!(SplitRatio::from_permille(99).is_err()); + let invalid = PaneDefinition { + id: id(PaneId::new, "browser"), + title: "Browser".into(), + surface: PaneSurface::Browser, + execution_target: ExecutionTarget::Local, + launch: Some(PaneLaunchIntent::UserShell { + working_directory: None, + }), + }; + assert!(invalid.validate().is_err()); + } +} diff --git a/crates/lumbridge-runtime/Cargo.toml b/crates/lumbridge-runtime/Cargo.toml index f77a8e5..c570b55 100644 --- a/crates/lumbridge-runtime/Cargo.toml +++ b/crates/lumbridge-runtime/Cargo.toml @@ -11,5 +11,8 @@ repository.workspace = true lumbridge-pty = { path = "../lumbridge-pty" } thiserror = "2.0" +[dev-dependencies] +lumbridge-terminal = { path = "../lumbridge-terminal" } + [lints] workspace = true diff --git a/crates/lumbridge-runtime/tests/terminal_pipeline.rs b/crates/lumbridge-runtime/tests/terminal_pipeline.rs new file mode 100644 index 0000000..5588923 --- /dev/null +++ b/crates/lumbridge-runtime/tests/terminal_pipeline.rs @@ -0,0 +1,78 @@ +use lumbridge_runtime::{ + CommandConfig, PtyOptions, RuntimeActor, RuntimeActorOptions, RuntimeCommand, RuntimeEvent, + TerminalSize, +}; +use lumbridge_terminal::{ + KeyModifiers, TerminalDimensions, TerminalEngine, TerminalEngineOptions, TerminalKey, + TerminalKeyEvent, +}; +use std::time::{Duration, Instant}; + +const TEST_TIMEOUT: Duration = Duration::from_secs(3); + +#[test] +fn actor_terminal_pipeline_accepts_input_resize_and_vt_output() { + let command = CommandConfig::new("/bin/sh") + .unwrap() + .args([ + "-c", + "printf '\x1b[31mready\x1b[0m\\n'; IFS= read -r line; stty size; printf 'got:%s\\n' \"$line\"", + ]); + let actor = RuntimeActor::spawn( + command, + PtyOptions::default(), + RuntimeActorOptions::default(), + ) + .unwrap(); + let dimensions = TerminalDimensions::new(41, 101).unwrap(); + let mut terminal = TerminalEngine::new(TerminalEngineOptions { + dimensions: TerminalDimensions::default(), + scrollback_lines: 64, + }); + assert!(terminal.resize(dimensions)); + actor + .try_send(RuntimeCommand::Resize(TerminalSize::new(41, 101).unwrap())) + .unwrap(); + + let text = terminal.encode_key(&TerminalKeyEvent { + key: TerminalKey::Text("hello-pipeline".into()), + modifiers: KeyModifiers::default(), + }); + actor.try_send(RuntimeCommand::Input(text)).unwrap(); + let enter = terminal.encode_key(&TerminalKeyEvent { + key: TerminalKey::Enter, + modifiers: KeyModifiers::default(), + }); + actor.try_send(RuntimeCommand::Input(enter)).unwrap(); + + let deadline = Instant::now() + TEST_TIMEOUT; + loop { + let remaining = deadline.saturating_duration_since(Instant::now()); + assert!(!remaining.is_zero(), "timed out waiting for pipeline exit"); + match actor.recv_timeout(remaining).unwrap() { + RuntimeEvent::Output { bytes, .. } => { + let update = terminal.process(&bytes); + for response in update.outbound { + actor.try_send(RuntimeCommand::Input(response)).unwrap(); + } + } + RuntimeEvent::Exited { status, .. } => { + assert!(status.success()); + break; + } + RuntimeEvent::Fault { message, .. } => panic!("runtime fault: {message}"), + RuntimeEvent::Started { .. } | RuntimeEvent::InputClosed { .. } => {} + } + } + + let contents = terminal.snapshot().plain_rows().join("\n"); + assert!(contents.contains("ready"), "missing ready marker"); + assert!( + contents.contains("41 101"), + "missing resized PTY dimensions" + ); + assert!( + contents.contains("got:hello-pipeline"), + "missing echoed input" + ); +} diff --git a/crates/lumbridge-terminal/Cargo.toml b/crates/lumbridge-terminal/Cargo.toml new file mode 100644 index 0000000..86c826d --- /dev/null +++ b/crates/lumbridge-terminal/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "lumbridge-terminal" +description = "Framework-neutral terminal state, snapshots, and input encoding for Lumbridge" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +alacritty_terminal = { version = "0.26.0", default-features = false } +thiserror = "2.0" + +[lints] +workspace = true diff --git a/crates/lumbridge-terminal/src/lib.rs b/crates/lumbridge-terminal/src/lib.rs new file mode 100644 index 0000000..f52fca1 --- /dev/null +++ b/crates/lumbridge-terminal/src/lib.rs @@ -0,0 +1,994 @@ +//! Framework-neutral terminal state for Lumbridge. +//! +//! This crate consumes raw PTY bytes, maintains VT state, creates immutable +//! render snapshots, and encodes human input. It deliberately owns neither a +//! PTY nor a UI framework. + +#![forbid(unsafe_code)] + +use alacritty_terminal::event::{Event, EventListener, WindowSize}; +use alacritty_terminal::grid::Dimensions; +use alacritty_terminal::term::cell::Flags; +use alacritty_terminal::term::{Config, Osc52, Term, TermMode, point_to_viewport}; +use alacritty_terminal::vte::ansi::{Color, CursorShape, NamedColor, Processor}; +use std::fmt; +use std::sync::{Arc, Mutex, MutexGuard}; +use thiserror::Error; + +const DEFAULT_SCROLLBACK_LINES: usize = 10_000; +const MAX_TITLE_BYTES: usize = 512; + +/// Validated terminal grid and cell dimensions. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct TerminalDimensions { + rows: u16, + columns: u16, + cell_width: u16, + cell_height: u16, +} + +impl TerminalDimensions { + /// Creates dimensions without pixel-cell measurements. + /// + /// # Errors + /// + /// Returns [`TerminalEngineError::InvalidDimensions`] for a zero row or + /// column count. + pub fn new(rows: u16, columns: u16) -> Result { + Self::with_cell_size(rows, columns, 0, 0) + } + + /// Creates dimensions with the cell size used for terminal size queries. + /// + /// # Errors + /// + /// Returns [`TerminalEngineError::InvalidDimensions`] for a zero row or + /// column count. + pub fn with_cell_size( + rows: u16, + columns: u16, + cell_width: u16, + cell_height: u16, + ) -> Result { + if rows == 0 || columns == 0 { + return Err(TerminalEngineError::InvalidDimensions); + } + Ok(Self { + rows, + columns, + cell_width, + cell_height, + }) + } + + #[must_use] + pub const fn rows(self) -> u16 { + self.rows + } + + #[must_use] + pub const fn columns(self) -> u16 { + self.columns + } + + const fn window_size(self) -> WindowSize { + WindowSize { + num_lines: self.rows, + num_cols: self.columns, + cell_width: self.cell_width, + cell_height: self.cell_height, + } + } +} + +impl Default for TerminalDimensions { + fn default() -> Self { + Self { + rows: 24, + columns: 80, + cell_width: 0, + cell_height: 0, + } + } +} + +impl Dimensions for TerminalDimensions { + fn total_lines(&self) -> usize { + usize::from(self.rows) + } + + fn screen_lines(&self) -> usize { + usize::from(self.rows) + } + + fn columns(&self) -> usize { + usize::from(self.columns) + } +} + +/// Configuration for a terminal state engine. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct TerminalEngineOptions { + pub dimensions: TerminalDimensions, + pub scrollback_lines: usize, +} + +impl Default for TerminalEngineOptions { + fn default() -> Self { + Self { + dimensions: TerminalDimensions::default(), + scrollback_lines: DEFAULT_SCROLLBACK_LINES, + } + } +} + +#[derive(Debug, Error, Eq, PartialEq)] +pub enum TerminalEngineError { + #[error("terminal rows and columns must both be greater than zero")] + InvalidDimensions, +} + +/// Color identity retained by an immutable terminal snapshot. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum TerminalColor { + Named(TerminalNamedColor), + Indexed(u8), + Rgb { red: u8, green: u8, blue: u8 }, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum TerminalNamedColor { + Black, + Red, + Green, + Yellow, + Blue, + Magenta, + Cyan, + White, + BrightBlack, + BrightRed, + BrightGreen, + BrightYellow, + BrightBlue, + BrightMagenta, + BrightCyan, + BrightWhite, + Foreground, + Background, + Cursor, + DimBlack, + DimRed, + DimGreen, + DimYellow, + DimBlue, + DimMagenta, + DimCyan, + DimWhite, + BrightForeground, + DimForeground, +} + +/// Render attributes for one terminal cell. +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct TerminalCellStyle(u16); + +impl TerminalCellStyle { + pub const BOLD: Self = Self(1 << 0); + pub const DIM: Self = Self(1 << 1); + pub const ITALIC: Self = Self(1 << 2); + pub const UNDERLINE: Self = Self(1 << 3); + pub const DOUBLE_UNDERLINE: Self = Self(1 << 4); + pub const UNDERCURL: Self = Self(1 << 5); + pub const DOTTED_UNDERLINE: Self = Self(1 << 6); + pub const DASHED_UNDERLINE: Self = Self(1 << 7); + pub const INVERSE: Self = Self(1 << 8); + pub const HIDDEN: Self = Self(1 << 9); + pub const STRIKEOUT: Self = Self(1 << 10); + + #[must_use] + pub const fn contains(self, other: Self) -> bool { + self.0 & other.0 == other.0 + } + + const fn with(mut self, flag: Self, enabled: bool) -> Self { + if enabled { + self.0 |= flag.0; + } + self + } +} + +/// One immutable cell. It intentionally has no `Debug` implementation so a +/// transcript cannot be accidentally dumped through snapshot diagnostics. +#[derive(Clone, Eq, PartialEq)] +pub struct TerminalCell { + pub text: String, + pub foreground: TerminalColor, + pub background: TerminalColor, + pub style: TerminalCellStyle, + pub wide: bool, + pub wide_spacer: bool, + pub hyperlink: Option, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum TerminalCursorShape { + Block, + Underline, + Beam, + HollowBlock, + Hidden, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct TerminalCursor { + pub row: u16, + pub column: u16, + pub shape: TerminalCursorShape, +} + +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct TerminalModes(u16); + +impl TerminalModes { + pub const ALTERNATE_SCREEN: Self = Self(1 << 0); + pub const APPLICATION_CURSOR: Self = Self(1 << 1); + pub const APPLICATION_KEYPAD: Self = Self(1 << 2); + pub const BRACKETED_PASTE: Self = Self(1 << 3); + pub const MOUSE_REPORTING: Self = Self(1 << 4); + pub const FOCUS_REPORTING: Self = Self(1 << 5); + pub const KITTY_KEYBOARD: Self = Self(1 << 6); + + #[must_use] + pub const fn contains(self, other: Self) -> bool { + self.0 & other.0 == other.0 + } + + const fn with(mut self, flag: Self, enabled: bool) -> Self { + if enabled { + self.0 |= flag.0; + } + self + } +} + +/// Immutable, framework-neutral render state. It intentionally omits `Debug` +/// because cells and titles may contain private terminal content. +#[derive(Clone, Eq, PartialEq)] +pub struct TerminalSnapshot { + pub revision: u64, + pub dimensions: TerminalDimensions, + pub cells: Vec, + pub cursor: TerminalCursor, + pub modes: TerminalModes, + pub title: Option, +} + +impl TerminalSnapshot { + #[must_use] + pub fn cell(&self, row: u16, column: u16) -> Option<&TerminalCell> { + if row >= self.dimensions.rows() || column >= self.dimensions.columns() { + return None; + } + let index = usize::from(row) * usize::from(self.dimensions.columns()) + usize::from(column); + self.cells.get(index) + } + + /// Returns visible plain-text rows for simple UI adapters and tests. + #[must_use] + pub fn plain_rows(&self) -> Vec { + (0..self.dimensions.rows()) + .map(|row| { + let mut text = String::new(); + for column in 0..self.dimensions.columns() { + let Some(cell) = self.cell(row, column) else { + continue; + }; + if cell.wide_spacer { + continue; + } + if cell.text.is_empty() || cell.style.contains(TerminalCellStyle::HIDDEN) { + text.push(' '); + } else { + text.push_str(&cell.text); + } + } + text.trim_end().to_owned() + }) + .collect() + } +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum TerminalQueryKind { + Color, + Clipboard, +} + +/// Semantic terminal event safe to pass to the application boundary. +/// Transcript-bearing title values are redacted from `Debug`. +#[derive(Clone, Eq, PartialEq)] +pub enum TerminalEvent { + Bell, + TitleChanged(String), + TitleReset, + ClipboardOperationBlocked, + UnsupportedQuery(TerminalQueryKind), + ExitRequested, +} + +impl fmt::Debug for TerminalEvent { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Bell => formatter.write_str("Bell"), + Self::TitleChanged(title) => formatter + .debug_struct("TitleChanged") + .field("bytes", &title.len()) + .finish_non_exhaustive(), + Self::TitleReset => formatter.write_str("TitleReset"), + Self::ClipboardOperationBlocked => formatter.write_str("ClipboardOperationBlocked"), + Self::UnsupportedQuery(kind) => formatter + .debug_tuple("UnsupportedQuery") + .field(kind) + .finish(), + Self::ExitRequested => formatter.write_str("ExitRequested"), + } + } +} + +/// Result of processing PTY output. `outbound` contains terminal-protocol +/// responses that must be serialized through the same actor input queue as +/// human input. +pub struct TerminalUpdate { + pub revision: u64, + pub outbound: Vec>, + pub events: Vec, +} + +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct KeyModifiers(u8); + +impl KeyModifiers { + pub const SHIFT: Self = Self(1 << 0); + pub const ALT: Self = Self(1 << 1); + pub const CONTROL: Self = Self(1 << 2); + pub const PLATFORM: Self = Self(1 << 3); + + #[must_use] + pub const fn contains(self, other: Self) -> bool { + self.0 & other.0 == other.0 + } + + #[must_use] + pub const fn union(self, other: Self) -> Self { + Self(self.0 | other.0) + } +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum TerminalKey { + Text(String), + Enter, + Backspace, + Tab, + Escape, + Up, + Down, + Left, + Right, + Home, + End, + Insert, + Delete, + PageUp, + PageDown, + Function(u8), +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct TerminalKeyEvent { + pub key: TerminalKey, + pub modifiers: KeyModifiers, +} + +#[derive(Default)] +struct ProxyState { + dimensions: TerminalDimensions, + outbound: Vec>, + events: Vec, + title: Option, +} + +#[derive(Clone, Default)] +struct EventProxy { + state: Arc>, +} + +impl EventProxy { + fn lock(&self) -> MutexGuard<'_, ProxyState> { + self.state + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + } + + fn set_dimensions(&self, dimensions: TerminalDimensions) { + self.lock().dimensions = dimensions; + } + + fn drain(&self, revision: u64) -> TerminalUpdate { + let mut state = self.lock(); + TerminalUpdate { + revision, + outbound: std::mem::take(&mut state.outbound), + events: std::mem::take(&mut state.events), + } + } + + fn title(&self) -> Option { + self.lock().title.clone() + } +} + +impl EventListener for EventProxy { + fn send_event(&self, event: Event) { + let mut state = self.lock(); + match event { + Event::PtyWrite(text) => state.outbound.push(text.into_bytes()), + Event::TextAreaSizeRequest(formatter) => { + let window_size = state.dimensions.window_size(); + state.outbound.push(formatter(window_size).into_bytes()); + } + Event::Title(title) => { + let title = sanitize_title(&title); + state.title = Some(title.clone()); + state.events.push(TerminalEvent::TitleChanged(title)); + } + Event::ResetTitle => { + state.title = None; + state.events.push(TerminalEvent::TitleReset); + } + Event::Bell => state.events.push(TerminalEvent::Bell), + Event::ClipboardStore(_, _) | Event::ClipboardLoad(_, _) => { + state.events.push(TerminalEvent::ClipboardOperationBlocked); + } + Event::ColorRequest(_, _) => state + .events + .push(TerminalEvent::UnsupportedQuery(TerminalQueryKind::Color)), + Event::Exit => state.events.push(TerminalEvent::ExitRequested), + Event::MouseCursorDirty + | Event::CursorBlinkingChange + | Event::Wakeup + | Event::ChildExit(_) => {} + } + } +} + +/// Single-owner terminal state engine. +pub struct TerminalEngine { + parser: Processor, + terminal: Term, + proxy: EventProxy, + dimensions: TerminalDimensions, + revision: u64, +} + +impl TerminalEngine { + #[must_use] + pub fn new(options: TerminalEngineOptions) -> Self { + let proxy = EventProxy::default(); + proxy.set_dimensions(options.dimensions); + let config = Config { + scrolling_history: options.scrollback_lines, + osc52: Osc52::Disabled, + ..Config::default() + }; + Self { + parser: Processor::new(), + terminal: Term::new(config, &options.dimensions, proxy.clone()), + proxy, + dimensions: options.dimensions, + revision: 0, + } + } + + /// Applies ordered raw PTY bytes and returns protocol responses/events. + pub fn process(&mut self, bytes: &[u8]) -> TerminalUpdate { + if !bytes.is_empty() { + self.parser.advance(&mut self.terminal, bytes); + self.revision = self.revision.saturating_add(1); + } + self.proxy.drain(self.revision) + } + + /// Resizes terminal state. The caller must send the equivalent PTY resize + /// through the runtime actor to keep both sides synchronized. + pub fn resize(&mut self, dimensions: TerminalDimensions) -> bool { + if self.dimensions == dimensions { + return false; + } + self.terminal.resize(dimensions); + self.proxy.set_dimensions(dimensions); + self.dimensions = dimensions; + self.revision = self.revision.saturating_add(1); + true + } + + #[must_use] + pub const fn dimensions(&self) -> TerminalDimensions { + self.dimensions + } + + #[must_use] + pub const fn revision(&self) -> u64 { + self.revision + } + + /// Encodes a key using the terminal's current input modes. + #[must_use] + pub fn encode_key(&self, event: &TerminalKeyEvent) -> Vec { + encode_key(event, *self.terminal.mode()) + } + + /// Encodes paste delimiters only when the child enabled bracketed paste. + #[must_use] + pub fn encode_paste(&self, text: &str) -> Vec { + if self.terminal.mode().contains(TermMode::BRACKETED_PASTE) { + let mut bytes = Vec::with_capacity(text.len() + 12); + bytes.extend_from_slice(b"\x1b[200~"); + bytes.extend_from_slice(text.as_bytes()); + bytes.extend_from_slice(b"\x1b[201~"); + bytes + } else { + text.as_bytes().to_vec() + } + } + + #[must_use] + pub fn snapshot(&self) -> TerminalSnapshot { + let renderable = self.terminal.renderable_content(); + let cursor_point = point_to_viewport(renderable.display_offset, renderable.cursor.point) + .unwrap_or_default(); + let mut cells = vec![ + blank_cell(); + usize::from(self.dimensions.rows) + * usize::from(self.dimensions.columns) + ]; + + for indexed in renderable.display_iter { + let Some(point) = point_to_viewport(renderable.display_offset, indexed.point) else { + continue; + }; + if point.line >= usize::from(self.dimensions.rows) + || point.column.0 >= usize::from(self.dimensions.columns) + { + continue; + } + let index = point.line * usize::from(self.dimensions.columns) + point.column.0; + cells[index] = snapshot_cell(indexed.cell); + } + + TerminalSnapshot { + revision: self.revision, + dimensions: self.dimensions, + cells, + cursor: TerminalCursor { + row: u16::try_from(cursor_point.line).unwrap_or(u16::MAX), + column: u16::try_from(cursor_point.column.0).unwrap_or(u16::MAX), + shape: map_cursor_shape(renderable.cursor.shape), + }, + modes: snapshot_modes(renderable.mode), + title: self.proxy.title(), + } + } +} + +impl Default for TerminalEngine { + fn default() -> Self { + Self::new(TerminalEngineOptions::default()) + } +} + +fn sanitize_title(title: &str) -> String { + title + .chars() + .filter(|character| !character.is_control()) + .scan(0_usize, |bytes, character| { + let next = *bytes + character.len_utf8(); + if next > MAX_TITLE_BYTES { + None + } else { + *bytes = next; + Some(character) + } + }) + .collect() +} + +fn snapshot_cell(cell: &alacritty_terminal::term::cell::Cell) -> TerminalCell { + let mut text = String::new(); + if !cell + .flags + .contains(Flags::WIDE_CHAR_SPACER | Flags::LEADING_WIDE_CHAR_SPACER) + { + text.push(cell.c); + if let Some(zero_width) = cell.zerowidth() { + text.extend(zero_width); + } + } + TerminalCell { + text, + foreground: map_color(cell.fg), + background: map_color(cell.bg), + style: TerminalCellStyle::default() + .with(TerminalCellStyle::BOLD, cell.flags.contains(Flags::BOLD)) + .with(TerminalCellStyle::DIM, cell.flags.contains(Flags::DIM)) + .with( + TerminalCellStyle::ITALIC, + cell.flags.contains(Flags::ITALIC), + ) + .with( + TerminalCellStyle::UNDERLINE, + cell.flags.contains(Flags::UNDERLINE), + ) + .with( + TerminalCellStyle::DOUBLE_UNDERLINE, + cell.flags.contains(Flags::DOUBLE_UNDERLINE), + ) + .with( + TerminalCellStyle::UNDERCURL, + cell.flags.contains(Flags::UNDERCURL), + ) + .with( + TerminalCellStyle::DOTTED_UNDERLINE, + cell.flags.contains(Flags::DOTTED_UNDERLINE), + ) + .with( + TerminalCellStyle::DASHED_UNDERLINE, + cell.flags.contains(Flags::DASHED_UNDERLINE), + ) + .with( + TerminalCellStyle::INVERSE, + cell.flags.contains(Flags::INVERSE), + ) + .with( + TerminalCellStyle::HIDDEN, + cell.flags.contains(Flags::HIDDEN), + ) + .with( + TerminalCellStyle::STRIKEOUT, + cell.flags.contains(Flags::STRIKEOUT), + ), + wide: cell.flags.contains(Flags::WIDE_CHAR), + wide_spacer: cell.flags.contains(Flags::WIDE_CHAR_SPACER), + hyperlink: cell.hyperlink().map(|link| link.uri().to_owned()), + } +} + +fn blank_cell() -> TerminalCell { + snapshot_cell(&alacritty_terminal::term::cell::Cell::default()) +} + +fn snapshot_modes(mode: TermMode) -> TerminalModes { + TerminalModes::default() + .with( + TerminalModes::ALTERNATE_SCREEN, + mode.contains(TermMode::ALT_SCREEN), + ) + .with( + TerminalModes::APPLICATION_CURSOR, + mode.contains(TermMode::APP_CURSOR), + ) + .with( + TerminalModes::APPLICATION_KEYPAD, + mode.contains(TermMode::APP_KEYPAD), + ) + .with( + TerminalModes::BRACKETED_PASTE, + mode.contains(TermMode::BRACKETED_PASTE), + ) + .with( + TerminalModes::MOUSE_REPORTING, + mode.intersects(TermMode::MOUSE_MODE), + ) + .with( + TerminalModes::FOCUS_REPORTING, + mode.contains(TermMode::FOCUS_IN_OUT), + ) + .with( + TerminalModes::KITTY_KEYBOARD, + mode.intersects(TermMode::KITTY_KEYBOARD_PROTOCOL), + ) +} + +const fn map_cursor_shape(shape: CursorShape) -> TerminalCursorShape { + match shape { + CursorShape::Block => TerminalCursorShape::Block, + CursorShape::Underline => TerminalCursorShape::Underline, + CursorShape::Beam => TerminalCursorShape::Beam, + CursorShape::HollowBlock => TerminalCursorShape::HollowBlock, + CursorShape::Hidden => TerminalCursorShape::Hidden, + } +} + +const fn map_color(color: Color) -> TerminalColor { + match color { + Color::Named(named) => TerminalColor::Named(map_named_color(named)), + Color::Indexed(index) => TerminalColor::Indexed(index), + Color::Spec(rgb) => TerminalColor::Rgb { + red: rgb.r, + green: rgb.g, + blue: rgb.b, + }, + } +} + +const fn map_named_color(color: NamedColor) -> TerminalNamedColor { + match color { + NamedColor::Black => TerminalNamedColor::Black, + NamedColor::Red => TerminalNamedColor::Red, + NamedColor::Green => TerminalNamedColor::Green, + NamedColor::Yellow => TerminalNamedColor::Yellow, + NamedColor::Blue => TerminalNamedColor::Blue, + NamedColor::Magenta => TerminalNamedColor::Magenta, + NamedColor::Cyan => TerminalNamedColor::Cyan, + NamedColor::White => TerminalNamedColor::White, + NamedColor::BrightBlack => TerminalNamedColor::BrightBlack, + NamedColor::BrightRed => TerminalNamedColor::BrightRed, + NamedColor::BrightGreen => TerminalNamedColor::BrightGreen, + NamedColor::BrightYellow => TerminalNamedColor::BrightYellow, + NamedColor::BrightBlue => TerminalNamedColor::BrightBlue, + NamedColor::BrightMagenta => TerminalNamedColor::BrightMagenta, + NamedColor::BrightCyan => TerminalNamedColor::BrightCyan, + NamedColor::BrightWhite => TerminalNamedColor::BrightWhite, + NamedColor::Foreground => TerminalNamedColor::Foreground, + NamedColor::Background => TerminalNamedColor::Background, + NamedColor::Cursor => TerminalNamedColor::Cursor, + NamedColor::DimBlack => TerminalNamedColor::DimBlack, + NamedColor::DimRed => TerminalNamedColor::DimRed, + NamedColor::DimGreen => TerminalNamedColor::DimGreen, + NamedColor::DimYellow => TerminalNamedColor::DimYellow, + NamedColor::DimBlue => TerminalNamedColor::DimBlue, + NamedColor::DimMagenta => TerminalNamedColor::DimMagenta, + NamedColor::DimCyan => TerminalNamedColor::DimCyan, + NamedColor::DimWhite => TerminalNamedColor::DimWhite, + NamedColor::BrightForeground => TerminalNamedColor::BrightForeground, + NamedColor::DimForeground => TerminalNamedColor::DimForeground, + } +} + +fn encode_key(event: &TerminalKeyEvent, mode: TermMode) -> Vec { + let modifiers = event.modifiers; + match &event.key { + TerminalKey::Text(text) => encode_text(text, modifiers), + TerminalKey::Enter => with_alt(b"\r".to_vec(), modifiers.contains(KeyModifiers::ALT)), + TerminalKey::Backspace => with_alt(vec![0x7f], modifiers.contains(KeyModifiers::ALT)), + TerminalKey::Tab if modifiers.contains(KeyModifiers::SHIFT) => b"\x1b[Z".to_vec(), + TerminalKey::Tab => with_alt(b"\t".to_vec(), modifiers.contains(KeyModifiers::ALT)), + TerminalKey::Escape => b"\x1b".to_vec(), + TerminalKey::Up => encode_cursor_key('A', modifiers, mode), + TerminalKey::Down => encode_cursor_key('B', modifiers, mode), + TerminalKey::Right => encode_cursor_key('C', modifiers, mode), + TerminalKey::Left => encode_cursor_key('D', modifiers, mode), + TerminalKey::Home => encode_cursor_key('H', modifiers, mode), + TerminalKey::End => encode_cursor_key('F', modifiers, mode), + TerminalKey::Insert => encode_csi_tilde(2, modifiers), + TerminalKey::Delete => encode_csi_tilde(3, modifiers), + TerminalKey::PageUp => encode_csi_tilde(5, modifiers), + TerminalKey::PageDown => encode_csi_tilde(6, modifiers), + TerminalKey::Function(number) => encode_function(*number, modifiers), + } +} + +fn encode_text(text: &str, modifiers: KeyModifiers) -> Vec { + let mut bytes = if modifiers.contains(KeyModifiers::CONTROL) { + control_text(text).unwrap_or_else(|| text.as_bytes().to_vec()) + } else { + text.as_bytes().to_vec() + }; + if modifiers.contains(KeyModifiers::ALT) { + bytes.insert(0, 0x1b); + } + bytes +} + +fn control_text(text: &str) -> Option> { + let mut characters = text.chars(); + let character = characters.next()?; + if characters.next().is_some() || !character.is_ascii() { + return None; + } + let byte = character as u8; + let control = match byte { + b'@'..=b'_' => byte - b'@', + b'a'..=b'z' => byte - b'a' + 1, + b'?' => 0x7f, + b' ' => 0, + _ => return None, + }; + Some(vec![control]) +} + +fn with_alt(mut bytes: Vec, alt: bool) -> Vec { + if alt { + bytes.insert(0, 0x1b); + } + bytes +} + +fn modifier_parameter(modifiers: KeyModifiers) -> u8 { + 1 + u8::from(modifiers.contains(KeyModifiers::SHIFT)) + + 2 * u8::from(modifiers.contains(KeyModifiers::ALT)) + + 4 * u8::from(modifiers.contains(KeyModifiers::CONTROL)) + + 8 * u8::from(modifiers.contains(KeyModifiers::PLATFORM)) +} + +fn encode_cursor_key(final_byte: char, modifiers: KeyModifiers, mode: TermMode) -> Vec { + let parameter = modifier_parameter(modifiers); + if parameter == 1 && mode.contains(TermMode::APP_CURSOR) { + format!("\x1bO{final_byte}").into_bytes() + } else if parameter == 1 { + format!("\x1b[{final_byte}").into_bytes() + } else { + format!("\x1b[1;{parameter}{final_byte}").into_bytes() + } +} + +fn encode_csi_tilde(number: u8, modifiers: KeyModifiers) -> Vec { + let parameter = modifier_parameter(modifiers); + if parameter == 1 { + format!("\x1b[{number}~").into_bytes() + } else { + format!("\x1b[{number};{parameter}~").into_bytes() + } +} + +fn encode_function(number: u8, modifiers: KeyModifiers) -> Vec { + let parameter = modifier_parameter(modifiers); + if let Some(final_byte) = [None, Some('P'), Some('Q'), Some('R'), Some('S')] + .get(usize::from(number)) + .copied() + .flatten() + { + if parameter == 1 { + return format!("\x1bO{final_byte}").into_bytes(); + } + return format!("\x1b[1;{parameter}{final_byte}").into_bytes(); + } + let code = match number { + 5 => 15, + 6 => 17, + 7 => 18, + 8 => 19, + 9 => 20, + 10 => 21, + 11 => 23, + 12 => 24, + _ => return Vec::new(), + }; + encode_csi_tilde(code, modifiers) +} + +#[cfg(test)] +mod tests { + use super::{ + KeyModifiers, TerminalCellStyle, TerminalDimensions, TerminalEngine, TerminalEngineOptions, + TerminalEvent, TerminalKey, TerminalKeyEvent, TerminalModes, TerminalNamedColor, + }; + + fn engine(rows: u16, columns: u16) -> TerminalEngine { + TerminalEngine::new(TerminalEngineOptions { + dimensions: TerminalDimensions::new(rows, columns).unwrap(), + scrollback_lines: 32, + }) + } + + #[test] + fn parses_cells_styles_unicode_cursor_and_title() { + let mut engine = engine(3, 8); + let update = engine.process(b"\x1b]2;safe\x07\x1b[31;1mhi\x1b[0m \xf0\x9f\x91\xa9\r\nnext"); + assert_eq!(update.events, [TerminalEvent::TitleChanged("safe".into())]); + let snapshot = engine.snapshot(); + assert_eq!(snapshot.title.as_deref(), Some("safe")); + let first = snapshot.cell(0, 0).unwrap(); + assert_eq!(first.text, "h"); + assert!(first.style.contains(TerminalCellStyle::BOLD)); + assert_eq!( + first.foreground, + super::TerminalColor::Named(TerminalNamedColor::Red) + ); + assert_eq!(snapshot.cell(0, 3).unwrap().text, "👩"); + assert!(snapshot.cell(0, 3).unwrap().wide); + assert!(snapshot.cell(0, 4).unwrap().wide_spacer); + assert_eq!(snapshot.plain_rows()[1], "next"); + assert_eq!((snapshot.cursor.row, snapshot.cursor.column), (1, 4)); + } + + #[test] + fn tracks_alternate_screen_and_bracketed_paste() { + let mut engine = engine(2, 8); + engine.process(b"primary\x1b[?1049h\x1b[H\x1b[?2004halt"); + let snapshot = engine.snapshot(); + assert!(snapshot.modes.contains(TerminalModes::ALTERNATE_SCREEN)); + assert!(snapshot.modes.contains(TerminalModes::BRACKETED_PASTE)); + assert_eq!(snapshot.plain_rows()[0], "alt"); + assert_eq!(engine.encode_paste("hello"), b"\x1b[200~hello\x1b[201~"); + engine.process(b"\x1b[?1049l"); + assert_eq!(engine.snapshot().plain_rows()[0], "primary"); + } + + #[test] + fn emits_protocol_replies_without_logging_input_content() { + let mut engine = engine(4, 10); + let update = engine.process(b"\x1b[6n\x1b[18t"); + assert!(update.outbound.iter().any(|reply| reply == b"\x1b[1;1R")); + assert!(update.outbound.iter().any(|reply| reply == b"\x1b[8;4;10t")); + assert!(update.events.is_empty()); + } + + #[test] + fn sanitizes_titles_and_blocks_clipboard_protocol() { + let mut engine = engine(2, 8); + let update = engine.process(b"\x1b]2;hello\x01world\x07\x1b]52;c;aGVsbG8=\x07"); + assert_eq!(engine.snapshot().title.as_deref(), Some("helloworld")); + assert!( + update + .events + .contains(&TerminalEvent::TitleChanged("helloworld".into())) + ); + assert!(update.outbound.is_empty()); + } + + #[test] + fn encodes_text_control_cursor_modifiers_and_function_keys() { + let mut engine = engine(2, 8); + let text = TerminalKeyEvent { + key: TerminalKey::Text("c".into()), + modifiers: KeyModifiers::CONTROL, + }; + assert_eq!(engine.encode_key(&text), [3]); + + let up = TerminalKeyEvent { + key: TerminalKey::Up, + modifiers: KeyModifiers::default(), + }; + assert_eq!(engine.encode_key(&up), b"\x1b[A"); + engine.process(b"\x1b[?1h"); + assert_eq!(engine.encode_key(&up), b"\x1bOA"); + + let modified = TerminalKeyEvent { + key: TerminalKey::Left, + modifiers: KeyModifiers::SHIFT.union(KeyModifiers::CONTROL), + }; + assert_eq!(engine.encode_key(&modified), b"\x1b[1;6D"); + + let function = TerminalKeyEvent { + key: TerminalKey::Function(12), + modifiers: KeyModifiers::default(), + }; + assert_eq!(engine.encode_key(&function), b"\x1b[24~"); + } + + #[test] + fn resize_updates_snapshots_and_terminal_size_queries() { + let mut engine = engine(2, 8); + let dimensions = TerminalDimensions::with_cell_size(5, 12, 9, 18).unwrap(); + assert!(engine.resize(dimensions)); + assert!(!engine.resize(dimensions)); + assert_eq!(engine.snapshot().dimensions, dimensions); + let update = engine.process(b"\x1b[14t\x1b[18t"); + assert!( + update + .outbound + .iter() + .any(|reply| reply == b"\x1b[4;90;108t") + ); + assert!(update.outbound.iter().any(|reply| reply == b"\x1b[8;5;12t")); + } + + #[test] + fn rejects_zero_dimensions() { + assert!(TerminalDimensions::new(0, 80).is_err()); + assert!(TerminalDimensions::new(24, 0).is_err()); + } +} diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index b0b7b44..1251a1d 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -41,8 +41,10 @@ messages should be real from the beginning. - `lumbridge`: installable application entry point. The scaffold currently contains `lumbridge-core`, `lumbridge-storage`, -`lumbridge-buzz`, `lumbridge-pty`, `lumbridge-runtime`, and the entry point. -Larger runtime crates are added after their architecture spikes pass. +`lumbridge-buzz`, `lumbridge-pty`, `lumbridge-runtime`, `lumbridge-terminal`, and +the entry point. `lumbridge-core` also contains the first typed workspace +command reducer. Larger runtime crates are added after their architecture spikes +pass. ## Terminal path @@ -55,19 +57,41 @@ scrollback. The terminal engine turns output into immutable render snapshots and bounded deltas for the UI. Scrollback is chunked and persisted separately from the live screen to prevent large agent transcripts from blocking input. +The first `lumbridge-terminal` implementation wraps `alacritty_terminal` behind +a Lumbridge-owned input and immutable snapshot contract. It parses styled cells, +cursor state, alternate screen, terminal modes, title events, keyboard input, +bracketed paste, resize, and terminal-generated protocol replies. OSC 52 +clipboard writes are disabled by default. The renderer never imports the +upstream terminal type, and protocol replies return through the same actor input +queue as human input. See decision 0005. + The first `lumbridge-runtime` actor now owns one `PtySession` on a dedicated thread. Bounded command and event queues serialize input, resize, close, and -shutdown against ordered raw-byte output. The GPUI slice consumes one actor -session while five surfaces retain deterministic comparison output. This actor -still runs in-process; moving the same framework-neutral contract behind local -authenticated IPC is the next durability step. See decision 0004. +shutdown against ordered raw-byte output. The GPUI slice feeds one actor session +through the terminal engine while five surfaces retain deterministic comparison +output. Its current text adapter intentionally renders plain rows and does not +yet paint cell styles, selection, or the cursor; the next rendering slice owns +that work. This actor still runs in-process; moving the same framework-neutral +contract behind local authenticated IPC is the next durability step. See +decisions 0004 and 0005. We should evaluate, not blindly copy, WezTerm, Zellij, RMUX, tmux, and cmux. The first spike must compare a reusable terminal crate with a small first-party layer. -Correctness cases include alternate screen, bracketed paste, OSC 8 links, Kitty +Remaining correctness cases include OSC 8 links, Kitty keyboard/graphics negotiation, Unicode width, IME, mouse modes, shell integration, and simultaneous automation plus human input. +## Workspace command plane + +Human UI, local automation, remote clients, and agents reduce the same typed +workspace commands. Stable request IDs make retries idempotent; validated pane +IDs, split ratios, launch intents, and close dispositions prevent untyped JSON +from becoming the product API. A multi-command setup plan is reduced atomically. +Observe, Configure, and Execute capabilities are checked before mutation, and a +layout-only agent cannot smuggle an executable or arbitrary arguments into a +split request. Current code is an in-process reducer; serialization, durable +events, and authenticated IPC are subsequent layers. See decision 0006. + ## UI decision gate Do not lock the project to a webview or to Zed's application implementation @@ -129,6 +153,19 @@ available because terminal fidelity and arbitrary CLI compatibility are product requirements. Harness-specific adapters translate both paths into the same event model without pretending a PTY has capabilities it cannot prove. +Lumbridge Harness is a separate optional orchestrator, not a UI framework. The +DeepSeek Harness snapshot is a useful MIT-licensed reference for plugin seams, +durable session events, approvals, ACP, and agent lifecycle, but its developer- +preview Node/TypeScript/web composition is not embedded into the Rust desktop +process. If we maintain a fork, it lives in its own repository and communicates +through a versioned, capability-scoped protocol. A first-party Rust service may +later replace that implementation without changing the desktop contract. + +The Harness can consume redacted workspace projections and emit suggestions or +typed command plans. Suggestions have no authority. Plan execution is routed +through the same command plane as human actions, and trace export to a hosted +model requires explicit scope and destination consent. See decision 0007. + ## Usage model Usage is an append-only observation stream, not a mutable percentage field. diff --git a/docs/BRAND.md b/docs/BRAND.md new file mode 100644 index 0000000..fd9f92c --- /dev/null +++ b/docs/BRAND.md @@ -0,0 +1,92 @@ +# Lumbridge brand mark + +## Concept + +Lumbridge's symbol is an original ember-flame wrapped around a bridge arch. The +diagonal negative space also reads as a terminal chevron or an open gateway. +Together, those shapes express a fast native workspace where engineers cross +between terminals, tools, hosts, and agents. + +The mark is symbol-only. Do not ship a Unicode fire emoji as the application +icon, add pseudo-medieval ornament, or attach generated lettering to the mark. + +## Color + +| Role | Hex | Intended surface | +| --- | --- | --- | +| Ember | `#FF6B35` | Canonical application icon and neutral contexts | +| Ember, light UI | `#D94824` | Light surfaces around `#F6F3EE` | +| Ember, dark UI | `#FF8A5B` | Dark surfaces around `#0B0F14` | + +All files have transparent backgrounds. The surface colors above are usage +guidance and are not baked into the assets. Do not add gradients, drop shadows, +outlines, or extra flame colors. + +## Assets + +The 1024 px master is +`assets/brand/master/lumbridge-mark-master-1024.png`. Use it as the source for +new platform exports. + +- `assets/brand/app-icons/lumbridge-app-{size}.png` contains the canonical Ember + icon at 16, 32, 48, 64, 128, 256, 512, and 1024 px. +- `assets/brand/light/lumbridge-mark-light-{size}.png` contains the light-UI + colorway at the same sizes. +- `assets/brand/dark/lumbridge-mark-dark-{size}.png` contains the dark-UI + colorway at the same sizes. + +The existing PNGs are RGBA and square. Packaging may derive platform-native +containers such as macOS `.icns` later, but those derived files should preserve +the supplied canvas and must not stretch or crop the symbol. + +## Placement + +- Preserve the mark's aspect ratio and transparent canvas. +- Outside an application-icon tile, keep clear space equal to at least one + eighth of the rendered mark height on every side. +- Prefer the prepared export nearest the requested display size. Do not scale a + 16 px export upward. +- At 16–24 px, use the canonical app-icon export without a wordmark, badge, or + status dot. The flame and gateway are the intended small-size reading; the + terminal chevron becomes secondary. +- Do not place detailed artwork or low-contrast orange immediately behind the + transparent mark. + +## Generation and production record + +The concept was generated once with the built-in `image_gen` mode using this +prompt: + +> Use case: logo-brand. Asset type: native desktop application icon master for +> Lumbridge, a very high-performance Rust terminal multiplexer and AI-agent +> workspace. Create one original symbol-only brand mark that expresses +> firemaking energy, a bridge or gateway, and a terminal prompt through a single +> strong silhouette. Use a compact upright ember-flame whose interior negative +> space forms a clean bridge arch or open gateway; incorporate one extremely +> subtle angular terminal chevron idea into the geometry without adding a +> separate floating glyph. Use a vector-friendly, flat, minimal geometric mark +> with precise edges, centered on a square transparent canvas. Use warm ember +> orange. Exactly one symbol; no text, letters, wordmark, emoji glyph, gradient, +> shadow, 3D, mockup, border tile, or watermark. Avoid RuneScape imagery or +> style, game trademarks, medieval crests, literal campfires, logs, swords, +> shields, runes, detailed sparks, characters, mascots, and decorative +> flourishes. + +The selected output's geometry was retained. Production exports were then made +deterministically: low-alpha detached pixels were removed, the mark was inset +onto a 1024 px transparent canvas, its generated shading was replaced with the +three exact flat colors above, and Lanczos downscales were produced. No +third-party artwork, typeface, or game asset is included. + +## Originality and release constraints + +This identity deliberately uses only generic fire, bridge, gateway, and terminal +ideas. Do not adapt or add artwork, interfaces, names, symbols, screenshots, or +other assets from RuneScape or another game. + +Generation and internal review are not a trademark search or legal clearance. +Before a public release, perform a similarity search for the symbol and obtain +product-name/trademark review; the original mark does not by itself clear the +name `Lumbridge`. Keep the prompt and this production record with the assets for +provenance, and review the image-generation provider's then-current output terms +before redistribution. diff --git a/docs/DISTRIBUTION.md b/docs/DISTRIBUTION.md index bbe7223..80166ab 100644 --- a/docs/DISTRIBUTION.md +++ b/docs/DISTRIBUTION.md @@ -11,10 +11,16 @@ Initial release artifacts: - Omarchy/Arch x86_64: signed package archive and an AUR recipe that downloads the matching release artifact. +Every package installs the canonical Lumbridge application icon into the native +platform location: the macOS asset catalog/`.icns`, Linux hicolor PNG sizes and +`.desktop` entry, and any package-manager metadata. Derived files come from the +transparent masters in `assets/brand/`; light and dark variants are for product +surfaces, while launchers use the canonical app icon unless a platform has a +documented adaptive-icon contract. + Each release includes SHA-256 checksums, a signed update manifest, SBOM, license notices, and the exact source commit. Reproducibility is a goal, but a release is not called reproducible until two clean builders produce matching artifacts. The updater must verify signatures before replacing binaries, retain the prior version for rollback, and never update a running session runtime in place. - diff --git a/docs/PRODUCT_SPEC.md b/docs/PRODUCT_SPEC.md index c479495..ce625a5 100644 --- a/docs/PRODUCT_SPEC.md +++ b/docs/PRODUCT_SPEC.md @@ -25,6 +25,10 @@ The product should feel faster and calmer as concurrency rises. user-owned machine reached through SSH or Tailscale. 9. Follow a project's Buzz channel and intentionally share a redacted pane image without leaving the workspace. +10. Inspect terminal, browser, tools, context, goal, and review views without + losing the pane's process identity or execution target. +11. Ask a local or selected-provider analyst for a small set of next actions, + then choose, edit, dismiss, or explicitly authorize one. ## Local and remote workspaces @@ -54,6 +58,39 @@ devices. An arbitrary command remains a supported harness through the generic PTY adapter. +## Pane surfaces and decision shelf + +A pane is the durable unit of work; its surface is a view over that work. The +first surface set is Terminal, Browser, Tools, Context, Goal, and Review. A +surface change never silently launches a process, moves the pane to another +host, or changes which agent owns the session. Unsupported surfaces are shown as +unavailable rather than simulated. + +An optional decision shelf sits below the active work surface. It may show an +answer draft, two or three concrete choices, why each was suggested, and the +capability each choice would need. Suggestions are inert data. Choosing one may +prepare a typed workspace plan, but any command, file mutation, credential use, +or external message still passes through the normal approval and command plane. + +## Lumbridge Harness + +Lumbridge Harness is an optional orchestrator distributed as a separately +versioned component. It can analyze explicitly shared workspace state, refine +prompts, recommend next steps, and coordinate supported agents. It does not own +the desktop shell and is not required for terminal multiplexing. + +Its model boundary is provider-neutral. Initial development targets an +OpenAI-compatible API so the same contract can use a local Spark/Qwen endpoint, +Cerebras, or another user-selected provider. Credentials stay in the OS +credential store and are resolved by opaque handle. Endpoint profiles must not +embed secrets in workspace layouts, command arguments, or traces. + +Trace analysis is off until the user enables it for a workspace and selects the +fields or sessions to share. Local analysis remains local. Sending trace data to +a hosted provider requires a destination preview and a separate consent. The +Harness receives only the Observe, Configure, or Execute capability granted for +that run; autopilot cannot manufacture a broader grant. + ## Provider modes Subscription mode delegates authentication to the installed upstream harness. @@ -95,6 +132,7 @@ in the operating-system credential store. - A new foundation-model training or inference service. - A hosted account or mandatory Lumbridge cloud. - Replacing every coding harness with one Lumbridge-owned agent loop. +- Making Lumbridge Harness, trace analysis, or autopilot mandatory. - Windows support. - Mobile control or collaborative hosted sessions. - Arbitrary third-party remote compute provisioning; the first release connects diff --git a/docs/RESEARCH.md b/docs/RESEARCH.md index e8af2af..2b70db5 100644 --- a/docs/RESEARCH.md +++ b/docs/RESEARCH.md @@ -48,6 +48,16 @@ They are shallow snapshots for study, not dependencies or vendored source. - `openclaw/openclaw` - `anomalyco/opencode` +DeepSeek Harness at the captured revision is MIT-licensed experimental software, +but it is a large Node/TypeScript workspace with a React web client, Cordis +plugin tree, native/platform payloads, and a broad third-party closure. Its own +safety notice says it is unaudited and can access processes, files, credentials, +and the network exposed to it. We will study its service seams, durable event +log, approval flow, ACP profile, and agent lifecycle. We will not embed its web +shell into Lumbridge or treat its sandbox as a security boundary. Any branded +fork is a separate repository/process with preserved notices and an explicit +dependency and payload review. + ## Research questions 1. Which terminal core gives us correctness without inheriting a product-shaped @@ -60,4 +70,3 @@ They are shallow snapshots for study, not dependencies or vendored source. must remain measured or unavailable? 6. Can one event model cover PTY, ACP, Git, usage, permissions, and recovery without turning into untyped JSON everywhere? - diff --git a/docs/RESEARCH_SNAPSHOTS.md b/docs/RESEARCH_SNAPSHOTS.md index 9c1f5a6..958e71e 100644 --- a/docs/RESEARCH_SNAPSHOTS.md +++ b/docs/RESEARCH_SNAPSHOTS.md @@ -39,5 +39,9 @@ only when a question genuinely requires upstream history. crate before adapting anything. - The captured BBARIT Terminal root did not contain a top-level license file. Treat its implementation as unlicensed unless upstream clarifies otherwise. +- DeepSeek Harness is MIT at the captured root, but it is an unaudited + developer preview with Node/TypeScript, React, native payloads, and packages + carrying their own terms. Preserve its license/notices and review the complete + shipped dependency closure before maintaining or distributing a fork. - Every other source still requires a file-level and dependency-level review before reuse; a top-level license filename is not sufficient clearance. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 705ea55..fb1a914 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -12,6 +12,8 @@ - Prove Buzz SDK message, attachment, cursor, reconnect, and duplicate-delivery behavior against a disposable local relay. - Decide terminal core, UI stack, IPC transport, and schema evolution policy. +- Define the Lumbridge Harness process boundary, trace-consent model, provider- + neutral endpoint profile, and upstream-fork maintenance policy. Exit: recorded decisions with working spikes and measured results. @@ -21,6 +23,8 @@ Exit: recorded decisions with working spikes and measured results. - Saved SSH/Tailscale hosts and durable remote panes through a per-user remote runtime; reconnect from a second Lumbridge installation. - Session restore, crash recovery, command palette, keybindings, notifications. +- Per-pane Terminal, Browser, Tools, Context, Goal, and Review surface tabs, plus + an inert decision shelf that can render typed suggestions without executing. - Repository/worktree creation and basic Git status/diff. - Optional Buzz collaboration pane, workspace channel binding, and confirmed redacted pane-image sharing. @@ -34,6 +38,9 @@ Exit: Lumbridge is worth using as a terminal multiplexer without AI features. - ACP client with capability negotiation and permission rendering. - Codex, Claude Code, DeepSeek Harness, Pi, and Hermes adapters. - Agent status, unread/needs-input state, resume, and transcript navigation. +- Separately versioned Lumbridge Harness with local/self-hosted OpenAI-compatible + model support, prompt refinement, trace projections, and capability-gated + workspace plans. Exit: daily multi-agent work is reliable and observable. diff --git a/docs/TESTING.md b/docs/TESTING.md index 048aca4..7db0103 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -111,9 +111,16 @@ who already have the final cargo-watch release installed. dimensions, and exclusion of provider credentials from the child environment. - `lumbridge-runtime` tests ordered actor output, serialized input and resize, event polling, invalid configuration, and bounded-time cleanup of a hung PTY. -- The GPUI slice tests byte line-framing across CRLF, chunk boundaries, split - UTF-8, and invalid bytes. It renders one real actor-owned PTY and keeps five - surfaces deterministic; line framing is explicitly not VT emulation. + A cross-crate integration test drives a real synthetic shell through actor + output, VT parsing, terminal key encoding, and a 41×101 resize. +- `lumbridge-terminal` fixtures cover styled Unicode, cursor/title state, + alternate screen, bracketed paste, protocol replies, sanitized title and + blocked OSC 52 behavior, key encoding, application-cursor mode, and resize. +- `lumbridge-core` tests capability-gated split/select/rename/close commands, + idempotent request IDs, close-tree promotion, and atomic agentic setup plans. +- The GPUI slice tests its key-event adapter. It renders one real actor-owned VT + session as plain snapshot rows and keeps five surfaces deterministic; styled + cell/cursor rendering remains a separate gate. - The current-GPUI probe compile-checks real AccessKit element wiring and real platform input-handler installation. Unit tests cover its semantic tree and UTF-16/UTF-8 composed-text mutations. OS screen readers, IME candidate windows, diff --git a/docs/UI_SPIKE_SCORECARD.md b/docs/UI_SPIKE_SCORECARD.md index a883b7c..6cc9020 100644 --- a/docs/UI_SPIKE_SCORECARD.md +++ b/docs/UI_SPIKE_SCORECARD.md @@ -21,9 +21,11 @@ from macOS and Linux and the hard gates pass. | Native menu/window/clipboard/drag-and-drop | review | pending | pending | | API clarity and maintenance burden | review | pending | pending | -The current programs establish dependency, build, launch, and static layout -baselines. The next iteration adds deterministic streaming, input timestamps, -accessibility identifiers, a native Markdown editor, and one Wry browser child. +The current programs establish dependency, build, launch, and interaction +baselines. GPUI now routes a real PTY through a VT engine and keyboard encoder; +its renderer still flattens the immutable screen snapshot to plain rows. The +next iteration adds styled cells/cursor/selection, measured pane-driven resize, +a native Markdown editor, and one isolated browser child. ## Ubuntu baseline — metal, 2026-08-31 @@ -85,7 +87,7 @@ fallback. Both renderers retain the same all-deterministic six-surface action stream for comparison. The GPUI integration mode replaces one terminal fixture with a real -actor-owned PTY and leaves five deterministic surfaces running. Counters +actor-owned VT session and leaves five deterministic surfaces running. Counters separate external PTY batches/lines from total model updates. The GPUI footer reports dispatch-to-element-build p50/p95 over a bounded 256-sample window. It is deliberately not called key-to-present or frame-present latency: neither diff --git a/docs/UX_VERTICAL_SLICE.md b/docs/UX_VERTICAL_SLICE.md index 5ec6976..36154ef 100644 --- a/docs/UX_VERTICAL_SLICE.md +++ b/docs/UX_VERTICAL_SLICE.md @@ -67,11 +67,18 @@ surface rather than a hosted Lumbridge control plane. in a stable order. 6. The footer groups connection state, selected-harness identity, usage-window provenance, and burn forecast into readable regions. +7. The selected pane has a quiet surface strip for Terminal, Browser, Tools, + Context, Goal, and Review. Switching surfaces keeps one pane identity. +8. A compact decision shelf may show local-analyst choices below the work + surface. It labels its model/provider, trace scope, and whether suggestions + are inert; no choice is visually conflated with an approved action. ## Keyboard task flow -- Arrow keys or `h/j/k/l`: move focus through the 2×3 pane grid. -- `1` through `6`: focus a pane directly. +- `Alt+Arrow` or `Alt+h/j/k/l`: move focus through the 2×3 pane grid while + leaving ordinary terminal arrows and text available to the PTY. +- `Alt+1` through `Alt+6`: focus a pane directly while leaving terminal digits + available to the PTY. - `Cmd+K` on macOS or `Ctrl+K` on Linux: open the command palette. - Typing while the palette is open changes its query; arrows change the result; `Enter` runs it; `Escape` closes it and restores pane focus. diff --git a/docs/decisions/0004-runtime-actor-owns-each-pty.md b/docs/decisions/0004-runtime-actor-owns-each-pty.md index 72dad20..2b80c7b 100644 --- a/docs/decisions/0004-runtime-actor-owns-each-pty.md +++ b/docs/decisions/0004-runtime-actor-owns-each-pty.md @@ -16,9 +16,10 @@ arrives. Process-local session IDs are correlation IDs only; durable IDs are assigned by the persisted runtime protocol later. Runtime events contain ordered raw PTY bytes. The UI spike may line-frame plain -fixture output for display, but ANSI/VT parsing, screen state, cursor behavior, -scrollback, and terminal input modes belong to `lumbridge-terminal`. The UI must -not infer terminal semantics from raw strings. +fixture output for deterministic surfaces, but the live pane sends bytes through +`lumbridge-terminal`. ANSI/VT parsing, screen state, cursor behavior, scrollback, +and terminal input modes never belong to the runtime actor or UI. The UI must not +infer terminal semantics from raw strings. Dropping the UI-side actor disconnects its bounded channels, releases an actor blocked by event backpressure, terminates the process group through diff --git a/docs/decisions/0005-terminal-engine-boundary.md b/docs/decisions/0005-terminal-engine-boundary.md new file mode 100644 index 0000000..58d862c --- /dev/null +++ b/docs/decisions/0005-terminal-engine-boundary.md @@ -0,0 +1,24 @@ +# 0005: Terminal semantics stay behind a Lumbridge-owned contract + +Status: accepted for the first terminal slice. + +Lumbridge uses `alacritty_terminal` with default features disabled as its first +VT state engine. The dependency is mature enough to cover substantially more +terminal behavior than a new parser, but its types do not cross into runtime, +storage, IPC, or UI APIs. + +`lumbridge-terminal` accepts ordered raw PTY bytes and exposes immutable +Lumbridge snapshots containing cells, styles, colors, cursor, terminal modes, +and sanitized title state. It owns terminal key and paste encoding. Protocol +replies such as device-status responses return as bytes and enter the same +bounded actor queue as all other PTY input, preserving ordering. + +Clipboard writes such as OSC 52 are disabled by default. Transcript-bearing +snapshots deliberately omit `Debug`, and terminal titles are bounded and stripped +of controls. A renderer may derive plain rows for a spike, but that is not the +terminal model and must not become the persistence or automation contract. + +Adopting this engine is reversible: conformance fixtures target the Lumbridge +contract, and no upstream application code is copied into this repository. +Kitty keyboard/graphics behavior, OSC 8 links, mouse modes, IME, selection, and +platform rendering remain explicit qualification work. diff --git a/docs/decisions/0006-workspace-command-plane.md b/docs/decisions/0006-workspace-command-plane.md new file mode 100644 index 0000000..865f9c2 --- /dev/null +++ b/docs/decisions/0006-workspace-command-plane.md @@ -0,0 +1,20 @@ +# 0006: Every workspace controller uses one typed command plane + +Status: accepted for implementation. + +Human UI, CLI automation, remote clients, and agents submit the same typed +workspace commands. Stable request IDs make retries idempotent. Pane IDs, split +ratios, surfaces, launch intents, and close dispositions are validated before +state changes, and a multi-command setup plan is applied atomically. Reusing an +ID with a different origin or command is a conflict, not a silent duplicate. + +Each request has an origin and an explicit Observe, Configure, or Execute grant. +The command declares the minimum capability it needs. Creating or terminating a +process requires Execute; layout-only changes require Configure. Launch intents +refer to a user shell or an approved harness profile and working directory, not +arbitrary executable arguments or secret values. + +This reducer is not an authorization bypass. The future IPC layer authenticates +the caller and supplies its granted capability; the reducer rechecks it before +mutation. Durable audit events record request and object identities, never +terminal input, transcript content, provider keys, or pane titles by default. diff --git a/docs/decisions/0007-optional-lumbridge-harness.md b/docs/decisions/0007-optional-lumbridge-harness.md new file mode 100644 index 0000000..1626c80 --- /dev/null +++ b/docs/decisions/0007-optional-lumbridge-harness.md @@ -0,0 +1,27 @@ +# 0007: Lumbridge Harness is optional, separate, and capability-scoped + +Status: accepted for architecture; implementation and fork policy pending. + +Lumbridge may distribute a separately versioned Lumbridge Harness for prompt +refinement, trace analysis, recommendations, and agent coordination. The native +Rust terminal workspace remains complete without it, and the Harness does not +run inside the UI process. + +The captured DeepSeek Harness is an MIT-licensed and architecturally useful +reference, but it is also an unaudited Node/TypeScript developer preview with a +web client and broad native dependency closure. A maintained fork, if selected, +lives in its own repository/process, preserves required notices, and exposes a +small versioned protocol. Its React UI is not embedded in Lumbridge. We can later +replace the implementation with a first-party Rust service without changing the +desktop contract. + +Model access is provider-neutral and begins with OpenAI-compatible endpoints so +development can use a self-hosted Spark/Qwen model or a user-selected service +such as Cerebras. Endpoint credentials are opaque secret-store handles. + +Trace analysis is opt-in per workspace. The user chooses the trace projection +and destination; local processing stays local, while hosted processing requires +an explicit preview and consent. Suggestions and decision-shelf choices carry no +authority. Any setup, launch, mutation, or autopilot action becomes a typed +workspace plan and can use only the Observe, Configure, or Execute capability +granted to that run. diff --git a/spikes/README.md b/spikes/README.md index be20dfe..94909b1 100644 --- a/spikes/README.md +++ b/spikes/README.md @@ -21,7 +21,10 @@ Both spikes must preserve the same information architecture: GPUI also has an integration mode with one real local PTY owned by `lumbridge-runtime`; the other five surfaces remain deterministic. Floem and the shared model retain the all-deterministic mode for like-for-like framework -comparison. The PTY display is plain byte line-framing, not terminal emulation. +comparison. GPUI feeds raw output through `lumbridge-terminal` and sends encoded +keyboard input and terminal protocol replies through the bounded runtime actor. +Its visual adapter currently flattens the VT snapshot to plain rows, so styled +cells, selection, and cursor painting remain intentionally unfinished. Build independently: diff --git a/spikes/gpui-shell/Cargo.lock b/spikes/gpui-shell/Cargo.lock index 9917d34..ccf07d7 100644 --- a/spikes/gpui-shell/Cargo.lock +++ b/spikes/gpui-shell/Cargo.lock @@ -42,6 +42,30 @@ dependencies = [ "memchr", ] +[[package]] +name = "alacritty_terminal" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda177466b9524d59f1b12f0dd30b68696788e9992a7e959021c4a0ed96fcf59" +dependencies = [ + "base64", + "bitflags 2.13.1", + "home", + "libc", + "log", + "miow", + "parking_lot", + "piper", + "polling", + "regex-automata", + "rustix 1.1.4", + "rustix-openpty", + "signal-hook", + "unicode-width", + "vte", + "windows-sys 0.59.0", +] + [[package]] name = "aligned" version = "0.4.3" @@ -1252,6 +1276,12 @@ version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" +[[package]] +name = "cursor-icon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" + [[package]] name = "data-url" version = "0.3.2" @@ -3007,12 +3037,21 @@ dependencies = [ "gpui", "lumbridge-runtime", "lumbridge-spike-model", + "lumbridge-terminal", ] [[package]] name = "lumbridge-spike-model" version = "0.0.1" +[[package]] +name = "lumbridge-terminal" +version = "0.0.1" +dependencies = [ + "alacritty_terminal", + "thiserror 2.0.20", +] + [[package]] name = "lyon" version = "1.0.19" @@ -3198,6 +3237,15 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "miow" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "536bfad37a309d62069485248eeaba1e8d9853aaf951caaeaed0585a95346f08" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "moxcms" version = "0.8.1" @@ -4499,6 +4547,17 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustix-openpty" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de16c7c59892b870a6336f185dc10943517f1327447096bbb7bb32cd85e2393" +dependencies = [ + "errno", + "libc", + "rustix 1.1.4", +] + [[package]] name = "rustls" version = "0.23.43" @@ -4907,6 +4966,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" +[[package]] +name = "signal-hook" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a0c28ca5908dbdbcd52e6fdaa00358ab88637f8ab33e1f188dd510eb44b53d" +dependencies = [ + "libc", + "signal-hook-registry", +] + [[package]] name = "signal-hook-registry" version = "1.4.8" @@ -5985,6 +6054,19 @@ dependencies = [ "libc", ] +[[package]] +name = "vte" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5924018406ce0063cd67f8e008104968b74b563ee1b85dde3ed1f7cb87d3dbd" +dependencies = [ + "arrayvec", + "bitflags 2.13.1", + "cursor-icon", + "log", + "memchr", +] + [[package]] name = "waker-fn" version = "1.2.0" diff --git a/spikes/gpui-shell/Cargo.toml b/spikes/gpui-shell/Cargo.toml index c6cd72e..a529d11 100644 --- a/spikes/gpui-shell/Cargo.toml +++ b/spikes/gpui-shell/Cargo.toml @@ -11,5 +11,6 @@ publish = false gpui = "0.2.2" lumbridge-runtime = { path = "../../crates/lumbridge-runtime" } lumbridge-spike-model = { path = "../ui-shell-model" } +lumbridge-terminal = { path = "../../crates/lumbridge-terminal" } [workspace] diff --git a/spikes/gpui-shell/src/main.rs b/spikes/gpui-shell/src/main.rs index 818e3ba..9cbc4a0 100644 --- a/spikes/gpui-shell/src/main.rs +++ b/spikes/gpui-shell/src/main.rs @@ -6,12 +6,17 @@ use gpui::{ WindowOptions, actions, div, prelude::*, px, rgb, size, }; use lumbridge_runtime::{ - CommandConfig, PtyOptions, RuntimeActor, RuntimeActorError, RuntimeActorOptions, RuntimeEvent, + CommandConfig, PtyOptions, RuntimeActor, RuntimeActorError, RuntimeActorOptions, + RuntimeCommand, RuntimeEvent, TerminalSize, }; use lumbridge_spike_model::{ ActionOutcome, FOOTER_RIGHT, FocusDirection, OutputSource, PaneId, PaneState, ShellAction, ShellModel, SurfaceKind, WORKSPACES, }; +use lumbridge_terminal::{ + KeyModifiers, TerminalDimensions, TerminalEngine, TerminalEngineOptions, TerminalKey, + TerminalKeyEvent, +}; const BG: u32 = 0x090c12; const PANEL: u32 = 0x101620; @@ -28,7 +33,9 @@ const TIMING_SAMPLE_LIMIT: usize = 256; const RUNTIME_POLL_INTERVAL: Duration = Duration::from_millis(16); const RUNTIME_DRAIN_LIMIT: usize = 64; const LIVE_PANE: PaneId = PaneId::CodexRuntime; -const LIVE_PTY_SCRIPT: &str = "i=0; printf 'Lumbridge runtime actor owns this PTY\\n'; while :; do printf '[pty %06d] /bin/sh · actor output\\n' \"$i\"; i=$((i+1)); sleep 1; done"; +const LIVE_PTY_SCRIPT: &str = "printf 'Lumbridge interactive PTY · type here\\n'; exec /bin/sh -i"; +const TERMINAL_ROW_STEP: u16 = 2; +const TERMINAL_COLUMN_STEP: u16 = 10; actions!( lumbridge, @@ -45,6 +52,10 @@ actions!( SelectPane4, SelectPane5, SelectPane6, + TerminalTaller, + TerminalShorter, + TerminalWider, + TerminalNarrower, ] ); @@ -53,7 +64,7 @@ struct LumbridgeShell { timing: RenderTiming, runtime: Option, runtime_status: LiveRuntimeStatus, - runtime_lines: PtyLineFramer, + terminal: TerminalEngine, last_runtime_sequence: u64, root_focus: FocusHandle, pane_focus: [FocusHandle; 6], @@ -106,38 +117,6 @@ impl LiveRuntimeStatus { } } -#[derive(Default)] -struct PtyLineFramer { - pending: Vec, -} - -impl PtyLineFramer { - fn push(&mut self, bytes: &[u8]) -> Vec { - self.pending.extend_from_slice(bytes); - let mut lines = Vec::new(); - while let Some(newline) = self.pending.iter().position(|byte| *byte == b'\n') { - let mut line = self.pending.drain(..=newline).collect::>(); - line.pop(); - if line.last() == Some(&b'\r') { - line.pop(); - } - lines.push(String::from_utf8_lossy(&line).into_owned()); - } - lines - } - - fn finish(&mut self) -> Vec { - if self.pending.is_empty() { - return Vec::new(); - } - let mut line = std::mem::take(&mut self.pending); - if line.last() == Some(&b'\r') { - line.pop(); - } - vec![String::from_utf8_lossy(&line).into_owned()] - } -} - #[derive(Default)] struct RenderTiming { pending_dispatch: Option, @@ -228,7 +207,8 @@ impl LumbridgeShell { }) .detach(); - let (runtime, runtime_status) = match start_live_runtime() { + let terminal = TerminalEngine::new(TerminalEngineOptions::default()); + let (runtime, runtime_status) = match start_live_runtime(terminal.dimensions()) { Ok(runtime) => (Some(runtime), LiveRuntimeStatus::Starting), Err(error) => (None, LiveRuntimeStatus::Fault(error.to_string())), }; @@ -239,7 +219,7 @@ impl LumbridgeShell { timing: RenderTiming::default(), runtime, runtime_status, - runtime_lines: PtyLineFramer::default(), + terminal, last_runtime_sequence: 0, root_focus, pane_focus, @@ -296,24 +276,20 @@ impl LumbridgeShell { break; } self.last_runtime_sequence = sequence; - let lines = self.runtime_lines.push(&bytes); - if !lines.is_empty() { - self.dispatch(ShellAction::AppendExternalOutput { - pane: LIVE_PANE, - lines, - }); - changed = true; + let update = self.terminal.process(&bytes); + for response in update.outbound { + if let Err(error) = + self.send_runtime_command(RuntimeCommand::Input(response)) + { + self.runtime_status = LiveRuntimeStatus::Fault(error.to_string()); + return true; + } } + self.publish_terminal_snapshot(); + changed = true; } RuntimeEvent::InputClosed { .. } => {} RuntimeEvent::Exited { status, .. } => { - let lines = self.runtime_lines.finish(); - if !lines.is_empty() { - self.dispatch(ShellAction::AppendExternalOutput { - pane: LIVE_PANE, - lines, - }); - } self.runtime_status = LiveRuntimeStatus::Exited(format!("PTY exited with code {}", status.code)); changed = true; @@ -332,6 +308,36 @@ impl LumbridgeShell { changed } + fn send_runtime_command(&self, command: RuntimeCommand) -> Result<(), RuntimeActorError> { + self.runtime + .as_ref() + .ok_or(RuntimeActorError::Disconnected)? + .try_send(command) + } + + fn publish_terminal_snapshot(&mut self) { + let lines = self.terminal.snapshot().plain_rows(); + self.dispatch(ShellAction::ReplaceExternalOutput { + pane: LIVE_PANE, + lines, + }); + } + + fn resize_terminal(&mut self, rows: u16, columns: u16, cx: &mut Context) { + let dimensions = TerminalDimensions::new(rows, columns) + .expect("resize actions always retain non-zero dimensions"); + if !self.terminal.resize(dimensions) { + return; + } + let pty_size = TerminalSize::new(rows, columns) + .expect("terminal engine dimensions are valid PTY dimensions"); + if let Err(error) = self.send_runtime_command(RuntimeCommand::Resize(pty_size)) { + self.runtime_status = LiveRuntimeStatus::Fault(error.to_string()); + } + self.publish_terminal_snapshot(); + cx.notify(); + } + fn select_pane(&mut self, pane: PaneId, window: &mut Window, cx: &mut Context) { self.dispatch(ShellAction::SelectPane(pane)); window.focus(&self.pane_focus[pane.index()]); @@ -375,8 +381,66 @@ impl LumbridgeShell { cx.notify(); } + fn terminal_taller(&mut self, _: &TerminalTaller, _: &mut Window, cx: &mut Context) { + let dimensions = self.terminal.dimensions(); + self.resize_terminal( + dimensions.rows().saturating_add(TERMINAL_ROW_STEP), + dimensions.columns(), + cx, + ); + } + + fn terminal_shorter(&mut self, _: &TerminalShorter, _: &mut Window, cx: &mut Context) { + let dimensions = self.terminal.dimensions(); + self.resize_terminal( + dimensions.rows().saturating_sub(TERMINAL_ROW_STEP).max(2), + dimensions.columns(), + cx, + ); + } + + fn terminal_wider(&mut self, _: &TerminalWider, _: &mut Window, cx: &mut Context) { + let dimensions = self.terminal.dimensions(); + self.resize_terminal( + dimensions.rows(), + dimensions.columns().saturating_add(TERMINAL_COLUMN_STEP), + cx, + ); + } + + fn terminal_narrower(&mut self, _: &TerminalNarrower, _: &mut Window, cx: &mut Context) { + let dimensions = self.terminal.dimensions(); + self.resize_terminal( + dimensions.rows(), + dimensions + .columns() + .saturating_sub(TERMINAL_COLUMN_STEP) + .max(20), + cx, + ); + } + fn on_key_down(&mut self, event: &KeyDownEvent, _window: &mut Window, cx: &mut Context) { if !self.model.command_palette().is_open() { + if self.model.selected_pane() != LIVE_PANE || self.runtime_status.is_terminal() { + return; + } + let modifiers = key_modifiers(event); + let Some(event) = terminal_key_from_parts( + event.keystroke.key.as_str(), + event.keystroke.key_char.as_deref(), + modifiers, + ) else { + return; + }; + let bytes = self.terminal.encode_key(&event); + if bytes.is_empty() { + return; + } + if let Err(error) = self.send_runtime_command(RuntimeCommand::Input(bytes)) { + self.runtime_status = LiveRuntimeStatus::Fault(error.to_string()); + } + cx.notify(); return; } @@ -390,6 +454,11 @@ impl LumbridgeShell { cx.notify(); return; } + "escape" => { + self.dispatch(ShellAction::CloseCommandPalette); + cx.notify(); + return; + } _ => { if let Some(character) = event.keystroke.key_char.as_deref() && !event.keystroke.modifiers.control @@ -409,6 +478,7 @@ impl LumbridgeShell { pane: &PaneState, selected: bool, runtime_status: LiveRuntimeStatus, + terminal_dimensions: TerminalDimensions, focus: FocusHandle, cx: &mut Context, ) -> gpui::AnyElement { @@ -478,7 +548,7 @@ impl LumbridgeShell { .child(format!("{}", id.index() + 1)), ) .child(if external { - "Shell · runtime actor" + "Shell · VT session" } else { pane.fixture().title }), @@ -495,16 +565,45 @@ impl LumbridgeShell { .text_xs() .text_color(rgb(MUTED)) .child(if external { - runtime_status.detail() + format!( + "{} · {}×{} · Alt+Shift+arrows resize", + runtime_status.detail(), + terminal_dimensions.columns(), + terminal_dimensions.rows() + ) } else { pane.fixture().target.to_owned() }) .when(selected, |view| view.child("FOCUSED")), ) + .when(external && selected, |view| { + view.child( + div() + .flex() + .items_center() + .gap_3() + .h(px(26.0)) + .flex_none() + .px_3() + .border_y_1() + .border_color(rgb(BORDER_QUIET)) + .bg(rgb(PANEL_ALT)) + .text_xs() + .child(div().text_color(rgb(ACCENT)).child("TERMINAL")) + .child(div().text_color(rgb(MUTED)).child("BROWSER")) + .child(div().text_color(rgb(MUTED)).child("TOOLS")) + .child(div().text_color(rgb(MUTED)).child("CONTEXT")) + .child(div().text_color(rgb(MUTED)).child("GOAL")) + .child(div().text_color(rgb(MUTED)).child("REVIEW")), + ) + }) .child( div() .flex() .flex_col() + .flex_1() + .min_h_0() + .overflow_hidden() .gap_1() .px_3() .pb_3() @@ -512,6 +611,36 @@ impl LumbridgeShell { .text_color(rgb(TEXT)) .children(pane.lines()[line_start..].iter().cloned()), ) + .when(external && selected, |view| { + view.child( + div() + .flex() + .items_center() + .justify_between() + .gap_2() + .h(px(38.0)) + .flex_none() + .px_3() + .border_t_1() + .border_color(rgb(BORDER_QUIET)) + .bg(rgb(PANEL_ALT)) + .text_xs() + .child( + div() + .text_color(rgb(MUTED)) + .child("LOCAL ANALYST · OFF · suggestions only"), + ) + .child( + div() + .flex() + .gap_2() + .text_color(rgb(TEXT)) + .child("Continue") + .child("Review plan") + .child("Ask…"), + ), + ) + }) .into_any_element() } @@ -767,7 +896,7 @@ impl Render for LumbridgeShell { .px_3() .text_xs() .text_color(rgb(MUTED)) - .child("1 live PTY · 5 deterministic · 1 waiting"), + .child("1 interactive VT · 5 deterministic · 1 waiting"), ); let pane_cards = self @@ -779,6 +908,7 @@ impl Render for LumbridgeShell { pane, self.model.selected_pane() == pane.id(), self.runtime_status.clone(), + self.terminal.dimensions(), self.pane_focus[pane.id().index()].clone(), cx, ) @@ -795,11 +925,11 @@ impl Render for LumbridgeShell { let counters = self.model.counters(); let footer_left = format!( - "rev {} · {} focus · {} external batches · {} PTY lines · {} total lines", + "rev {} · VT rev {} · {} focus · {} VT snapshots · {} synthetic lines", self.model.revision(), + self.terminal.revision(), counters.focus_moves, - counters.external_output_batches, - counters.external_lines_appended, + counters.external_snapshot_updates, counters.terminal_lines_appended ); let timing = self.timing.summary(); @@ -815,6 +945,10 @@ impl Render for LumbridgeShell { .on_action(cx.listener(Self::focus_down)) .on_action(cx.listener(Self::open_palette)) .on_action(cx.listener(Self::close_palette)) + .on_action(cx.listener(Self::terminal_taller)) + .on_action(cx.listener(Self::terminal_shorter)) + .on_action(cx.listener(Self::terminal_wider)) + .on_action(cx.listener(Self::terminal_narrower)) .on_action(cx.listener(|shell, _: &SelectPane1, window, cx| { shell.select_pane(PaneId::CodexRuntime, window, cx); })) @@ -908,13 +1042,62 @@ impl Render for LumbridgeShell { } } -fn start_live_runtime() -> Result { +fn key_modifiers(event: &KeyDownEvent) -> KeyModifiers { + let mut modifiers = KeyModifiers::default(); + if event.keystroke.modifiers.shift { + modifiers = modifiers.union(KeyModifiers::SHIFT); + } + if event.keystroke.modifiers.alt { + modifiers = modifiers.union(KeyModifiers::ALT); + } + if event.keystroke.modifiers.control { + modifiers = modifiers.union(KeyModifiers::CONTROL); + } + if event.keystroke.modifiers.platform { + modifiers = modifiers.union(KeyModifiers::PLATFORM); + } + modifiers +} + +fn terminal_key_from_parts( + key: &str, + key_char: Option<&str>, + modifiers: KeyModifiers, +) -> Option { + let key = match key { + "enter" => TerminalKey::Enter, + "backspace" => TerminalKey::Backspace, + "tab" => TerminalKey::Tab, + "escape" => TerminalKey::Escape, + "up" => TerminalKey::Up, + "down" => TerminalKey::Down, + "left" => TerminalKey::Left, + "right" => TerminalKey::Right, + "home" => TerminalKey::Home, + "end" => TerminalKey::End, + "insert" => TerminalKey::Insert, + "delete" => TerminalKey::Delete, + "pageup" => TerminalKey::PageUp, + "pagedown" => TerminalKey::PageDown, + function if function.starts_with('f') => { + let number = function.strip_prefix('f')?.parse::().ok()?; + TerminalKey::Function(number) + } + _ if !modifiers.contains(KeyModifiers::PLATFORM) => TerminalKey::Text(key_char?.to_owned()), + _ => return None, + }; + Some(TerminalKeyEvent { key, modifiers }) +} + +fn start_live_runtime(dimensions: TerminalDimensions) -> Result { let command = CommandConfig::new("/bin/sh") .map_err(RuntimeActorError::Start)? .args(["-c", LIVE_PTY_SCRIPT]); + let pty_size = TerminalSize::new(dimensions.rows(), dimensions.columns()) + .map_err(RuntimeActorError::Start)?; RuntimeActor::spawn( command, - PtyOptions::default(), + PtyOptions::new(pty_size), RuntimeActorOptions::default(), ) } @@ -922,22 +1105,21 @@ fn start_live_runtime() -> Result { fn main() { Application::new().run(|cx: &mut App| { cx.bind_keys([ - KeyBinding::new("left", FocusLeft, Some("LumbridgeShell")), - KeyBinding::new("right", FocusRight, Some("LumbridgeShell")), - KeyBinding::new("up", FocusUp, Some("LumbridgeShell")), - KeyBinding::new("down", FocusDown, Some("LumbridgeShell")), - KeyBinding::new("h", FocusLeft, Some("LumbridgeShell")), - KeyBinding::new("l", FocusRight, Some("LumbridgeShell")), - KeyBinding::new("k", FocusUp, Some("LumbridgeShell")), - KeyBinding::new("j", FocusDown, Some("LumbridgeShell")), + KeyBinding::new("alt-left", FocusLeft, Some("LumbridgeShell")), + KeyBinding::new("alt-right", FocusRight, Some("LumbridgeShell")), + KeyBinding::new("alt-up", FocusUp, Some("LumbridgeShell")), + KeyBinding::new("alt-down", FocusDown, Some("LumbridgeShell")), KeyBinding::new("secondary-k", OpenPalette, Some("LumbridgeShell")), - KeyBinding::new("escape", ClosePalette, Some("LumbridgeShell")), - KeyBinding::new("1", SelectPane1, Some("LumbridgeShell")), - KeyBinding::new("2", SelectPane2, Some("LumbridgeShell")), - KeyBinding::new("3", SelectPane3, Some("LumbridgeShell")), - KeyBinding::new("4", SelectPane4, Some("LumbridgeShell")), - KeyBinding::new("5", SelectPane5, Some("LumbridgeShell")), - KeyBinding::new("6", SelectPane6, Some("LumbridgeShell")), + KeyBinding::new("alt-1", SelectPane1, Some("LumbridgeShell")), + KeyBinding::new("alt-2", SelectPane2, Some("LumbridgeShell")), + KeyBinding::new("alt-3", SelectPane3, Some("LumbridgeShell")), + KeyBinding::new("alt-4", SelectPane4, Some("LumbridgeShell")), + KeyBinding::new("alt-5", SelectPane5, Some("LumbridgeShell")), + KeyBinding::new("alt-6", SelectPane6, Some("LumbridgeShell")), + KeyBinding::new("alt-shift-up", TerminalTaller, Some("LumbridgeShell")), + KeyBinding::new("alt-shift-down", TerminalShorter, Some("LumbridgeShell")), + KeyBinding::new("alt-shift-right", TerminalWider, Some("LumbridgeShell")), + KeyBinding::new("alt-shift-left", TerminalNarrower, Some("LumbridgeShell")), ]); let bounds = Bounds::centered(None, size(px(1500.0), px(960.0)), cx); @@ -959,22 +1141,21 @@ fn main() { #[cfg(test)] mod tests { - use super::PtyLineFramer; + use super::{KeyModifiers, TerminalKey, terminal_key_from_parts}; #[test] - fn frames_split_crlf_and_utf8_chunks_without_losing_bytes() { - let mut framer = PtyLineFramer::default(); - assert!(framer.push(b"first\r").is_empty()); - assert_eq!(framer.push(b"\nsecond\npart"), ["first", "second"]); - assert!(framer.push(&[0xf0, 0x9f]).is_empty()); - assert!(framer.push(&[0x91, 0xa9]).is_empty()); - assert_eq!(framer.finish(), ["part👩"]); + fn maps_named_and_composed_gpui_keys_to_terminal_input() { + let enter = terminal_key_from_parts("enter", None, KeyModifiers::default()).unwrap(); + assert_eq!(enter.key, TerminalKey::Enter); + + let composed = terminal_key_from_parts("é", Some("é"), KeyModifiers::default()).unwrap(); + assert_eq!(composed.key, TerminalKey::Text("é".into())); } #[test] - fn replaces_invalid_utf8_only_after_a_complete_line() { - let mut framer = PtyLineFramer::default(); - assert!(framer.push(&[0xff]).is_empty()); - assert_eq!(framer.push(b"\n"), ["�"]); + fn reserves_platform_text_shortcuts_for_the_workspace() { + assert!(terminal_key_from_parts("c", Some("c"), KeyModifiers::PLATFORM).is_none()); + let control = terminal_key_from_parts("c", Some("c"), KeyModifiers::CONTROL).unwrap(); + assert_eq!(control.key, TerminalKey::Text("c".into())); } } diff --git a/spikes/ui-shell-model/src/lib.rs b/spikes/ui-shell-model/src/lib.rs index 3f0583f..2266f2e 100644 --- a/spikes/ui-shell-model/src/lib.rs +++ b/spikes/ui-shell-model/src/lib.rs @@ -288,6 +288,7 @@ pub enum ShellAction { SetCommandPaletteQuery(String), SyntheticStreamTick, AppendExternalOutput { pane: PaneId, lines: Vec }, + ReplaceExternalOutput { pane: PaneId, lines: Vec }, } /// Counters prove both candidates replayed the same workload. Framework @@ -308,6 +309,7 @@ pub struct MeasurementCounters { pub terminal_lines_appended: u64, pub external_output_batches: u64, pub external_lines_appended: u64, + pub external_snapshot_updates: u64, } #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -536,6 +538,21 @@ impl ShellModel { changed = true; } } + ShellAction::ReplaceExternalOutput { pane, mut lines } => { + let pane = &mut self.panes[pane.index()]; + if pane.output_source == OutputSource::External { + if lines.len() > self.terminal_line_limit { + lines.drain(..lines.len() - self.terminal_line_limit); + } + if pane.lines != lines { + pane.lines = lines; + self.counters.surface_updates += 1; + self.counters.external_output_batches += 1; + self.counters.external_snapshot_updates += 1; + changed = true; + } + } + } } if changed { self.revision += 1; @@ -786,6 +803,14 @@ mod tests { assert_eq!(model.counters().surface_updates, 6); assert_eq!(model.counters().external_output_batches, 1); assert_eq!(model.counters().external_lines_appended, 2); + + let snapshot = model.dispatch(ShellAction::ReplaceExternalOutput { + pane: PaneId::CodexRuntime, + lines: vec!["prompt $".into()], + }); + assert!(snapshot.changed); + assert_eq!(model.pane(PaneId::CodexRuntime).lines(), ["prompt $"]); + assert_eq!(model.counters().external_snapshot_updates, 1); } #[test]