Bootstrap shop workspace
Wayland-only, GPU-accelerated terminal emulator for Alloy.
Workspace layout: binary at crates/shop, public kitty-graphics crate
at crates/kitty-graphics. Internal crates (shop-vt, shop-grid,
shop-render, shop-wayland, shop-xkb, shop-pty, shop-sixel) added as
each is implemented.
Design hub: ~/Wiki/shop-overview.md. Work: GoingsOn project 'shop'.
- Co-Authored-By
- Claude Opus 4.7 (1M context) <noreply@anthropic.com>
15 files changed,
+281 insertions,
-0 deletions
|
1 |
+ |
target/
|
|
2 |
+ |
Cargo.lock.bak
|
|
3 |
+ |
*.swp
|
|
4 |
+ |
.DS_Store
|
|
5 |
+ |
CLAUDE.md
|
|
6 |
+ |
CLAUDE.local.md
|
|
7 |
+ |
.claude/
|
|
1 |
+ |
# Attributions
|
|
2 |
+ |
|
|
3 |
+ |
Third-party code adapted into this workspace. Pinned to the version read at
|
|
4 |
+ |
adaptation time; refresh when the source is re-consulted.
|
|
5 |
+ |
|
|
6 |
+ |
None yet — this file will populate as files are lifted from external sources.
|
|
7 |
+ |
|
|
8 |
+ |
## Reference reads (not adapted, but consulted during design)
|
|
9 |
+ |
|
|
10 |
+ |
- [rio](https://github.com/raphamorim/rio) v0.4.12 — MIT. Architectural read
|
|
11 |
+ |
notes at `~/Wiki/rio-source-notes.md`. Rio's file structure and design
|
|
12 |
+ |
choices inform shop's crate layout; no rio code is currently vendored.
|
|
13 |
+ |
- [foot](https://codeberg.org/dnkl/foot) — MIT. Spirit reference for the
|
|
14 |
+ |
"Wayland-only, no built-in multiplexing" design.
|
|
15 |
+ |
- [alacritty_terminal](https://github.com/alacritty/alacritty) — Apache-2.0.
|
|
16 |
+ |
Reference for VT parser (`vte` crate) and grid/reflow design.
|
|
1 |
+ |
# Contributing
|
|
2 |
+ |
|
|
3 |
+ |
Solo project. External contributions aren't accepted yet — the design is still
|
|
4 |
+ |
moving. When that changes this file will grow.
|
|
5 |
+ |
|
|
6 |
+ |
## Working in this repo
|
|
7 |
+ |
|
|
8 |
+ |
- Design and load-bearing decisions live in `~/Wiki/shop-*.md`, not here.
|
|
9 |
+ |
- Work backlog is in GoingsOn (project `shop`), not `todo.md`.
|
|
10 |
+ |
- Rust 2024 edition, latest stable toolchain.
|
|
11 |
+ |
- `cargo deny check` must pass before commit. No GPL/LGPL/AGPL, ever.
|
|
12 |
+ |
- `cargo fmt` + `cargo clippy --all-targets` clean.
|
|
13 |
+ |
- Commits are concise, imperative, no emoji.
|
|
14 |
+ |
|
|
15 |
+ |
## Adding a component crate
|
|
16 |
+ |
|
|
17 |
+ |
Internal crates are scaffolded when they start, not up front. When you begin
|
|
18 |
+ |
`shop-vt`:
|
|
19 |
+ |
|
|
20 |
+ |
```
|
|
21 |
+ |
cargo new --lib crates/shop-vt
|
|
22 |
+ |
```
|
|
23 |
+ |
|
|
24 |
+ |
Then add it to `Cargo.toml`'s `[workspace] members`, add the `[lints]
|
|
25 |
+ |
workspace = true` block, and inherit `edition`/`rust-version`/`authors`/
|
|
26 |
+ |
`repository`/`license` from `[workspace.package]`.
|
|
27 |
+ |
|
|
28 |
+ |
## Attribution
|
|
29 |
+ |
|
|
30 |
+ |
Files adapted from external sources (rio, alacritty, foot, etc.) get a
|
|
31 |
+ |
header comment naming the source, its license, and the commit SHA or version
|
|
32 |
+ |
tag. See `ATTRIBUTIONS.md` for the full list.
|
|
1 |
+ |
# This file is automatically @generated by Cargo.
|
|
2 |
+ |
# It is not intended for manual editing.
|
|
3 |
+ |
version = 4
|
|
4 |
+ |
|
|
5 |
+ |
[[package]]
|
|
6 |
+ |
name = "kitty-graphics"
|
|
7 |
+ |
version = "0.0.0"
|
|
8 |
+ |
|
|
9 |
+ |
[[package]]
|
|
10 |
+ |
name = "shop"
|
|
11 |
+ |
version = "0.0.1"
|
|
1 |
+ |
[workspace]
|
|
2 |
+ |
resolver = "2"
|
|
3 |
+ |
members = [
|
|
4 |
+ |
"crates/shop",
|
|
5 |
+ |
"crates/kitty-graphics",
|
|
6 |
+ |
]
|
|
7 |
+ |
|
|
8 |
+ |
[workspace.package]
|
|
9 |
+ |
edition = "2024"
|
|
10 |
+ |
rust-version = "1.85"
|
|
11 |
+ |
authors = ["Max Johnson <me@maxj.phd>"]
|
|
12 |
+ |
repository = "https://git.sr.ht/~maxjmath/shop"
|
|
13 |
+ |
license = "MIT"
|
|
14 |
+ |
|
|
15 |
+ |
[workspace.lints.rust]
|
|
16 |
+ |
unsafe_code = "warn"
|
|
17 |
+ |
missing_debug_implementations = "warn"
|
|
18 |
+ |
|
|
19 |
+ |
[workspace.lints.clippy]
|
|
20 |
+ |
pedantic = { level = "warn", priority = -1 }
|
|
21 |
+ |
module_name_repetitions = "allow"
|
|
22 |
+ |
missing_errors_doc = "allow"
|
|
23 |
+ |
missing_panics_doc = "allow"
|
|
24 |
+ |
|
|
25 |
+ |
[profile.release]
|
|
26 |
+ |
lto = "thin"
|
|
27 |
+ |
codegen-units = 1
|
|
28 |
+ |
strip = "symbols"
|
|
29 |
+ |
|
|
30 |
+ |
[profile.dev]
|
|
31 |
+ |
opt-level = 1
|
|
1 |
+ |
MIT License
|
|
2 |
+ |
|
|
3 |
+ |
Copyright (c) 2026 Max Johnson
|
|
4 |
+ |
|
|
5 |
+ |
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6 |
+ |
of this software and associated documentation files (the "Software"), to deal
|
|
7 |
+ |
in the Software without restriction, including without limitation the rights
|
|
8 |
+ |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9 |
+ |
copies of the Software, and to permit persons to whom the Software is
|
|
10 |
+ |
furnished to do so, subject to the following conditions:
|
|
11 |
+ |
|
|
12 |
+ |
The above copyright notice and this permission notice shall be included in all
|
|
13 |
+ |
copies or substantial portions of the Software.
|
|
14 |
+ |
|
|
15 |
+ |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16 |
+ |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17 |
+ |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18 |
+ |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19 |
+ |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20 |
+ |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21 |
+ |
SOFTWARE.
|
|
1 |
+ |
# shop
|
|
2 |
+ |
|
|
3 |
+ |
Wayland-only, GPU-accelerated terminal emulator. Foot-inspired: small,
|
|
4 |
+ |
focused, no built-in tabs/splits (tmux/zellij do that). Adds the three things
|
|
5 |
+ |
foot refuses to do — GPU rendering, Kitty graphics protocol, ligatures.
|
|
6 |
+ |
|
|
7 |
+ |
Ships as the default terminal in [Alloy](https://git.sr.ht/~maxjmath/alloy).
|
|
8 |
+ |
Standalone-usable on any Wayland compositor.
|
|
9 |
+ |
|
|
10 |
+ |
## Status
|
|
11 |
+ |
|
|
12 |
+ |
Pre-code. Bootstrap in progress.
|
|
13 |
+ |
|
|
14 |
+ |
## Layout
|
|
15 |
+ |
|
|
16 |
+ |
- `crates/shop/` — the binary.
|
|
17 |
+ |
- `crates/kitty-graphics/` — public library (published to crates.io):
|
|
18 |
+ |
rendering-agnostic Kitty graphics protocol parser.
|
|
19 |
+ |
- `crates/shop-{vt,grid,render,wayland,xkb,pty,sixel}/` — added as each
|
|
20 |
+ |
component is implemented. See design hub.
|
|
21 |
+ |
|
|
22 |
+ |
## Non-goals
|
|
23 |
+ |
|
|
24 |
+ |
- Cross-platform. Wayland Linux only. No X11, no macOS, no Windows.
|
|
25 |
+ |
- Tabs, splits, panes. Use tmux/zellij.
|
|
26 |
+ |
- Config DSL. TOML is enough.
|
|
27 |
+ |
|
|
28 |
+ |
## License
|
|
29 |
+ |
|
|
30 |
+ |
MIT.
|
|
31 |
+ |
|
|
32 |
+ |
## Design
|
|
33 |
+ |
|
|
34 |
+ |
Design hub and rationale live in the private wiki (`~/Wiki/shop-overview.md`).
|
|
35 |
+ |
Work backlog lives in GoingsOn (project `shop`), not in this repo.
|
|
1 |
+ |
[package]
|
|
2 |
+ |
name = "kitty-graphics"
|
|
3 |
+ |
version = "0.0.0"
|
|
4 |
+ |
description = "Rendering-agnostic implementation of the Kitty terminal graphics protocol"
|
|
5 |
+ |
edition.workspace = true
|
|
6 |
+ |
rust-version.workspace = true
|
|
7 |
+ |
authors.workspace = true
|
|
8 |
+ |
repository.workspace = true
|
|
9 |
+ |
license.workspace = true
|
|
10 |
+ |
keywords = ["terminal", "kitty", "graphics", "protocol"]
|
|
11 |
+ |
categories = ["parser-implementations", "command-line-interface"]
|
|
12 |
+ |
readme = "README.md"
|
|
13 |
+ |
|
|
14 |
+ |
[lints]
|
|
15 |
+ |
workspace = true
|
|
16 |
+ |
|
|
17 |
+ |
[dependencies]
|
|
1 |
+ |
# kitty-graphics
|
|
2 |
+ |
|
|
3 |
+ |
Rendering-agnostic Rust implementation of the [Kitty terminal graphics
|
|
4 |
+ |
protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/).
|
|
5 |
+ |
|
|
6 |
+ |
Parses APC-payload bytes from a VT stream and emits structured commands
|
|
7 |
+ |
(transmit, place, delete, animate, query). Does not decode images, does not
|
|
8 |
+ |
render pixels, does not own a grid — the host does all three.
|
|
9 |
+ |
|
|
10 |
+ |
Extracted from [shop](https://git.sr.ht/~maxjmath/shop), a Wayland terminal for
|
|
11 |
+ |
[Alloy](https://git.sr.ht/~maxjmath/alloy).
|
|
12 |
+ |
|
|
13 |
+ |
## Status
|
|
14 |
+ |
|
|
15 |
+ |
Pre-1.0, API unstable.
|
|
16 |
+ |
|
|
17 |
+ |
## License
|
|
18 |
+ |
|
|
19 |
+ |
MIT.
|
|
1 |
+ |
//! Rendering-agnostic implementation of the [Kitty terminal graphics protocol].
|
|
2 |
+ |
//!
|
|
3 |
+ |
//! This crate parses APC-payload bytes from a VT stream and emits structured
|
|
4 |
+ |
//! commands (transmit, place, delete, animate, query). It does not decode
|
|
5 |
+ |
//! images, does not render pixels, and does not own a grid — the host does all
|
|
6 |
+ |
//! three. The crate manages command parsing, chunk reassembly, image-ID
|
|
7 |
+ |
//! lifecycle, and placement metadata.
|
|
8 |
+ |
//!
|
|
9 |
+ |
//! [Kitty terminal graphics protocol]: https://sw.kovidgoyal.net/kitty/graphics-protocol/
|
|
10 |
+ |
//!
|
|
11 |
+ |
//! Bring your own image decoder (`image` crate pairs naturally), your own
|
|
12 |
+ |
//! renderer (wgpu, GL, softbuffer — the crate does not care), and your own
|
|
13 |
+ |
//! scrollback (placement lifecycle events tell you when to move or drop
|
|
14 |
+ |
//! images).
|
|
15 |
+ |
//!
|
|
16 |
+ |
//! Status: skeleton. See `~/Wiki/shop-overview.md` for the crate design.
|
|
17 |
+ |
|
|
18 |
+ |
#![deny(unsafe_code)]
|
|
19 |
+ |
|
|
20 |
+ |
// Parser, commands, state — filled in during shop development.
|
|
1 |
+ |
[package]
|
|
2 |
+ |
name = "shop"
|
|
3 |
+ |
version = "0.0.1"
|
|
4 |
+ |
description = "Wayland-only, GPU-accelerated terminal emulator for Alloy"
|
|
5 |
+ |
edition.workspace = true
|
|
6 |
+ |
rust-version.workspace = true
|
|
7 |
+ |
authors.workspace = true
|
|
8 |
+ |
repository.workspace = true
|
|
9 |
+ |
license.workspace = true
|
|
10 |
+ |
|
|
11 |
+ |
[lints]
|
|
12 |
+ |
workspace = true
|
|
13 |
+ |
|
|
14 |
+ |
[[bin]]
|
|
15 |
+ |
name = "shop"
|
|
16 |
+ |
path = "src/main.rs"
|
|
17 |
+ |
|
|
18 |
+ |
[dependencies]
|
|
1 |
+ |
//! shop — Wayland terminal emulator.
|
|
2 |
+ |
//!
|
|
3 |
+ |
//! <!-- wiki: shop -->
|
|
4 |
+ |
//! Design hub: `~/Wiki/shop-overview.md`.
|
|
5 |
+ |
|
|
6 |
+ |
fn main() {
|
|
7 |
+ |
println!("shop: bootstrap");
|
|
8 |
+ |
}
|
|
1 |
+ |
# cargo-deny config. Load-bearing rule: NEVER GPL/LGPL/AGPL.
|
|
2 |
+ |
# Per `~/Code/CLAUDE.md`, taking on a copyleft dep is incompatible with the
|
|
3 |
+ |
# ecosystem's licensing plan (MIT for tooling, PolyForm-NC for products).
|
|
4 |
+ |
|
|
5 |
+ |
[graph]
|
|
6 |
+ |
all-features = true
|
|
7 |
+ |
|
|
8 |
+ |
[advisories]
|
|
9 |
+ |
version = 2
|
|
10 |
+ |
yanked = "deny"
|
|
11 |
+ |
|
|
12 |
+ |
[licenses]
|
|
13 |
+ |
version = 2
|
|
14 |
+ |
confidence-threshold = 0.9
|
|
15 |
+ |
allow = [
|
|
16 |
+ |
"MIT",
|
|
17 |
+ |
"MIT-0",
|
|
18 |
+ |
"Apache-2.0",
|
|
19 |
+ |
"Apache-2.0 WITH LLVM-exception",
|
|
20 |
+ |
"BSD-2-Clause",
|
|
21 |
+ |
"BSD-3-Clause",
|
|
22 |
+ |
"ISC",
|
|
23 |
+ |
"Zlib",
|
|
24 |
+ |
"Unicode-3.0",
|
|
25 |
+ |
"Unicode-DFS-2016",
|
|
26 |
+ |
"MPL-2.0",
|
|
27 |
+ |
"CC0-1.0",
|
|
28 |
+ |
"BSL-1.0",
|
|
29 |
+ |
]
|
|
30 |
+ |
|
|
31 |
+ |
[bans]
|
|
32 |
+ |
multiple-versions = "warn"
|
|
33 |
+ |
wildcards = "deny"
|
|
34 |
+ |
|
|
35 |
+ |
[sources]
|
|
36 |
+ |
unknown-registry = "deny"
|
|
37 |
+ |
unknown-git = "deny"
|
|
38 |
+ |
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
|
|
1 |
+ |
[toolchain]
|
|
2 |
+ |
channel = "stable"
|
|
3 |
+ |
components = ["rustfmt", "clippy"]
|
|
4 |
+ |
profile = "minimal"
|
|
1 |
+ |
# todo
|
|
2 |
+ |
|
|
3 |
+ |
Work backlog lives in GoingsOn, project `shop`. This file is a stub per the
|
|
4 |
+ |
CLAUDE.md convention.
|