# moein-alas/obsidian-intake architecture

> Architecture diagram of the GitHub repository moein-alas/obsidian-intake, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-09). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/moein-alas/obsidian-intake
- Repository: https://github.com/moein-alas/obsidian-intake

## Overview

Obsidian Intake manages external files through an Obsidian extension and a Python router: files are staged in the Vault, tracked by identity and history, then synchronized, recovered, retained, or made permanent. The extension provides the user-facing controls; the router performs filesystem operations and coordinates persistence. The graph preserves the documented dashboard and Deleted-Notes capabilities, but their detailed handlers are not fully shown in the sampled excerpts, so only documented or excerpt-supported relationships are connected.

Main entry points: [`router/main.py`](https://github.com/moein-alas/obsidian-intake/blob/main/router/main.py) (Router CLI), [`extension/main.js`](https://github.com/moein-alas/obsidian-intake/blob/main/extension/main.js) (Obsidian extension), [`router/sync.py`](https://github.com/moein-alas/obsidian-intake/blob/main/router/sync.py) (Change synchronization), [`router/migration.py`](https://github.com/moein-alas/obsidian-intake/blob/main/router/migration.py) (Migration and conflicts)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_user_flow["Intake and Vault UI"]
  node_extension["Obsidian extension<br/>[main.js]"]
  node_banner["File banner<br/>[main.js]"]
  node_dashboard["Dashboard<br/>[main.js]"]
  node_deleted_ui["Deleted-Notes UI<br/>[main.js]"]
  node_settings["Settings panel<br/>[main.js]"]
end

subgraph group_router["Router operations"]
  node_router_cli["Router CLI<br/>[main.py]"]
  node_intake_lifecycle["File intake and lifecycle<br/>[main.py]"]
end

subgraph group_lifecycle["Lifecycle engines"]
  node_sync["Change synchronization<br/>[sync.py]"]
  node_migration["Migration and conflicts<br/>[migration.py]"]
  node_hashing["File hashing<br/>[hashing.py]"]
  node_headers["Source headers<br/>[header.py]"]
end

subgraph group_state["Configuration and state"]
  node_config["Runtime configuration<br/>[config.py]"]
  node_database["File records and events<br/>[database.py]"]
  node_sqlite[("SQLite state store<br/>[schema.sql]")]
end

node_user(("Obsidian user"))
node_external["External files"]

node_user -->|"uses"| node_extension
node_user -->|"opens"| node_external
node_extension -->|"renders"| node_banner
node_extension -->|"provides"| node_dashboard
node_extension -->|"provides"| node_deleted_ui
node_extension -->|"provides"| node_settings
node_extension -->|"invokes JSON CLI"| node_router_cli
node_external -->|"routes open"| node_router_cli
node_router_cli -->|"dispatches"| node_intake_lifecycle
node_router_cli -->|"calls"| node_database
node_router_cli -->|"loads"| node_config
node_router_cli -->|"dispatches sync"| node_sync
node_router_cli -->|"dispatches migration"| node_migration
node_router_cli -->|"uses hashes"| node_hashing
node_router_cli -->|"uses headers"| node_headers
node_router_cli -->|"reads and writes"| node_external
node_banner -->|"checks and updates"| node_router_cli
node_extension -->|"moves on close"| node_router_cli
node_config -->|"reads plugin data"| node_settings
node_database -->|"persists records"| node_sqlite
node_sync -->|"updates state"| node_database
node_sync -->|"computes hashes"| node_hashing
node_sync -->|"preserves headers"| node_headers
node_migration -->|"updates state"| node_database
node_migration -->|"checks external"| node_hashing
node_migration -->|"handles headers"| node_headers

click node_extension "https://github.com/moein-alas/obsidian-intake/blob/main/extension/main.js"
click node_banner "https://github.com/moein-alas/obsidian-intake/blob/main/extension/main.js"
click node_dashboard "https://github.com/moein-alas/obsidian-intake/blob/main/extension/main.js"
click node_deleted_ui "https://github.com/moein-alas/obsidian-intake/blob/main/extension/main.js"
click node_settings "https://github.com/moein-alas/obsidian-intake/blob/main/extension/main.js"
click node_router_cli "https://github.com/moein-alas/obsidian-intake/blob/main/router/main.py"
click node_intake_lifecycle "https://github.com/moein-alas/obsidian-intake/blob/main/router/main.py"
click node_sync "https://github.com/moein-alas/obsidian-intake/blob/main/router/sync.py"
click node_migration "https://github.com/moein-alas/obsidian-intake/blob/main/router/migration.py"
click node_hashing "https://github.com/moein-alas/obsidian-intake/blob/main/router/hashing.py"
click node_headers "https://github.com/moein-alas/obsidian-intake/blob/main/router/header.py"
click node_config "https://github.com/moein-alas/obsidian-intake/blob/main/router/config.py"
click node_database "https://github.com/moein-alas/obsidian-intake/blob/main/router/database.py"
click node_sqlite "https://github.com/moein-alas/obsidian-intake/blob/main/database/schema.sql"

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_extension,node_banner,node_dashboard,node_deleted_ui,node_settings,node_user toneBlue
class node_router_cli,node_intake_lifecycle toneAmber
class node_sync,node_migration,node_hashing,node_headers toneMint
class node_config,node_database,node_sqlite toneRose
class node_external toneIndigo
```

## Components

### Intake and Vault UI

- [Obsidian extension](https://github.com/moein-alas/obsidian-intake/blob/main/extension/main.js): `extension/main.js`
- [File banner](https://github.com/moein-alas/obsidian-intake/blob/main/extension/main.js): `extension/main.js`
- [Dashboard](https://github.com/moein-alas/obsidian-intake/blob/main/extension/main.js): `extension/main.js`
- [Deleted-Notes UI](https://github.com/moein-alas/obsidian-intake/blob/main/extension/main.js): `extension/main.js`
- [Settings panel](https://github.com/moein-alas/obsidian-intake/blob/main/extension/main.js): `extension/main.js`

### Router operations

- [Router CLI](https://github.com/moein-alas/obsidian-intake/blob/main/router/main.py): `router/main.py`
- [File intake and lifecycle](https://github.com/moein-alas/obsidian-intake/blob/main/router/main.py): `router/main.py`

### Lifecycle engines

- [Change synchronization](https://github.com/moein-alas/obsidian-intake/blob/main/router/sync.py): `router/sync.py`
- [Migration and conflicts](https://github.com/moein-alas/obsidian-intake/blob/main/router/migration.py): `router/migration.py`
- [File hashing](https://github.com/moein-alas/obsidian-intake/blob/main/router/hashing.py): `router/hashing.py`
- [Source headers](https://github.com/moein-alas/obsidian-intake/blob/main/router/header.py): `router/header.py`

### Configuration and state

- [Runtime configuration](https://github.com/moein-alas/obsidian-intake/blob/main/router/config.py): `router/config.py`
- [File records and events](https://github.com/moein-alas/obsidian-intake/blob/main/router/database.py): `router/database.py`
- [SQLite state store](https://github.com/moein-alas/obsidian-intake/blob/main/database/schema.sql): `database/schema.sql`

### Other components

- **Obsidian user**
- **External files**

## Connections

- Obsidian user → Obsidian extension: uses (evidence: `README.md`)
- Obsidian user → External files: opens (evidence: `README.md`)
- Obsidian extension → File banner: renders (evidence: `extension/main.js`)
- Obsidian extension → Dashboard: provides (evidence: `README.md`)
- Obsidian extension → Deleted-Notes UI: provides (evidence: `README.md`)
- Obsidian extension → Settings panel: provides (evidence: `README.md`)
- Obsidian extension → Router CLI: invokes JSON CLI (evidence: `README.md`)
- External files → Router CLI: routes open (evidence: `README.md`)
- Router CLI → File intake and lifecycle: dispatches (evidence: `router/main.py`)
- Router CLI → File records and events: calls (evidence: `router/main.py`)
- Router CLI → Runtime configuration: loads (evidence: `router/main.py`)
- Router CLI → Change synchronization: dispatches sync (evidence: `router/main.py`)
- Router CLI → Migration and conflicts: dispatches migration (evidence: `router/main.py`)
- Router CLI → File hashing: uses hashes (evidence: `router/main.py`)
- Router CLI → Source headers: uses headers (evidence: `router/main.py`)
- Router CLI → External files: reads and writes (evidence: `router/main.py`)
- File banner → Router CLI: checks and updates (evidence: `extension/main.js`)
- Obsidian extension → Router CLI: moves on close (evidence: `extension/main.js`)
- Runtime configuration → Settings panel: reads plugin data (evidence: `router/config.py`)
- File records and events → SQLite state store: persists records (evidence: `router/database.py`)
- Change synchronization → File records and events: updates state (evidence: `router/sync.py`)
- Change synchronization → File hashing: computes hashes (evidence: `router/sync.py`)
- Change synchronization → Source headers: preserves headers (evidence: `router/sync.py`)
- Migration and conflicts → File records and events: updates state (evidence: `router/migration.py`)
- Migration and conflicts → File hashing: checks external (evidence: `router/migration.py`)
- Migration and conflicts → Source headers: handles headers (evidence: `router/migration.py`)
