diff --git a/Backend/tauri.conf.json b/Backend/tauri.conf.json
index 371b2708..bb39db98 100644
--- a/Backend/tauri.conf.json
+++ b/Backend/tauri.conf.json
@@ -77,8 +77,8 @@
"updater": {
"active": true,
"endpoints": [
- "https://github.com/Jordonbc/OpenVCS/releases/latest/download/latest.json",
- "https://github.com/Jordonbc/OpenVCS/releases/download/openvcs-nightly/latest.json"
+ "https://github.com/Open-VCS/OpenVCS/releases/latest/download/latest.json",
+ "https://github.com/Open-VCS/OpenVCS/releases/download/openvcs-nightly/latest.json"
],
"dialog": false,
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDhBQzc3RDI3RTg4MDUzNzMKUldSelU0RG9KMzNIaWdNaFI3R1JoVzZOb0h4c2hNdFdCMTBneFQyamZkT1VKc2E0NjZhODB5WkQK"
diff --git a/README.md b/README.md
index 510340ec..150d6a21 100644
--- a/README.md
+++ b/README.md
@@ -1,271 +1,493 @@
-
+
-
+
OpenVCS
-[](https://github.com/Open-VCS/OpenVCS-Plugin-Git/actions/workflows/nightly.yml) [](https://github.com/Open-VCS/OpenVCS-Plugin-Git/actions/workflows/ci.yml) [](https://github.com/Open-VCS/OpenVCS-Plugin-Git/actions/workflows/release.yml)
+
+ A desktop client for every VCS.
+
-
+
+ Plugin-based by design, starting with Git.
+
-**The open‑source, fully customisable VCS client.**
+[](https://github.com/Open-VCS/OpenVCS/actions/workflows/nightly.yml)
+[](https://github.com/Open-VCS/OpenVCS/actions/workflows/beta.yml)
+[](https://github.com/Open-VCS/OpenVCS/actions/workflows/publish-stable.yml)
+[](LICENSE)
-OpenVCS is a new and upcoming cross‑platform version control client built with [Tauri](https://tauri.app/), [Rust](https://www.rust-lang.org/), and a modern [TypeScript](https://www.typescriptlang.org/) + [Vite](https://vitejs.dev/) frontend. It aims to be the **all‑in‑one solution** for version control: clean, fast, and extensible. Features are actively being explored and are **not yet finalised**.
+
+ Overview
+ ·
+ Quick Start
+ ·
+ Features
+ ·
+ Screenshots
+ ·
+ Architecture
+ ·
+ Roadmap
+ ·
+ Contributing
+
-> **Scope note:** The first main release focuses on **Git** to keep the scope tight. The long‑term vision is to support **all major VCS systems** through a backend/plugin architecture (e.g., Mercurial, SVN, Perforce, Fossil, etc.).
+---
-## Quick Install (AppImage)
+## Overview
-OpenVCS provides a convenience script that fetches the latest AppImage, stores it at `~/Applications/openvcs.AppImage`, and creates a desktop entry so you can launch it from your app menu. Run:
+OpenVCS is a desktop version control client focused on **speed**, **clarity**, and **customisation**.
-```bash
-curl -fsSL https://raw.githubusercontent.com/Jordonbc/OpenVCS/stable/install.sh | bash
-```
+
+
+
+
+The client itself stays **VCS-agnostic**. It provides the desktop shell, core framework, plugin runtime, and base UI; VCS support, themes, UI changes, and additional product features are provided by plugins. A single plugin can provide any combination of these capabilities. The first major release ships with the `openvcs.git` plugin so Git workflows can stabilise before other VCS support is explored.
+
+> [!IMPORTANT]
+> OpenVCS is in early development. Features, APIs, packaging, plugin behaviour, and UI details may change while the core Git workflow stabilises.
+
+
+
+
+ ⚡ Fast by design
+ Rust and Tauri keep the app lightweight while still allowing native desktop integration.
+ |
+
+ 🧩 Built to extend
+ VCS providers, UI extensions, themes, and extra features are delivered through plugins.
+ |
+
+ 🌿 Git first
+ Git support comes from the built-in plugin, not from Git-specific client architecture.
+ |
+
+
+
+---
+
+## Project Status
+
+| Area | Status | Notes |
+| ------------------ | ----------- | ------------------------------------------------------------------- |
+| **Git plugin** | Active | Built-in `openvcs.git` plugin using system Git execution |
+| **Linux AppImage** | Active | Primary distribution target |
+| **Windows builds** | Supported | Build support exists; reliability will continue improving |
+| **macOS builds** | Not planned | Community interest may influence this later |
+| **Flatpak** | Test build | Released from stable builds, but provided as experimental/test-only |
+| **Themes** | Early | Themes are plugins and can change application styling |
+| **Plugins** | Early | Plugins can add, remove, or modify UI, themes, VCSs, and features |
+| **Multi-VCS** | Planned | Future VCS support should arrive through plugins |
+
+---
+
+## Quick Start
+
+OpenVCS desktop builds are distributed through **GitHub Releases**.
-The script targets Linux, leaves existing configuration untouched, and can be re-run to pull the newest release.
+### Download from GitHub Releases
-Desktop builds keep using the legacy shared `OpenVCS` config and plugin directories.
+| Build | Best for | Notes |
+| ------------------------- | ------------------------ | ---------------------------------------------- |
+| **Latest stable release** | Most users | Recommended default download |
+| **Pre-release / nightly** | Testing upcoming changes | May contain regressions or incomplete features |
+| **Source archive** | Reviewing release source | Use the repository directly for development |
-**Install pre-release (nightly):**
+1. Open the [latest release](https://github.com/Open-VCS/OpenVCS/releases/latest) on GitHub.
+2. Download the appropriate asset for your platform.
+3. Run the downloaded build locally.
+
+### Linux AppImage
+
+Download the latest AppImage from GitHub Releases, make it executable, and run it directly:
```bash
-curl -fsSL https://raw.githubusercontent.com/Jordonbc/OpenVCS/stable/install.sh | bash -s -- --prerelease
+chmod +x OpenVCS-*.AppImage
+./OpenVCS-*.AppImage
```
-**Uninstall:**
+The AppImage can be stored anywhere. No installation step is required.
+
+| Step | Action |
+| --------------- | ----------------------------------------------------------------------- |
+| Download | Get the latest AppImage asset from GitHub Releases |
+| Allow execution | Run `chmod +x OpenVCS-*.AppImage` |
+| Launch | Run `./OpenVCS-*.AppImage` |
+| Update | Download a newer AppImage from GitHub Releases and replace the old file |
+
+### Windows
+
+Download the Windows installer from GitHub Releases and run it like a standard desktop application installer.
+
+| Step | Action |
+| --------- | -------------------------------------------------------------------------------- |
+| Download | Open the latest GitHub Release and download the Windows installer asset |
+| Install | Run the downloaded installer and follow the prompts |
+| Launch | Start OpenVCS from the Start menu or desktop shortcut |
+| Update | Download the newer Windows installer from GitHub Releases and run it again |
+| Uninstall | Remove OpenVCS from Windows Settings → Apps, or use the provided uninstall entry |
+
+If Windows SmartScreen warns about the installer, verify that the file came from the official GitHub Release before choosing whether to continue.
+
+### Build from source
+
+For development builds, clone the repository and run OpenVCS through Tauri:
```bash
-curl -fsSL https://raw.githubusercontent.com/Jordonbc/OpenVCS/stable/install.sh | bash -s -- --uninstall
+git clone https://github.com/Open-VCS/OpenVCS.git
+cd OpenVCS
+npm --prefix Frontend install
+cd Backend
+cargo tauri dev
```
-Swap `stable` for `dev` in the URL if you want the bleeding-edge installer.
+### Flatpak
+
+Flatpak packaging exists under `packaging/flatpak/`. Stable-channel Flatpak builds may be published, but they are provided as experimental test builds rather than a recommended install path. See the [Flatpak](#flatpak) section before relying on it for regular use.
-Pre-release AppImage installs use a separate launcher and install path when the selected release is branded as beta or nightly, so they can coexist with stable on the same machine.
+> [!NOTE]
+> Desktop builds currently continue to use the legacy shared `OpenVCS` configuration and plugin directories.
---
-## Key Goals
+## Release Channels
-- 🧩 **Fully customisable** - themes, layout, and extensibility at the core.
-- 🗂 **Multi‑VCS architecture** - designed to support many backends beyond Git.
-- ⚡ **Lightweight & fast** - native shell via Tauri + Rust.
-- 🧰 **Developer‑first UX** - frictionless flows for common VCS tasks.
+| Channel | Intended use | Stability |
+| ----------- | ---------------------------------- | ----------------------------- |
+| **Stable** | General use and manual testing | Most reliable available build |
+| **Beta** | Previewing upcoming release work | May contain regressions |
+| **Nightly** | Testing latest development changes | Experimental |
-## Platform Targets
+---
-- 🐧 **Linux‑first** (primary target)
-- 🪟 **Windows** builds supported
-- 🍏 **macOS** not currently planned (community interest welcome)
+## Features
-## Features (Current)
+OpenVCS keeps the README short. The full feature list lives in [docs/Features.md](docs/Features.md).
-- 🔗 **Git support** via the built-in `openvcs.git` plugin (System Git execution).
-- 📁 **Repo workflows:** clone, open existing repos, recent repos list, optional reopen of last repo on launch.
-- ✅ **Status & diffs:** working tree status, per-file diff, commit diff, discard changes.
-- 🧩 **Staging & commits:** stage files, partial staging/commits via patch, commit from index.
-- 🌿 **Branches:** list local/remote, create, checkout, rename, delete, set upstream tracking.
-- 🔀 **Merge & conflicts:** merge branches, conflict details, checkout ours/theirs, save merged result, launch external merge tool, abort/continue merge.
-- 🧳 **Stash:** list, push, apply, pop, drop, show.
-- 🌐 **Sync & remotes:** set remote URL, fetch (single/all), pull (fast-forward only), push.
-- 🗃 **Git LFS helpers:** fetch/pull/prune, track/untrack, inspect tracked paths.
-- 🔐 **SSH helpers:** trust host keys, list/add SSH agent keys, key discovery.
-- 🎨 **Themes:** built-in light/dark themes, plus plugin-provided themes (standalone theme `.zip` packs are not supported).
-- 🧩 **Plugins (early):** config-driven npm or local-path plugins synchronized into the app on startup.
-- 🔄 **Updater & logs:** update check/install, VCS output log window, app log tail/clear.
+Highlights:
-## Planned / Exploratory
+- Plugin-first and VCS-agnostic architecture
+- Plugins can add, remove, or modify UI
+- Themes are plugins
+- Additional features and VCS backends are plugins too
-- 🔌 **More VCS backends** via the existing backend abstraction.
-- 🧩 **Plugin & theme store** (distribution/discovery UX).
-- 🖼 **More UI workflows** and keyboard-first polish.
+---
-> Priorities may shift as we iterate on feedback and stabilize the core Git workflows.
+## Screenshots
+
+
+
+
+ 
+ Add existing repository
+ |
+
+ 
+ Settings
+ |
+
+
+
+
+
+
+ 
+ Plugin list
+ |
+
+
+
+> [!NOTE]
+> The interface is still evolving while the core workflows stabilise.
---
-## Repository Structure
+## Architecture
+
+OpenVCS is a plugin-first desktop framework. The client provides the application shell, core services, plugin host, and base UI. VCS integrations, themes, UI customisations, and additional features are supplied by plugins.
+
+Plugin capabilities are composable rather than split into strict plugin types. A single plugin can add themes, modify UI, provide a VCS integration, add workflows, or combine those responsibilities.
+The client should remain VCS-agnostic: Git is supported by the built-in `openvcs.git` plugin, not by hard-coding Git as the application's core model.
+
+```mermaid
+flowchart LR
+ Shell[Desktop shell
Tauri] --> UI[Base UI
TypeScript + Vite]
+ Shell --> Backend[Core framework
Rust services]
+ Backend --> Host[Plugin host
JSON-RPC over stdio]
+ Host --> Git[openvcs.git
Git workflows]
+ Host --> PluginA[Plugin A
themes + UI changes]
+ Host --> PluginB[Plugin B
VCS + workflows]
+ Host --> PluginC[Plugin C
mixed capabilities]
+ Host -. future .-> OtherVcs[Future plugins
Mercurial / SVN / Perforce / Fossil]
```
+
+### Architecture responsibilities
+
+| Layer | Technology | Responsibility |
+| ------------------ | ----------------- | ------------------------------------------------------------ |
+| **Desktop shell** | Tauri | Windowing, app lifecycle, frontend/backend bridge |
+| **Base UI** | TypeScript + Vite | Core interface, interaction patterns, and plugin surfaces |
+| **Core framework** | Rust | Native services, filesystem access, process execution |
+| **Plugin host** | Rust + Node.js | Load npm/local plugins and communicate over JSON-RPC stdio |
+| **Plugins** | npm / local path | Add any mix of VCS support, themes, UI changes, and features |
+
+### Repository layout
+
+```text
.
-├── Backend/ # Rust + Tauri backend (native logic, app entry)
-├── Frontend/ # TypeScript + Vite frontend (UI layer)
-├── Cargo.toml # Workspace manifest
+├── Backend/ # Rust + Tauri backend, native logic, and app entry point
+├── Frontend/ # TypeScript + Vite frontend
+├── docs/ # UX, plugin, architecture, and packaging documentation
+├── packaging/flatpak/ # Experimental Flatpak manifests and notes
+├── scripts/ # Build and plugin-materialisation helpers
+├── Cargo.toml # Rust workspace manifest
+├── Justfile # Common build/test/fix commands
├── LICENSE
└── README.md
```
----
-
-## Getting Started
+### Design principles
-### Prerequisites
+| Principle | Direction |
+| --------------------------- | ------------------------------------------------------------------------------------------------------------ |
+| **VCS agnostic core** | The client framework should not assume Git or any other VCS as the core model. |
+| **Everything is a plugin** | VCS providers, themes, UI changes, and extra workflows should be delivered by plugins. |
+| **Composable capabilities** | A plugin can provide one capability or many; themes, UI, VCSs, and features are not separate plugin classes. |
+| **Extensible UI** | Plugins can add, remove, or modify UI without requiring a fork of the client. |
+| **Themes are plugins** | Themes are plugin capabilities and can change styles, presentation, and visual assets. |
+| **Visible operations** | VCS commands and logs should be inspectable rather than hidden behind vague progress states. |
-- [Rust](https://www.rust-lang.org/tools/install) (latest stable recommended)
-- [Cargo](https://doc.rust-lang.org/cargo/) (ships with Rust)
-- [Node.js](https://nodejs.org/) (for the frontend toolchain)
-- [npm](https://www.npmjs.com/) (package manager)
-- **Git** installation (system Git is currently required)
+---
-### Installation
+## Build from Source
-For the automated installer, see [Quick Install (AppImage)](#quick-install-appimage).
+### Requirements
-#### Manual AppImage download
+| Requirement | Purpose |
+| ----------------------------------------------- | ----------------------------------- |
+| [Rust](https://www.rust-lang.org/tools/install) | Backend and Tauri application |
+| [Cargo](https://doc.rust-lang.org/cargo/) | Rust package manager and build tool |
+| [Node.js](https://nodejs.org/) | Frontend toolchain |
+| [npm](https://www.npmjs.com/) | Frontend dependency installation |
+| [Git](https://git-scm.com/) | Required by the current Git plugin |
+| [just](https://github.com/casey/just) | Recommended command runner |
-Prefer a portable setup? Download the latest AppImage from the GitHub releases page (e.g. https://github.com/Jordonbc/OpenVCS/releases/latest), make it executable, and run it directly:
+### Developer setup
```bash
-chmod +x OpenVCS-*.AppImage
-./OpenVCS-*.AppImage
+git clone https://github.com/Open-VCS/OpenVCS.git
+cd OpenVCS
+npm --prefix Frontend install
+cd Backend
+cargo tauri dev
```
-Store the AppImage wherever you like; no installation step is required.
+### Build commands
-#### Flatpak (experimental)
+| Command | Description |
+| ----------------------- | -------------------------------- |
+| `just tauri-build` | Build a stable production bundle |
+| `just tauri-build beta` | Build a beta channel bundle |
+| `just build stable` | Build stable channel output |
+| `just build beta` | Build beta channel output |
+| `just build nightly` | Build nightly channel output |
+| `cargo build` | Compile the Rust workspace only |
-A Flatpak manifest exists under `packaging/flatpak/`, but Flatpak support is currently **experimental** and may be broken even if the bundle builds successfully.
+These commands wrap the Tauri build flow and set `NO_STRIP=true` to avoid AppImage `linuxdeploy` strip failures on newer Linux toolchains.
-Known issues/limitations:
+---
-- The sandbox does not provide `git`, and OpenVCS currently relies on **system Git** via plugin execution.
-- If the frontend assets are not included correctly, the app can show a blank window / “could not connect to localhost” (dev server) instead of loading `Frontend/dist`.
+## Flatpak
-For local build notes see `packaging/flatpak/README.md`.
+A Flatpak manifest exists under:
-#### Build from source
+```text
+packaging/flatpak/
+```
-Clone the repository:
+| Limitation | Impact |
+| ------------------------------------------ | ----------------------------------------------------------------------- |
+| Sandbox does not currently provide `git` | OpenVCS currently relies on system Git through plugin execution |
+| Frontend assets must be packaged correctly | Otherwise the app may show a blank window or localhost connection error |
+| Flatpaks are stable-channel test builds | They may be released, but remain experimental and are not recommended |
-```bash
-git clone https://github.com/Jordonbc/OpenVCS.git
-cd openvcs
-```
+In short: Flatpak users are helping test the packaging path. Expect rough edges.
-Install frontend dependencies:
+For local Flatpak build notes, see:
-```bash
-cd Frontend
-npm install
-```
+[packaging/flatpak/README.md](packaging/flatpak/README.md)
-**Run in development mode (dev server):**
+---
-```bash
-cd Backend
-cargo tauri dev
-```
+## Development Workflow
-**Build a release bundle (production):**
+### Internal paths
-```bash
-just tauri-build
-just tauri-build beta
-```
+| Path | Purpose |
+| ---------------------------------- | ------------------------------------------- |
+| `Backend/src/core/` | Shared VCS models and traits |
+| `Backend/src/plugin_runtime/` | Node.js plugin host and JSON-RPC transport |
+| `Backend/tauri.conf.json` | Tauri configuration and precommand hooks |
+| `openvcs.plugins.json` | Channel-aware built-in plugin configuration |
+| `openvcs.plugins.local.json` | Optional local plugin override |
+| `target/openvcs/built-in-plugins/` | Materialised built-in plugin output |
-This wraps `cargo tauri build` with `NO_STRIP=true` to avoid AppImage
-linuxdeploy strip failures on newer Linux toolchains.
+### Notes
-`just build`, `just build stable`, `just build beta`, and `just build nightly`
-use the same channel-aware Tauri build flow.
+* Tauri precommands intentionally use an explicit hook `cwd` of `Backend/`.
+* This prevents Tauri from resolving hooks from nested plugin directories.
+* Built-in plugins are materialised from `openvcs.plugins.json` before app builds.
+* Local development can override the active plugin list with `openvcs.plugins.local.json`.
-The Tauri precommands in `Backend/tauri.conf.json` intentionally set an
-explicit hook `cwd` to `Backend/` so Tauri does not resolve them from nested
-plugin directories, and built-in plugins are materialized from the
-channel-aware `openvcs.plugins.json` into `target/openvcs/built-in-plugins/`
-before the app is built. Local development can optionally override the active
-channel list with `openvcs.plugins.local.json`.
+---
-### Optional: Rust‑only build
+## Testing and Quality Checks
-If you want to verify the Rust workspace compiles independently (without running Tauri):
+### Main commands
-```bash
-cargo build
-```
+| Command | Runs |
+| ------------------------------------------------------------- | ---------------------------------------------------- |
+| just test | Full project test/check flow |
+| just fix | Formatting, Clippy fixes, and frontend type checking |
+| cargo fmt --all | Rust formatting |
+| cargo fmt --all -- --check | CI formatting check |
+| cargo clippy --all-targets --all-features -- -D warnings | CI lint check |
+| npm --prefix Frontend exec tsc -- -p tsconfig.json --noEmit | Frontend type checking |
+| npm --prefix Frontend test | Frontend tests |
+
+### just test includes
+
+| Step | Purpose |
+| ------------------------ | ---------------------- |
+| cargo test --workspace | Rust workspace tests |
+| Frontend typecheck | TypeScript correctness |
+| Frontend tests | Vitest unit tests |
---
-## Development Workflow
+## Roadmap
-- **Frontend:** TypeScript + Vite for a fast iteration loop.
-- **Backend:** Rust + Tauri commands for native operations.
-- **Backend contracts:** shared Rust VCS models/traits now live in `Backend/src/core/` and are owned by the backend module.
-- **Bridge:** Tauri `invoke` is used to call Rust from the UI; events are used for progress/streaming.
+### Near term
----
+| Item | Status |
+| -------------------------------------------------------- |:------:|
+| Stabilise core Git workflows | ✅ |
+| Improve Linux AppImage installation and update behaviour | ✅ |
+| Improve Windows build reliability | ✅ |
+| Refine the main repository UI | ✅ |
+| Expand backend/frontend test coverage | ✅ |
-## Testing
+### Medium term
-- Use `just test` to run the full project test/check flow (runs `cargo test --workspace`, then frontend typecheck and tests).
-- Use `just fix` to run formatting and clippy fixes plus a frontend typecheck.
-- Frontend-only commands (from `Frontend/`):
- - `npm exec tsc -- -p tsconfig.json --noEmit` — TypeScript typecheck for the frontend.
- - `npm test` — run Vitest unit tests (added to the frontend devDependencies).
+| Item | Status |
+| --------------------------------------------------- |:------:|
+| Harden plugin loading and plugin configuration | 🧭 |
+| Improve theme support | 🧭 |
+| Add more keyboard-first workflows | 🧭 |
+| Improve merge and conflict resolution UX | 🧭 |
+| Expand documentation for plugin and backend authors | 🧭 |
-Note: Some commands (installing Node deps, running Tauri dev/build) may require network access and native toolchain components.
+### Long term
-Design principles:
+| Item | Status |
+| ------------------------------------------------------------- |:------:|
+| Add at least one non-Git VCS plugin | 🧭 |
+| Validate the VCS-agnostic client model with non-Git workflows | 🧭 |
+| Explore plugin and theme discovery flows | 🧭 |
+| Explore a plugin/theme store | 🧭 |
+| Mature OpenVCS into a multi-VCS desktop client | 🧭 |
-1. **Separation of concerns** - UI logic stays in the frontend; VCS logic lives in backend crates.
-2. **Backend abstraction** - a trait‑driven interface to enable multiple VCS backends over time.
-3. **Extensibility** - theming and plugin hooks are planned as part of the long‑term architecture, but will follow after the core VCS features are complete.
+Legend: ✅ active · 🧭 planned/exploratory
---
-## Contributing
+## Project Repositories
-OpenVCS is **open source** and community‑driven. Contributions of all kinds are welcome:
+| Repository | Purpose |
+| ---------------------------------------------------------------------------- | ------------------------------------------ |
+| [Open-VCS](https://github.com/Open-VCS) | GitHub organisation |
+| [OpenVCS-Plugin-Git](https://github.com/Open-VCS/OpenVCS-Plugin-Git) | Git VCS plugin implementation |
+| [OpenVCS-SDK](https://github.com/Open-VCS/OpenVCS-SDK) | SDK, runtime helpers, and shared contracts |
+| [OpenVCS-Plugin-Themes](https://github.com/Open-VCS/OpenVCS-Plugin-Themes) | Theme plugin work |
+| [ExamplePlugins](https://github.com/Open-VCS/ExamplePlugins) | Example plugin implementations |
+| [PluginTemplate](https://github.com/Open-VCS/PluginTemplate) | Starter template for new plugins |
-- Bug reports & feature proposals
-- UX feedback and design mocks
-- Backend adapters for other VCS
-- Theme prototypes and early plugin experiments
+---
-Formatting requirement (Rust):
-- Run `cargo fmt --all` before pushing.
-- CI enforces `cargo fmt --all -- --check` and will fail if formatting is off.
-- CI also runs `cargo clippy --all-targets -- -D warnings` and will fail on warnings.
-Convenience (if you have `just` installed): `just fix`
+## Contributing
-> See `CONTRIBUTING.md` (coming soon). Until then, feel free to open an issue or a discussion to propose changes.
+OpenVCS is open source and community-driven. Contributions are welcome across code, design, testing, documentation, and product feedback.
-### Proposed Roadmap (High‑level)
+| Contribution type | Examples |
+| --------------------- | ---------------------------------------------------------- |
+| **Bug reports** | Broken workflows, crashes, packaging issues |
+| **Feature proposals** | New Git workflows, UX improvements, plugin ideas |
+| **Design feedback** | Layout, accessibility, theme direction, interaction polish |
+| **Backend work** | Git improvements, future VCS adapters, core contracts |
+| **Frontend work** | UI workflows, state handling, keyboard-first flows |
+| **Documentation** | Build notes, plugin notes, architecture explanations |
+| **Themes/plugins** | Theme prototypes and early plugin experiments |
-- **MVP:** Stable Git workflows; Linux and Windows builds; core UI.
-- **Theming:** Planned for later; starting with plugin-provided theme packs before exploring a gallery or store.
-- **Plugins:** Planned for later; will likely begin as simple plugin bundles (e.g. zip files in a directory) before evolving toward a store with discovery UX.
-- **Multi‑VCS:** Add at least one non‑Git backend to validate the abstraction.
+A dedicated `CONTRIBUTING.md` is planned. Until then, please open an issue or discussion before making large changes.
---
## Recommended IDE Setup
-- [Visual Studio Code](https://code.visualstudio.com/)
-- Extensions:
- - [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode)
- - [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
- - [TypeScript ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
+| Tool | Purpose |
+| ----------------------------------------------------------------------------------------------- | ------------------------- |
+| [Visual Studio Code](https://code.visualstudio.com/) | Recommended editor |
+| [Tauri extension](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) | Tauri development support |
+| [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) | Rust language support |
+| [TypeScript ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) | Frontend linting support |
---
-## Project Status
+## FAQ
-OpenVCS is in **early development**. Features and APIs are not yet finalised and may change frequently. Feedback will directly shape the roadmap.
+
+Is OpenVCS Git-only?
-## License
+Today, the first supported backend is Git through the built-in `openvcs.git` plugin. The long-term architecture is intended to support additional VCS backends.
+
+
+
+
+Does OpenVCS require system Git?
-[GPL-3.0](LICENSE)
+Yes. The current Git plugin executes against the system Git installation.
-## Screenshots / Demos
+
-The UI is actively evolving as core features take shape. Below is a small preview of the current design (subject to change):
+
+Is Flatpak supported?
-
-
-
+Flatpak builds may be released from the stable channel, but they are provided as experimental test builds. The current reliance on system Git creates sandboxing limitations, so expect rough edges.
+
+
+
+
+Can stable and nightly builds be installed together?
+
+Yes. Pre-release AppImage installs use a separate launcher and install path when the selected release is branded as beta or nightly.
+
+
+
+
+Are standalone theme zip packs supported?
+
+No. OpenVCS currently supports built-in themes and plugin-provided themes, but not standalone theme `.zip` packs.
+
+
+
+---
+
+## License
-More screenshots and demos will be shared once the design stabilises and a reliable build is ready.
+OpenVCS is licensed under the [GPL-3.0](LICENSE).
diff --git a/channel-metadata.json b/channel-metadata.json
index 4e053fff..fcf57033 100644
--- a/channel-metadata.json
+++ b/channel-metadata.json
@@ -1,5 +1,5 @@
{
- "repo": "https://github.com/Jordonbc/OpenVCS",
+ "repo": "https://github.com/Open-VCS/OpenVCS",
"channels": {
"stable": {
"slug": "stable",
@@ -7,7 +7,7 @@
"productName": "OpenVCS",
"identifier": "dev.jordon.openvcs",
"windowTitle": "OpenVCS",
- "updaterEndpoints": ["https://github.com/Jordonbc/OpenVCS/releases/latest/download/latest.json"]
+ "updaterEndpoints": ["https://github.com/Open-VCS/OpenVCS/releases/latest/download/latest.json"]
},
"beta": {
"slug": "beta",
@@ -16,8 +16,8 @@
"identifier": "dev.jordon.openvcs.beta",
"windowTitle": "OpenVCS Beta",
"updaterEndpoints": [
- "https://github.com/Jordonbc/OpenVCS/releases/download/openvcs-beta/latest.json",
- "https://github.com/Jordonbc/OpenVCS/releases/latest/download/latest.json"
+ "https://github.com/Open-VCS/OpenVCS/releases/download/openvcs-beta/latest.json",
+ "https://github.com/Open-VCS/OpenVCS/releases/latest/download/latest.json"
]
},
"nightly": {
@@ -27,9 +27,9 @@
"identifier": "dev.jordon.openvcs.nightly",
"windowTitle": "OpenVCS Nightly",
"updaterEndpoints": [
- "https://github.com/Jordonbc/OpenVCS/releases/download/openvcs-nightly/latest.json",
- "https://github.com/Jordonbc/OpenVCS/releases/download/openvcs-beta/latest.json",
- "https://github.com/Jordonbc/OpenVCS/releases/latest/download/latest.json"
+ "https://github.com/Open-VCS/OpenVCS/releases/download/openvcs-nightly/latest.json",
+ "https://github.com/Open-VCS/OpenVCS/releases/download/openvcs-beta/latest.json",
+ "https://github.com/Open-VCS/OpenVCS/releases/latest/download/latest.json"
]
}
}
diff --git a/docs/Features.md b/docs/Features.md
new file mode 100644
index 00000000..849aee1c
--- /dev/null
+++ b/docs/Features.md
@@ -0,0 +1,122 @@
+
+
+
+
+# Features
+
+OpenVCS is plugin-first and VCS-agnostic. Features, themes, UI changes, and VCS integrations are all delivered by plugins.
+
+## Current capability areas
+
+
+
+ | Feature |
+ Status |
+ Notes |
+
+ | Clone repository | ✅ | Available through the Git plugin |
+ | Open existing repository | ✅ | Includes recent repository tracking |
+ | Reopen last repository on launch | ✅ | Optional behaviour |
+ | Working tree status | ✅ | Shows repository changes |
+ | Per-file diff | ✅ | File-level change inspection |
+ | Commit diff | ✅ | Commit-level inspection |
+ | Discard changes | ✅ | Working tree cleanup |
+
+
+
+
+ | Feature |
+ Status |
+ Notes |
+
+ | Stage files | ✅ | Standard index workflow |
+ | Partial staging | ✅ | Patch-based staging |
+ | Partial commits | ✅ | Commit selected patch content |
+ | Commit from index | ✅ | Commit staged changes |
+
+
+
+
+ | Feature |
+ Status |
+ Notes |
+
+ | List local branches | ✅ | Local branch visibility |
+ | List remote branches | ✅ | Remote branch visibility |
+ | Create branch | ✅ | Standard branch creation |
+ | Checkout branch | ✅ | Switch active branch |
+ | Rename branch | ✅ | Local branch rename |
+ | Delete branch | ✅ | Branch cleanup |
+ | Set upstream tracking | ✅ | Configure tracking |
+
+
+
+
+ | Feature |
+ Status |
+ Notes |
+
+ | Merge branch | ✅ | Branch merge workflow |
+ | Inspect conflicts | ✅ | Conflict details surfaced in UI |
+ | Checkout ours/theirs | ✅ | Conflict-side selection |
+ | Save merged result | ✅ | Persist resolved files |
+ | Launch external merge tool | ✅ | Uses configured external tooling |
+ | Abort merge | ✅ | Cancel active merge |
+ | Continue merge | ✅ | Complete merge after resolution |
+
+
+
+
+ | Feature |
+ Status |
+ Notes |
+
+ | List stashes | ✅ | Stash overview |
+ | Push stash | ✅ | Save working changes |
+ | Apply stash | ✅ | Apply without dropping |
+ | Pop stash | ✅ | Apply and remove |
+ | Drop stash | ✅ | Delete stash entry |
+ | Show stash | ✅ | Inspect stash content |
+ | Set remote URL | ✅ | Remote configuration |
+ | Fetch single remote | ✅ | Targeted fetch |
+ | Fetch all remotes | ✅ | Full remote update |
+ | Pull fast-forward only | ✅ | Conservative pull behaviour |
+ | Push | ✅ | Push local changes |
+
+
+
+
+ | Feature |
+ Status |
+ Notes |
+
+ | LFS fetch | ✅ | Fetch LFS objects |
+ | LFS pull | ✅ | Pull LFS objects |
+ | LFS prune | ✅ | Remove old LFS objects |
+ | LFS track/untrack | ✅ | Manage LFS paths |
+ | Inspect LFS tracked paths | ✅ | View tracked files/patterns |
+ | Trust SSH host keys | ✅ | Host-key trust helper |
+ | List SSH agent keys | ✅ | Agent key visibility |
+ | Add SSH agent keys | ✅ | Agent key helper |
+ | Discover SSH keys | ✅ | Local key discovery |
+
+
+
+
+ | Feature |
+ Status |
+ Notes |
+
+ | Light theme | ✅ | Built in |
+ | Dark theme | ✅ | Built in |
+ | Plugin-provided themes | ✅ | Supported through plugins |
+ Standalone theme .zip packs | ❌ | Not currently supported |
+ | npm plugin loading | 🧪 | Early support |
+ | local-path plugin loading | 🧪 | Early support |
+ | Update check/install | ✅ | Application update flow |
+ | VCS output log | ✅ | Dedicated output window |
+ | App log tail/clear | ✅ | Runtime log tooling |
+ | Plugin/theme store | 🧭 | Planned/exploratory |
+
+
+Legend: ✅ available · 🧪 early/experimental · 🧭 planned · ❌ not supported
diff --git a/install.sh b/install.sh
deleted file mode 100755
index 861a7fc3..00000000
--- a/install.sh
+++ /dev/null
@@ -1,400 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-# ===== OpenVCS Installer (interactive + CLI flags) =====
-# - No flags: show a dialog (Stable / Pre-release / Uninstall)
-# - --prerelease: install latest pre-release
-# - --uninstall : uninstall
-# - Safe atomic install; no rm -f/-rf
-# =======================================================
-
-# --- Config ---
-REPO_OWNER="Jordonbc"
-REPO_NAME="OpenVCS"
-
-INSTALL_DIR="${HOME}/Applications"
-DESKTOP_DIR="${HOME}/.local/share/applications"
-ICON_NAME="openvcs"
-ICON_SOURCE_PATH="docs/images/logos/OpenVCS-256.png"
-ICON_URL_BRANCH="Dev"
-ICON_THEME_DIR="${HOME}/.local/share/icons/hicolor"
-ICON_TARGET_DIR="${ICON_THEME_DIR}/256x256/apps"
-ICON_PATH="${ICON_TARGET_DIR}/${ICON_NAME}.png"
-
-APP_VARIANT="stable"
-APP_DISPLAY_NAME="OpenVCS"
-TARGET_BASENAME="openvcs.AppImage"
-DESKTOP_BASENAME="openvcs.desktop"
-TARGET_PATH="${INSTALL_DIR%/}/${TARGET_BASENAME}"
-DESKTOP_PATH="${DESKTOP_DIR}/${DESKTOP_BASENAME}"
-
-# --- State ---
-INCLUDE_PRERELEASE=false
-UNINSTALL=false
-INTERACTIVE_MODE=false
-DIALOG_TOOL="none"
-
-# --- Helpers: dialogs ---
-detect_dialog_tool() {
- if command -v kdialog >/dev/null 2>&1; then
- DIALOG_TOOL="kdialog"
- elif command -v zenity >/dev/null 2>&1; then
- DIALOG_TOOL="zenity"
- elif command -v whiptail >/dev/null 2>&1; then
- DIALOG_TOOL="whiptail"
- elif command -v dialog >/dev/null 2>&1; then
- DIALOG_TOOL="dialog"
- else
- DIALOG_TOOL="none"
- fi
-}
-
-show_info() { # $1: message
- case "$DIALOG_TOOL" in
- kdialog) kdialog --msgbox "$1" 2>/dev/null || true ;;
- zenity) zenity --info --title="OpenVCS Installer" --text="$1" 2>/dev/null || true ;;
- whiptail) whiptail --title "OpenVCS Installer" --msgbox "$1" 10 70 || true ;;
- dialog) dialog --title "OpenVCS Installer" --msgbox "$1" 10 70 || true; clear ;;
- *) printf '\n%s\n' "$1" ;;
- esac
-}
-
-show_error() { # $1: message
- case "$DIALOG_TOOL" in
- kdialog) kdialog --error "$1" 2>/dev/null || true ;;
- zenity) zenity --error --title="OpenVCS Installer" --text="$1" 2>/dev/null || true ;;
- whiptail) whiptail --title "OpenVCS Installer" --msgbox "❌ $1" 10 70 || true ;;
- dialog) dialog --title "OpenVCS Installer" --msgbox "❌ $1" 10 70 || true; clear ;;
- *) printf '\n❌ %s\n' "$1" >&2 ;;
- esac
-}
-
-install_icon() {
- [[ -z "${ICON_DOWNLOAD_URL:-}" ]] && return 1
- echo "Installing icon to ${ICON_PATH}..."
- mkdir -p "${ICON_TARGET_DIR}"
- local tmp_icon
- tmp_icon="$(mktemp)" || return 1
- if ! curl -fsSL "${ICON_DOWNLOAD_URL}" -o "${tmp_icon}"; then
- rm -f "${tmp_icon}"
- return 1
- fi
- install -m 0644 "${tmp_icon}" "${ICON_PATH}" || {
- rm -f "${tmp_icon}"
- return 1
- }
- rm -f "${tmp_icon}"
- if command -v gtk-update-icon-cache >/dev/null 2>&1; then
- gtk-update-icon-cache -q "${ICON_THEME_DIR}" >/dev/null 2>&1 || true
- fi
- return 0
-}
-
-refresh_desktop_entries() {
- sleep 2
- if command -v update-desktop-database >/dev/null 2>&1; then
- update-desktop-database "${DESKTOP_DIR}" >/dev/null 2>&1 || true
- fi
- if command -v xdg-desktop-menu >/dev/null 2>&1; then
- xdg-desktop-menu forceupdate >/dev/null 2>&1 || true
- fi
- if command -v kbuildsycoca6 >/dev/null 2>&1; then
- kbuildsycoca6 --noincremental >/dev/null 2>&1 || true
- elif command -v kbuildsycoca5 >/dev/null 2>&1; then
- kbuildsycoca5 --noincremental >/dev/null 2>&1 || true
- elif command -v kbuildsycoca4 >/dev/null 2>&1; then
- kbuildsycoca4 >/dev/null 2>&1 || true
- fi
-}
-
-set_install_variant() { # $1: stable|beta|nightly|prerelease
- case "$1" in
- beta)
- APP_VARIANT="beta"
- APP_DISPLAY_NAME="OpenVCS Beta"
- TARGET_BASENAME="openvcs-beta.AppImage"
- DESKTOP_BASENAME="openvcs-beta.desktop"
- ;;
- nightly)
- APP_VARIANT="nightly"
- APP_DISPLAY_NAME="OpenVCS Nightly"
- TARGET_BASENAME="openvcs-nightly.AppImage"
- DESKTOP_BASENAME="openvcs-nightly.desktop"
- ;;
- prerelease)
- APP_VARIANT="prerelease"
- APP_DISPLAY_NAME="OpenVCS Pre-release"
- TARGET_BASENAME="openvcs-prerelease.AppImage"
- DESKTOP_BASENAME="openvcs-prerelease.desktop"
- ;;
- *)
- APP_VARIANT="stable"
- APP_DISPLAY_NAME="OpenVCS"
- TARGET_BASENAME="openvcs.AppImage"
- DESKTOP_BASENAME="openvcs.desktop"
- ;;
- esac
-
- TARGET_PATH="${INSTALL_DIR%/}/${TARGET_BASENAME}"
- DESKTOP_PATH="${DESKTOP_DIR}/${DESKTOP_BASENAME}"
-}
-
-detect_release_variant() { # $1: release tag, $2: asset name
- local combined
- combined="${1,,} ${2,,}"
-
- case "$combined" in
- *nightly*|*openvcs-nightly*) printf 'nightly' ;;
- *beta*|*openvcs-beta*) printf 'beta' ;;
- *)
- if $INCLUDE_PRERELEASE; then
- printf 'prerelease'
- else
- printf 'stable'
- fi
- ;;
- esac
-}
-
-remove_file_if_present() { # $1: path, $2: label
- if [[ -f "$1" ]]; then
- echo "Removing $2: $1"
- rm "$1"
- else
- echo "No $2 found at $1"
- fi
-}
-
-# --- Parse flags ---
-for arg in "${@:-}"; do
- case "$arg" in
- --prerelease) INCLUDE_PRERELEASE=true ;;
- --uninstall) UNINSTALL=true ;;
- --help|-h)
- cat < interactive dialog: stable (default), prerelease, or uninstall.
-EOF
- exit 0
- ;;
- esac
-done
-
-# --- Interactive mode (no flags) ---
-if ! $INCLUDE_PRERELEASE && ! $UNINSTALL && [[ "$#" -eq 0 ]]; then
- detect_dialog_tool
- INTERACTIVE_MODE=true
-
- cancel_exit() { echo "Cancelled by user."; exit 0; }
-
- CHOICE=""
- RC=0
- case "$DIALOG_TOOL" in
- kdialog)
- CHOICE="$(kdialog --menu "OpenVCS installer: choose action" \
- stable "Install latest stable" \
- prerelease "Install latest pre-release" \
- uninstall "Uninstall OpenVCS")" || RC=$?
- (( RC != 0 )) && cancel_exit
- ;;
- zenity)
- CHOICE="$(zenity --list --title="OpenVCS Installer" \
- --text="Choose action" --radiolist \
- --column="" --column="Option" \
- TRUE "stable" FALSE "prerelease" FALSE "uninstall")" || RC=$?
- (( RC != 0 )) && cancel_exit
- ;;
- whiptail)
- CHOICE="$(whiptail --title "OpenVCS Installer" --radiolist "Choose action" 12 64 3 \
- "stable" "Install latest stable" ON \
- "prerelease" "Install latest pre-release" OFF \
- "uninstall" "Uninstall OpenVCS" OFF 3>&1 1>&2 2>&3)" || RC=$?
- (( RC != 0 )) && cancel_exit
- ;;
- dialog)
- CHOICE="$(dialog --title "OpenVCS Installer" --radiolist "Choose action" 12 64 3 \
- "stable" "Install latest stable" ON \
- "prerelease" "Install latest pre-release" OFF \
- "uninstall" "Uninstall OpenVCS" OFF 3>&1 1>&2 2>&3)" || RC=$?
- clear
- (( RC != 0 )) && cancel_exit
- ;;
- none)
- printf '\nOpenVCS installer\n 1) Install stable (default)\n 2) Install pre-release\n 3) Uninstall\nSelect [1-3] (Esc/Ctrl-D to cancel): '
- if ! read -r ans; then
- cancel_exit
- fi
- case "${ans:-1}" in
- 2) CHOICE="prerelease" ;;
- 3) CHOICE="uninstall" ;;
- *) CHOICE="stable" ;;
- esac
- ;;
- esac
-
- # Extra guard: empty choice -> cancel
- [[ -z "${CHOICE:-}" ]] && cancel_exit
-
- case "${CHOICE}" in
- prerelease) INCLUDE_PRERELEASE=true ;;
- uninstall) UNINSTALL=true ;;
- *) ;; # stable default
- esac
-fi
-
-# --- Error trap: show GUI error if interactive ---
-trap 'if $INTERACTIVE_MODE; then show_error "Installation failed. Check network access or GitHub releases, then try again."; fi' ERR
-
-# --- Uninstall mode ---
-if $UNINSTALL; then
- echo "Uninstalling OpenVCS variants..."
- for variant in stable beta nightly prerelease; do
- set_install_variant "$variant"
- remove_file_if_present "${TARGET_PATH}" "${APP_DISPLAY_NAME} AppImage"
- remove_file_if_present "${DESKTOP_PATH}" "${APP_DISPLAY_NAME} desktop entry"
- done
-
- if [[ -f "${ICON_PATH}" ]]; then
- echo "Removing icon: ${ICON_PATH}"
- rm "${ICON_PATH}"
- if command -v gtk-update-icon-cache >/dev/null 2>&1; then
- gtk-update-icon-cache -q "${ICON_THEME_DIR}" >/dev/null 2>&1 || true
- fi
- else
- echo "No icon found at ${ICON_PATH}"
- fi
-
- refresh_desktop_entries
-
- echo "✅ OpenVCS variants uninstalled."
- if $INTERACTIVE_MODE; then
- show_info "✅ OpenVCS variants were uninstalled."
- fi
- exit 0
-fi
-
-# --- Install mode ---
-mkdir -p "${INSTALL_DIR}" "${DESKTOP_DIR}"
-
-# --- Fetch release metadata ---
-if $INCLUDE_PRERELEASE; then
- API_URL="https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/releases?per_page=20"
- echo "Fetching ${REPO_NAME} pre-releases..."
- RELEASES_JSON="$(curl -fsSL "${API_URL}")"
-else
- API_URL="https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/releases/latest"
- echo "Fetching ${REPO_NAME} latest stable..."
- RELEASES_JSON="$(curl -fsSL "${API_URL}")"
-fi
-
-# --- Extract AppImage asset info ---
-DOWNLOAD_URL=""
-ASSET_NAME=""
-RELEASE_TAG=""
-ICON_DOWNLOAD_URL=""
-
-if command -v jq >/dev/null 2>&1; then
- if $INCLUDE_PRERELEASE; then
- SEL="$(jq -r '
- ( .[] | select(.draft|not) | select(.prerelease==true) ) as $rel
- | ($rel.assets[] | select(.name|endswith(".AppImage"))
- | [ .browser_download_url, .name, $rel.tag_name ] | @tsv)
- ' <<<"$RELEASES_JSON" | head -n1)"
- ICON_SEL="$(jq -r '
- ( .[] | select(.draft|not) | select(.prerelease==true) ) as $rel
- | ($rel.assets[] | select(.name|test("(?i)icon.*\\.png$"))
- | [ .browser_download_url, .name ] | @tsv)
- ' <<<"$RELEASES_JSON" | head -n1)"
- else
- SEL="$(jq -r '
- . as $rel
- | ($rel.assets[] | select(.name|endswith(".AppImage"))
- | [ .browser_download_url, .name, $rel.tag_name ] | @tsv)
- ' <<<"$RELEASES_JSON" | head -n1)"
- ICON_SEL="$(jq -r '
- . as $rel
- | ($rel.assets[] | select(.name|test("(?i)icon.*\\.png$"))
- | [ .browser_download_url, .name ] | @tsv)
- ' <<<"$RELEASES_JSON" | head -n1)"
- fi
- if [[ -n "${SEL:-}" ]]; then
- IFS=$'\t' read -r DOWNLOAD_URL ASSET_NAME RELEASE_TAG <<<"${SEL}"
- fi
- if [[ -n "${ICON_SEL:-}" ]]; then
- IFS=$'\t' read -r ICON_DOWNLOAD_URL _ <<<"${ICON_SEL}"
- fi
-else
- DOWNLOAD_URL="$(printf '%s' "$RELEASES_JSON" \
- | grep -oE '"browser_download_url":[[:space:]]*"[^"]+\.AppImage"' \
- | head -n1 | sed -E 's/.*"([^"]+)".*/\1/')"
- ASSET_NAME="$(basename "${DOWNLOAD_URL:-}")"
- RELEASE_TAG="unknown"
-fi
-
-if [[ -z "${ICON_DOWNLOAD_URL}" ]]; then
- ICON_DOWNLOAD_URL="https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${ICON_URL_BRANCH}/${ICON_SOURCE_PATH}"
-fi
-
-if [[ -z "${DOWNLOAD_URL}" ]]; then
- echo "error: no AppImage asset found in the selected release." >&2
- exit 1
-fi
-
-echo "Selected release tag: ${RELEASE_TAG:-unknown}"
-$INCLUDE_PRERELEASE && echo "(including pre-releases)"
-
-set_install_variant "$(detect_release_variant "${RELEASE_TAG:-}" "${ASSET_NAME:-}")"
-echo "Installing variant: ${APP_DISPLAY_NAME}"
-
-# --- Download safely (atomic on same filesystem) ---
-TMP_FILE="$(mktemp --tmpdir="${INSTALL_DIR}" ".openvcs.XXXXXXXX")"
-trap '[[ -f "${TMP_FILE:-}" ]] && rm "${TMP_FILE}"' EXIT
-echo "Downloading ${ASSET_NAME}..."
-curl -fL "${DOWNLOAD_URL}" -o "${TMP_FILE}"
-
-echo "Installing to ${TARGET_PATH}..."
-mv "${TMP_FILE}" "${TARGET_PATH}"
-trap - EXIT
-chmod +x "${TARGET_PATH}"
-
-if ! install_icon; then
- echo "warning: failed to install icon. Desktop entry may lack icon." >&2
-fi
-
-# --- Desktop entry ---
-echo "Writing desktop entry: ${DESKTOP_PATH}"
-cat > "${DESKTOP_PATH}" <