A glass-box reasoning workspace. You give the AI a goal; the AI's reasoning is materialized as a navigable graph of typed nodes (thoughts, tool calls, artifacts) on an infinite canvas. Every step is an event in an append-only log, so the whole session is replayable, forkable, and diff-able.
The product value is legibility and steerability of LLM reasoning. The graph is not a side-effect of the AI working — it is the workspace and the artifact you save.
- Java 25
- Docker (for the bundled Ollama + one-command run)
- Bun (or Node 20.19+/22.12+ if you swap package managers)
- A Gemini API key — free tier is enough to try it out. Local Ollama works too if you'd rather not use Gemini.
git clone https://github.com/techtheist/yapp.git
cd yappcp .env.example .env
# edit .env: set GEMINI_API_KEY=...docker compose up # Ollama + Spring backend + Caddy-served frontend- App:
http://localhost:3000(Caddy serves the SPA and reverse-proxies/api+/wsto the backend). - Backend direct (optional; Swagger lives here):
http://localhost:8080/swagger-ui.html. - Ollama:
http://localhost:11434.
Default credentials (override via .env): admin / change_me.
# One-time: fetch the sqlite-vec loadable for your OS/arch (macOS/Linux,
# arm64/x86_64). Docker bakes its own copy; this is only for bootRun.
./scripts/install-sqlite-vec.sh
# then add this to .env (the ".so" / ".dylib" suffix is auto-appended):
# YAPP_SQLITE_VECTOR_EXTENSION_PATH=./sqlite-extensions/vec0
# SqliteConfig also tries ./backend/sqlite-extensions/vec0 as a fallback,
# so the same value works regardless of whether you launch the JVM from
# the repo root or from backend/.
cd backend && ./gradlew bootRun # :8080
cd frontend && bun install && bun run dev # :5173, talks to :8080RAG + memory auto-disable cleanly if the extension isn't wired up — the backend boots and chat still works, with a single ERROR line telling you what to set if you want vector retrieval.
- Create / list / rename / delete workspaces.
- See the AI build a graph live —
Thought,Artifact,ToolCallnodes appear on the canvas as the orchestrator emits them, with typed edges between them. - Drag nodes — positions persist.
- Open a node's detail panel; delete it from there.
- Multi-line prompts in the command bar; selection-aware (no selection = continues from the oldest root, or "+ New thread" for a fresh root).
- Fork a run at its head; switch between runs from the top-right dropdown.
- LLM rate-limited or errors? The bar refills the failed prompt and shows a "retry in ~Ns" hint when the API tells us how long to wait.
- Backend: Java 25, Spring Boot, Spring AI, SQLite +
sqlite-vec, WebSocket/STOMP, Flyway. Event-sourced with materialized*_viewtables. - Frontend: Vue 3 + TypeScript, Tailwind 4, Vite, VueFlow, Pinia, VueUse, STOMP/SockJS.
- LLM providers:
- Gemini (default chat) — model id configured in
backend/src/main/resources/application.properties. - Ollama (local chat alternative, and always the embeddings provider) —
activate the
ollamaSpring profile to flip chat over.
- Gemini (default chat) — model id configured in
.
├── docker-compose.yml # Ollama + backend + Caddy frontend edge
├── .env.example # env template
├── scripts/
│ └── install-sqlite-vec.sh # pulls sqlite-vec for local bootRun
├── backend/
│ ├── Dockerfile # multi-arch JRE image w/ sqlite-vec baked in
│ └── src/main/java/com/yapp/
│ ├── controller/ # REST (workspaces, runs, nodes, commands, artifacts, auth)
│ ├── service/
│ │ ├── event/ # EventService, EventReducer, EventStreamPublisher
│ │ ├── graph/ # WorkspaceService, RunService, GraphMapper, ...
│ │ └── orchestrator/ # OrchestratorService + Spring AI @Tool services
│ ├── model/graph/ # JPA entities + enums
│ └── repository/graph/ # Spring Data repositories
└── frontend/
├── Dockerfile # multi-stage: bun build -> Caddy
├── Caddyfile # static SPA + reverse proxy to backend
└── src/
├── components/
│ ├── canvas/ # WorkspaceCanvas, CommandBar, RunSwitcher, NodeDetail
│ ├── nodes/ # ThoughtNode / ArtifactNode / ToolCallNode
│ ├── layout/ # AppLayout, PublicLayout, TheSideMenu
│ ├── ui/ # design-system primitives (V*)
│ └── workspace/ # WorkspacesView card + create modal
├── composables/ # useAuth, useGraphView, useEventStream, ...
├── services/ # api wrapper + per-domain service modules
├── stores/ # Pinia (auth, activeWorkspace)
├── types/ # backend-mirroring TypeScript contracts
└── views/ # routes
MIT © techtheist
