# xhargh/clawford architecture

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

- Interactive diagram: https://gitdiagram.com/xhargh/clawford
- Repository: https://github.com/xhargh/clawford

## Overview

Clawford is a browser-based music reference and practice app. A user selects an instrument and tuning, then a key/scale or chord; the app maps pitches to playable string/fret positions and presents them in notation or fretboard views. It also supports note playback, microphone-based tuning, and a configurable metronome. The graph includes settings persistence and the documented PWA offline branch. The excerpts are partial, so links between the app and some renderers or tuner internals are omitted where call ownership is not shown.

Main entry points: [`js/app.js`](https://github.com/xhargh/clawford/blob/main/js/app.js) (App coordinator), [`index.html`](https://github.com/xhargh/clawford/blob/main/index.html) (App page), [`js/mapping.js`](https://github.com/xhargh/clawford/blob/main/js/mapping.js) (Note mapping), [`js/chords.js`](https://github.com/xhargh/clawford/blob/main/js/chords.js) (Chord logic)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_reference["Music reference"]
  node_instruments["Instruments<br/>[instruments.js]"]
  node_tunings["Tunings<br/>[tunings.js]"]
  node_scales["Scales and keys<br/>[scales.js]"]
  node_chords["Chord logic<br/>[chords.js]"]
  node_pitch["Pitch utilities<br/>[pitch.js]"]
  node_mapping["Note mapping<br/>[mapping.js]"]
  node_scale_board["Scale board notes<br/>[scale-board.js]"]
  node_notation["Notation view"]
  node_fretboard["Fretboard view"]
end

subgraph group_practice["Practice tools"]
  node_playback_interactions["Diagram playback"]
  node_player["Note player<br/>[player.js]"]
  node_synth["Pluck synthesis<br/>[synth.js]"]
  node_tuner_lifecycle["Tuner lifecycle<br/>[tuner-lifecycle.js]"]
  node_mic["Microphone session"]
  node_detector["Pitch detection<br/>[pitch-detector.js]"]
  node_tuner["Tuner logic<br/>[tuner.js]"]
  node_tuner_view["Tuner display<br/>[tuner-renderer.js]"]
  node_metronome["Metronome<br/>[metronome.js]"]
  node_metronome_view["Beat display"]
  node_tap_tempo["Tap tempo<br/>[tap-tempo.js]"]
end

subgraph group_appstate["App and settings"]
  node_page["App page<br/>[index.html]"]
  node_app["App coordinator<br/>[app.js]"]
  node_state["State and URL<br/>[state.js]"]
  node_storage["Saved settings<br/>[storage.js]"]
end

subgraph group_offline["Offline app"]
  node_manifest["PWA manifest"]
  node_sw["Offline caching<br/>[sw.js]"]
end

node_user(("User"))
node_browser(("Browser"))

node_user -->|"opens and uses"| node_page
node_page -->|"loads"| node_app
node_app -->|"builds and encodes"| node_state
node_app -->|"loads and saves"| node_storage
node_app -->|"offers choices"| node_instruments
node_app -->|"offers choices"| node_tunings
node_app -->|"generates notes"| node_mapping
node_mapping -->|"converts pitches"| node_pitch
node_mapping -->|"uses scale data"| node_scales
node_app -->|"generates chord notes"| node_chords
node_chords -->|"uses pitch data"| node_pitch
node_chords -->|"uses scale data"| node_scales
node_app -->|"generates scale positions"| node_scale_board
node_scale_board -->|"maps positions"| node_mapping
node_app -->|"renders notation"| node_notation
node_app -->|"renders fretboard"| node_fretboard
node_notation -->|"parses note names"| node_pitch
node_app -->|"selects voicing"| node_playback_interactions
node_app -->|"plays notes"| node_player
node_player -->|"renders plucks"| node_synth
node_app -->|"starts and stops"| node_tuner_lifecycle
node_tuner_lifecycle -->|"creates session"| node_mic
node_mic -->|"requests microphone"| node_browser
node_app -->|"analyzes tuner frames"| node_detector
node_app -->|"updates tuner"| node_tuner
node_app -->|"renders tuner"| node_tuner_view
node_app -->|"controls timing"| node_metronome
node_metronome -->|"reports beats"| node_app
node_app -->|"renders beat"| node_metronome_view
node_app -->|"records taps"| node_tap_tempo
node_page -->|"declares installability"| node_manifest
node_page -->|"registers"| node_sw
node_sw -->|"caches app shell"| node_browser

click node_page "https://github.com/xhargh/clawford/blob/main/index.html"
click node_app "https://github.com/xhargh/clawford/blob/main/js/app.js"
click node_state "https://github.com/xhargh/clawford/blob/main/js/state.js"
click node_storage "https://github.com/xhargh/clawford/blob/main/js/storage.js"
click node_instruments "https://github.com/xhargh/clawford/blob/main/js/instruments.js"
click node_tunings "https://github.com/xhargh/clawford/blob/main/js/tunings.js"
click node_scales "https://github.com/xhargh/clawford/blob/main/js/scales.js"
click node_chords "https://github.com/xhargh/clawford/blob/main/js/chords.js"
click node_pitch "https://github.com/xhargh/clawford/blob/main/js/pitch.js"
click node_mapping "https://github.com/xhargh/clawford/blob/main/js/mapping.js"
click node_scale_board "https://github.com/xhargh/clawford/blob/main/js/scale-board.js"
click node_notation "https://github.com/xhargh/clawford/blob/main/js/notation-renderer.js"
click node_fretboard "https://github.com/xhargh/clawford/blob/main/js/fretboard-renderer.js"
click node_playback_interactions "https://github.com/xhargh/clawford/blob/main/js/playback-interactions.js"
click node_player "https://github.com/xhargh/clawford/blob/main/js/audio/player.js"
click node_synth "https://github.com/xhargh/clawford/blob/main/js/audio/synth.js"
click node_tuner_lifecycle "https://github.com/xhargh/clawford/blob/main/js/tuner-lifecycle.js"
click node_mic "https://github.com/xhargh/clawford/blob/main/js/audio/microphone-session.js"
click node_detector "https://github.com/xhargh/clawford/blob/main/js/audio/pitch-detector.js"
click node_tuner "https://github.com/xhargh/clawford/blob/main/js/tuner.js"
click node_tuner_view "https://github.com/xhargh/clawford/blob/main/js/tuner-renderer.js"
click node_metronome "https://github.com/xhargh/clawford/blob/main/js/metronome.js"
click node_metronome_view "https://github.com/xhargh/clawford/blob/main/js/metronome-renderer.js"
click node_tap_tempo "https://github.com/xhargh/clawford/blob/main/js/tap-tempo.js"
click node_manifest "https://github.com/xhargh/clawford/blob/main/manifest.webmanifest"
click node_sw "https://github.com/xhargh/clawford/blob/main/sw.js"

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_instruments,node_tunings,node_scales,node_chords,node_pitch,node_mapping,node_scale_board,node_notation,node_fretboard,node_user,node_browser toneBlue
class node_playback_interactions,node_player,node_synth,node_tuner_lifecycle,node_mic,node_detector,node_tuner,node_tuner_view,node_metronome,node_metronome_view,node_tap_tempo toneAmber
class node_page,node_app,node_state,node_storage toneMint
class node_manifest,node_sw toneRose
```

## Components

### Music reference

- [Instruments](https://github.com/xhargh/clawford/blob/main/js/instruments.js): `js/instruments.js`
- [Tunings](https://github.com/xhargh/clawford/blob/main/js/tunings.js): `js/tunings.js`
- [Scales and keys](https://github.com/xhargh/clawford/blob/main/js/scales.js): `js/scales.js`
- [Chord logic](https://github.com/xhargh/clawford/blob/main/js/chords.js): `js/chords.js`
- [Pitch utilities](https://github.com/xhargh/clawford/blob/main/js/pitch.js): `js/pitch.js`
- [Note mapping](https://github.com/xhargh/clawford/blob/main/js/mapping.js): `js/mapping.js`
- [Scale board notes](https://github.com/xhargh/clawford/blob/main/js/scale-board.js): `js/scale-board.js`
- [Notation view](https://github.com/xhargh/clawford/blob/main/js/notation-renderer.js): `js/notation-renderer.js`
- [Fretboard view](https://github.com/xhargh/clawford/blob/main/js/fretboard-renderer.js): `js/fretboard-renderer.js`

### Practice tools

- [Diagram playback](https://github.com/xhargh/clawford/blob/main/js/playback-interactions.js): `js/playback-interactions.js`
- [Note player](https://github.com/xhargh/clawford/blob/main/js/audio/player.js): `js/audio/player.js`
- [Pluck synthesis](https://github.com/xhargh/clawford/blob/main/js/audio/synth.js): `js/audio/synth.js`
- [Tuner lifecycle](https://github.com/xhargh/clawford/blob/main/js/tuner-lifecycle.js): `js/tuner-lifecycle.js`
- [Microphone session](https://github.com/xhargh/clawford/blob/main/js/audio/microphone-session.js): `js/audio/microphone-session.js`
- [Pitch detection](https://github.com/xhargh/clawford/blob/main/js/audio/pitch-detector.js): `js/audio/pitch-detector.js`
- [Tuner logic](https://github.com/xhargh/clawford/blob/main/js/tuner.js): `js/tuner.js`
- [Tuner display](https://github.com/xhargh/clawford/blob/main/js/tuner-renderer.js): `js/tuner-renderer.js`
- [Metronome](https://github.com/xhargh/clawford/blob/main/js/metronome.js): `js/metronome.js`
- [Beat display](https://github.com/xhargh/clawford/blob/main/js/metronome-renderer.js): `js/metronome-renderer.js`
- [Tap tempo](https://github.com/xhargh/clawford/blob/main/js/tap-tempo.js): `js/tap-tempo.js`

### App and settings

- [App page](https://github.com/xhargh/clawford/blob/main/index.html): `index.html`
- [App coordinator](https://github.com/xhargh/clawford/blob/main/js/app.js): `js/app.js`
- [State and URL](https://github.com/xhargh/clawford/blob/main/js/state.js): `js/state.js`
- [Saved settings](https://github.com/xhargh/clawford/blob/main/js/storage.js): `js/storage.js`

### Offline app

- [PWA manifest](https://github.com/xhargh/clawford/blob/main/manifest.webmanifest): `manifest.webmanifest`
- [Offline caching](https://github.com/xhargh/clawford/blob/main/sw.js): `sw.js`

### Other components

- **User**
- **Browser**

## Connections

- User → App page: opens and uses
- App page → App coordinator: loads
- App coordinator → State and URL: builds and encodes
- App coordinator → Saved settings: loads and saves
- App coordinator → Instruments: offers choices
- App coordinator → Tunings: offers choices
- App coordinator → Note mapping: generates notes
- Note mapping → Pitch utilities: converts pitches
- Note mapping → Scales and keys: uses scale data
- App coordinator → Chord logic: generates chord notes
- Chord logic → Pitch utilities: uses pitch data
- Chord logic → Scales and keys: uses scale data
- App coordinator → Scale board notes: generates scale positions
- Scale board notes → Note mapping: maps positions
- App coordinator → Notation view: renders notation
- App coordinator → Fretboard view: renders fretboard
- Notation view → Pitch utilities: parses note names
- App coordinator → Diagram playback: selects voicing
- App coordinator → Note player: plays notes
- Note player → Pluck synthesis: renders plucks
- App coordinator → Tuner lifecycle: starts and stops
- Tuner lifecycle → Microphone session: creates session
- Microphone session → Browser: requests microphone
- App coordinator → Pitch detection: analyzes tuner frames
- App coordinator → Tuner logic: updates tuner
- App coordinator → Tuner display: renders tuner
- App coordinator → Metronome: controls timing
- Metronome → App coordinator: reports beats
- App coordinator → Beat display: renders beat
- App coordinator → Tap tempo: records taps
- App page → PWA manifest: declares installability
- App page → Offline caching: registers
- Offline caching → Browser: caches app shell
