Commit Graph
17 Commits
Author SHA1 Message Date
Athena 952ef8a0c4 refactor(preview): simplify compile and validation paths
Load Sucrase only when a JSX/TSX preview is opened, remove the hand-written transform, and leave subjective render evaluation to the reader while retaining structural fence validation.
2026-08-26 03:37:29 -05:00
AthenaandCursor 656c14caf3 feat(preview): add sandboxed live code previews
Render validated HTML, SVG, JSX, and TSX fences locally while preserving tool context and preventing explanatory JSON from triggering actions.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-26 03:34:19 -05:00
janvanwan 42eaed647a feat: sync with upstream — v1.2.0, in-app updates, Projects, modules
Brings the public tree back in line with the development repo after several
weeks of drift caused by a stale publish include list.

New:
- In-app update path: GET /update/check compares the checkout against
  origin/main and POST /update/apply runs `ncp upgrade` detached (pull,
  rebuild, restart). The sidebar shows the version, checks on click, and
  offers an "update available" pill.
- Projects: a project workspace groups chats and RAG documents, with
  per-project instructions and document retrieval scoped to the active
  project. Replaces the standalone Documents page.
- modules/: auto-discovered feature plugins (mail, network) with their
  frontend counterparts and tests.
- Memory curation runs in-process (synapse/memory/curator.py) on the chat
  model when a conversation goes idle. The separate memory service on :8001
  is gone, along with the launcher lines that started it.

Also: the KDE theme, panel and Promethean terminal assets, the full test
suite, and VERSION 1.2.0.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-08-25 09:13:55 -05:00
AthenaandCursor 4a7451f5f5 feat(security): request-size caps, concurrency limits, model-pull allowlist
DoS/quota guardrails for the unauthenticated local APIs:

* Body-size middleware rejects oversized requests (Content-Length) before they
  are buffered/base64-decoded (NEXUS_MAX_REQUEST_MB, default 32).
* Document upload enforces a decoded-byte cap (NEXUS_MAX_UPLOAD_MB, default 20)
  and a PDF page-count cap (NEXUS_MAX_PDF_PAGES, default 500) as backstops for
  chunked bodies and pathological files.
* A counter-based in-flight limiter bounds concurrent chats and document
  ingests (NEXUS_MAX_CONCURRENT_CHATS/UPLOADS), returning 429 when saturated;
  the chat slot is held for the whole SSE stream and released on completion or
  client disconnect.
* /models/pull gains an opt-in allowlist (NEXUS_MODEL_ALLOWLIST); empty by
  default so behaviour is unchanged, otherwise a bare repo name permits all its
  tags.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 09:41:53 -05:00
AthenaandCursor 1f6beed0d2 feat(security): SSRF guard on fetch_url + single-use tool-approval tokens
Two tool/agent-layer hardening changes:

* fetch_url now resolves the target host and refuses to connect if any
  resolved address is loopback, private (RFC1918/ULA), link-local (incl. the
  169.254.169.254 cloud-metadata endpoint), multicast, reserved, or
  unspecified. IPv4-mapped IPv6 is unwrapped first, and the guard re-runs on
  every redirect hop so a public URL cannot 302 its way to an internal target.

* /chat/approve now requires a single-use token minted when the stream pauses
  for approval and delivered only in that stream's tool_request event, compared
  in constant time. Previously the pending approval was keyed solely on a
  client-supplied conversation_id, so anyone who could enumerate a
  conversation_id could approve another client's pending action.

The frontend threads the token from the tool_request event into the approve
call.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 09:41:09 -05:00
AthenaandCursor fe12eb1821 feat(security): bind services to loopback with Host + CORS allowlists
The Synapse backend and memory service bound 0.0.0.0 with wildcard CORS and no
auth, exposing the full unauthenticated admin/data API to the LAN. Default the
uvicorn bind to 127.0.0.1 (NEXUS_BIND_HOST override), scope CORS to known local
origins instead of "*", and add TrustedHostMiddleware to reject foreign Host
headers (which defeats DNS-rebinding, something same-origin CORS cannot stop).

NEXUS_ALLOWED_HOSTS / NEXUS_ALLOWED_ORIGINS allow opt-in LAN exposure, intended
to be paired with real authentication.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 09:40:12 -05:00
Jon Wingender cc20ceac64 fix(launch): reliable Windows launcher; feat(ui): compact sidebar, Vite toggle, chat Think toggle
Ported from the private repo via bin/publish.sh, plus a manual catch-up
on files that had drifted out of sync before today:

- launch_nexus.ps1: health-check based restart decisions instead of a
  bare port-listen check (a wedged leftover process squatting a port
  used to look "already running" and block the real service from
  starting), a script-path quoting fix for Start-Process, hidden
  console via a wscript.exe wrapper (bin/launch_nexus_hidden.vbs), and
  a taskbar/window icon for the native app window.
- Sidebar: slim icon+text nav rows instead of bulky bordered buttons,
  tighter spacing throughout.
- Settings: full-width layout, a Vite dev-server Start/Stop toggle
  (synapse/frontend_manager.py + /frontend/* endpoints), and the
  Linux-only Icon Branding section now gated on the new /status
  `platform` field instead of always rendering.
- Chatbot: a Think toggle next to the model picker, so extended
  thinking can be flipped without leaving the chat page.
- management/ncp.py: faster start/stop polling (0.25s steps instead of
  1s), Vite no longer blocks `ncp start` on Linux and is skipped
  outright on Windows.

Note: the private repo also has a Mail (IMAP/SMTP) feature; it's
intentionally not included here, so the Mail-only pieces of main.py,
App.jsx, and requirements-windows.txt were left out of this port.
2026-07-28 11:23:35 -05:00
jonandClaude Opus 4.8 031e522704 feat(models): auto-mode intent remap + real coder models in preference
Settings "Auto model routing" picks which installed model fires for chat vs
coding intent when no model is pinned (auto_chat_model / auto_code_model).
_auto_select_model honors the remap; _MODEL_PREFERENCE["code"] prefers real
coder models first.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 16:06:46 -05:00
jonandClaude Opus 4.8 9aea6d4228 feat(models): skip install-time pull; hardware-aware picks in Models tab
Windows installer no longer auto-downloads models; points to the Models tab.
synapse/hardware.py detects RAM + best-effort VRAM and a curated catalog;
GET /models/recommended annotates each model with fit (gpu/ram/no); the Models
page shows detected RAM/VRAM with fit badges and per-row Pull buttons.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 15:46:48 -05:00
jonandClaude Opus 4.8 52b3c5c3f0 feat(tools): per-call approval for action tools
3-way action_tool_policy (off/ask/allow). In "ask", the chat stream stays
open and the tool loop awaits approval: emits event:tool_request, the UI
shows Approve/Deny, POST /chat/approve resumes the same stream. Declined
actions return a denied result; a timeout denies.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 14:39:00 -05:00
jonandClaude Opus 4.8 492020b547 feat: per-conversation project binding + action-tool consent gate
- Conversations bind to a project on creation; RAG scopes to the
  conversation's project, not the global setting.
- Action tools (web_search/fetch_url/remember) are withheld unless
  allow_action_tools is enabled (off by default). Settings toggle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 14:29:40 -05:00
jonandClaude Opus 4.8 ba6a4ac4e4 feat: workspaces, agentic action tools, local Whisper STT, vec recall
- Projects/workspaces: documents grouped into projects; chat RAG scopes to the
  active project. Switcher in the Documents page.
- Agentic action tools: web_search, fetch_url, and remember (first write tool),
  allowlist-gated per playbook.
- Local Whisper STT (faster-whisper, no torch): on-device dictation replacing
  the browser Web Speech API. POST /stt + GET /stt/status; browser fallback.
- Vector index extended to conversation recall (message_vectors), with the
  brute-force cosine scan kept as the fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 14:22:46 -05:00
jonandClaude Opus 4.8 f4aea78b55 feat(rag): overlapping chunker, retrieval knobs, sqlite-vec index
- Chunker: char overlap across boundaries + hard-split of oversized paragraphs.
- Retrieval knobs: rag_top_k / rag_min_score in settings + Settings UI.
- Vector index: sqlite-vec ANN over document embeddings, dual-written and
  backfilled, with brute-force cosine as the guaranteed fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:58:05 -05:00
jonandClaude Opus 4.8 ac0eb1e5f6 feat(rag): PDF/docx ingest + chat citations
- Upload endpoint (base64 JSON, no multipart dep): extracts text from
  pdf/docx/txt/md via pypdf + python-docx, then runs the existing
  chunk/embed pipeline. Documents page uploads files straight through.
- Citations: the chat stream emits an SSE `sources` event listing the
  documents that fed the answer; the UI shows them as chips under the reply.
- Deps: pypdf, python-docx (both pure-Python, Windows-safe).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:48:32 -05:00
jonandClaude Opus 4.8 f509034fdd feat: playbook tools, RAG, vision, voice, chat controls, faster boot
- Tool-using playbooks: read-only tool registry (search_memory,
  search_history, search_documents, list_models, get_time), per-playbook
  allowlist, agentic loop, and a "running tool" status indicator.
- Document ingest / RAG: documents table + chunker + embed/cosine retrieval
  reusing the existing stack; Documents page (upload/paste, viewer, delete);
  top-k chunks injected into the system prompt.
- Vision chat: attach images, base64 into /api/chat.
- Voice I/O: Web Speech dictation + read-aloud (browser-native, no backend).
- Chat controls: stop, regenerate, edit-and-resend; num_ctx knob in Settings.
- Per-playbook model override.
- History polish: per-conversation + bulk ShareGPT export.
- Faster ncp start: UI up first, Ollama warms in the background, with a
  per-phase timing readout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:31:48 -05:00
jonandClaude Opus 4.8 6755a2477d fix(status): /status blocked the event loop and outran its own client timeout
The backend logged 200 OK for polls the client had already timed out on.
is_running() waited 2s for an Ollama that ships OFF (now 0.5s), is_available()
spawned 'ollama --version' every call and that command blocks ~5s when Ollama is
wedged (now cached), and both ran synchronously inside an async def, stalling the
event loop on every poll while the UI polls continuously (now to_thread).

Measured with Ollama's port blackholed: /status 5.89s -> 0.64s, concurrent GET /
stalled -> 0.06s. Poll timeout in nexus_window.py raised 2s -> 5s for margin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 15:39:04 -05:00
Jon Wingender 714b9fc890 Initial commit: NexusOS - local AI assistant platform 2026-07-21 22:48:38 -05:00