# haydenull/skills-manager architecture

> Architecture diagram of the GitHub repository haydenull/skills-manager, 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/haydenull/skills-manager
- Repository: https://github.com/haydenull/skills-manager

## Overview

1. **What this app is**
   - `skills-manager` is an Electron desktop app that manages local “skills” for two external agents: Claude Code and Codex.
   - The core job is to install, update, debug-toggle, and remove skills from the user’s local filesystem and from the agents’ configured skills directories.

2. **Top-level process split**
   - The repository is clearly divided into Electron’s three-part architecture:
     - `src/main`: privileged backend/runtime process
     - `src/preload`: typed IPC bridge
     - `src/renderer`: React UI
   - This boundary matters because the renderer handles user interaction only, while filesystem, network, and OS integration live in the main process.

3. **Main-process domain layer**
   - `src/main/skills-service.ts` is the likely core domain service for skill management.
   - It appears to own the business logic for:
     - discovering skills from GitHub, GitLab, or local directories
     - reading update metadata
     - installing/removing skills into managed storage
     - switching debug mode between managed storage and a user-selected local directory
     - syncing entries into Claude Code / Codex skill locations
   - This is the main architectural boundary where repository-independent skill logic lives.

4. **Renderer UI structure**
   - The renderer is a single-page React app with route-based screens under `src/renderer/src/routes`.
   - Main screens are:
     - `install.tsx` for previewing and installing skills from a source
     - `settings.tsx` for theme, GitLab tokens, update checks, and directory shortcuts
     - `index.tsx` as the installed-skills view
   - `__root.tsx` and `routeTree.gen.ts` indicate TanStack Router-style routing with generated route metadata.

5. **Renderer-to-main data flow**
   - The renderer never directly touches the filesystem or external APIs.
   - Instead, UI actions call typed query/helper modules such as:
     - `src/renderer/src/skills-queries.ts`
     - likely IPC-backed data access from the preload bridge
   - That gives the architecture a clean flow: user action in React UI → IPC call → main-process service → filesystem/network result → UI state update.

6. **Preload as the trust boundary**
   - `src/preload/index.ts` and its declarations in `src/preload/index.d.ts` provide the secure bridge between renderer and main.
   - The existence of explicit typings suggests the app exposes a limited API surface rather than enabling arbitrary Node access in the UI.
   - This is the key security boundary for a desktop app that manages local files and tokens.

7. **Shared types and UI/domain consistency**
   - `src/shared/skills-types.ts` contains shared TypeScript contracts used by both sides.
   - This likely includes the shape of a skill record, install/update metadata, source descriptors, and agent targets.
   - Shared types keep renderer views and main-process operations aligned, which is important because the app’s data model crosses process boundaries.

8. **External source and update model**
   - The README shows three source classes the architecture must support:
     - GitHub repositories
     - self-hosted GitLab repositories
     - local directories
   - Update detection differs by source:
     - GitHub uses directory tree SHA comparison
     - GitLab and local sources use `sha256` file-hash-based tracking
   - This implies the main service needs source-specific adapters and metadata normalization before the UI can present “updatable” status.

9. **Filesystem integration and agent directories**
   - The app manages two external filesystem targets:
     - Claude Code skills directory
     - Codex skills directory
   - Default locations are user-home based, but can be overridden via environment variables (`CLAUDE_CONFIG_DIR`, `CODEX_HOME`).
   - The app also stores its own managed copy of skills in an application data directory, which acts as the authoritative local cache for installed skills and debug state.

10. **GitLab token storage and authenticated access**
   - Settings include per-host GitLab Personal Access Tokens.
   - The token is associated with a GitLab host, not globally, which implies the main process persists host-scoped credentials and injects them only when calling the matching GitLab API.
   - This is a separate infrastructure concern from skill storage and affects source fetching only.

11. **Update and distribution layer**
   - App self-update is part of the settings screen, so the main process likely integrates with Electron update or release mechanics.
   - Build and packaging are handled by:
     - `electron-vite` for development/build bundling
     - `electron-builder.yml` for packaging/distribution
     - GitHub Actions release workflow under `.github/workflows/release.yml`
   - This makes the repo both an app and a distributable desktop product.

12. **UI composition and styling**
   - The renderer uses React components plus local CSS assets:
     - `src/renderer/src/assets/base.css`
     - `src/renderer/src/assets/main.css`
     - `src/renderer/src/components/Versions.tsx`
   - The UI appears lightweight and route-driven rather than using a heavy global state framework.
   - Styling and component structure are secondary to the app’s main concern: presenting skill inventory and actions.

13. **Architecture diagram emphasis**
   - If drawing the system, the most important boxes are:
     - React renderer screens
     - preload IPC bridge
     - main-process skill service
     - managed app-data skill store
     - external agent directories for Claude Code and Codex
     - remote skill sources: GitHub/GitLab/local filesystem
   - The primary arrows are:
     - UI requests → IPC → skill service
     - skill service ↔ remote source
     - skill service ↔ managed store
     - skill service → agent directories
     - settings ↔ persisted app config/token store

14. **Repo shape summary**
   - This is not a server-client app; it is a desktop orchestration tool with a thin UI and a centralized main-process domain service.
   - The architecture is optimized for safe local automation around filesystem state, source fetching, and agent-specific integration rather than for network serving or background distributed compute.

Main entry points: [`src/main/skills-service.ts`](https://github.com/haydenull/skills-manager/blob/main/src/main/skills-service.ts) (Skills service), [`src/renderer/src/skills-queries.ts`](https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/skills-queries.ts) (Skills queries), [`src/renderer/src/routes/__root.tsx`](https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/routes/__root.tsx) (Route root), [`src/renderer/src/routes/index.tsx`](https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/routes/index.tsx) (Installed view)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_main["Main process"]
  node_main_entry["Main entry<br/>electron main<br/>[index.ts]"]
  node_skills_service{{"Skills service<br/>domain service<br/>[skills-service.ts]"}}
end

subgraph group_bridge["Preload bridge"]
  node_preload_bridge["IPC bridge<br/>preload<br/>[index.ts]"]
  node_preload_types["Bridge types<br/>d.ts<br/>[index.d.ts]"]
end

subgraph group_renderer["Renderer UI"]
  node_renderer_app["Renderer app<br/>react shell<br/>[main.tsx]"]
  node_router_root["Route root<br/>router shell<br/>[__root.tsx]"]
  node_route_installed["Installed view<br/>screen<br/>[index.tsx]"]
  node_route_install["Install screen<br/>[install.tsx]"]
  node_route_settings["Settings screen<br/>[settings.tsx]"]
  node_skills_queries["Skills queries<br/>client data<br/>[skills-queries.ts]"]
  node_versions_ui["Versions UI<br/>[Versions.tsx]"]
end

subgraph group_shared["Shared types"]
  node_shared_types["Skill types<br/>shared contracts<br/>[skills-types.ts]"]
end

subgraph group_external["External systems"]
  node_skill_sources{{"Skill sources<br/>source adapters"}}
  node_managed_store[("Managed store<br/>app data")]
  node_claude_dir[("Claude skills<br/>filesystem target")]
  node_codex_dir[("Codex skills<br/>filesystem target")]
  node_settings_store[("Config store<br/>persisted config")]
end

subgraph group_build["Build and release"]
  node_build_pipeline["Build pipeline<br/>packaging"]
end

node_main_entry -->|"initializes"| node_skills_service
node_skills_service -->|"fetches from"| node_skill_sources
node_skills_service -->|"reads/writes"| node_managed_store
node_skills_service -->|"syncs to"| node_claude_dir
node_skills_service -->|"syncs to"| node_codex_dir
node_skills_service -->|"persists"| node_settings_store
node_preload_bridge -->|"IPC calls"| node_skills_service
node_preload_bridge -->|"exposes"| node_preload_types
node_renderer_app -->|"mounts"| node_router_root
node_router_root -->|"navigates"| node_route_installed
node_router_root -->|"navigates"| node_route_install
node_router_root -->|"navigates"| node_route_settings
node_route_installed -->|"uses"| node_skills_queries
node_route_install -->|"uses"| node_skills_queries
node_route_settings -->|"uses"| node_skills_queries
node_skills_queries -->|"calls through"| node_preload_bridge
node_route_installed -.->|"renders"| node_versions_ui
node_skills_service -->|"conforms to"| node_shared_types
node_skills_queries -->|"conforms to"| node_shared_types
node_preload_types -->|"mirrors"| node_shared_types
node_build_pipeline -.->|"bundles"| node_main_entry
node_build_pipeline -.->|"bundles"| node_renderer_app

click node_main_entry "https://github.com/haydenull/skills-manager/blob/main/src/main/index.ts"
click node_skills_service "https://github.com/haydenull/skills-manager/blob/main/src/main/skills-service.ts"
click node_preload_bridge "https://github.com/haydenull/skills-manager/blob/main/src/preload/index.ts"
click node_preload_types "https://github.com/haydenull/skills-manager/blob/main/src/preload/index.d.ts"
click node_renderer_app "https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/main.tsx"
click node_router_root "https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/routes/__root.tsx"
click node_route_installed "https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/routes/index.tsx"
click node_route_install "https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/routes/install.tsx"
click node_route_settings "https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/routes/settings.tsx"
click node_skills_queries "https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/skills-queries.ts"
click node_versions_ui "https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/components/Versions.tsx"
click node_shared_types "https://github.com/haydenull/skills-manager/blob/main/src/shared/skills-types.ts"
click node_build_pipeline "https://github.com/haydenull/skills-manager/blob/main/electron.vite.config.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_main_entry,node_skills_service toneBlue
class node_preload_bridge,node_preload_types toneAmber
class node_renderer_app,node_router_root,node_route_installed,node_route_install,node_route_settings,node_skills_queries,node_versions_ui toneMint
class node_shared_types toneRose
class node_skill_sources,node_managed_store,node_claude_dir,node_codex_dir,node_settings_store toneIndigo
class node_build_pipeline toneTeal
```

## Components

### Main process

Privileged Electron backend and domain logic

- [Main entry](https://github.com/haydenull/skills-manager/blob/main/src/main/index.ts): electron main · Bootstraps the Electron app and wires IPC/service setup · `src/main/index.ts`
- [Skills service](https://github.com/haydenull/skills-manager/blob/main/src/main/skills-service.ts): domain service · Core skill management logic for discover, install, update, debug toggle, and sync · `src/main/skills-service.ts`

### Preload bridge

Typed IPC boundary between renderer and main

- [IPC bridge](https://github.com/haydenull/skills-manager/blob/main/src/preload/index.ts): preload · Secure typed API exposed to the renderer · `src/preload/index.ts`
- [Bridge types](https://github.com/haydenull/skills-manager/blob/main/src/preload/index.d.ts): d.ts · Type declarations for the preload-exposed surface · `src/preload/index.d.ts`

### Renderer UI

React screens and client-side data flow

- [Renderer app](https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/main.tsx): react shell · Client-side UI bootstrap and route host · `src/renderer/src/main.tsx`
- [Route root](https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/routes/__root.tsx): router shell · Top-level router composition · `src/renderer/src/routes/__root.tsx`
- [Installed view](https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/routes/index.tsx): screen · Shows installed skills and their status · `src/renderer/src/routes/index.tsx`
- [Install screen](https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/routes/install.tsx): screen · Previews and installs skills from a source · `src/renderer/src/routes/install.tsx`
- [Settings screen](https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/routes/settings.tsx): screen · Configures theme, tokens, update checks, and shortcuts · `src/renderer/src/routes/settings.tsx`
- [Skills queries](https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/skills-queries.ts): client data · Renderer-side helpers for IPC-backed skill operations · `src/renderer/src/skills-queries.ts`
- [Versions UI](https://github.com/haydenull/skills-manager/blob/main/src/renderer/src/components/Versions.tsx): Small reusable version/status display component · `src/renderer/src/components/Versions.tsx`

### Shared types

Contracts used across process boundaries

- [Skill types](https://github.com/haydenull/skills-manager/blob/main/src/shared/skills-types.ts): shared contracts · Cross-process TypeScript models for skills, sources, and updates · `src/shared/skills-types.ts`

### External systems

Remote sources and local filesystem targets

- **Skill sources**: source adapters · GitHub, GitLab, and local-directory discovery and metadata normalization
- **Managed store**: app data · Authoritative local cache for installed skills and debug state
- **Claude skills**: filesystem target · External skills directory used by Claude Code
- **Codex skills**: filesystem target · External skills directory used by Codex
- **Config store**: persisted config · Saved app settings including tokens, paths, and update preferences

### Build and release

Bundling and packaging pipeline

- [Build pipeline](https://github.com/haydenull/skills-manager/blob/main/electron.vite.config.ts): packaging · Development bundling, desktop packaging, and release automation · `electron.vite.config.ts`

## Connections

- Main entry → Skills service: initializes · Main process wires the skill domain service
- Skills service → Skill sources: fetches from · Discovers and normalizes skills from remote and local sources
- Skills service → Managed store: reads/writes · Maintains installed skill records and debug-local state
- Skills service → Claude skills: syncs to · Installs or removes skills in Claude Code's directory
- Skills service → Codex skills: syncs to · Installs or removes skills in Codex's directory
- Skills service → Config store: persists · Uses saved paths, tokens, and update preferences
- IPC bridge → Skills service: IPC calls · Renderer requests are forwarded through the trusted bridge
- IPC bridge → Bridge types: exposes · Typed surface definitions for renderer consumption
- Renderer app → Route root: mounts · Renderer bootstraps the routed UI
- Route root → Installed view: navigates · Installed-skills screen
- Route root → Install screen: navigates · Install workflow screen
- Route root → Settings screen: navigates · Settings and preferences screen
- Installed view → Skills queries: uses · Fetches installed skills and actions
- Install screen → Skills queries: uses · Queries previews and triggers installs
- Settings screen → Skills queries: uses · Reads and updates app settings
- Skills queries → IPC bridge: calls through · Renderer-side helper layer delegates to IPC
- Installed view → Versions UI: renders · Shows version or update status metadata
- Skills service → Skill types: conforms to · Domain objects align with shared contracts
- Skills queries → Skill types: conforms to · Client-side data helpers use the same contracts
- Bridge types → Skill types: mirrors · Bridge API is typed to match shared models
- Build pipeline → Main entry: bundles · Desktop build includes main-process code
- Build pipeline → Renderer app: bundles · Desktop build includes renderer assets
