Initial commit: NexusOS - local AI assistant platform
@@ -0,0 +1,43 @@
|
|||||||
|
---
|
||||||
|
name: Ponyman
|
||||||
|
description: "Minimalist coding agent with a caveman-speaking toggle. Use for pragmatic bug fixes, small implementations, reviews, and cleanup where the shortest correct solution matters. Say 'caveman mode' for compressed speech or 'normal mode' for standard speech."
|
||||||
|
tools: [read, search, edit, execute, todo]
|
||||||
|
user-invocable: true
|
||||||
|
---
|
||||||
|
You are Ponytail Caveman, a pragmatic senior coding agent.
|
||||||
|
|
||||||
|
Your engineering rule is ponytail minimalism: understand the real control path, reuse existing code, prefer the standard library and native platform features, and make the smallest correct change. Fix root causes. Do not add speculative abstractions, dependencies, boilerplate, or unrelated refactors. Never simplify away security, validation, error handling, accessibility, or tests needed to protect changed behavior. After this statement, the rest of the readme will be in caveman talk to provide a reference for how it should sound.
|
||||||
|
|
||||||
|
Caveman talk dumb. Grunt words. "Me", "you", "big", "broke", "good". Short. Sound like cave person poke rock with stick. BUT point always land — reader still know what happen and what do next. Dumb sound, smart meaning. Keep code, file name, command, error word exact — no dumb those.
|
||||||
|
|
||||||
|
## How Me Talk
|
||||||
|
- No word say: me talk normal. Clear.
|
||||||
|
- You say `caveman mode`, `talk caveman`, or `/caveman`: me go dumb caveman. Still say enough, point land.
|
||||||
|
- You say `normal mode`, `talk normally`, or `/caveman normal`: me talk normal again.
|
||||||
|
- Me keep same talk till you change it.
|
||||||
|
- Talk change word only. Me brain and safe stay smart.
|
||||||
|
|
||||||
|
## Me Do Work Like This
|
||||||
|
1. Find thing. File, symbol, broke part, command, or test.
|
||||||
|
2. Look small part near. Make one guess me can prove wrong. Pick one cheap check.
|
||||||
|
3. Fix right code path. Smallest patch. No more.
|
||||||
|
4. Run small check. Now, not later.
|
||||||
|
5. Add or fix test for tricky part. Security, save-data, parse, error path — these most.
|
||||||
|
6. Run big check when change touch many module.
|
||||||
|
7. Other dirty change — no touch. Never reset, revert, commit, or make branch unless you ask.
|
||||||
|
|
||||||
|
## Me Pick Tool
|
||||||
|
- Read and look before me edit.
|
||||||
|
- Use pattern and command repo already got.
|
||||||
|
- Use real parser/API for structured data.
|
||||||
|
- Use `apply_patch` for hand edit.
|
||||||
|
- Like focused test, lint, typecheck, or build more than diff-only check.
|
||||||
|
- Comment rare, only useful. No talk what code already say.
|
||||||
|
|
||||||
|
## Me Say Back
|
||||||
|
Normal mode: say what change, what me check, what risk left. Few short line.
|
||||||
|
|
||||||
|
Caveman mode: dumb short grunt, point still land. Like this:
|
||||||
|
`Me fix big bug. Add test. pytest: 8 pass. One warning still there — old deprecation, no scare.`
|
||||||
|
|
||||||
|
Look-over work: bad thing first, worst on top, with file link and how me fix. No bad thing → say so, name test gap or risk left.
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
Promethean/
|
||||||
|
ollama/
|
||||||
|
interface/web/node_modules/
|
||||||
|
interface/web/dist/
|
||||||
|
runtime/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
synapse/memory/memory.db
|
||||||
|
synapse/memory/memory.db-wal
|
||||||
|
synapse/memory/memory.db-shm
|
||||||
|
*.db-wal
|
||||||
|
*.db-shm
|
||||||
|
.DS_Store
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Ollama model blobs (~15G, regenerable via `ollama pull`)
|
||||||
|
models/
|
||||||
|
|
||||||
|
# local editor / assistant tooling
|
||||||
|
.vscode/
|
||||||
|
.claude/
|
||||||
|
.claude-backup/
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Promethean Terminal shell init
|
||||||
|
[[ -f ~/.bashrc ]] && source ~/.bashrc
|
||||||
|
export VIRTUAL_ENV_DISABLE_PROMPT=1
|
||||||
|
if [[ -f "$HOME/nexus-core/Promethean/bin/activate" ]]; then
|
||||||
|
source "$HOME/nexus-core/Promethean/bin/activate"
|
||||||
|
fi
|
||||||
|
export PS1='\[\e[0;35m\](Promethean)\[\e[0m\] ${debian_chroot:+($debian_chroot)}\[\e[0;37m\]\u@\h\[\e[0m\]:\[\e[1;32m\]\w\[\e[0m\]\$ '
|
||||||
|
printf '\e]0;Promethean Terminal\a'
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## What is NexusOS
|
||||||
|
|
||||||
|
NexusOS is a local AI assistant platform. It runs a Python/FastAPI backend (Synapse) that interfaces with a locally bundled Ollama instance, a dedicated memory microservice, and a React/Vite frontend. All AI inference runs through Ollama on `localhost`; no external AI provider is configured or called.
|
||||||
|
|
||||||
|
## Running the Project
|
||||||
|
|
||||||
|
NexusOS runs **single-process**: the Synapse backend on port 8000 serves the
|
||||||
|
built web UI (`interface/web/dist`) itself, so there is no separate Vite server
|
||||||
|
at runtime. Ollama is started manually (sidebar **Start AI** / `nexus-cli.sh
|
||||||
|
start --ai`), not on backend startup.
|
||||||
|
|
||||||
|
**Windows (recommended):**
|
||||||
|
```powershell
|
||||||
|
powershell -ExecutionPolicy Bypass -File .\install-windows.ps1 # one-time native install
|
||||||
|
.\launch_nexus.ps1 # memory :8001 + backend :8000
|
||||||
|
```
|
||||||
|
|
||||||
|
**Linux full stack (dev):**
|
||||||
|
```bash
|
||||||
|
./launch_nexus.sh
|
||||||
|
```
|
||||||
|
This activates the `Promethean` venv and starts the memory service on port 8001 and the Synapse backend on port 8000 (which also serves the built UI). It additionally starts a **Vite dev server** for frontend hot-reload — a Linux-dev convenience, unlike the single-process Windows/production path where the backend serves `dist/` alone. It does **not** start Ollama.
|
||||||
|
|
||||||
|
**Individual services via CLI:**
|
||||||
|
```bash
|
||||||
|
# From nexus-core/ with Promethean venv active:
|
||||||
|
source Promethean/bin/activate
|
||||||
|
|
||||||
|
# Backend (serves the built UI at :8000 too)
|
||||||
|
uvicorn synapse.main:sio_app --host 0.0.0.0 --port 8000 --reload
|
||||||
|
|
||||||
|
# Memory service
|
||||||
|
uvicorn synapse.memory.service:app --host 0.0.0.0 --port 8001 --reload
|
||||||
|
|
||||||
|
# Frontend DEV server (hot-reload) — only when editing the UI; production is the
|
||||||
|
# built dist/ served by the backend. Run `npm run build` to refresh dist/.
|
||||||
|
cd interface/web && npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
**Management CLI** (`ncp`) — start/stop services with PID tracking, plus terminal
|
||||||
|
access to the same features as the web UI (all via the REST API on `:8000`):
|
||||||
|
```bash
|
||||||
|
./management/nexus-cli.sh start # starts backend + frontend
|
||||||
|
./management/nexus-cli.sh stop
|
||||||
|
./management/nexus-cli.sh start --backend|-b / --frontend|-f / --memory|-m
|
||||||
|
|
||||||
|
# Feature commands (dispatch to management/nexus_api.py — httpx, no TUI):
|
||||||
|
ncp chat "<message>" # stream a reply (POST /chat/stream)
|
||||||
|
ncp memory list|add <text>|rm <id>
|
||||||
|
ncp playbook list|show <id> # first playbook (*) is the active system prompt
|
||||||
|
ncp history [query] # recent conversations
|
||||||
|
```
|
||||||
|
The old curses TUIs (`nexus-chat.py`, `nexus-playbook.py`) were removed in favor of
|
||||||
|
these API-backed subcommands. The CLI covers chat, memory, playbooks, and history;
|
||||||
|
the web UI and control panel expose the remaining management features.
|
||||||
|
`management/controlpanel.py` (tkinter GUI, wired into the XFCE panel via
|
||||||
|
`bin/panel/nexus-popup.py`) stays.
|
||||||
|
|
||||||
|
**Checks (the release gate):**
|
||||||
|
```bash
|
||||||
|
./bin/check.sh # pytest (tests/ + management/) + eslint + .ps1 parse check
|
||||||
|
```
|
||||||
|
There is no hosted CI — the remote is self-hosted Gitea with no act_runner — so
|
||||||
|
this script *is* the gate. Run it before tagging a release.
|
||||||
|
|
||||||
|
**Frontend lint only:**
|
||||||
|
```bash
|
||||||
|
cd interface/web && npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
**Frontend build:**
|
||||||
|
```bash
|
||||||
|
cd interface/web && npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Python venv
|
||||||
|
All Python code runs inside `Promethean/` (a local venv). Always activate it before running backend commands: `source Promethean/bin/activate`. Dependencies are layered: `requirements-base.txt` holds the GPU-agnostic core, and a thin overlay pins the right PyTorch build for the target — `requirements-amd.txt` (ROCm), `requirements-nvidia.txt` (CUDA, generated by `bin/gen-nvidia-reqs.py`), or `requirements-wsl.txt` (CPU-only). `bin/install.sh` selects NVIDIA, AMD, or CPU/WSL requirements from the host.
|
||||||
|
|
||||||
|
### Synapse Backend (`synapse/`)
|
||||||
|
FastAPI app at `synapse/main.py`. Key responsibilities:
|
||||||
|
- `/chat/stream` — chat with Ollama; streaming uses SSE (the only chat endpoint — the non-stream `/chat` was removed). After each exchange the stream endpoint calls the Memory Service to auto-extract persistent facts.
|
||||||
|
- `/playbooks` — CRUD for playbooks stored as YAML files in `data/playbooks/` via `synapse/playbooks/store.py`.
|
||||||
|
- `/memory` — CRUD for persistent facts (proxies the same SQLite store as the memory service).
|
||||||
|
- `/models` — lists, pulls, and deletes Ollama models by proxying Ollama's HTTP API.
|
||||||
|
- `/settings` and `/ollama` — persist runtime settings and control Ollama lifecycle.
|
||||||
|
- `/conversations` — persists, retrieves, edits, deletes, and exports full chat history from SQLite.
|
||||||
|
- `/icons` — lists local application icons and applies NexusOS branding.
|
||||||
|
|
||||||
|
**System prompt assembly** (in `main.py` `chat_stream_endpoint`): the final system prompt is built by layering the active playbook instructions → reference playbook context → persistent memory facts → relevant past conversation snippets retrieved by `store.search_conversations`.
|
||||||
|
|
||||||
|
### Memory Service (`synapse/memory/`)
|
||||||
|
A separate FastAPI app on port 8001. `service.py` exposes `/memories/extract` which calls `extractor.py` — an Ollama prompt that decides whether to persist a new fact from a conversation exchange. The main Synapse backend calls this asynchronously after each streaming response. Both services share the same SQLite database (`synapse/memory/memory.db`).
|
||||||
|
|
||||||
|
### Playbook System (`synapse/playbooks/` + `synapse/playbook_manager.py`)
|
||||||
|
Playbooks are ordered records (title, goal, instructions, tags), each persisted as a `{id}.yaml` file in `data/playbooks/` by `PlaybookFileStore` (the dir is `PLAYBOOK_DIR` in `nexus_config.py`). The **first** playbook by order is the active system prompt; all subsequent playbooks are injected as reference context. `PlaybookManager` is the thin class the backend uses to retrieve them and assemble the system prompt.
|
||||||
|
|
||||||
|
### Ollama (`ollama/bin/ollama`)
|
||||||
|
A bundled Ollama binary lives at `ollama/bin/ollama`. `OllamaManager` in `synapse/ollama_manager.py` manages its lifecycle (start/stop/health-check) and selects the best available model. GPU detection uses Vulkan (`vulkaninfo`) to prefer discrete AMD/NVIDIA GPUs. The Ollama HTTP API is at `http://127.0.0.1:11434` (overridable via `OLLAMA_HOST` env var).
|
||||||
|
|
||||||
|
### Frontend (`interface/web/`)
|
||||||
|
React 19 + Vite. No routing library — `App.jsx` manages page state in a single `currentPage` useState. All API calls hit `http://localhost:8000` (configured in `src/config.js`). Built to `dist/` (gitignored) via `npm run build` and served by the backend at `:8000` — the mount is in `synapse/main.py` (`_DIST` at `/`, guarded by `is_dir()`), so `dist/` must be built for the UI to appear. Pages: Chatbot, Playbook editor, Conversation History, Models, Memory, Settings, Logs.
|
||||||
|
|
||||||
|
### Persistent Storage
|
||||||
|
Most data lands in `synapse/memory/memory.db` (SQLite, WAL mode). Tables: memory facts, conversations, messages, app settings. `synapse/memory/store.py` (`PersistentMemoryStore`) owns the schema and all queries. Playbooks are the exception — they live as YAML files in `data/playbooks/` (see Playbook System). `nexus_config.py` defines all paths; it also ensures all required directories exist on import.
|
||||||
|
|
||||||
|
### Logs & Runtime State
|
||||||
|
- `runtime/backend.log`, `runtime/frontend.log`, `runtime/memory.log` — service stdout
|
||||||
|
- `runtime/logs/ollama.log`, `runtime/logs/chat.log`
|
||||||
|
- `runtime/pids/backend.pid`, `runtime/pids/frontend.pid` — used by the management CLI
|
||||||
|
|
||||||
|
## Key Config
|
||||||
|
|
||||||
|
| Concern | Location |
|
||||||
|
|---|---|
|
||||||
|
| Ollama host | `OLLAMA_HOST` env var (default `http://127.0.0.1:11434`) |
|
||||||
|
| All filesystem paths | `synapse/nexus_config.py` `Settings` class |
|
||||||
|
| Frontend API base URL | `interface/web/src/config.js` |
|
||||||
|
| Default chat/memory models | `synapse/nexus_config.py` `DEFAULT_CHAT_MODEL` / `DEFAULT_MEMORY_MODEL` |
|
||||||
|
| Python dependencies (base) | `requirements-base.txt` |
|
||||||
|
| Python dependencies (AMD/ROCm) | `requirements-amd.txt` |
|
||||||
|
| Python dependencies (NVIDIA/CUDA) | `requirements-nvidia.txt` (generated by `bin/gen-nvidia-reqs.py`) |
|
||||||
|
| Python dependencies (WSL/CPU) | `requirements-wsl.txt` |
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
<div align="center">
|
||||||
|
|
||||||
|
<img src="assets/gitnexus-logo.svg" alt="NexusOS" width="96">
|
||||||
|
|
||||||
|
# NexusOS
|
||||||
|
|
||||||
|
**A local-first AI assistant platform.** Runs entirely on your machine — a
|
||||||
|
Python/FastAPI backend, a bundled Ollama instance for inference, a persistent
|
||||||
|
memory service, and a React frontend. No external AI provider is called.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What it is
|
||||||
|
|
||||||
|
NexusOS ("Nexus") is a self-hosted assistant you actually own. All inference
|
||||||
|
runs through a **locally bundled Ollama** on `localhost`; conversations, facts,
|
||||||
|
and settings live in local SQLite. It ships with desktop branding (XFCE theme,
|
||||||
|
icons, boot splash) so it can be run as a full assistant environment, not just
|
||||||
|
a web app.
|
||||||
|
|
||||||
|
- **Chat** — streaming responses from local Ollama models (SSE).
|
||||||
|
- **Persistent memory** — a dedicated service auto-extracts durable facts from
|
||||||
|
each exchange and layers them into future prompts.
|
||||||
|
- **Playbooks** — ordered YAML system-prompt records; the first is the active
|
||||||
|
persona, the rest are injected as reference context.
|
||||||
|
- **Model management** — list, pull, and delete Ollama models from the UI/CLI.
|
||||||
|
- **History** — full conversation persistence, search, edit, export.
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
NexusOS runs **single-process**: the backend on `:8000` serves the built web UI
|
||||||
|
itself, so there's no separate frontend server at runtime. Ollama is started
|
||||||
|
manually from the app (**Start AI** in the sidebar), not at boot.
|
||||||
|
|
||||||
|
### Windows (recommended)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# 1. Install Git, then clone (Gitea user + PAT):
|
||||||
|
winget install Git.Git
|
||||||
|
# open a NEW PowerShell window, then:
|
||||||
|
git clone https://git.enderofwings.com/enderofwings/NexusOS.git nexus-core
|
||||||
|
cd nexus-core
|
||||||
|
|
||||||
|
# 2. Native install — winget Python/Node/Ollama, venv, pip, web build, desktop icon
|
||||||
|
powershell -ExecutionPolicy Bypass -File .\install-windows.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Execution policy:** Windows blocks unsigned `.ps1` scripts by default, so
|
||||||
|
> run them with `-ExecutionPolicy Bypass` as shown (a one-run override — nothing
|
||||||
|
> permanent). Double-clicking `install-windows.ps1` or running `.\install-windows.ps1`
|
||||||
|
> bare will fail with *"running scripts is disabled on this system"*.
|
||||||
|
> The installer self-elevates (a UAC prompt will appear).
|
||||||
|
>
|
||||||
|
> To allow scripts persistently instead (then you can run `.\...ps1` directly):
|
||||||
|
> ```powershell
|
||||||
|
> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
|
||||||
|
> ```
|
||||||
|
|
||||||
|
Then double-click the **NexusOS** desktop icon (the shortcut already passes the
|
||||||
|
bypass), or launch from a shell with:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
powershell -ExecutionPolicy Bypass -File .\launch_nexus.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
The app opens at `:8000`; click **Start AI** to launch Ollama. The installer
|
||||||
|
uses `requirements-wsl.txt` (CPU-only, pure-Python — no ML stack, since Ollama
|
||||||
|
does all inference over HTTP).
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Install deps into the Promethean venv (auto-selects AMD/NVIDIA/CPU)
|
||||||
|
./bin/install.sh
|
||||||
|
|
||||||
|
# 2. Launch (memory :8001, backend :8000 — backend also serves the built UI)
|
||||||
|
./launch_nexus.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Python deps are layered: `requirements-base.txt` (GPU-agnostic core) plus one
|
||||||
|
GPU overlay — `requirements-amd.txt` (ROCm) or `requirements-nvidia.txt` (CUDA).
|
||||||
|
`requirements-wsl.txt` is the standalone CPU-only runtime (no base overlay).
|
||||||
|
`bin/install.sh` picks the right one for the host.
|
||||||
|
|
||||||
|
### Individual services
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source Promethean/bin/activate
|
||||||
|
|
||||||
|
uvicorn synapse.main:sio_app --host 0.0.0.0 --port 8000 --reload # backend (serves the UI too)
|
||||||
|
uvicorn synapse.memory.service:app --host 0.0.0.0 --port 8001 --reload # memory
|
||||||
|
|
||||||
|
# Frontend dev server (hot-reload) — only needed when editing the UI;
|
||||||
|
# production serves the built dist/ from the backend at :8000.
|
||||||
|
cd interface/web && npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## CLI (`ncp`)
|
||||||
|
|
||||||
|
Start/stop services and drive the same features as the web UI over the REST API:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./management/nexus-cli.sh start # backend + frontend (--backend|--frontend|--memory)
|
||||||
|
./management/nexus-cli.sh stop
|
||||||
|
|
||||||
|
ncp chat "<message>" # stream a reply
|
||||||
|
ncp memory list | add <text> | rm <id>
|
||||||
|
ncp playbook list | show <id> # first playbook (*) = active system prompt
|
||||||
|
ncp history [query] # recent conversations
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
| Component | Location | Role |
|
||||||
|
|---|---|---|
|
||||||
|
| **Synapse** (backend) | `synapse/` | FastAPI app. `/chat/stream`, `/playbooks`, `/memory`, `/models`, `/conversations`, `/settings`, `/ollama`, `/icons`. Assembles the system prompt: active playbook → reference playbooks → memory facts → relevant past snippets. |
|
||||||
|
| **Memory service** | `synapse/memory/` | Separate FastAPI app (:8001). `/memories/extract` uses an Ollama prompt to decide what to persist. Shares the SQLite DB with the backend. |
|
||||||
|
| **Playbooks** | `synapse/playbooks/` + `data/playbooks/` | Ordered `{id}.yaml` records managed by `PlaybookManager`. |
|
||||||
|
| **Ollama** | `ollama/bin/ollama` | Bundled binary; `OllamaManager` handles lifecycle + model selection (Vulkan GPU detection). HTTP API at `127.0.0.1:11434`. |
|
||||||
|
| **Frontend** | `interface/web/` | React 19 + Vite. Built to `dist/` and served by the backend at `:8000` (single-process). Pages: Chat, Playbooks, History, Models, Memory, Settings. |
|
||||||
|
|
||||||
|
### Storage
|
||||||
|
|
||||||
|
Most data lives in `synapse/memory/memory.db` (SQLite, WAL) — facts,
|
||||||
|
conversations, messages, settings. Playbooks are the exception (YAML files in
|
||||||
|
`data/playbooks/`). All paths are defined in `synapse/nexus_config.py`.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
synapse/ FastAPI backend + memory service + playbook/ollama managers
|
||||||
|
interface/web/ React + Vite frontend
|
||||||
|
management/ nexus-cli.sh, ncp API client, control panel, desktop theme
|
||||||
|
bin/ install, backup/restore, panel + provisioning scripts
|
||||||
|
assets/ branding: icons, boot splash, XFCE/GTK theme
|
||||||
|
data/playbooks/ active playbook YAML
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
| Concern | Location |
|
||||||
|
|---|---|
|
||||||
|
| Ollama host | `OLLAMA_HOST` env (default `http://127.0.0.1:11434`) |
|
||||||
|
| Filesystem paths | `synapse/nexus_config.py` |
|
||||||
|
| Frontend API base URL | `interface/web/src/config.js` |
|
||||||
|
| Python deps | `requirements-base.txt` + amd/nvidia GPU overlay; `requirements-wsl.txt` = standalone CPU runtime |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<div align="center"><sub>NexusOS · local AI, self-hosted on <a href="https://git.enderofwings.com/enderofwings/NexusOS">GitNexus</a></sub></div>
|
||||||
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 2.1 MiB |
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Bakes a real, dereferenced copy of the NexusOS Plymouth theme into the
|
||||||
|
# initramfs. The theme files live in nexus-core and are exposed at
|
||||||
|
# /usr/share/plymouth/themes/my-custom-logo via a symlink into /home, which
|
||||||
|
# the stock initramfs plymouth hook copies verbatim -> it dangles at early
|
||||||
|
# boot (before /home is mounted) and Plymouth falls back to text mode.
|
||||||
|
# This hook runs after the stock "plymouth" hook and replaces that dangling
|
||||||
|
# symlink with the actual theme files.
|
||||||
|
|
||||||
|
PREREQS="plymouth"
|
||||||
|
prereqs() { echo "$PREREQS"; }
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
prereqs)
|
||||||
|
prereqs
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
. /usr/share/initramfs-tools/hook-functions
|
||||||
|
|
||||||
|
THEME_SRC="/home/jon/nexus-core/assets/boot/my-custom-logo"
|
||||||
|
THEME_DEST="${DESTDIR}/usr/share/plymouth/themes/my-custom-logo"
|
||||||
|
|
||||||
|
[ -d "${THEME_SRC}" ] || exit 0
|
||||||
|
|
||||||
|
rm -rf "${THEME_DEST}"
|
||||||
|
mkdir -p "${THEME_DEST}"
|
||||||
|
cp -aL "${THEME_SRC}/." "${THEME_DEST}/"
|
||||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 151 B |
|
After Width: | Height: | Size: 469 B |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 494 B |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
@@ -0,0 +1,54 @@
|
|||||||
|
[Plymouth Theme]
|
||||||
|
Name=My Custom Logo
|
||||||
|
Description=Custom boot logo with shimmer effect
|
||||||
|
ModuleName=two-step
|
||||||
|
|
||||||
|
[two-step]
|
||||||
|
Font=Cantarell 12
|
||||||
|
TitleFont=Cantarell Light 30
|
||||||
|
ImageDir=/usr/share/plymouth/themes/my-custom-logo
|
||||||
|
DialogHorizontalAlignment=.5
|
||||||
|
DialogVerticalAlignment=.382
|
||||||
|
TitleHorizontalAlignment=.5
|
||||||
|
TitleVerticalAlignment=.382
|
||||||
|
HorizontalAlignment=.5
|
||||||
|
VerticalAlignment=.5
|
||||||
|
WatermarkHorizontalAlignment=.5
|
||||||
|
WatermarkVerticalAlignment=.96
|
||||||
|
Transition=none
|
||||||
|
TransitionDuration=0.0
|
||||||
|
BackgroundStartColor=0x000000
|
||||||
|
BackgroundEndColor=0x000000
|
||||||
|
ProgressBarBackgroundColor=0x606060
|
||||||
|
ProgressBarForegroundColor=0xffffff
|
||||||
|
MessageBelowAnimation=true
|
||||||
|
|
||||||
|
[boot-up]
|
||||||
|
UseEndAnimation=false
|
||||||
|
|
||||||
|
[shutdown]
|
||||||
|
UseEndAnimation=false
|
||||||
|
|
||||||
|
[reboot]
|
||||||
|
UseEndAnimation=false
|
||||||
|
|
||||||
|
[updates]
|
||||||
|
SuppressMessages=true
|
||||||
|
ProgressBarShowPercentComplete=true
|
||||||
|
UseProgressBar=true
|
||||||
|
Title=Installing Updates...
|
||||||
|
SubTitle=Do not turn off your computer
|
||||||
|
|
||||||
|
[system-upgrade]
|
||||||
|
SuppressMessages=true
|
||||||
|
ProgressBarShowPercentComplete=true
|
||||||
|
UseProgressBar=true
|
||||||
|
Title=Upgrading System...
|
||||||
|
SubTitle=Do not turn off your computer
|
||||||
|
|
||||||
|
[firmware-upgrade]
|
||||||
|
SuppressMessages=true
|
||||||
|
ProgressBarShowPercentComplete=true
|
||||||
|
UseProgressBar=true
|
||||||
|
Title=Upgrading Firmware...
|
||||||
|
SubTitle=Do not turn off your computer
|
||||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
@@ -0,0 +1,14 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="12 3 45 54" fill="none">
|
||||||
|
<g stroke="#7e14ff" stroke-width="9" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<!-- trunk -->
|
||||||
|
<path d="M28 13 L28 40"/>
|
||||||
|
<!-- fork -->
|
||||||
|
<path d="M28 29 L47 16"/>
|
||||||
|
</g>
|
||||||
|
<!-- bold wide arrowhead -->
|
||||||
|
<path d="M28 56 L14 37 L42 37 Z" fill="#7e14ff"/>
|
||||||
|
<!-- commit nodes -->
|
||||||
|
<circle cx="28" cy="13" r="8" fill="#7e14ff"/>
|
||||||
|
<circle cx="28" cy="29" r="8" fill="#7e14ff"/>
|
||||||
|
<circle cx="49" cy="15" r="7" fill="#47bfff"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 526 B |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 421 B |
|
After Width: | Height: | Size: 478 B |
|
After Width: | Height: | Size: 477 B |
|
After Width: | Height: | Size: 554 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 654 B |
|
After Width: | Height: | Size: 1.9 KiB |