Compare commits
14 Commits
6cb48f372b
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ceaaedd225 | |||
| 9f4e58ddf2 | |||
| 86a26233dc | |||
| 8451662d9c | |||
| 838860fdf0 | |||
| 3d1168ff8c | |||
| 5c2df30342 | |||
| 53eaed4c7f | |||
| f4f77c5196 | |||
| 3ec57f9140 | |||
| 6bbdd428db | |||
| f431baf413 | |||
| eba1db0ece | |||
| a5ed5a3655 |
@@ -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.
|
||||
@@ -1,30 +1,22 @@
|
||||
# Large machine-specific / regenerable trees (never commit)
|
||||
# Promethean/ = 16G ROCm venv (recreate from requirements*.txt)
|
||||
# ollama/ = 7.4G bundled Ollama binary; models/ = 4.9G Ollama blobs
|
||||
Promethean/
|
||||
ollama/
|
||||
models/
|
||||
interface/web/node_modules/
|
||||
|
||||
# Runtime state & user data
|
||||
runtime/
|
||||
data/uploads/
|
||||
data/exports/
|
||||
*.db
|
||||
*.db-wal
|
||||
*.db-shm
|
||||
|
||||
# Build / cache artifacts
|
||||
interface/web/dist/
|
||||
runtime/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
||||
# Editor / DE / local cruft
|
||||
synapse/memory/memory.db
|
||||
synapse/memory/memory.db-wal
|
||||
synapse/memory/memory.db-shm
|
||||
*.db-wal
|
||||
*.db-shm
|
||||
.DS_Store
|
||||
.directory
|
||||
*.bak
|
||||
*.bak-*
|
||||
*.tar.gz
|
||||
|
||||
# Local-only Claude config (machine-specific)
|
||||
.claude/settings.local.json
|
||||
# Ollama model blobs (~15G, regenerable via `ollama pull`)
|
||||
models/
|
||||
|
||||
# local editor / assistant tooling
|
||||
.vscode/
|
||||
.claude/
|
||||
|
||||
@@ -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'
|
||||
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
## 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. Everything runs on `localhost` with no external AI API calls — the LLM is served via Ollama.
|
||||
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
|
||||
|
||||
@@ -29,12 +29,24 @@ uvicorn synapse.memory.service:app --host 0.0.0.0 --port 8001 --reload
|
||||
cd interface/web && npm run dev
|
||||
```
|
||||
|
||||
**Management CLI** (start/stop individual services with PID tracking):
|
||||
**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 / start_frontend
|
||||
./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.
|
||||
|
||||
**Frontend lint:**
|
||||
```bash
|
||||
@@ -49,15 +61,17 @@ 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`. The AMD ROCm PyTorch stack is installed here (`requirements.txt`).
|
||||
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` and `/chat/stream` — chat with Ollama; streaming uses SSE. After each exchange the stream endpoint calls the Memory Service to auto-extract persistent facts.
|
||||
- `/playbooks` — CRUD for playbooks stored in SQLite via `synapse/playbooks/store.py`.
|
||||
- `/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/bin/ollama`'s HTTP API.
|
||||
- `/conversations` — persists and retrieves full chat history from SQLite.
|
||||
- `/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`.
|
||||
|
||||
@@ -65,7 +79,7 @@ FastAPI app at `synapse/main.py`. Key responsibilities:
|
||||
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) stored in SQLite. 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 and render them.
|
||||
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).
|
||||
@@ -74,10 +88,10 @@ A bundled Ollama binary lives at `ollama/bin/ollama`. `OllamaManager` in `synaps
|
||||
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`). Pages: Chatbot, Playbook editor, Conversation History, Models, Memory, Settings.
|
||||
|
||||
### Persistent Storage
|
||||
All data lands in `synapse/memory/memory.db` (SQLite, WAL mode). Tables: memory facts, conversations, messages, playbooks, app settings. `synapse/memory/store.py` (`PersistentMemoryStore`) owns the schema and all queries. `nexus_config.py` defines all paths; it also ensures all required directories exist on import.
|
||||
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` — service stdout
|
||||
- `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
|
||||
|
||||
@@ -88,5 +102,36 @@ All data lands in `synapse/memory/memory.db` (SQLite, WAL mode). Tables: memory
|
||||
| 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` |
|
||||
| Python dependencies (AMD) | `requirements.txt` / `amd_requirements.txt` |
|
||||
| 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` |
|
||||
|
||||
## Cross-Machine Notes
|
||||
|
||||
A shared scratch log so the two Claude Code instances (this NexusOS box and the WSL box) can hand off context. **Protocol for both instances:** only append under *your own* machine's heading — never edit the other's — and prefix every entry with an ISO date, e.g. `- [2026-06-11] …`. Owning-your-own-section keeps the two sides conflict-free, so the file can be merged by plain concatenation whenever it syncs. **Handoff ritual:** when you start a session after a sync, scan the *other* machine's section for items addressed to you (e.g. a bold `**WSL box:**` / `**NexusOS box:**` callout), act on them, and append the outcome — done or still blocked — under your *own* heading with the date.
|
||||
|
||||
> This file does **not** auto-sync between machines; it has to be carried across (see handoff below). The split-by-machine layout is what makes that merge painless.
|
||||
|
||||
### NexusOS box — native Linux · T2 Mac / AMD · XFCE
|
||||
- [2026-06-11] Started this shared-notes log.
|
||||
- [2026-06-12] Canonical backup folder is now `router:/tmp/mnt/Wingdrive2/nexus-core` (resolved the old nexus-core/nexus-backup cross-wiring). `bin/backup.sh` now targets `nexus-core` (was `nexus-backup`) so backup and restore use the same folder.
|
||||
- [2026-06-12] Added `-c | --claude` check mode to `bin/backup.sh` + `bin/restore.sh`: a `--checksum` content-level dry-run that changes nothing and skips the rebuild — use it to decide whether a real backup/restore is actually needed.
|
||||
- [2026-06-12] Added `--no-owner --no-group` to the real backup/restore rsyncs so they stop re-syncing group metadata on every file against the busybox router (quieter, faster).
|
||||
- [2026-06-12] Fixed `management/nexus-cli.sh` `ensure_router_reachable` (~line 412): the `nmcli connection up wgs_client` WireGuard fallback dies under WSL (no NetworkManager → "permission denied"). It's now conditional on nmcli + the wgs_client connection existing. **WSL box:** you're a desktop with a direct LAN link to the server, so just make `ssh router` work (Host `router` → 192.168.50.1:9001, user jon, key `id_iWings`, in `~/.ssh/config` — which is NOT synced, set it up there) — then `ncp restore` passes the first check and never hits the VPN fallback.
|
||||
- [2026-07-10] Over-engineering purge. Removed dead backend endpoints (`POST /chat`, `/memory/{id}/move[_to]`, `/playbook/run`, `/search`) + their orphaned store methods, and the sync chat wrappers. Deleted the two curses TUIs (`nexus-chat.py`, `nexus-playbook.py`, ~1280 lines) and replaced them with API-backed `ncp` subcommands (`chat`/`memory`/`playbook`/`history` → `management/nexus_api.py`). `controlpanel.py` kept (panel GUI). `/conversations/export` kept (ShareGPT export for future fine-tuning).
|
||||
- [2026-07-10] Nuked the ML + scientific/GUI stack from THIS venv only: torch/transformers/accelerate/bitsandbytes/etc + numpy/scipy/pandas/matplotlib/PySide6 + 53 orphans total. **Promethean 16G → 108M.** Requirements files are UNCHANGED — `pip install -r requirements-amd.txt` restores the declared ML stack. Caveat: some installed extras (peft, datasets, mergekit, gguf, hf-xet) were NOT in any requirements file; if the desktop ML work needs them, add them to requirements first. Rollback freeze snapshot was taken pre-purge. **WSL box:** your venv is separate and untouched; run the same `pip uninstall` sweep if you want the space back (nothing in `synapse/` imports any of it — Ollama does inference over HTTP).
|
||||
- [2026-07-11] Stood up self-hosted **Gitea** at `git.enderofwings.com` (runs on the router in chroot `/tmp/mnt/GitHead`, Gitea 1.26.4, `DISABLE_SSH=true` so pushes are HTTPS+token). Applied full Nexus/GitNexus branding (custom dir `/var/lib/gitea/custom`). Pushed nexus-core → `enderofwings/NexusOS`.
|
||||
- [2026-07-11] **Backup/restore rewritten to use git→Gitea instead of rsync to `router:/tmp/mnt/Wingdrive2/nexus-core`.** `bin/backup.sh` now: dump `memory.db`→`synapse/memory/memory.db.sql` (diff-friendly, so the assistant's memory+history is versioned), `git add -A && commit "backup: <ts>" && push`. `bin/restore.sh` now: clone-or-`git pull`, rebuild the DB from the dump (only if no live DB), then rebuild venv/npm/theme/terminal/panel. `-c|--claude` dry-run kept (git status / incoming diff). Heavies (Promethean, ollama/, models/, node_modules, dist, runtime) still excluded and rebuilt on restore. Auth via `git config credential.helper store` (`~/.git-credentials`, 0600, Gitea PAT). The old `Wingdrive2/nexus-core` rsync folder is being retired — verify a `restore` on a scratch dir before deleting it. **WSL box:** switch your restore path to `git clone/pull https://git.enderofwings.com/enderofwings/NexusOS.git` (make a Gitea account/token; `ssh router` no longer required for backup/restore). Old `ncp restore` rsync path is dead.
|
||||
|
||||
### WSL box — Windows 11 · WSL2 Ubuntu · DESKTOP-WINGX
|
||||
- [2026-06-11] `install-windows.ps1` had a PowerShell syntax error at line 73 (`Unexpected token '}'`); fixed brace mismatch in the script.
|
||||
- [2026-06-11] `$USER` env var unset error at line 103 — PowerShell doesn't inherit Linux env vars; fixed by reading user via `wsl -- bash -c "echo $USER"` with proper escaping.
|
||||
- [2026-06-11] Promethean venv was not landing inside `nexus-core/` in WSL; root cause was the bootstrap path resolving to a Windows path instead of `\\wsl.localhost\Ubuntu\home\jon\nexus-core`. Fixed by rewriting `bin/wsl-bootstrap.sh` to resolve paths from within WSL.
|
||||
- [2026-06-11] Added GPU detection script to auto-select `requirements-amd.txt` vs `requirements-nvidia.txt`.
|
||||
- [2026-06-11] Added `ncp` as a `~/.bashrc` alias and wired a "Promethean Terminal" entry into the Windows right-click context menu.
|
||||
- [2026-06-11] Python dependency install was failing; traced to pip resolving inside the wrong environment before venv was fully activated.
|
||||
- [2026-06-11] Added `sudo apt install snapd` + `sudo snap install ollama` to `wsl-bootstrap.sh`; systemd must be enabled in `/etc/wsl.conf` for snap to work — added that check to bootstrap.
|
||||
- [2026-06-11] `wsl-bootstrap.sh` requires `sudo`; wired `sudo ~/nexus-core/bin/wsl-bootstrap.sh` invocation into `install-windows.ps1`.
|
||||
- [2026-06-11] Nuked WSL and re-provisioned a fresh Ubuntu instance to validate the full install path. WSL provisioned successfully (user `jon` created) but bootstrap did not fire — timing/invocation issue in the PS script.
|
||||
- [2026-06-11] Session ended with `ncp restore` returning permission denied on `nexus-cli.sh:412` and WireGuard (`wgs_client`) unable to reach the router. Unresolved at session close.
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
<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
|
||||
|
||||
Requires Python 3, Node, and a GPU is optional (CPU works).
|
||||
|
||||
```bash
|
||||
# 1. Install deps into the Promethean venv (auto-selects AMD/NVIDIA/CPU)
|
||||
./bin/install.sh
|
||||
|
||||
# 2. Launch the full stack (memory :8001, backend :8000, frontend :5173)
|
||||
./launch_nexus.sh
|
||||
```
|
||||
|
||||
Python deps are layered: `requirements-base.txt` (GPU-agnostic core) plus one
|
||||
overlay — `requirements-amd.txt` (ROCm), `requirements-nvidia.txt` (CUDA), or
|
||||
`requirements-wsl.txt` (CPU-only). `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
|
||||
uvicorn synapse.memory.service:app --host 0.0.0.0 --port 8001 --reload # memory
|
||||
cd interface/web && npm run dev # frontend
|
||||
```
|
||||
|
||||
## 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. 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/wsl overlay |
|
||||
|
||||
---
|
||||
|
||||
<div align="center"><sub>NexusOS · local AI, self-hosted on <a href="https://git.enderofwings.com/enderofwings/NexusOS">GitNexus</a></sub></div>
|
||||
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 151 B After Width: | Height: | Size: 151 B |
|
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 469 B |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 494 B After Width: | Height: | Size: 494 B |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 8.9 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 |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
@@ -0,0 +1 @@
|
||||
../../../.claude/projects/-home-jon-nexus-core/memory/MEMORY.md
|
||||
@@ -0,0 +1,12 @@
|
||||
# assets/notes
|
||||
|
||||
In-repo snapshot of the project's working notes (Claude Code memory).
|
||||
|
||||
**Canonical source:** `~/.claude/projects/-home-jon-nexus-core/memory/`
|
||||
The files here are a committed copy so the notes travel with the repo and survive
|
||||
a fresh machine. They are **not** read by any code at runtime — purely reference.
|
||||
|
||||
`MEMORY.md` is the index; the other `*.md` files are one note each.
|
||||
|
||||
If the two locations drift, the `~/.claude/.../memory/` copy is authoritative —
|
||||
re-sync from there, not the other way around.
|
||||
@@ -0,0 +1 @@
|
||||
../../../.claude/projects/-home-jon-nexus-core/memory/code-widget-lifecycle.md
|
||||
@@ -0,0 +1 @@
|
||||
../../../.claude/projects/-home-jon-nexus-core/memory/cross-machine-sync-constraint.md
|
||||
@@ -0,0 +1 @@
|
||||
../../../.claude/projects/-home-jon-nexus-core/memory/fusion360_linux_proton.md
|
||||
@@ -0,0 +1 @@
|
||||
../../../.claude/projects/-home-jon-nexus-core/memory/multimonitor_primary_follow.md
|
||||
@@ -0,0 +1 @@
|
||||
../../../.claude/projects/-home-jon-nexus-core/memory/nexusos_desktop_theme.md
|
||||
@@ -0,0 +1 @@
|
||||
../../../.claude/projects/-home-jon-nexus-core/memory/nexusos_distro_identity_wine.md
|
||||
@@ -0,0 +1 @@
|
||||
../../../.claude/projects/-home-jon-nexus-core/memory/nexusos_genmon_applet_pattern.md
|
||||