Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,34 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt pytest
python -m pip install -r requirements.txt ".[test]"

- name: Diagnose QtWidgets before system GUI libraries
run: |
python - <<'PY'
import traceback

try:
from PySide6.QtWidgets import QMessageBox
except Exception:
print("QtWidgets import failed before installing system GUI libraries:", flush=True)
traceback.print_exc()
else:
print(f"QtWidgets imported before system GUI libraries: {QMessageBox.__name__}")
PY

- name: Install Linux Qt runtime libraries
run: |
sudo apt-get update
sudo apt-get install -y libegl1 libgl1 libxkbcommon-x11-0 libdbus-1-3

- name: Verify QtWidgets import
run: |
python - <<'PY'
from PySide6.QtWidgets import QMessageBox

print(f"QtWidgets import OK: {QMessageBox.__name__}")
PY

- name: Compile Python sources
run: python -m compileall -q main.py manage_translations.py translator.py src
Expand Down
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Alle wesentlichen Änderungen an diesem Projekt werden hier dokumentiert.
Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.1.0/).

## [Unreleased — 2026-10-06]
## [Unreleased — 2026-10-12]

### Fixed
- GUI workers (`QThread`) are now kept alive until `finished` (`src/gui/worker_utils.py`); a running extraction is never replaced, queued files are no longer dropped, and `closeEvent` stops and waits for all workers before saving.
Expand All @@ -12,9 +12,17 @@ Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.1.0/).
- RAG search uses relevance scores (higher = better) instead of raw distances for confidence and thresholds.
- Chat always receives the current project's document manager (no unfiltered queries over the shared collection) and a disabled RAG engine is propagated as `None`.
- New projects inherit provider/model/URL from the saved app config; the LLM client is initialised at startup; projects are opened by ID, the current project is saved first, and project directories get a unique suffix.
- Ollama API keys use allowlisted native operating-system credential services, with an explicit user-triggered migration for legacy plaintext keys and a non-persisted environment override.
- The local ChromaDB client disables anonymized usage telemetry explicitly.
- Authenticated Ollama setup failures no longer retry without headers; provider exceptions and worker messages omit raw URLs, userinfo, headers, and secret-bearing exception text.
- Workspace export now shows a content disclosure and requires confirmation before writing; the disclosure states that reports, chat, and excerpts are not anonymized.
- Privacy and companion docs now distinguish remote Ollama transfer from local processing and describe that imported PWA workspaces remain session-only while review notes and UI locale persist locally.
- Supported file types come from one shared set (adds `.pptx`, `.html`, `.htm`; drops unsupported `.odt`, `.ods`); HTML is converted to plain text.
- Extractor: Excel `0`/`False` cells kept, RTF `\uN` fallback skipping and multi-byte code pages fixed, BOM/cp1252 detection for plain text, PPTX slides sorted numerically, PDF/Excel/MSG handles closed reliably.
- Ollama availability is re-checked lazily instead of being cached forever after a failed start-up check.
- Package metadata now uses the AGPL-3.0-only SPDX expression and setuptools 77+; the explicit local dependency bootstrap lives in `setup_environment.py`, while `setup.py` is a side-effect-free setuptools entry point.
- Source archives include the `src*` runtime, selected public assets/docs/tests, and license files, while excluding local workspace, profile, output, and vector-store data.
- Desktop and Store documentation now distinguish the primarily German desktop UI from the six-language Web/PWA Companion and describe confirmed workspace exports and remote-provider transfer accurately.
- YAML front matter quotes title/author, GUI PDF export has a timeout, error message and temp-file cleanup, chat messages render as plain text, translator hint matching uses whole words, and the Web Companion stores review notes per project ID (new optional `workspace.id` in the export).

## [Unreleased — 2026-09-22]
Expand Down
34 changes: 23 additions & 11 deletions EXPORTFORMAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@ Stand: 2026-06-05
## Zweck

`notespacellm-workspace-v1.json` ist der Austauschvertrag zwischen der
Desktop-App und Web-/PWA-/Mobile-Companions. Das Format ermöglicht mobile
Recherche- und Review-Workflows, ohne lokale Rohdatenordner, Vektordatenbanken
oder API-Schlüssel zu kopieren.
Desktop-App und Web-/PWA-/Mobile-Companions. Der Export kann den vollständigen
Bericht und Chatverlauf sowie ausgewählte abgeschlossene Dokumentauszüge
enthalten. Er wird nicht anonymisiert. Lokale Rohdokumente, Vektordatenbanken
und gespeicherte API-Schlüsselfelder werden nicht kopiert. Frei verfasste
Bericht- und Chattexte können dennoch Geheimnisse enthalten und sollten vor dem
Weitergeben geprüft werden.

Der erste Consumer liegt unter `web_companion/`: ein read-only PWA-Reader, der
Workspace-JSON lokal im Browser importiert, Bericht und Dokumentmetadaten
anzeigt, den zuletzt geladenen Workspace offline wiederherstellt und eigene
Review-Notizen als Markdown exportiert.
anzeigt und eigene Review-Notizen als Markdown exportiert. Der importierte
Workspace bleibt nur in der aktuellen Sitzung; zum erneuten Öffnen muss die
Datei erneut importiert werden. Review-Notizen und UI-Sprache werden lokal
gespeichert.

## Implementierungsstatus

Expand All @@ -26,15 +31,22 @@ Review-Notizen als Markdown exportiert.

## Datenschutzregeln

- API-Schlüssel werden nie exportiert.
- Gespeicherte API-Schlüsselfelder werden nicht exportiert. Frei verfasste
Bericht- und Chattexte werden nicht auf Geheimnisse geprüft und sollten vor
dem Weitergeben überprüft werden.
- `chroma_db/`, lokale Datenbanken und Cache-Verzeichnisse werden nie exportiert.
- Rohdokumente werden standardmäßig nicht eingebettet.
- Dokumentauszüge werden nur exportiert, wenn sie bereits für Bericht, Chat,
Prompt oder Review ausgewählt wurden.
- Externe Provider werden nur als Typ und Konfigurationshinweis dokumentiert,
nicht mit geheimen Werten.
- Vollständige Rohdokumente werden nicht eingebettet; ausgewählte abgeschlossene
Sub-Query-Ergebnisse erscheinen als auf 2.000 Zeichen begrenzte Auszüge.
- Auszüge erscheinen nur für ausgewählte Dokumente und nur, wenn
`include_subquery_excerpts` aktiviert ist.
- Der aktuelle vollständige Bericht und Chatnachrichten von Nutzern und Assistenten
können enthalten sein; der Export ist nicht anonymisiert.
- Externe Provider werden nur als Typ und lokale/entfernte/unklare Einordnung
dokumentiert. Die konfigurierte URL und geheime Werte werden nicht exportiert.
- Lokale absolute Pfade werden auf redigierte Hinweise oder relative
`path_hint`-Werte reduziert.
- Vor dem Schreiben zeigt die Desktop-App die enthaltenen Bereiche an und fragt
ausdrücklich nach Bestätigung.

## Minimales Schema

Expand Down
34 changes: 34 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
include README.md README_de.md
include LICENSE NOTICE THIRD_PARTY_LICENSES.md THIRD_PARTY_LICENSES.txt
include CHANGELOG.md ARCHITECTURE.txt CODE_OF_CONDUCT.md CONTRIBUTING.md
include EXPORTFORMAT.md PRIVACY_POLICY.md SECURITY.md STORE_LISTING.md SUPPORT.md
include WINDOWS_STORE_PREP.md llms.txt
include pyproject.toml requirements.txt setup.py setup_environment.py MANIFEST.in
include main.py notespacellm_launcher.py manage_translations.py translator.py
include run.bat start.bat build_exe.bat NoteSpaceLLM.ico store_package.json
include locales/translations.json
include scripts/check_store_readiness.py
recursive-include .github/workflows *.yml *.yaml
graft src
graft assets
graft tests
graft web_companion
global-exclude __pycache__ *.py[cod] *.pyo *.db *.sqlite *.sqlite3 *.log
global-exclude .DS_Store Thumbs.db desktop.ini
exclude .env .env.* credentials.json client_secret*.json token.json
prune .git
prune .venv
prune venv
prune build
prune dist
prune data
prune output
prune profiles
prune workflows
prune storage
prune chroma_db
prune releases
prune .pytest_cache
prune .pytest_temp
prune .ruff_cache
prune web_companion/node_modules
10 changes: 10 additions & 0 deletions MARKETING-LOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ Kanonisches Repo: https://github.com/file-bricks/NoteSpaceLLM
Organisations-Kontext: file-bricks / open-bricks
Distributionsmodus: GitHub Source + PySide6 Desktop GUI + Web/PWA Companion

Geltungsbereich aktualisiert: 2026-10-12
Die folgenden Einträge dokumentieren frühere Positionierungen und Annahmen vom
22.09.2026. Sie sind keine aktuellen, verifizierten Produktgarantien oder
vollständigen Sicherheits-, Lizenz- oder Rechtsprüfungen. Insbesondere die
früheren INV-LOCAL-/Zero-Egress-/Offline-/Parserhärtungs-/SBOM-/Lizenzkompatibilitäts-
und § 521-/SLA-Aussagen sind überholt und nicht als heutige Zusicherung zu lesen.
Aktuelle, begrenzte Produkt- und Datenflussbeschreibungen stehen in README.md,
README_de.md, SECURITY.md, PRIVACY_POLICY.md, NOTICE und THIRD_PARTY_LICENSES.*.
Die Datumsangaben der historischen Einträge bleiben erhalten.

===============================================================================
1. POSITIONIERUNG & MARKTKONTEXT
===============================================================================
Expand Down
69 changes: 28 additions & 41 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ NoteSpaceLLM
=============

Copyright (c) 2026 Lukas Geiger (c/o file-bricks / open-bricks)
Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
Licensed under the GNU Affero General Public License v3.0 only (AGPL-3.0-only).
See LICENSE for the full license text.

This NOTICE file is provided for informational and attribution purposes
Expand All @@ -13,44 +13,31 @@ source code and in substantial portions of the software.
1. Purpose & Architecture
--------------------------------------------------------------------

NoteSpaceLLM is an unprivileged, local-first PySide6 desktop application
and offline research companion designed as a private alternative to Google
NotebookLM. It enables document analysis, multi-document synthesis, RAG-assisted
inquiries, and structured report generation across PDF, Word (DOCX), Markdown,
plain text, spreadsheets (XLSX), and email archives (EML, MSG). A lightweight
Web/PWA Companion provides zero-server mobile review of exported workspaces.
NoteSpaceLLM is a local-first PySide6 desktop application for document analysis,
research, and report generation across PDF, Word (DOCX), Markdown, plain text,
spreadsheets (XLSX), and email archives (EML, MSG). Project files and the
ChromaDB index are stored locally by default. When a remote model or embedding
endpoint is configured, the text and prompts used for that operation are sent
to the selected endpoint. A lightweight Web/PWA Companion opens exported
workspaces in a browser.

The software is engineered with the following explicit invariants:
* Local-First Privacy Boundary (INV-LOCAL-01): Documents, extracted texts,
ChromaDB vector stores, and SQLite workspace indexes remain strictly on the
local machine and are never transmitted to external cloud systems without
explicit user configuration.
* Unprivileged User-Space Execution (INV-LOCAL-02): RunAsInvoker non-elevation;
both PySide6 desktop GUI and CLI run with regular user privileges without
requiring administrator or elevated operating system rights.
* Zero Unsolicited Egress (INV-LOCAL-03): Core document parsing, text chunking,
and local vector retrieval perform zero unsolicited network calls; optional
cloud LLM integrations (OpenAI, Anthropic) activate only upon explicit user
selection and key provisioning.
* Offline-First Local Model Execution (INV-LOCAL-04): Native integration with
local Ollama instances provides private LLM synthesis without requiring an
active internet connection.
* Hardened Parser Security (INV-LOCAL-05): Dependency floors for document
parsers (openpyxl>=3.1.3, PyMuPDF>=1.24.10, python-docx>=1.1.0) guard
against XML entity expansion (CVE-2024-34064) and archive bombs.
* Portable Workspace Serialization (INV-LOCAL-06): Standardized JSON workspace
format (`notespacellm-workspace-v1.json`) allows safe, schema-validated
interchange with external tools and mobile review companions.
* PWA Offline Isolation (INV-LOCAL-07): The Web Companion operates 100%
client-side via Service Worker caching with zero telemetry or tracking.
* AGPL-3.0 & LGPL-3.0 Boundary Purity (INV-LOCAL-08): Full compliance with
PyMuPDF AGPL-3.0 copyleft and PySide6 LGPL-3.0 dynamic linking isolation.
* Version Freeze Discipline (INV-LOCAL-09): Strict compliance with policy
T-20260920-167562623; hygiene and marketing passes never modify the
application version outside authorized release ceremonies.
* Statutory Disclaimer & SLA (INV-LOCAL-10): Unpaid open-source software under
§§ 516 ff. BGB with liability governed by § 521 BGB; vulnerability reports
are subject to a 48-hour acknowledgment and 5-day triage SLA.
The following are selected implementation notes for this source snapshot, not a
security certification, complete network audit, complete SBOM, or legal
compliance assessment:
* The app disables ChromaDB's anonymized telemetry for its local client and
does not implement its own telemetry. This does not characterize behavior
of the operating system, browser, extensions, or configured providers.
* Saved credential fields are excluded from workspace exports, but user-authored
reports and chats may contain secrets and should be checked before sharing.
* A remote Ollama endpoint receives document text used for embeddings and
prompts/context for responses. An API key is sent to the configured URL in
a Bearer header; HTTP does not encrypt content or credentials.
* The PWA service worker caches application shell assets. Imported workspace
content is kept in the current page session and is not cached as workspace
data by the app.
* Declared dependency version constraints and selected license notes are
listed in THIRD_PARTY_LICENSES.md and THIRD_PARTY_LICENSES.txt. They are
not a resolved dependency inventory, security audit, or compatibility review.

--------------------------------------------------------------------
2. Organizational & Umbrella Context
Expand All @@ -67,13 +54,13 @@ the open-bricks software federation:
--------------------------------------------------------------------

NoteSpaceLLM utilizes open-source components:
* PySide6 / shiboken6 (The Qt Company) - LGPL-3.0-only
* PySide6 / shiboken6 (The Qt Company) - multiple upstream licensing options; see resolved distribution license files
* PyMuPDF / fitz (Artifex Software) - AGPL-3.0-or-later
* ChromaDB (Chroma) - Apache-2.0
* LangChain ecosystem (Harrison Chase) - MIT
* python-docx (Steve Canny) - MIT
* openpyxl (Eric Gazoni, Charlie Clark) - MIT
* extract-msg (Ian Coleman) - MIT

Detailed licenses, runtime package matrices, and SBOM disclosures are
maintained in THIRD_PARTY_LICENSES.md and THIRD_PARTY_LICENSES.txt.
Selected dependency and license notes are maintained in THIRD_PARTY_LICENSES.md
and THIRD_PARTY_LICENSES.txt; these files are not complete component inventories.
16 changes: 16 additions & 0 deletions PRIVACY_POLICY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,26 @@ Nicht für Git vorgesehen sind insbesondere `data/`, `profiles/`, `workflows/`,

Wenn externe oder entfernte LLM-Provider aktiviert werden, können Prompts und ausgewählte Dokumentauszüge an diese Dienste oder Server übertragen werden. Dazu zählen insbesondere OpenAI, Anthropic, Claude Code und Remote-Ollama-Server. Die Verantwortung für die Auswahl geeigneter Provider und den Umgang mit vertraulichen Dokumenten liegt beim Nutzer.

Bei einem entfernten Ollama-Endpunkt werden außerdem Dokumenttexte zur Erstellung von Embeddings sowie Prompts und Kontext für die Antwortgenerierung an die konfigurierte URL gesendet. Ein gespeicherter Ollama-Schlüssel wird als Bearer-Header an diesen Endpunkt übermittelt. HTTP verschlüsselt weder Inhalt noch Zugangsdaten; HTTPS hängt vom Endpunkt und dessen Zertifikat ab. NoteSpaceLLM prüft nicht, welchem Betreiber ein entfernter Endpunkt gehört.

Die Anwendung deaktiviert die anonymisierte ChromaDB-Telemetrie für ihren lokalen Client und implementiert keine eigene Telemetrie.

Gespeicherte Ollama-Schlüssel nutzt die App über unterstützte native Zugangsdienste des Betriebssystems. Verfügbarkeit und Schutz hängen von Betriebssystem und dessen Konfiguration ab. `NOTESPACELLM_OLLAMA_API_KEY` überschreibt den gespeicherten Schlüssel, wird aber nicht von der App gespeichert. Vorhandene ältere Klartextschlüssel bleiben bis zu einer ausdrücklich gestarteten Migration in der Konfigurationsdatei und werden vorher nicht gesendet.

Workspace-Exporte können den vollständigen Bericht, den Chatverlauf und ausgewählte abgeschlossene Dokumentauszüge enthalten. Sie werden nicht anonymisiert. Die PWA hält importierte Workspace-Inhalte nur in der aktuellen Sitzung; lokal gespeichert werden eigene Review-Notizen und die UI-Sprache.

## English

NoteSpaceLLM is designed as a local desktop application. Project files, document indexes, profiles, workflow settings, and exports stay on the local device by default.

Paths such as `data/`, `profiles/`, `workflows/`, `output/`, `chroma_db/`, local builds, and personal configuration files are not intended for Git and are excluded via `.gitignore`.

When external or remote LLM providers are enabled, prompts and selected document excerpts may be sent to those services or servers. This includes OpenAI, Anthropic, Claude Code, and remote Ollama servers. Users are responsible for choosing suitable providers and handling confidential documents appropriately.

With a remote Ollama endpoint, document text used to create embeddings and prompts/context sent for answer generation are also sent to the configured URL. A saved Ollama key is sent to that endpoint in a Bearer header. Plain HTTP encrypts neither content nor credentials; HTTPS protection depends on the endpoint and its certificate. NoteSpaceLLM does not verify who operates a remote endpoint.

The application disables ChromaDB's anonymized telemetry for its local client and does not implement its own telemetry.

Saved Ollama keys are accessed through supported native operating-system credential services. Availability and protection depend on the operating system and its configuration. `NOTESPACELLM_OLLAMA_API_KEY` overrides a saved key but is not saved by the app. Existing legacy plaintext keys remain in the configuration file until the user explicitly starts migration and are not sent before then.

Workspace exports can contain the complete report, chat history, and selected completed document excerpts. They are not anonymized. The PWA keeps imported workspace content only in the current session; only the user's review notes and UI language are stored locally.
Loading
Loading