Inventivus v1.8.6
Inventivus
Engineering mission control — a local-first Windows desktop application for
engineering calculators, machine architectures, native app overlays, version
control, and a built-in AI assistant named Athena.
Inventivus is an Electron app. A React + TypeScript SPA runs in the renderer, a
Fastify + SQLite backend runs as a child process of the Electron main process, and
everything — projects, simulation history, git repos, encrypted credentials — stays
on the user's machine. There is no hosted application server.
Two small cloud pieces exist and are optional: a PartyKit room for real-time
collaboration, and a Cloudflare Worker licence issuer that signs Pro tokens
after a Stripe webhook. Neither holds project data.
Changelog
v1.8.6 — 6 September 2026
Bug fixes
Workspace creation
- Fixed EasyEDA Pro
.eprj(and.eprj2,.elib) files being rejected at workspace creation with "file type not supported". The extension whitelist inserver/utils/path-safety.tshad drifted out of sync with the app catalog and was missing every EasyEDA format plus ~40 other catalog extensions (.kicad_pro,.fcstd,.prjpcb,.sldprt, and more). Added a regression test that enumerates the full catalog so this class of bug cannot silently reappear.
Onboarding
- The AI setup step is now skippable. Users without Ollama or an API key can click "Skip for now" and configure AI later in Settings → AI Provider. The app opens normally in the meantime; document analysis returns a clear "no AI configured" message rather than failing silently.
- Added a collapsible step-by-step setup guide per provider (install commands, model pull commands, exact URLs, port numbers) shown inline on the AI step.
- Rewrote the "connection failed" advice into numbered, actionable troubleshooting steps for each provider.
Team / sharing
- Free-tier project-share cap could be bypassed by using the bulk share path (
POST /api/team/share/applywith noproject_id). Fixed: bulk path now pre-counts and enforces the cap. - Task delete (
DELETE /api/team/tasks/:id) had no authorisation — any team member could delete any task. Fixed: only the task creator or a team owner may delete. POST /api/team/events?month=had no format validation; an unvalidated value was used as a SQLLIKEoperand, returning all events. Fixed: reject anything not matchingYYYY-MM.- Optional fields on events and tasks (
description,time,assigned_to_member_id) were stored as empty strings instead ofNULL, breakingIS NULLqueries. Fixed to storeNULL. - Task unassign was impossible —
assigned_to_member_idonly accepted a string, notnull. Fixed: acceptsz.string().nullable(). - Post display-name fallback used the team name instead of
member_id. Fixed.
Payments / Stripe
customer.subscription.deletedwebhook clearedtierandstatusbut leftsubscription_idset. Subsequent subscription refresh and portal calls would then attempt to operate on the deleted subscription, returning 402/404 from Stripe. Fixed: null outsubscription_idon deletion.- Success page copy said "Pro subscription is active" for all plans, including Enterprise customers. Fixed to neutral wording.
Version control
- Data loss: renaming a workspace then running a scoped commit silently dropped the renamed workspace's manifest entry (matched by name instead of stable
repo_path), causingpruneOrphansto delete the file from the repository. Fixed: carry-forward matches byrepo_path. Added a regression test. POST /vcs/unstagereturned a raw 500 stack trace when called on a file that was never committed to HEAD. Fixed: returns 400 with the git error message.- Commit error detection in
VersionControl.tsxmatched(e as Error).message.includes('409')— any error message containing "409" would show "Nothing to commit" instead of the real error. Fixed toe instanceof ApiError && e.status === 409. stageAll()returned the count of all files with any status rather than files newly staged. Fixed.
Cross-domain checking (core feature)
disciplineOfreturned'other'for EDA, firmware, and CAD nodes not yet placed in a container, in three separate locations:drift.ts,consequence.ts, andinference.ts. This silently excluded real cross-discipline connections from drift reports, consequence assessments, and the inference brief sent to the AI model — the most critical output of the system. Fixed in all three with a detector-based fallback.- EasyEDA Pro document detector ID was hardcoded to
'easyeda-schematic'instead of'document-projection', breaking the provenance chain for.eprjfiles in drift detection. Fixed. - Support-part warnings were emitted twice in EasyEDA Pro document detection (once in
warnings, once viaomitted). Fixed. - Detection warnings were concatenated twice into the machine-links response, doubling every warning shown to the user. Fixed.
partStateswas not passed tocomputeStalenessin the/inferenceendpoint (unlike/staleness), so CAD parts from container documents were always shown as current to the AI model regardless of actual state. Fixed.- Inference test fixture
DRIFTwas missing requiredrevisedandconsequencesfields, causing tests to exercise the wrong struct shape. Fixed.
Repository layout
.
├── inventivus/ ← the actual product. Everything below this line is here.
├── memory/PRD.md Original product requirements and backlog
├── backend/ Emergent scaffold (FastAPI "Hello World" + Mongo) — unused
├── frontend/ Emergent scaffold (CRA + shadcn/ui starter) — unused
├── tests/ Empty pytest package left by the scaffold
└── test_result.md Scaffold testing-protocol file
backend/, frontend/, and tests/ are leftovers from the project generator. They
are not wired into the desktop app and can be ignored (or deleted) — the Fastify
backend the app actually runs is inventivus/server/.
Quick start
Requires Node 20+ and Yarn 1.x.
cd inventivus
yarn install
yarn devyarn dev runs three things concurrently: the Vite dev server on :5173, a
TypeScript build of the Electron main + preload into dist-electron/, and Electron
itself — which spawns the Fastify backend on a free port.
First launch opens the onboarding wizard. To skip the paywall while developing:
yarn dev:unlockedFull setup walkthrough, including where each Stripe key goes:
inventivus/SETUP.md.
Deeper reference on architecture and internals:
inventivus/README.md.
Stack
| Layer | Tech |
|---|---|
| Shell | Electron 43 (contextBridge IPC, no nodeIntegration) |
| Renderer | React 18 · TypeScript · Vite 6 · Tailwind CSS |
| State | Zustand (global) · TanStack Query (server) |
| Graph / canvas | React Flow |
| Backend | Fastify 5, spawned as a child process on launch |
| Storage | SQLite via better-sqlite3 (WAL + FTS5 full-text search) |
| Version control | isomorphic-git — real git repos per project |
| Collaboration | Yjs + PartyKit (y-partykit) |
| Native interop | koffi FFI for Win32 window tracking |
| AI | Ollama · LM Studio · OpenAI-compatible · Anthropic |
| Payments | Stripe Node SDK + Ed25519-signed licence tokens |
| Packaging | electron-builder → Windows NSIS installer |
What's in the app
- Mission — dashboard and telemetry across projects.
- Calculators — truss FEM, beam, buckling, and co-simulation, with sandboxed
controller expressions and live charting. - Machines — visual architecture layout wired to simulation runs.
- Integrations — register any executable (CAD tool, simulator, terminal),
launch it, and park a frameless HUD window in front of it. The HUD is a genuine
second window owned by the launched app, not a reparented overlay — see
SETUP.md § "The HUD is not an overlay". - Version control — git plus entity-level history, mirrored to a workspace.
- Athena — full-page chat and a floating dock, SSE-streamed from the local
backend so API keys never reach the renderer. - Projects — CRUD, invites, join flow, status control, GitHub sign-in via
device flow. - Global search — SQLite FTS5 behind a Ctrl/⌘+K
command palette.
Editions and the free/Pro split
Two builds ship from one codebase with a single branch taken:
- Standard — free tier with feature gates (calculators, machines, HUD live help)
and quantity caps (5 projects, 3 integrations). - Unlocked — same code,
resolveEntitlementshort-circuits to Pro.
Version control and collaboration are free on purpose: a lapsed subscription must
never appear to have eaten someone's work. Limits are enforced on creation only,
so a user who drops from Pro keeps everything they already have.
Pro is proved by an Ed25519-signed licence token minted by the issuer worker
after a Stripe webhook — never by a local database column. The app embeds only the
public key, so it can verify a licence but cannot mint one. Enforcement is
server-side: gated routes return 402 regardless of what the UI renders.
Building the installers
cd inventivus
yarn package:standard # → release/standard/Inventivus-Setup-0.1.0.exe
yarn package:unlocked # → release/unlocked/
yarn package:both # build once, package twice
yarn package:dir # unpacked build, faster for testingScripts reference
yarn dev # Vite + Electron + live backend
yarn dev:unlocked # same, with Pro entitlements
yarn build # renderer + electron main + server
yarn lint # tsc --noEmit && eslint
yarn start:server # backend only, for debugging
yarn verify:editions # assert standard/unlocked packages differ correctly
yarn verify:persistence # assert userData survives reinstall
yarn verify:webhooks # sign synthetic Stripe events → SQLite
yarn verify:pathb # polling-based subscription refresh
yarn verify:ai # AI provider proxy round-tripUnit tests are colocated as *.test.ts next to their subjects and run with Vitest
(vitest.config.ts).
Where data lives
| Path | Contents |
|---|---|
<userData>/inventivus.db |
SQLite database (WAL) |
<userData>/config.enc |
Stripe + AI credentials, AES-256-GCM |
<userData>/.inventivus.key |
32-byte key generated on first launch, 0600 |
<userData> is %APPDATA%/Inventivus/ on Windows,
~/Library/Application Support/Inventivus/ on macOS,
~/.config/Inventivus/ on Linux.
Further reading
| Document | Covers |
|---|---|
| inventivus/SETUP.md | First-time setup, keys, HUD, licensing, pitfalls |
| inventivus/README.md | Architecture and module-level reference |
| inventivus/issuer/README.md | Deploying the licence issuer (~15 min) |
| memory/PRD.md | Original requirements and backlog |
| FILE_OPERATIONS_FIX.md | File open/save handling notes |
| VERIFICATION_CHECKLIST.md | Manual pre-release checklist |
License
Proprietary. © Inventivus. All rights reserved.