Desktop operating system for meta-learners. Electron GUI over an org-mode knowledge graph, harnessed to Claude Code for ingest.
Status: v0.1 scaffold — built for Ship it Sunday #008 (2026-04-19, Harness theme).
You have a folder of org files (~/org/) that is your personal wiki. You have a raw pile of unprocessed materials (~/org/raw/): podcast transcripts, web clippings, roundtable drafts. Inquiro shows you:
- Homepage dashboard — today's new nodes, inbox of pending materials, most-cited concepts, islands with no cross-references.
- Ingest in one click — picks a pending file, calls Claude with a tight
--allowedToolswhitelist, watches it produce structured nodes with sources and confidence ratings. No git round-tripping, nothing magic. - Echo terminal — a real-time feed of the agent's stdout pinned to the bottom of the window. The harness is visible, not hidden.
- Piano chime — a single C5 + E5 + G5 triad plays when an ingest finishes. IGNITION signature.
The thesis: in an AI era that trains people to be passive answer-consumers, Inquiro is a tool for slow, deliberate meta-learners who want every question they ever asked to leave a trace in a knowledge graph they'll still have three years from now.
- macOS arm64 (Intel build possible but not tested)
- Node.js 20 or higher (tested with 24)
- Claude CLI (
claude) installed and logged in. The app checks on launch and disables ingest if missing. - An
~/org/directory containing at minimumsummary.organd one ofentities.org/concepts.org/sources.org/analyses.org. The canonical ingest tool iszzzhizhia/ingest.
npm install
npm run dev # boots Electron + Vite dev server with HMR
npm run typecheck # runs node + web tsc
npm run build # bundles main + preload + renderer to out/
npm run dist:mac # packages .dmg (arm64) under release/src/
├── main/ # Electron main process
│ ├── index.ts # BrowserWindow + app lifecycle
│ ├── ipc.ts # IPC handlers, owns the org snapshot
│ ├── ingest-adapter.ts # invokes claude CLI with --allowedTools
│ ├── claude-check.ts # startup check for claude CLI presence
│ └── inbox-scan.ts # scans ~/org/raw/ against .ingest-lock.json
├── preload/ # contextBridge surface exposing window.inquiro
├── renderer/ # React app
│ ├── App.tsx # shell + simple view router
│ ├── pages/Homepage.tsx
│ ├── components/
│ │ ├── Card.tsx # single surface primitive (no side-stripes!)
│ │ ├── Badges.tsx # kind + confidence badge components
│ │ ├── EchoTerminal.tsx # real stdout feed, sticky footer
│ │ └── PianoChime.tsx # WebAudio C5+E5+G5 on ingest done
│ ├── store/useOrgStore.ts # Zustand, imperative stdout append
│ └── styles/tokens.css # OKLCH design tokens
└── shared/
├── types.ts # domain model + IPC channel names
├── orgParser.ts # minimal, tolerant parser (node-only)
├── orgSerializer.ts # BlockNote JSON → org with backup+rollback
└── summaryLog.ts # parses summary.org ingest events
All color and spacing tokens live in src/renderer/styles/tokens.css. The palette is OKLCH-based with warm neutrals (hue 55) for text on cool-tinted dark surfaces (hue 245). See .impeccable.md for the full aesthetic rationale.
Channel names are centralized in src/shared/types.ts as the IPC constant. The renderer only talks to the main process through window.inquiro which is established by the preload script.
Writing a node back to disk goes through orgSerializer.ts::writeNodeBody(). Before writing, we copy the file to {file}.backup-{timestamp}. After writing, we re-parse and verify the target node still exists; if anything looks wrong we revert from backup. This is the hard rule: we will never silently corrupt 13 days of accumulated knowledge.
- BlockNote editor integration (the scaffold is ready, wiring is next)
- Graph fullscreen view (react-force-graph-2d is installed, not yet rendered)
- Onboarding for users without an existing
~/org/vault - Auto-writing to
.ingest-lock.json(we defer to the canonicalingestCLI for lock authority) - Windows / Linux packaging
- Unit tests (manual rehearsal covers v0.1; v0.2 adds Playwright E2E)
MIT. The knowledge your vault contains is yours; this tool is free.