Host apps and the standalone engine¶
Status: hosts decided, standalone engine draft
The engine server, the host element source and the client are decided (2026-10-22) and built; monsterbrain is the first host (monsterbrain is the first h... (DEC_HOST_ORDER)). The standalone engine further down is still a proposal.
A host is an app that renders content itself and shows deciwa inside it: monsterbrain first, then VS Code. Two decisions frame this page:
Host apps get deciwa as an ... (DEC_HOST_EXTENSIONS) – the host only offers generic extension points; everything deciwa-specific is an extension in this repository.
The Python parts can be shi... (DEC_STANDALONE_ENGINE) – the Python parts ship as a standalone binary, so a host works without Python on the machine.
Parts¶
Part |
Where |
Task |
|---|---|---|
engine |
|
all logic, |
client |
|
find, start and stop the engine, check its version, typed calls to the JSON API |
overlay |
|
card, panel, bars, guided review – with a third element source for hosts ( |
host adapter |
|
maps the host’s extension points to client and overlay – small, no logic |
The host adapters depend on client and overlay, never on each other
(deciwa is one repository of... (DEC_PACKAGES)). Logic stays in deciwa-core (The CLI is the master, with... (DEC_CLI_MASTER));
the TypeScript parts only call the engine.
Engine as a server for a host¶
A host talks to deciwa serv... (DEC_SERVE_API_ONLY)
$ deciwa serve --api-only --root <folder> --port 0
{"deciwa": "0.0.1", "api": 1, "port": 41873, "token": "…", "root": "/home/daniel/brain"}
Handshake: the first line on stdout.
rootis the folder that holds.deciwa/– it may lie above the folder the host opened; the host maps its paths by the difference. Without.deciwa/the line is{"api": 1, "error": {"code": "no-deciwa", …}}and the engine exits with 2; the host can then offerdeciwa init --at <folder>.Token: every request carries the header
X-Deciwa-Token; other local pages cannot call the API.--tokenorDECIWA_TOKENset it, otherwise it is random.Lifetime: the engine stops when its stdin closes, so it never outlives the host.
--keep-runningturns this off (for trying it in a terminal).No site: everything outside
/api/answers 404.
Endpoints for hosts, next to the ones of the review server (/api/page,
/api/annotate, /api/reply, /api/project, /api/todo, …):
Endpoint |
Returns |
|---|---|
|
|
|
the elements of a file with selector, kind, label, line, text and fingerprint – from the elements index of a build, else from the adapter for the file type |
|
keeps the elements of a page the host scanned itself (rendered HTML), like the pages of a website in |
|
per file: counts per state, open questions, jobs for the AI, required and done – without |
|
the facts of facts files ( |
|
approve every fact of these facts files that is not approved yet, and each file as a whole |
|
server-sent events |
Files without a build are read by their adapter on the fly
(Adapters), so a plain Markdown folder such as a knowledge
base needs no Sphinx: deciwa todo, show and the project overview cover
every file with review data and every file under review.paths.
Overlay in a host¶
In a host the overlay gets ... (DEC_HOST_ELEMENTS)
The host marks its rendered view:
every block carries
data-line="<first source line, 0-based>"– what markdown-it does with its token maps and what the VS Code Markdown preview already does; lines count the frontmatter,the host adapter sets
data-deciwa-source="<path relative to the root>"on the container.
hostElements() in packages/ui/js/host.js loads nothing itself: the
adapter passes the elements from /api/elements, and each is matched to the
block of its kind that starts on its line (heading → h1–h6, paragraph →
p, item → li, row → tr, code → pre). Elements of a build index whose
lines are not exact (Sphinx) fall back to their text. Blocks without a match
are not reviewable.
startOverlay() takes a few options for hosts: api (calls go through the
host, not fetch), scroller (the element the content scrolls in; the UI is
mounted inside it), keys: "review" (keys only in review mode – the host keeps
its own shortcuts), tools: false (no floating pill), openDoc (open another
file in the host) and focus. It returns dock() / undock() to put the
panel into the host’s side panel, setReview(), focus(), refresh() and
destroy(). Tree views also pass reveal(node) (see below).
Line views (source code): the host marks every line with data-line; with
hostElements(container, elements, {ranges: true}) the lines from line to
end of each element are grouped into one block, nested as the elements
are, so methods sit inside their class. unwrapRanges() undoes it.
Tree views (JSON, YAML): the host marks every node of the tree with
data-pointer="<JSON Pointer>". Elements that carry a pointer (the data
adapters, JSON and YAML files are rev... (DEC_DATA_ADAPTERS)) are matched to the node with the same
pointer (pointerElements() in host.js). A tree hides collapsed nodes, so
the host passes reveal(node) to startOverlay(): the overlay calls it
before it shows or opens an element, and the host opens the collapsed nodes
around it. The state bars skip elements that are hidden.
In a diff the overlay runs on the new side only; the old side is read only.
Rendered HTML files: the host marks every start tag with data-line; the
elements come from the engine’s HTML adapter and are matched by line and
tag (HTML files are read by an a... (DEC_HTML_ADAPTER)). Only a page the adapter cannot read falls
back to the DOM scan of the web script, whose elements go to the engine with
POST /api/elements.
The monsterbrain extension¶
packages/monsterbrain maps monsterbrain’s extension interface v0
(docs/extensions.md in the monsterbrain repository) to client and overlay:
monsterbrain extension point |
deciwa uses it for |
|---|---|
background process ( |
start the engine for the open folder, stop it with the app |
calls and events |
the window’s API calls go through the main process (the token stays there); change events refresh overlays and marks |
view injection ( |
overlay on rendered Markdown ( |
frame scripts |
overlay in rendered HTML pages; monsterbrain marks start tags with |
panel section |
the deciwa panel of the file, docked ( |
toolbar |
the switch Review on/off next to View · Source · Diff |
decorations |
marks in tree and change view from |
commands |
|
children of side bar views |
the facts view: the facts of every file from |
MCP tools |
|
Views opened while the engine is still starting attach as soon as it is ready. Review mode is one setting for all files: the overlay keeps it, and rendered HTML pages follow it.
Client¶
One TypeScript client for a... (DEC_CLIENT_PACKAGE)
packages/client (@danwos/deciwa-client) runs in Node – the host’s main or
extension process, never in a page, so the token stays there:
findEngine()– the path from the host’s settings, the engines bundled with the host, thendeciwaonPATH,new Engine({root, enginePath, bundled}).start()– startsserve --api-only, reads the handshake, refuses another API major (api-mismatch), restarts after a crash (at most three times a minute),typed calls (
elements,page,summary,todo,annotate,hostPage,callfor any endpoint) andevents()with reconnect,initFolder()–deciwa init --at <folder>.
npm test in packages/client starts the engine of the checkout against a
temporary folder.
Standalone engine¶
|
|
Proposal: PyInstaller – widely used, simple, no C compiler. Alternatives: Nuitka (compiles to C: faster and smaller, but long builds and a C compiler per platform); python-build-standalone plus the installed packages (no freezing problems, but bigger and many loose files). |