How ajithpunnakula/sherpa works
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: orchestrator.ts Orchestrator · App.tsx Panel app · build-index.ts Index builder · main.ts Main process
Components 17
Desktop shell
Electron control plane, tray, permissions, and app lifecycle.
- Main process · Owns tray, shortcuts, window lifecycle, and macOS permissions.
electron/main.ts - Preload bridge · Exposes a narrow typed API from main to renderer.
electron/preload.ts - App 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 · Coordinates retrieval, mode prompts, provider calls, and response shaping.
server/copilot/orchestrator.ts - Sales modes · Defines the eight scenario-specific prompts and output schemas.
server/copilot/modes.ts - Providers · 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 · Turns wiki markdown into retrieval-ready text chunks.
server/kb/chunker.ts - Retriever · Ranks local chunks against user prompts and returns relevant snippets.
server/kb/retriever.ts - KB types · Shared types for chunks, documents, and retrieval results.
server/kb/types.ts - Index builder · 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 · Shell for the mode switcher, composer, sources, and status views.
src/App.tsx - Sherpa API · Typed client wrapper with browser fallback for the renderer.
src/lib/sherpa.ts - Demo cases · Built-in sales-call scenarios used for preview and offline exercise.
src/lib/demos.ts - Panel state · Rendered call guidance, sources, and connection status.
External systems
Read-only wiki source and optional outbound LLM APIs.
- Wiki repo · External coffeeandai wiki/content source consumed during index build.
- Local index · User-data search index and related local state under the app data area.
- LLM APIs · Optional Anthropic and OpenAI network dependencies.
Connections 18
- 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.