commit 8971ddcf581116cffc9b5ec15dc3ed357b3429c9 Author: Kartios Date: Mon Aug 31 14:37:49 2026 -0700 Scaffold Lumbridge architecture and research plan diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d6f134f --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +/target/ +/.idea/ +/.zed/ +/.vscode/ +.DS_Store +*.log +.env +.env.* +!.env.example + +# Upstream research checkouts live beside this repository, never inside it. +/Research/ +/research-checkouts/ + diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..efde112 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,44 @@ +# AGENTS.md + +These rules apply to the entire Lumbridge repository. + +## Product boundary + +Lumbridge is a terminal/workspace runtime and ACP client. It may host, supervise, +and observe coding harnesses, but must not silently impersonate them, scrape their +private credentials, or claim provider quota data that cannot be verified. + +## Research boundary + +Upstream repositories are cloned outside this Git repository under the desktop +workspace's `Research/` directory. They are references, not vendored code. + +- Do not copy upstream implementation code without an explicit license review. +- Record the source repository and relevant license for any adapted design. +- AGPL/GPL and unlicensed repositories may be studied for behavior and UX only + unless the project deliberately changes its licensing strategy. + +## Engineering rules + +- Keep provider, harness, protocol, terminal, persistence, and UI boundaries + separate. A provider is not a harness and ACP is not a provider API. +- Preserve a PTY fallback. ACP adds structure but must not be required to open a + normal shell or run an arbitrary CLI. +- Keep secrets out of SQLite, logs, crash reports, command-line arguments, and + repository files. Store only opaque secret references in application state. +- Usage values must include a provenance and confidence classification. +- Avoid platform behavior hidden behind scattered `cfg` blocks; isolate it in + platform adapters with shared contract tests. +- No telemetry is enabled by default. Any future telemetry must be documented, + opt-in, redacted, and independently disableable. + +## Verification + +Before committing Rust changes, run: + +```bash +cargo fmt --all --check +cargo clippy --workspace --all-targets --all-features -- -D warnings +cargo test --workspace --all-features +``` + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..b6365b1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,12 @@ +# Contributing + +Lumbridge is early. Architecture changes should begin as a short document in +`docs/decisions/` and include the rejected alternatives, portability impact, +security impact, and a way to reverse the decision. + +Please keep changes small, add tests for behavior, and do not commit generated +artifacts, API keys, subscription tokens, transcripts, or upstream research +checkouts. + +By contributing, you agree that your contribution is licensed under Apache-2.0. + diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..95b007c --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,14 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "lumbridge" +version = "0.0.1" +dependencies = [ + "lumbridge-core", +] + +[[package]] +name = "lumbridge-core" +version = "0.0.1" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ac873d0 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,18 @@ +[workspace] +members = ["apps/lumbridge", "crates/lumbridge-core"] +resolver = "2" + +[workspace.package] +version = "0.0.1" +edition = "2024" +rust-version = "1.85" +license = "Apache-2.0" +repository = "https://git.karti.ai/lumbridge-public/lumbridge-code" + +[workspace.lints.rust] +unsafe_code = "forbid" + +[workspace.lints.clippy] +all = "warn" +pedantic = "warn" + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..aa7cf93 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2026 Lumbridge + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..28b8054 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# Lumbridge + +Lumbridge is a fast, local-first workspace and terminal multiplexer for agentic +engineers. It will run coding harnesses side by side, preserve their sessions, +connect rich agents through ACP, and show trustworthy account and usage context +without forcing users into one model vendor. + +The first supported desktop platforms are: + +- macOS (Apple Silicon first, Intel when CI capacity is available) +- Ubuntu Linux +- Omarchy and compatible Arch Linux systems + +Lumbridge is free and open source under Apache-2.0. Releases will be published +as installable binaries; building from source will remain supported. + +## Status + +This repository is in architecture and product-definition phase. The current +binary is deliberately only a scaffold. We are validating the terminal engine, +UI stack, process/session model, ACP integration, packaging, and usage-data +contracts before committing to a large implementation. + +## Product shape + +- A native desktop shell with tabs, panes, workspaces, worktrees, diffs, and an + agent-aware footer. +- A Rust session runtime that survives UI restarts and can later run headless. +- ACP-native integrations where available, with supervised PTYs as the universal + fallback for any CLI harness. +- First-class harnesses for Claude Code, Codex, DeepSeek Harness, Pi, Hermes, + OpenClaw, Goose, Gemini CLI, and OpenCode. +- Subscription login owned by the upstream harness, plus separate BYOK provider + profiles for OpenAI, Anthropic, Gemini, Groq, Cerebras, DeepSeek, and more. +- Usage history, burn rate, reset windows, and forecasts with visible data + provenance instead of invented precision. + +Start with [the product spec](docs/PRODUCT_SPEC.md), +[architecture](docs/ARCHITECTURE.md), and [research map](docs/RESEARCH.md). + +## Scaffold + +```bash +cargo test --workspace +cargo run -p lumbridge +``` + diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..9956457 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,13 @@ +# Security + +Lumbridge will launch shells and coding agents with the user's authority. That +makes process isolation, approval visibility, secret handling, and transcript +redaction core product behavior rather than optional hardening. + +Do not report vulnerabilities in a public issue while the disclosure channel is +being established. For now, contact the repository owners privately through the +Lumbridge organization on git.karti.ai. + +Never include real credentials, private prompts, source code, or terminal output +in a vulnerability report without first agreeing on a secure transfer method. + diff --git a/apps/lumbridge/Cargo.toml b/apps/lumbridge/Cargo.toml new file mode 100644 index 0000000..3b8d893 --- /dev/null +++ b/apps/lumbridge/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "lumbridge" +description = "Local-first workspace and terminal multiplexer for agentic engineers" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +lumbridge-core = { path = "../../crates/lumbridge-core" } + +[lints] +workspace = true + diff --git a/apps/lumbridge/src/main.rs b/apps/lumbridge/src/main.rs new file mode 100644 index 0000000..ce0a043 --- /dev/null +++ b/apps/lumbridge/src/main.rs @@ -0,0 +1,11 @@ +use lumbridge_core::{Platform, ProductStatus}; + +fn main() { + let status = ProductStatus::architecture_phase(Platform::current()); + println!( + "Lumbridge {} ({})", + env!("CARGO_PKG_VERSION"), + status.platform + ); + println!("{}", status.message); +} diff --git a/crates/lumbridge-core/Cargo.toml b/crates/lumbridge-core/Cargo.toml new file mode 100644 index 0000000..0d0ae9c --- /dev/null +++ b/crates/lumbridge-core/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "lumbridge-core" +description = "Domain contracts for Lumbridge" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +repository.workspace = true + +[lints] +workspace = true + diff --git a/crates/lumbridge-core/src/lib.rs b/crates/lumbridge-core/src/lib.rs new file mode 100644 index 0000000..be52a22 --- /dev/null +++ b/crates/lumbridge-core/src/lib.rs @@ -0,0 +1,79 @@ +//! Stable domain contracts shared by Lumbridge frontends and runtimes. + +use std::fmt; + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum Platform { + MacOs, + UbuntuLinux, + ArchLinux, + OtherLinux, + Unsupported, +} + +impl Platform { + #[must_use] + pub const fn current() -> Self { + if cfg!(target_os = "macos") { + Self::MacOs + } else if cfg!(target_os = "linux") { + Self::OtherLinux + } else { + Self::Unsupported + } + } +} + +impl fmt::Display for Platform { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + let name = match self { + Self::MacOs => "macOS", + Self::UbuntuLinux => "Ubuntu Linux", + Self::ArchLinux => "Arch Linux / Omarchy", + Self::OtherLinux => "Linux", + Self::Unsupported => "unsupported platform", + }; + formatter.write_str(name) + } +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum UsageProvenance { + ProviderReported, + HarnessReported, + LocallyMeasured, + Estimated, + Unavailable, +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ProductStatus { + pub platform: Platform, + pub message: &'static str, +} + +impl ProductStatus { + #[must_use] + pub const fn architecture_phase(platform: Platform) -> Self { + Self { + platform, + message: "Architecture scaffold only; no terminal sessions are started yet.", + } + } +} + +#[cfg(test)] +mod tests { + use super::{Platform, ProductStatus, UsageProvenance}; + + #[test] + fn scaffold_status_is_explicit() { + let status = ProductStatus::architecture_phase(Platform::UbuntuLinux); + assert!(status.message.contains("scaffold")); + } + + #[test] + fn usage_can_be_explicitly_unavailable() { + assert_eq!(UsageProvenance::Unavailable, UsageProvenance::Unavailable); + } +} diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..1af0394 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,116 @@ +# Architecture + +## Recommended shape + +Lumbridge should be two cooperating Rust processes: + +```text +native desktop UI + | local authenticated IPC +Lumbridge session runtime + |-- PTYs and process trees + |-- ACP clients and adapters + |-- repositories and worktrees + |-- usage/event ledger + `-- secret-store handles +``` + +Separating the UI from the session runtime lets terminals survive renderer +restarts, permits a future headless/SSH mode, and gives persistence one owner. +The first development build may run both in one process, but boundaries and IPC +messages should be real from the beginning. + +## Planned crates + +- `lumbridge-core`: IDs, commands, events, errors, capability and usage types. +- `lumbridge-runtime`: session ownership, supervision, recovery, IPC server. +- `lumbridge-pty`: portable PTY and process-tree adapters. +- `lumbridge-terminal`: VT parsing, scrollback, selection, search, render model. +- `lumbridge-acp`: ACP client, capability negotiation, transcript normalization. +- `lumbridge-harness`: manifests, launch profiles, hooks, PTY fallback adapters. +- `lumbridge-provider`: BYOK providers and provider-neutral usage records. +- `lumbridge-storage`: SQLite migrations, event log, snapshots, retention. +- `lumbridge-secrets`: Keychain/libsecret adapters and redaction. +- `lumbridge-git`: repositories, worktrees, diffs, status, conflict state. +- `lumbridge-ui`: native desktop state and rendering. +- `lumbridge`: installable application entry point. + +Only `lumbridge-core` and the entry point exist in the scaffold. New crates are +added after their architecture spike passes. + +## Terminal path + +The runtime owns PTYs, child process groups, resize signals, input ordering, and +raw output. 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. + +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 +keyboard/graphics negotiation, Unicode width, IME, mouse modes, shell integration, +and simultaneous automation plus human input. + +## UI decision gate + +Do not lock the project to a webview or to Zed's private implementation details +before a measured spike. Compare: + +1. GPUI for a Zed-like native model and excellent text-heavy interaction. +2. Iced/wgpu plus a dedicated terminal renderer for stable Rust portability. +3. Tauri only as a delivery-speed baseline, not the assumed winner. + +The winner must render six busy panes smoothly, keep input latency low, support +IME/accessibility, package on macOS and both Linux targets, and avoid a license +or upstream-stability trap. + +## Harness integration + +Each harness is described by a versioned manifest: executable discovery, launch +arguments, environment allowlist, resume semantics, status/usage probes, ACP +command when available, and hook installation rules. + +ACP is preferred because it provides structured prompts, plans, tool calls, +permissions, content blocks, and session lifecycle. A supervised PTY is always +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. + +## Usage model + +Usage is an append-only observation stream, not a mutable percentage field. +Observations include account profile, provider, harness, model, units, time +window, reset time, provenance, confidence, and source timestamp. Projections are +derived views that can be recomputed as forecasting improves. + +Subscription balance is provider-specific and sometimes unavailable. BYOK calls +usually expose token counts but cost still depends on cached tokens, reasoning, +tool calls, and current pricing. Adapters normalize facts without erasing their +source or uncertainty. + +## Persistence + +SQLite in WAL mode stores metadata, commands/events, normalized usage, and small +snapshots. Large scrollback chunks and binary attachments use content-addressed +files. A write-ahead event is committed before an external mutation is reported +as accepted. Startup replays incomplete operations and reconciles live children. + +## Security + +- macOS secrets: Keychain; Linux secrets: Secret Service/libsecret, with an + explicit encrypted-file fallback only if the user enables it. +- Never pass keys in process arguments. Prefer inherited file descriptors or a + minimal child environment when a harness requires environment variables. +- IPC is local, authenticated, permission-restricted, and version-negotiated. +- Transcript and crash-report redaction happens before persistence or export. +- Repository trust, harness approval mode, and sandbox mode are visible per pane. +- Remote control and plugins are out of scope until a capability/permission model + exists. + +## Platform adapters + +Shared contracts cover PTY, process tree, notifications, secret store, paths, +autostart, updater, and packaging. macOS uses `forkpty`/process groups and native +Keychain. Ubuntu and Omarchy use Unix PTYs, cgroups/systemd scopes when available, +and Secret Service. Omarchy is treated as Arch Linux, not as a separate kernel. + diff --git a/docs/DISTRIBUTION.md b/docs/DISTRIBUTION.md new file mode 100644 index 0000000..bbe7223 --- /dev/null +++ b/docs/DISTRIBUTION.md @@ -0,0 +1,20 @@ +# Distribution plan + +Lumbridge source and release metadata live in the public Gitea repository. Users +should not need a Rust toolchain. + +Initial release artifacts: + +- macOS arm64: signed and notarized `.dmg` plus a tar archive. +- macOS x86_64: added when a maintained Intel runner is available. +- Ubuntu x86_64: `.deb` and AppImage. +- Omarchy/Arch x86_64: signed package archive and an AUR recipe that downloads + the matching release artifact. + +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 new file mode 100644 index 0000000..decd74a --- /dev/null +++ b/docs/PRODUCT_SPEC.md @@ -0,0 +1,84 @@ +# Product specification + +## One sentence + +Lumbridge is a high-performance, local-first terminal and workspace multiplexer +that lets engineers run, steer, compare, and understand many coding agents +without surrendering control of their accounts, keys, repositories, or shells. + +## Primary user + +An engineer who works across several repositories and routinely keeps multiple +coding agents, shells, test watchers, servers, and review surfaces alive at once. +The product should feel faster and calmer as concurrency rises. + +## Core jobs + +1. Open a repository and create a durable workspace with terminals and panes. +2. Launch a supported harness through its subscription login or a BYOK profile. +3. See whether each agent is working, waiting, blocked, complete, or disconnected. +4. Steer work without losing terminal fidelity or bypassing approval prompts. +5. Review file and Git changes by workspace or worktree. +6. Understand usage, rate-limit windows, burn rate, and likely exhaustion time. +7. Resume the entire workspace after the UI or machine restarts. + +## Initial harnesses + +- Claude Code +- OpenAI Codex +- DeepSeek Harness +- Pi and compatible Pi distributions +- Hermes Agent +- OpenClaw +- Goose +- Gemini CLI +- OpenCode + +An arbitrary command remains a supported harness through the generic PTY adapter. + +## Provider modes + +Subscription mode delegates authentication to the installed upstream harness. +Lumbridge observes only documented status, usage, and protocol surfaces. + +BYOK mode supports OpenAI, Anthropic, Google Gemini, Groq, Cerebras, DeepSeek, +and OpenAI-compatible endpoints. Keys live in the operating-system credential +store. A provider adapter receives an opaque secret handle, never a value stored +in project state. + +Provider and harness selection are independent. For example, a generic harness +may use Cerebras by API key while Codex uses a ChatGPT subscription. + +## Usage footer + +The footer answers five questions in a glance: + +- Which harness, provider, model, and account profile is active? +- How much of the current usage window has been consumed? +- When does the window reset? +- What is the recent and projected burn rate? +- How trustworthy is the number? + +Every value is labeled internally and in detail views as provider-reported, +harness-reported, locally measured, estimated, or unavailable. Lumbridge must +not scrape browser cookies or reverse-engineer private account APIs to manufacture +an exact remaining balance. When only local observations exist, the UI says so. + +## Non-goals for the first release + +- 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. +- Windows support. +- Mobile control, collaborative cloud sessions, or remote execution. +- Bundling third-party subscriptions or reselling model tokens. + +## Experience principles + +- Terminal truth first: no hidden process state and no fake terminal emulation. +- Keyboard fast, mouse understandable. +- Dense information with a quiet default presentation. +- Approval and security boundaries stay visible. +- Local and offline workflows remain useful. +- Estimates are useful only when their uncertainty is honest. + diff --git a/docs/RESEARCH.md b/docs/RESEARCH.md new file mode 100644 index 0000000..e8af2af --- /dev/null +++ b/docs/RESEARCH.md @@ -0,0 +1,63 @@ +# Research map + +The working checkouts live outside this repository at: + +```text +Desktop/Lumbridge Code/Research/ +``` + +They are shallow snapshots for study, not dependencies or vendored source. + +## Multiplexers and terminal engines + +- `manaflow-ai/cmux`: the current cmux product; native workspace/pane model, + automation socket, embedded browser, agent hooks, and terminal UX. +- `Helvesec/rmux`: Rust multiplexer engine, daemon, typed SDKs, tmux surface. +- `tmux/tmux`: the durable client/server and command model to remain compatible + with where useful. +- `zellij-org/zellij`: Rust workspace, layouts, plugins, collaboration, web client. +- `wez/wezterm`: mature Rust terminal emulator, multiplexer, rendering, and PTY + portability reference. + +## Agent IDEs and orchestration products + +- `stablyai/orca`: parallel worktrees, many harnesses, terminals, usage tracking, + remote execution, and review surfaces. +- `get-bb/bb`: self-drivable agent IDE with desktop, web, CLI, and API surfaces. +- `coder/xum`: isolated parallel agent workspaces, remote execution, review, and + cost/context UX; AGPL, so treat implementation as study-only. +- `zed-industries/zed`: high-performance Rust editor, GPUI, terminal, and ACP + client. Review the dual-license boundary file by file. +- `aaif-goose/goose`: Rust desktop/CLI/API agent, many providers, MCP, and ACP. +- `block/buzz`: Rust human/agent collaboration plus production ACP harness design. +- `bbarit/terminal`: Rust agent terminal/IDE ideas. No top-level license file was + present in the captured snapshot, so do not reuse implementation code. + +## Protocols + +- `agentclientprotocol/agent-client-protocol`: canonical ACP schema and spec. +- `agentclientprotocol/rust-sdk`: official high-level Rust client/agent runtime. + +## Harnesses + +- `openai/codex` +- `deepseek-ai/deepseek-harness` +- `google-gemini/gemini-cli` +- `badlogic/pi-mono` +- `NousResearch/hermes-agent` +- `openclaw/openclaw` +- `anomalyco/opencode` + +## Research questions + +1. Which terminal core gives us correctness without inheriting a product-shaped + dependency or incompatible license? +2. Can the runtime maintain smooth human input while agents read/write other + panes through automation? +3. Which UI stack meets latency, IME, accessibility, and packaging requirements? +4. What is the smallest honest common denominator across ACP harnesses? +5. Which official provider/harness surfaces expose subscription quota, and what + 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/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 0000000..19a0272 --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,47 @@ +# Roadmap + +## Phase 0 — research and decisions + +- Capture upstream snapshots, licenses, relevant modules, and architectural notes. +- Benchmark UI candidates with six animated terminal panes. +- Spike PTY correctness and process-tree cleanup on macOS, Ubuntu, and Omarchy. +- Connect the official ACP Rust SDK to two contrasting harnesses. +- Audit actual usage/quota surfaces for every launch provider. +- Decide terminal core, UI stack, IPC transport, and schema evolution policy. + +Exit: recorded decisions with working spikes and measured results. + +## Phase 1 — terminal workspace alpha + +- Durable runtime, local IPC, workspaces, tabs, splits, shells, scrollback. +- Session restore, crash recovery, command palette, keybindings, notifications. +- Repository/worktree creation and basic Git status/diff. +- macOS, Ubuntu, and Omarchy development packages. + +Exit: Lumbridge is worth using as a terminal multiplexer without AI features. + +## Phase 2 — agent alpha + +- Generic harness manifest and PTY adapter. +- 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. + +Exit: daily multi-agent work is reliable and observable. + +## Phase 3 — providers and usage + +- Subscription profile discovery without credential extraction. +- BYOK profiles for OpenAI, Anthropic, Gemini, Groq, Cerebras, and DeepSeek. +- OS credential storage, redaction, provider/model catalog. +- Usage ledger, reset windows, burn charts, forecasts, export, and footer. + +Exit: usage displays are useful, auditable, and honest about uncertainty. + +## Phase 4 — public beta + +- Goose, Gemini CLI, OpenClaw, and OpenCode adapters. +- Signed/notarized macOS releases, `.deb`, AppImage, and Arch package. +- Delta updater with signed manifests and rollback. +- Accessibility, performance, soak, migration, and recovery qualification. + diff --git a/docs/decisions/0001-product-boundary.md b/docs/decisions/0001-product-boundary.md new file mode 100644 index 0000000..401e1b9 --- /dev/null +++ b/docs/decisions/0001-product-boundary.md @@ -0,0 +1,15 @@ +# 0001: Lumbridge is the workspace, not one more mandatory agent + +Status: accepted for the architecture phase. + +Lumbridge owns terminals, workspaces, session durability, integration, review, +and usage observability. Existing coding harnesses remain first-class processes. +ACP provides rich structure and PTYs provide universal compatibility. + +This boundary preserves user subscriptions, harness-native capabilities, and +choice. It also prevents an early attempt to build a terminal, IDE, multiplexer, +provider SDK, and universal agent loop as one inseparable component. + +We may later ship an optional Lumbridge-native harness, but the application must +remain valuable without it. + diff --git a/docs/decisions/0002-usage-provenance.md b/docs/decisions/0002-usage-provenance.md new file mode 100644 index 0000000..aecf407 --- /dev/null +++ b/docs/decisions/0002-usage-provenance.md @@ -0,0 +1,15 @@ +# 0002: Usage data always carries provenance + +Status: accepted for the architecture phase. + +Provider quotas and subscription windows do not share a stable universal API. +Lumbridge therefore stores observations with their source and derives forecasts +without overwriting the facts. + +Allowed provenance values begin as provider-reported, harness-reported, locally +measured, estimated, and unavailable. The UI may simplify these labels in compact +views, but the detail view and export retain them. + +Lumbridge will not scrape browser cookies, copy upstream OAuth tokens, or label a +local estimate as an exact remaining subscription balance. +