Skip to content

Repository files navigation

Mnemosyne, the memory of Archivist

Archivist

A local-first AI workspace for durable project memory, curated context, and inspectable computer work.

Archivist turns projects into persistent Collection workspaces. A Collection can bring together multiple Libraries, durable Chats, Agents, open files, and the exact desktop state needed for one task.

Instead of treating every AI session as disposable, Archivist preserves the working context around the conversation:

Choose a Collection
→ restore its tabs, layout, Chats, and active Library
→ browse code, documentation, assets, and research
→ retrieve or attach trusted evidence
→ work through a persistent Agent
→ inspect the exact context used
→ return later without reconstructing the session

Archivist is under active development. The native Qt/QML application in frontend/ is the product frontend. The retired Electron/React prototype is kept outside this repository as a historical reference.

Core features

  • Collection workspaces — group multiple Libraries, Chats, and Agents into task-specific environments that can be switched without rebuilding the session.
  • Persistent editor tabs — open files and Chats as first-class tabs, reorder them with polished drag-and-drop, restore their order and active state after restart, and reuse the same file identity and icon mapping as the Explorer.
  • Embedded development workspace — edit source through Monaco, run persistent terminals through xterm.js, and keep navigation inside Archivist tabs.
  • Workspace-scoped language support — supervise local language servers per project for TypeScript/JavaScript, React/Next, QML, C/C++, Rust, Python, Go, YAML, Bash, and Markdown.
  • Built-in web and SQL tooling — use Monaco workers for HTML, CSS/SCSS/Less, and JSON, with SQL highlighting and completion isolated to SQL files.
  • Archivist editor commands — own the editor command registry and context menu instead of depending on Monaco private APIs.
  • Multi-Library Collections — attach separate code, documentation, asset, research, or design Libraries to the same Collection.
  • Persistent Library trees — remember the selected Library, expanded folders, selected node, filter text, and scroll position independently for every Library.
  • Git-aware Explorer — merge Library scans with repository status, decorate existing files and folders, mute ignored paths, summarize descendant changes on folders, and never resurrect deleted files as phantom tree rows.
  • Shared native icon system — use locally vendored Codicons for controls, Streamline artwork for folders, and the actual VS Code Seti font for compact file icons across the Explorer and editor tabs.
  • Local-first Libraries — register folders, scan their contents, and browse cataloged files without surrendering ownership of the filesystem.
  • Safe native file preview — open supported text and source files through a root-constrained, read-only backend boundary.
  • Deterministic text indexing — extract supported UTF-8 files, split them into stable chunks, preserve line provenance, and index them with SQLite FTS5.
  • Incremental rescanning — reuse unchanged documents, replace changed chunks, remove stale records, and report failed or unavailable files honestly.
  • Automatic Library retrieval — search the active Library for each normal Chat request and provide bounded, relevant excerpts without requiring manual attachments.
  • Durable Chat — preserve conversations, selected state, Agent assignments, and large histories with cursor-based pagination.
  • Explicit file attachments — attach specific Library files to an individual Chat when the user wants guaranteed evidence.
  • Bounded context — budget recent history, automatic retrieval, and attached evidence through the selected Context Compiler without replacing the user's current intent.
  • Durable Context Inspector — inspect the compiler, model, token accounting, warnings, message selection, retrieval mode, and source outcomes behind individual assistant responses.
  • Reviewable AI edits — let model tools propose bounded Library file creation, full-content patches, directory creation, renames, and moves without writing immediately; persist the proposal, require human approval, fail closed on stale state, synchronize derived Library state after execution, and support guarded undo.
  • Configurable Agents — create reusable AI identities and attach Agent rosters to conversations.
  • Native management workflows — create, rename, archive, restore, duplicate, and delete Collections, Chats, and Agents through the Qt client.
  • Provider abstraction — OpenAI is currently supported behind an adapter boundary so project continuity does not belong to one model vendor.
  • Managed native development — build and run the backend and Qt desktop client from the repository root in one supervised terminal session.

Product philosophy

Archivist is designed around a few simple rules:

  1. Local before cloud. User files and project continuity should remain under the user's control.
  2. Durable history, temporary provider context. Chats persist; only curated context is sent to a model.
  3. Evidence is not intent. Retrieved material must remain visibly distinct from the user's current request.
  4. Inspection before automation. A context system should explain what it used before it begins making broader decisions.
  5. Read-only before mutation. Inspection and retrieval come before file-writing or autonomous actions.
  6. Human approval before consequences. Important operations should be reviewable, attributable, and reversible.
  7. Providers are workers, not owners. Archivist owns memory, sources, permissions, artifacts, and continuity.
  8. Complexity must pay rent. Prefer small, complete vertical slices over speculative infrastructure.

Workspace model

Archivist separates durable project content from the local desktop state used to work with it:

Collection
├── Libraries
│   ├── codebase
│   ├── documentation
│   ├── assets
│   └── research
├── Chats
├── Agent roster and defaults
└── local workspace state
    ├── open file and Chat tabs
    ├── active tab
    ├── Explorer visibility and width
    ├── Chat dock mode and height
    ├── active Library
    └── per-Library tree expansion, filter, selection, and scroll

Switching Collections should feel like switching complete task desktops. Worktrees, split editor groups, dockable panes, and multi-monitor layouts are planned extensions of this same boundary.

Architecture

Archivist is a local modular monolith with clear domain boundaries:

Qt 6 / QML desktop
  Collection workspaces, editor tabs, Explorer, Chat, previews, Context Inspector
        |
C++ domain stores
  HTTP requests, client state, QML-facing models
        |
Express API
  validation, orchestration, product behavior
        |
Domain models and services
  persistence, safe file access, context compilation
        |
SQLite + filesystem + AI providers
  durable state, authoritative files, retrieval, generation

The API owns business rules. QML owns presentation and interaction. C++ stores bridge the two without duplicating backend invariants.

Context flow

current user message
+ recent durable conversation
+ automatically retrieved Library excerpts
+ explicitly attached Library evidence
→ Context Compiler
→ bounded provider request
→ assistant response
→ durable context-run snapshot
→ native Context Inspector

The current user message remains the highest-priority intent. Automatically retrieved and explicitly attached files are evidence, not instructions. Explicit attachments remain stronger than automatic candidates.

Context inspection

Each newly generated assistant response can preserve:

compiler ID and version
provider, model, and Agent
input budget and response reserve
estimated tokens used
included and omitted messages
compiler warnings and timing
source outcomes and token contributions

Source outcomes are explicit:

Included
Truncated
Omitted
Unavailable
Failed

Context records describe what happened during a specific response. They are not reconstructed later from files that may have changed.

Data ownership

Filesystem  → authoritative user file contents
SQLite      → Collections, Libraries, Chats, Agents, messages, attachments, context records, indexes
QSettings   → local Collection, tab, layout, and Library-tree workspace state
Providers   → temporary generation workers
Archivist   → continuity, context, permissions, provenance, outcomes

Repository layout

Archivist/
├── assets/               README artwork and project media
├── backend/              Express 5, TypeScript, SQLite, AI and cognition domains
├── frontend/             Primary Qt 6 / QML desktop frontend
│   ├── qml/App/          Workbench, Explorer, Chat, previews, inspectors and editors
│   ├── qml/App/Icons/    Shared controls, file resolvers, generated Seti registry and licenses
│   ├── qml/App/Workbench/IdeHost/Web/
│   │                     Embedded Monaco and xterm.js feature
│   └── src/App/Domains/  C++ Library, Chat and Agent stores
├── language-test-lab/    Small cross-language fixtures for editor smoke tests
├── scripts/              Native build, runtime, cleanup, smoke-test and context helpers
├── devHandoff.md         Current development state and coding-chat handoff
└── README.md

Requirements

The current development environment targets macOS.

  • Node.js 24 LTS
  • npm 10 or newer
  • Qt 6.8 or newer
  • CMake 3.24 or newer
  • Ninja

Example macOS dependencies:

brew install qt cmake ninja

Setup

From the repository root:

nvm use
npm install
npm run lsp:install

cp backend/.env.example backend/.env
# Add the required AI-provider credentials to backend/.env.

npm run dev

The root development command owns the complete native session:

validate Node and better-sqlite3
→ stop the previous managed backend
→ clean up stale Archivist listeners
→ start one backend
→ wait for API health
→ build the embedded IDE assets
→ build the Qt client
→ launch Archivist
→ clean up the backend when Archivist exits

The backend API runs at:

http://127.0.0.1:3333/api

Development commands

Build the complete active application:

npm run build

Build and launch the backend and native Qt client in one terminal:

npm run dev

Stop a previous managed development session:

npm run dev:stop

Focused native commands:

npm run dev:qt
npm run build:qt
npm run qt:configure
npm run qt:run

Regenerate the locally vendored icon assets and Seti registry after changing the icon manifest or vendor script:

npm run icons:vendor

The generated assets live under frontend/qml/App/Icons/Assets/. Keep frontend/qml/App/Icons/THIRD_PARTY_ICONS.md synchronized with every vendored source.

Diagnostics and context handoffs

Use the repository helpers to collect evidence before changing code when a failure is unclear.

Start a detached diagnostic session when Archivist must remain running while other commands inspect it:

./scripts/qt-dev-detached
./scripts/qt-dev-detached --follow
./scripts/qt-stop

The detached launcher writes bounded backend and frontend logs under backend/data/runtime/logs/. Without --follow, it leaves Archivist running; with --follow, it streams both logs and stops the managed session on exit.

Run focused diagnostics and audits with:

./scripts/diagnose-navigation
npm run diagnose:language-support
node scripts/diagnose-language-support.mjs --lines 1500
node scripts/diagnose-language-support.mjs --full
./scripts/qt-typography-audit
./scripts/qt-typography-audit --check

diagnose-navigation writes navigation-diagnostic.txt at the repository root. The language diagnostic includes Git and runtime state, tool availability, live language-server configuration and sessions when the backend is running, client events, fixtures, and recent logs. Use --lines for a larger log window or --full for unfiltered tails. The typography audit reports current usage; --check rejects regressions against the committed baseline.

Run focused backend verification with:

npm run build
node scripts/test-collections.mjs
node scripts/test-chat-agent-rosters.mjs
npm run test:library-index -- "a term you know exists"

The Collection and Chat-Agent smoke tests use temporary databases. The Library index test expects Archivist's backend to be running and rescans the currently active Library before searching it.

Generate a fresh coding-chat context bundle with:

./scripts/qt-context
./scripts/qt-context backend/src/api/cognition frontend/qml/App/Files
./scripts/qt-context 12 backend/src/api/languageSupport

Without a number, the script creates the next available qt-context-NNN.txt. An optional leading number selects the sequence, and each remaining argument adds a focused file or directory. The bundle records Git state, recent commits, the repository tree, relevant uncommitted diff, and included file contents while skipping large and binary files. Upload the generated bundle instead of pasting source files piecemeal.

Language-support commands:

npm run lsp:install
npm run lsp:doctor
npm run lsp:check
npm run check:language-support
npm run diagnose:language-support
npm run clean:language-test-lab

lsp:install synchronizes the exact npm-managed tool versions in scripts/language-tools.json. Native tools such as qmlls, clangd, rust-analyzer, gopls, and Marksman are discovered from PATH. Missing optional native tools do not disable ordinary editing.

Set ARCHIVIST_LANGUAGE_SERVER_TRACE=1 before npm run dev when raw server stderr is needed. Normal runs suppress known setup chatter while preserving warnings, process exits, and diagnostic telemetry.

Supported language services

Surface Provider Current scope
TypeScript, JavaScript, TSX, JSX TypeScript language server React/Next navigation, completion, diagnostics, references, rename, formatting, and code actions
QML qmlls Workspace-aware completion, diagnostics, and navigation
C and C++ clangd Best with compile_commands.json, compile_flags.txt, or CMake metadata
Rust rust-analyzer Cargo workspace intelligence
Python Pyright Completion, navigation, and type diagnostics
Go gopls Optional; available when the local Go toolchain provides it
YAML, Bash, Markdown Language servers Completion, diagnostics, and navigation where advertised
HTML, CSS, SCSS, Less, JSON Monaco workers Built-in validation, completion, hover, and formatting
SQL files Monaco SQL provider Syntax highlighting and isolated generic completion; no database-schema awareness yet

Useful checks:

npm run lint
curl http://127.0.0.1:3333/api/health
sqlite3 backend/data/archivist.db "PRAGMA user_version;"
lsof -nP -iTCP:3333 -sTCP:LISTEN

Runtime management

The managed backend PID is stored at:

backend/data/runtime/qt-dev-backend.pid

npm run dev owns the backend process tree and cleans it up when the Qt application exits or the terminal receives Ctrl+C.

When a previous session ended unexpectedly:

npm run dev:stop
npm run dev

The cleanup script only stops backend processes belonging to this Archivist repository. It refuses to kill an unrelated application using port 3333 and reports the conflicting process instead.

Native-module recovery

better-sqlite3 is compiled for a specific Node ABI. After changing Node versions:

nvm use
npm rebuild better-sqlite3
npm run dev

A native-module mismatch commonly appears as:

ERR_DLOPEN_FAILED

The development launcher validates the active Node version and SQLite module before starting the application.

The backend also logs the active database path, schema version, and important table readiness during startup.

Status

Archivist currently has:

native Qt Workbench
→ Collection-scoped task workspaces
→ draggable persistent file and Chat tabs with shared Seti file icons
→ multiple Libraries per Collection
→ Git-aware Explorer decorations without phantom deleted files
→ compact Collection and Library controls with native iconography
→ independently restored Library trees and scroll positions
→ durable Chats and Agent rosters
→ safe Library file preview
→ deterministic Library indexing and lexical retrieval
→ bounded attached and retrieved evidence
→ durable Context Inspector records
→ embedded Monaco and xterm.js development workspace
→ workspace-scoped language services with local diagnostics
→ one-command native development workflow

The current daily-driver loop is:

select a Collection
→ resume its exact workspace
→ switch among code, documentation, assets, or research Libraries
→ open files and Chats as tabs
→ ask through the assigned Agent
→ inspect the evidence and context used

The next product milestone is rich file rendering on top of the shared icon and file-identity system:

pleasant native Markdown reading
→ renderer selection by file type
→ images and structured data
→ PDFs, diffs, and richer asset previews
→ keep source files read-only until mutation workflows are explicit

Capability-driven editor commands such as Find References, Rename, Quick Fix, and formatting remain the next focused IDE slice after the renderer foundation.

Current deliberate limits:

  • only one Library tree is displayed at a time, even when a Collection references several Libraries;
  • automatic retrieval searches the active Library rather than every Library in the Collection;
  • most files still use a plain text preview;
  • the shared icon registry currently covers the Explorer, editor tabs, navigation controls, and terminal workbench; larger branded surfaces and preview-specific artwork remain future work;
  • tabs and Library contents are not yet worktree-scoped;
  • split editor groups and dockable panes are not implemented yet.

Persistent projects. Swappable workspaces. Curated context. Inspectable memory. Local ownership.

About

Archivist is a local-first AI workspace that helps you organize projects, chat with your files, and keep long-term context across coding, research, writing, and creative work. It combines persistent AI conversations, searchable libraries, an integrated editor, terminals, Git workflows, and human-controlled automation in one private desktop app.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages