2025-12-24 16:29:33 +00:00
# Tech Stack & Constraints
## Overview
2026-02-13 12:31:36 +00:00
This project is a standalone Rust **web server binary** that serves a Vite/React frontend and exposes a **WebSocket API** . The built frontend assets are packaged with the binary (in a `frontend` directory) and served as static files. It functions as an **Agentic Code Assistant** capable of safely executing tools on the host system.
2025-12-24 16:29:33 +00:00
## Core Stack
2026-02-13 12:31:36 +00:00
* **Backend:** Rust (Web Server)
2025-12-24 16:29:33 +00:00
* **MSRV:** Stable (latest)
2026-02-13 12:31:36 +00:00
* **Framework:** Poem HTTP server with WebSocket support for streaming; HTTP APIs should use Poem OpenAPI (Swagger) for non-streaming endpoints.
2025-12-24 16:29:33 +00:00
* **Frontend:** TypeScript + React
* **Build Tool:** Vite
2026-03-14 18:09:58 +00:00
* **Package Manager:** npm
2025-12-24 16:29:33 +00:00
* **Styling:** CSS Modules or Tailwind (TBD - Defaulting to CSS Modules)
* **State Management:** React Context / Hooks
* **Chat UI:** Rendered Markdown with syntax highlighting.
## Agent Architecture
The application follows a **Tool-Use (Function Calling)** architecture:
1. **Frontend:** Collects user input and sends it to the LLM.
2. **LLM:** Decides to generate text OR request a **Tool Call** (e.g., `execute_shell` , `read_file` ).
2026-02-13 12:31:36 +00:00
3. **Web Server Backend (The "Hand"):**
2025-12-24 16:29:33 +00:00
* Intercepts Tool Calls.
* Validates the request against the **Safety Policy** .
* Executes the native code (File I/O, Shell Process, Search).
* Returns the output (stdout/stderr/file content) to the LLM.
2026-02-13 12:31:36 +00:00
* **Streaming:** The backend sends real-time updates over WebSocket to keep the UI responsive during long-running Agent tasks.
2025-12-24 16:29:33 +00:00
## LLM Provider Abstraction
To support both Remote and Local models, the system implements a `ModelProvider` abstraction layer.
* **Strategy:**
* Abstract the differences between API formats (OpenAI-compatible vs Anthropic vs Gemini).
* Normalize "Tool Use" definitions, as each provider handles function calling schemas differently.
* **Supported Providers:**
* **Ollama:** Local inference (e.g., Llama 3, DeepSeek Coder) for privacy and offline usage.
2025-12-27 19:37:01 +00:00
* **Anthropic:** Claude 3.5 models (Sonnet, Haiku) via API for coding tasks (Story 12).
* **Provider Selection:**
* Automatic detection based on model name prefix:
* `claude-` → Anthropic API
* Otherwise → Ollama
* Single unified model dropdown with section headers ("Anthropic", "Ollama")
* **API Key Management:**
2026-02-13 12:31:36 +00:00
* Anthropic API key stored server-side and persisted securely
2025-12-27 19:37:01 +00:00
* On first use of Claude model, user prompted to enter API key
* Key persists across sessions (no re-entry needed)
2025-12-24 16:29:33 +00:00
## Tooling Capabilities
### 1. Filesystem (Native)
* **Scope:** Strictly limited to the user-selected `project_root` .
* **Operations:** Read, Write, List, Delete.
* **Constraint:** Modifications to `.git/` are strictly forbidden via file APIs (use Git tools instead).
### 2. Shell Execution
* **Library:** `tokio::process` for async execution.
* **Constraint:** We do **not** run an interactive shell (repl). We run discrete, stateless commands.
* **Allowlist:** The agent may only execute specific binaries:
* `git`
* `cargo` , `rustc` , `rustfmt` , `clippy`
* `npm` , `node` , `yarn` , `pnpm` , `bun`
* `ls` , `find` , `grep` (if not using internal search)
* `mkdir` , `rm` , `touch` , `mv` , `cp`
### 3. Search & Navigation
* **Library:** `ignore` (by BurntSushi) + `grep` logic.
* **Behavior:**
* Must respect `.gitignore` files automatically.
* Must be performant (parallel traversal).
## Coding Standards
### Rust
* **Style:** `rustfmt` standard.
2025-12-27 16:50:18 +00:00
* **Linter:** `clippy` - Must pass with 0 warnings before merging.
2025-12-24 16:29:33 +00:00
* **Error Handling:** Custom `AppError` type deriving `thiserror` . All Commands return `Result<T, AppError>` .
* **Concurrency:** Heavy tools (Search, Shell) must run on `tokio` threads to avoid blocking the UI.
2025-12-27 16:50:18 +00:00
* **Quality Gates:**
* `cargo clippy --all-targets --all-features` must show 0 errors, 0 warnings
* `cargo check` must succeed
2026-02-17 13:34:32 +00:00
* `cargo nextest run` must pass all tests
2026-02-25 09:21:04 +00:00
* **Test Coverage:**
* Generate JSON report: `cargo llvm-cov nextest --no-clean --json --output-path .story_kit/coverage/server.json`
* Generate lcov report: `cargo llvm-cov report --lcov --output-path .story_kit/coverage/server.lcov`
* Reports are written to `.story_kit/coverage/` (excluded from git)
2025-12-24 16:29:33 +00:00
### TypeScript / React
2025-12-27 16:50:18 +00:00
* **Style:** Biome formatter (replaces Prettier/ESLint).
* **Linter:** Biome - Must pass with 0 errors, 0 warnings before merging.
2025-12-24 16:29:33 +00:00
* **Types:** Shared types with Rust (via `tauri-specta` or manual interface matching) are preferred to ensure type safety across the bridge.
2026-02-17 13:34:32 +00:00
* **Testing:** Vitest for unit/component tests; Playwright for end-to-end tests.
2025-12-27 16:50:18 +00:00
* **Quality Gates:**
* `npx @biomejs/biome check src/` must show 0 errors, 0 warnings
* `npm run build` must succeed
2026-03-14 18:09:58 +00:00
* `npm test` must pass
* `npm run test:e2e` must pass
2025-12-27 16:50:18 +00:00
* No `any` types allowed (use proper types or `unknown` )
* React keys must use stable IDs, not array indices
* All buttons must have explicit `type` attribute
2025-12-24 16:29:33 +00:00
## Libraries (Approved)
* **Rust:**
* `serde` , `serde_json` : Serialization.
* `ignore` : Fast recursive directory iteration respecting gitignore.
2025-12-24 16:59:14 +00:00
* `walkdir` : Simple directory traversal.
2025-12-24 16:29:33 +00:00
* `tokio` : Async runtime.
2025-12-27 19:37:01 +00:00
* `reqwest` : For LLM API calls (Anthropic, Ollama).
* `eventsource-stream` : For Server-Sent Events (Anthropic streaming).
2025-12-24 17:17:35 +00:00
* `uuid` : For unique message IDs.
* `chrono` : For timestamps.
2026-02-13 12:31:36 +00:00
* `poem` : HTTP server framework.
* `poem-openapi` : OpenAPI (Swagger) for non-streaming HTTP APIs.
2025-12-24 16:29:33 +00:00
* **JavaScript:**
* `react-markdown` : For rendering chat responses.
2026-02-17 13:34:32 +00:00
* `vitest` : Unit/component testing.
* `playwright` : End-to-end testing.
2025-12-24 16:29:33 +00:00
2026-02-20 11:37:29 +00:00
## Running the App (Worktrees & Ports)
Multiple instances can run simultaneously in different worktrees. To avoid port conflicts:
- **Backend:** Set `STORYKIT_PORT` to a unique port (default is 3001). Example: `STORYKIT_PORT=3002 cargo run`
2026-03-14 18:09:58 +00:00
- **Frontend:** Run `npm run dev` from `frontend/` . It auto-selects the next unused port. It reads `STORYKIT_PORT` to know which backend to talk to, so export it before running: `export STORYKIT_PORT=3002 && cd frontend && npm run dev`
2026-02-20 11:37:29 +00:00
When running in a worktree, use a port that won't conflict with the main instance (3001). Ports 3002+ are good choices.
2025-12-24 16:29:33 +00:00
## Safety & Sandbox
1. **Project Scope:** The application must strictly enforce that it does not read/write outside the `project_root` selected by the user.
2. **Human in the Loop:**
* Shell commands that modify state (non-readonly) should ideally require a UI confirmation (configurable).
* File writes must be confirmed or revertible.