# ajithpunnakula/sherpa architecture

> Architecture diagram of the GitHub repository ajithpunnakula/sherpa, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-18). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ajithpunnakula/sherpa
- Repository: https://github.com/ajithpunnakula/sherpa

## Overview

1. **What this repo is**
   Sherpa is a macOS-first Electron app with a React renderer. Its purpose is to generate sales-call guidance in real time, grounded in a local knowledge base built from a separate, read-only wiki repo (`coffeeandai`).

2. **Top-level architecture**
   The app has three major runtime pieces:
   - **Electron main process** for tray icon, global hotkeys, window lifecycle, permissions, and IPC.
   - **Renderer UI** built with React/Vite for the panel experience.
   - **Pure TypeScript “server” modules** that do retrieval, prompt orchestration, and provider selection. These are not a network backend; they run in-process from Electron.

3. **Knowledge base boundary**
   The knowledge source is external to this repo. `scripts/build-index.ts` walks the sibling `coffeeandai` wiki/content directories and produces a local JSON index. This is a one-way ingest boundary: Sherpa reads from the source repo but never writes back.

4. **Indexing and retrieval flow**
   The build step turns markdown into search chunks, then persists them as an index under the user data area (`~/.sherpa/...`, per README). At runtime, retrieval uses BM25 over those chunks to find the most relevant wiki snippets for a user prompt.

5. **Core copilot pipeline**
   The main runtime flow is:
   user input or pasted context → retrieval against the index → mode-specific prompt assembly → LLM call → structured response returned to the UI.
   The orchestrator in `server/copilot/orchestrator.ts` ties these steps together.

6. **Sales-mode abstraction**
   `server/copilot/modes.ts` defines the eight sales modes described in the README. Each mode contributes its own system prompt and output structure, so the app’s behavior changes by scenario without changing the underlying retrieval/provider pipeline.

7. **LLM provider layer**
   `server/copilot/providers.ts` abstracts Anthropic Claude, OpenAI, and a stub/fallback path. Provider choice is driven by environment variables and can be overridden per call. This makes the AI dependency a replaceable boundary rather than a hard-coded integration.

8. **Electron main-process responsibilities**
   `electron/main.ts` owns the menu-bar tray, the global shortcut (`⌘⇧Space`), panel show/hide behavior, and macOS permission/status handling. It is the control plane of the app and mediates access to the copilot service through IPC.

9. **Preload and renderer boundary**
   `electron/preload.ts` exposes a typed, narrow bridge into the renderer via `contextBridge`. The React app in `src/` consumes that bridge through `src/lib/sherpa.ts`, which also supports a graceful browser fallback for development or non-Electron rendering.

10. **UI composition**
   The renderer is a panel UI centered on a mode switcher, a composer/input area, a suggestion card, source snippets, and a status bar. The UI is intentionally thin: it renders whatever the copilot service returns rather than implementing the AI logic itself.

11. **Demo and preview support**
   `src/lib/demos.ts` provides built-in scenarios for each sales mode so the app can be exercised without live call data. The README also notes that if no LLM key is configured, the app still runs and shows retrieved snippets plus a clearly labeled stub response.

12. **Testing strategy**
   The deterministic logic lives in `server/` and is unit-tested: chunking, retrieval ranking, provider selection, mode definitions, and orchestration wiring. The React UI is mostly exercised through the running Electron app rather than component tests.

13. **Operational model**
   There is no standalone server deployment. The app is a desktop client that loads a local index, talks to external LLM APIs when configured, and keeps permission-sensitive features like mic/screen/accessibility off by default. Manual paste is the MVP interaction path.

14. **Key diagram boundaries to show**
   If you draw this architecture, emphasize these boundaries:
   - external read-only wiki repo → index builder → local index
   - Electron main process ↔ renderer via IPC/preload
   - retrieval/orchestration/provider logic inside the main-process-side TypeScript modules
   - external LLM APIs as optional outbound dependencies
   - local user data directory as the persistence boundary for index/logs/state

Main entry points: [`server/copilot/orchestrator.ts`](https://github.com/ajithpunnakula/sherpa/blob/main/server/copilot/orchestrator.ts) (Orchestrator), [`src/App.tsx`](https://github.com/ajithpunnakula/sherpa/blob/main/src/App.tsx) (Panel app), [`scripts/build-index.ts`](https://github.com/ajithpunnakula/sherpa/blob/main/scripts/build-index.ts) (Index builder), [`electron/main.ts`](https://github.com/ajithpunnakula/sherpa/blob/main/electron/main.ts) (Main process)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_desktop["Desktop shell"]
  node_electron_main["Main process<br/>Electron control<br/>[main.ts]"]
  node_electron_preload["Preload bridge<br/>IPC bridge<br/>[preload.ts]"]
  node_electron_service["App service<br/>IPC service<br/>[service.ts]"]
end

subgraph group_copilot["Copilot engine"]
  node_copilot_orchestrator["Orchestrator<br/>Pipeline<br/>[orchestrator.ts]"]
  node_copilot_modes["Sales modes<br/>Mode defs<br/>[modes.ts]"]
  node_copilot_providers["Providers<br/>LLM adapter<br/>[providers.ts]"]
end

subgraph group_kb["Knowledge base"]
  node_kb_chunker["Chunker<br/>Markdown chunking<br/>[chunker.ts]"]
  node_kb_retriever["Retriever<br/>BM25 search<br/>[retriever.ts]"]
  node_kb_types["KB types<br/>Data model<br/>[types.ts]"]
  node_index_builder["Index builder<br/>Build ingest<br/>[build-index.ts]"]
end

subgraph group_ui["Renderer UI"]
  node_renderer_app["Panel app<br/>React UI<br/>[App.tsx]"]
  node_sherpa_bridge["Sherpa API<br/>Client bridge<br/>[sherpa.ts]"]
  node_demo_data["Demo cases<br/>Mock scenarios<br/>[demos.ts]"]
  node_ui_status["Panel state<br/>View model"]
end

subgraph group_external["External systems"]
  node_wiki_repo["Wiki repo<br/>Read-only source"]
  node_local_index[("Local index<br/>Persistent KB")]
  node_llm_apis(("LLM APIs<br/>Outbound AI"))
end

node_electron_main -->|"exposes bridge"| node_electron_preload
node_electron_preload -->|"typed API"| node_sherpa_bridge
node_sherpa_bridge -->|"consumed by"| node_renderer_app
node_renderer_app -->|"requests"| node_electron_service
node_electron_service -->|"delegates"| node_copilot_orchestrator
node_copilot_orchestrator -->|"retrieves"| node_kb_retriever
node_copilot_orchestrator -->|"applies mode"| node_copilot_modes
node_copilot_orchestrator -->|"calls LLM"| node_copilot_providers
node_copilot_orchestrator -->|"returns"| node_ui_status
node_kb_retriever -->|"reads"| node_local_index
node_index_builder -->|"ingests"| node_wiki_repo
node_index_builder -->|"chunks"| node_kb_chunker
node_kb_chunker -->|"uses"| node_kb_types
node_index_builder -->|"writes"| node_local_index
node_copilot_providers -->|"optional outbound"| node_llm_apis
node_demo_data -->|"feeds demos"| node_renderer_app
node_renderer_app -->|"renders"| node_ui_status
node_electron_main -.->|"controls"| node_copilot_orchestrator

click node_electron_main "https://github.com/ajithpunnakula/sherpa/blob/main/electron/main.ts"
click node_electron_preload "https://github.com/ajithpunnakula/sherpa/blob/main/electron/preload.ts"
click node_electron_service "https://github.com/ajithpunnakula/sherpa/blob/main/electron/service.ts"
click node_renderer_app "https://github.com/ajithpunnakula/sherpa/blob/main/src/App.tsx"
click node_sherpa_bridge "https://github.com/ajithpunnakula/sherpa/blob/main/src/lib/sherpa.ts"
click node_demo_data "https://github.com/ajithpunnakula/sherpa/blob/main/src/lib/demos.ts"
click node_copilot_orchestrator "https://github.com/ajithpunnakula/sherpa/blob/main/server/copilot/orchestrator.ts"
click node_copilot_modes "https://github.com/ajithpunnakula/sherpa/blob/main/server/copilot/modes.ts"
click node_copilot_providers "https://github.com/ajithpunnakula/sherpa/blob/main/server/copilot/providers.ts"
click node_kb_chunker "https://github.com/ajithpunnakula/sherpa/blob/main/server/kb/chunker.ts"
click node_kb_retriever "https://github.com/ajithpunnakula/sherpa/blob/main/server/kb/retriever.ts"
click node_kb_types "https://github.com/ajithpunnakula/sherpa/blob/main/server/kb/types.ts"
click node_index_builder "https://github.com/ajithpunnakula/sherpa/blob/main/scripts/build-index.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_electron_main,node_electron_preload,node_electron_service toneBlue
class node_copilot_orchestrator,node_copilot_modes,node_copilot_providers toneAmber
class node_kb_chunker,node_kb_retriever,node_kb_types,node_index_builder toneMint
class node_renderer_app,node_sherpa_bridge,node_demo_data,node_ui_status toneRose
class node_wiki_repo,node_local_index,node_llm_apis toneIndigo
```

## Components

### Desktop shell

Electron control plane, tray, permissions, and app lifecycle.

- [Main process](https://github.com/ajithpunnakula/sherpa/blob/main/electron/main.ts): Electron control · Owns tray, shortcuts, window lifecycle, and macOS permissions. · `electron/main.ts`
- [Preload bridge](https://github.com/ajithpunnakula/sherpa/blob/main/electron/preload.ts): IPC bridge · Exposes a narrow typed API from main to renderer. · `electron/preload.ts`
- [App service](https://github.com/ajithpunnakula/sherpa/blob/main/electron/service.ts): IPC service · Main-process service layer that mediates UI requests to the copilot pipeline. · `electron/service.ts`

### Copilot engine

In-process retrieval, prompt assembly, and LLM provider selection.

- [Orchestrator](https://github.com/ajithpunnakula/sherpa/blob/main/server/copilot/orchestrator.ts): Pipeline · Coordinates retrieval, mode prompts, provider calls, and response shaping. · `server/copilot/orchestrator.ts`
- [Sales modes](https://github.com/ajithpunnakula/sherpa/blob/main/server/copilot/modes.ts): Mode defs · Defines the eight scenario-specific prompts and output schemas. · `server/copilot/modes.ts`
- [Providers](https://github.com/ajithpunnakula/sherpa/blob/main/server/copilot/providers.ts): LLM adapter · Selects Anthropic, OpenAI, or stub fallback via environment and call overrides. · `server/copilot/providers.ts`

### Knowledge base

Index build and retrieval over the read-only wiki content.

- [Chunker](https://github.com/ajithpunnakula/sherpa/blob/main/server/kb/chunker.ts): Markdown chunking · Turns wiki markdown into retrieval-ready text chunks. · `server/kb/chunker.ts`
- [Retriever](https://github.com/ajithpunnakula/sherpa/blob/main/server/kb/retriever.ts): BM25 search · Ranks local chunks against user prompts and returns relevant snippets. · `server/kb/retriever.ts`
- [KB types](https://github.com/ajithpunnakula/sherpa/blob/main/server/kb/types.ts): Data model · Shared types for chunks, documents, and retrieval results. · `server/kb/types.ts`
- [Index builder](https://github.com/ajithpunnakula/sherpa/blob/main/scripts/build-index.ts): Build ingest · Walks the sibling wiki repo and writes the local search index. · `scripts/build-index.ts`

### Renderer UI

React panel, typed bridge, and presentation layer.

- [Panel app](https://github.com/ajithpunnakula/sherpa/blob/main/src/App.tsx): React UI · Shell for the mode switcher, composer, sources, and status views. · `src/App.tsx`
- [Sherpa API](https://github.com/ajithpunnakula/sherpa/blob/main/src/lib/sherpa.ts): Client bridge · Typed client wrapper with browser fallback for the renderer. · `src/lib/sherpa.ts`
- [Demo cases](https://github.com/ajithpunnakula/sherpa/blob/main/src/lib/demos.ts): Mock scenarios · Built-in sales-call scenarios used for preview and offline exercise. · `src/lib/demos.ts`
- **Panel state**: View model · Rendered call guidance, sources, and connection status.

### External systems

Read-only wiki source and optional outbound LLM APIs.

- **Wiki repo**: Read-only source · External coffeeandai wiki/content source consumed during index build.
- **Local index**: Persistent KB · User-data search index and related local state under the app data area.
- **LLM APIs**: Outbound AI · Optional Anthropic and OpenAI network dependencies.

## Connections

- Main process → Preload bridge: exposes bridge · Main process publishes a narrow API surface to the renderer.
- Preload bridge → Sherpa API: typed API · Preload maps IPC into the renderer-facing client wrapper.
- Sherpa API → Panel app: consumed by · The React panel uses the typed bridge for all app actions.
- Panel app → App service: requests · UI actions flow back to the main-process service through IPC.
- App service → Orchestrator: delegates · Service forwards user prompts and UI events into the copilot pipeline.
- Orchestrator → Retriever: retrieves · The orchestrator looks up relevant wiki snippets for the current prompt.
- Orchestrator → Sales modes: applies mode · Scenario-specific prompts and response schemas shape the output.
- Orchestrator → Providers: calls LLM · The orchestrator submits the assembled prompt to the selected provider.
- Orchestrator → Panel state: returns · Structured response is handed back for rendering in the panel.
- Retriever → Local index: reads · Retrieval operates over the persisted local search index.
- Index builder → Wiki repo: ingests · Build step walks the external read-only wiki content.
- Index builder → Chunker: chunks · Markdown is split into search chunks before indexing.
- Chunker → KB types: uses · Chunking shares common KB data structures.
- Index builder → Local index: writes · The build step persists the generated index to local user data.
- Providers → LLM APIs: optional outbound · Configured providers call external AI APIs when keys are present.
- Demo cases → Panel app: feeds demos · Built-in scenarios allow the UI to be exercised without live call data.
- Panel app → Panel state: renders · The panel presents guidance, snippets, and status as a thin view layer.
- Main process → Orchestrator: controls · Main process owns the app control plane and triggers copilot work indirectly.
