- Source code lives in
src/clj_karaoke/. - Tests live in
test/clj_karaoke/(currently centered incore_test.clj). - CI workflows are under
.github/workflows/. - Documentation and references are in
doc/andREADME.md. - Utility scripts for local media processing are at repo root:
midi-to-mp3.fishandsanitize_lyrics_files.fish.
Namespace naming follows Clojure conventions: clj-karaoke.* in code maps to src/clj_karaoke/*.clj(c) paths.
lein depsinstalls project dependencies.lein testruns the test suite (clojure.test).lein uberjarbuilds the runnable JAR intarget/.java -jar target/<uberjar>.jar input.mid output.json --type jsonruns single-file extraction.java -jar target/<uberjar>.jar -i <input-dir> -o <output-dir> -t ass --offset -1000runs batch extraction.
Use the same commands in local validation that CI uses (lein test, lein uberjar).
clojure-mcpis the primary toolset for this repository.- Prefer
clojure-mcptools for project exploration and edits:clojure_inspect_projectfor high-level orientation.glob_files/grepfor fast file and content discovery.read_filefor focused reads.clojure_edit/clojure_edit_replace_sexpfor structural Clojure edits.clojure_evalfor REPL verification of behavior.
- Use
reftools for external documentation lookup:ref_search_documentationto find relevant docs or references.ref_read_urlto read the selected source URL content.
- Use
context7for library/framework API docs and examples:- First call
resolve-library-id. - Then call
query-docswith the resolved library ID. - Keep queries specific to the task to minimize noise.
- First call
- Use idiomatic Clojure formatting with two-space indentation and aligned bindings.
- Prefer
kebab-casefor vars/functions, lowercase keywords, and descriptive namespace aliases (str,io,json). - Keep protocol and record names in
CamelCase(PMidiReader,MidiReader). - Preserve the existing separation of concerns: MIDI parsing (
midi.clj), lyric model/event/frame logic (lyrics_*.cljc), and CLI entrypoint (core.clj).
- Write tests with
clojure.testusingdeftest+testingblocks. - Place tests in matching namespace files (example:
clj-karaoke.core-testintest/clj_karaoke/core_test.clj). - Add focused assertions around timing offsets, frame splitting/joining, and output format behavior when changing parsing logic.
- Run
lein testbefore opening a PR.
- Keep commits short, imperative, and scoped (history examples:
readme update,opts,Update subtitles.yml). - Prefer one logical change per commit.
- PRs should include: purpose, key behavior changes, test evidence (
lein testoutput), and sample CLI usage when output format behavior changes. - If workflow behavior changes, reference the touched file in
.github/workflows/.