# Tech Stack & Constraints

## Overview
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.

## Core Stack
*   **Backend:** Rust (Web Server)
    *   **MSRV:** Stable (latest)
    *   **Framework:** Poem HTTP server with WebSocket support for streaming; HTTP APIs should use Poem OpenAPI (Swagger) for non-streaming endpoints.
*   **Frontend:** TypeScript + React
    *   **Build Tool:** Vite
    *   **Package Manager:** npm
    *   **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`).
3.  **Web Server Backend (The "Hand"):**
    *   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.
    *   **Streaming:** The backend sends real-time updates over WebSocket to keep the UI responsive during long-running Agent tasks.

## 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.
    *   **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:**
    *   Anthropic API key stored server-side and persisted securely
    *   On first use of Claude model, user prompted to enter API key
    *   Key persists across sessions (no re-entry needed)

## 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.
*   **Linter:** `clippy` - Must pass with 0 warnings before merging.
*   **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.
*   **Quality Gates:**
    *   `cargo clippy --all-targets --all-features` must show 0 errors, 0 warnings
    *   `cargo check` must succeed
    *   `cargo nextest run` must pass all tests
*   **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)

### TypeScript / React
*   **Style:** Biome formatter (replaces Prettier/ESLint).
*   **Linter:** Biome - Must pass with 0 errors, 0 warnings before merging.
*   **Types:** Shared types with Rust (via `tauri-specta` or manual interface matching) are preferred to ensure type safety across the bridge.
*   **Testing:** Vitest for unit/component tests; Playwright for end-to-end tests.
*   **Quality Gates:**
    *   `npx @biomejs/biome check src/` must show 0 errors, 0 warnings
    *   `npm run build` must succeed
    *   `npm test` must pass
    *   `npm run test:e2e` must pass
    *   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

## Libraries (Approved)
*   **Rust:**
    *   `serde`, `serde_json`: Serialization.
    *   `ignore`: Fast recursive directory iteration respecting gitignore.
    *   `walkdir`: Simple directory traversal.
    *   `tokio`: Async runtime.
    *   `reqwest`: For LLM API calls (Anthropic, Ollama).
    *   `eventsource-stream`: For Server-Sent Events (Anthropic streaming).
    *   `uuid`: For unique message IDs.
    *   `chrono`: For timestamps.
    *   `poem`: HTTP server framework.
    *   `poem-openapi`: OpenAPI (Swagger) for non-streaming HTTP APIs.
*   **JavaScript:**
    *   `react-markdown`: For rendering chat responses.
    *   `vitest`: Unit/component testing.
    *   `playwright`: End-to-end testing.

## Running the App (Worktrees & Ports)

Multiple instances can run simultaneously in different worktrees. To avoid port conflicts:

- **Backend:** Set `STORKIT_PORT` to a unique port (default is 3001). Example: `STORKIT_PORT=3002 cargo run`
- **Frontend:** Run `npm run dev` from `frontend/`. It auto-selects the next unused port. It reads `STORKIT_PORT` to know which backend to talk to, so export it before running: `export STORKIT_PORT=3002 && cd frontend && npm run dev`

When running in a worktree, use a port that won't conflict with the main instance (3001). Ports 3002+ are good choices.

## 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.
