Project-local context for Claude Code sessions. Read on startup, update when conventions or open work changes. Do not document features that already exist — those live in the code. This file is for what's in flight and what we've agreed.
- Origin:
oje-studio/oje-cue-monitor - Active branch:
cleanup/cue-monitor-polish- Built on top of Codex's
bb21bd2onmain(improved editing, performance, remote, and PDF workflows).
- Built on top of Codex's
mainhas not yet been updated with the polish branch; merge is pending operator review.- An older branch
claude/continue-work-AKHpDexists on remote with an earlier abandoned SHOW MONITOR experiment + Codex merge. Safe to delete oncecleanup/cue-monitor-polishis merged.
There is only one app: ØJE CUE MONITOR — a live-show LTC cue
monitor with a Performance Mode and a Web Remote.
Earlier attempts to scaffold a second app (SHOW MONITOR with
scene-based timing) were dropped; do not re-create that work unless
the operator explicitly asks again.
Entry point: python3 main.py. Build: bash build.sh (macOS) or
build_win.bat (Windows). PyInstaller specs: OJECueMonitor.spec,
OJECueMonitor_win.spec. CI in .github/workflows/build.yml produces
artefacts on push to main and a tagged release on v*.
- After each fix: commit with a clear message that explains the why,
then
git pushto the active branch. The operator pulls on their Mac and tests. Don't batch fixes into a single mega-commit. - Never push to
maindirectly — keep work on the feature branch. - Tests where they exist live in
python3 -c "..."smoke checks run withQT_QPA_PLATFORM=offscreen. There is no formal test suite; visual / behavioural verification on the operator's Mac is the acceptance signal. - The operator runs the app with:
pkill -f "python3 main.py",git pull,python3 main.py. If a fix isn't reaching them, the most likely cause is a stale Python process holding port 8080.
These are gotchas we already fixed; flag if they regress.
QLineEdit.setInputMask("00:00:00:00;0")— when the blank char equals a valid digit,text()strips typed zeros. ReaddisplayText()instead. Fixed inui/cue_table.py→ seeTimecodePopup._try_apply.- CSS specificity tie —
.hiddenrule must come AFTER.overlayor be marked!important. We use!importantinweb_remote.py. - iOS Safari rubber-band scroll — body needs
position: fixed,inset: 0,overscroll-behavior: none,touch-action: pan-yto stop the page sliding under the finger. 100dvhlets content slip under iOS Safari toolbar — use100svhinstead. Trade-off: tiny dark band when toolbar collapses, acceptable.- iOS first-load zoom —
meta viewportneedsmaximum-scale=1, user-scalable=noto render at native scale on first paint (no "page is slightly too big until you pinch" state). - Non-linear cue triggering — cues are matched by timecode, not
list order.
get_current_cuewalks every cue (no earlybreak).get_next_cuewalks the list FROM the current row (list order is show order).is_pastincue_table.pyis by frames, not by row. OP_COOKIEin password mode vs no-password mode — only honoured in password mode. No-password mode renders empty operator on every load so the picker shows. See_handle_indexinweb_remote.py.
Tried four interpretations (strict equality, 30-s hold past last,
end-of-show clearing, persistent + UI hint), all reverted (fe0d5ec).
Operator's request is genuinely ambiguous between:
- flash on hit (cue current only at exact TC)
- persistent until next (current behaviour, never clears past last)
- some hybrid (clear past last but not too quickly)
Don't reopen this without a concrete table from the operator: "LTC = X with cues at A,B,C → should show: Y." Until then the engine stays as-is (persistent).
Branch is ready. Operator hasn't given the green light to merge;
they want to test more first. When they say go: open a PR, merge,
optionally tag v0.97.1 or similar so CI ships a release.
The repo doesn't exist on GitHub yet. Operator needs to create it
manually (Claude's GitHub MCP scope is restricted to
oje-studio/oje-cue-monitor). When created, prepare
profile/README.md content based on the studio About section in
the main README.
claude/continue-work-AKHpD on remote — old SHOW MONITOR experiment.
Delete after cleanup/cue-monitor-polish merges to main.
main.py # PyQt entry point
cue_engine.py # Cue list + non-linear matching
ltc_decoder.py # LTC audio → timecode (libltc + portaudio)
show_file.py # .ojeshow JSON load/save
web_remote.py # aiohttp server: HTTP + WebSocket + page render
ui/main_window.py # Edit window + Performance toggle + PDF export
ui/cue_table.py # Cue list table widget + TimecodePopup
ui/performance_view.py # Fullscreen operator view (clock, VU, cue card)
ui/settings_dialog.py # Show settings (audio device, operators, etc.)
ui/remote_panel.py # Mac panel showing remote URL + QR
ui/fonts.py # Mac mono / sans helpers
- Tone in commit messages: explain the why + concrete symptom that prompted the change. The operator reads the log.
- Comments in code are sparing — only when why is non-obvious.
- Don't add features beyond what's asked. If a fix doesn't need surrounding cleanup, don't include it.
- Russian / English mix in chat is fine; commit messages and code comments are English only.