diff --git a/eslint.config.js b/eslint.config.js index f028798..04d0adb 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -18,6 +18,7 @@ const sharedOverlay = { startPurr: 'readonly', stopPurr: 'readonly', playChirp: 'readonly', playMrrp: 'readonly', // effects.js provides these: drawThinkBubble: 'readonly', drawWorkBubble: 'readonly', drawDoneSpark: 'readonly', drawHeart: 'readonly', + drawGuitar: 'readonly', drawNote: 'readonly', }; const CONSUMER_OVERLAY = ['src/renderer.js', 'src/settings-renderer.js', 'src/cat-preview.js']; @@ -30,7 +31,7 @@ module.exports = [ { // Node / CommonJS: main process, workers, scripts, tests, configs, template.js files: ['**/*.js'], - ignores: [...CONSUMER_OVERLAY, 'src/cat-sprite.js', 'src/patterns.js', 'src/audio.js', 'src/effects.js'], + ignores: [...CONSUMER_OVERLAY, 'src/cat-sprite.js', 'src/patterns.js', 'src/audio.js', 'src/effects.js', 'src/jam.js'], languageOptions: { sourceType: 'commonjs', ecmaVersion: 2023, globals: { ...globals.node } }, }, { @@ -48,6 +49,12 @@ module.exports = [ files: ['src/effects.js'], languageOptions: { sourceType: 'script', ecmaVersion: 2023, globals: { ...globals.browser, ctx: 'readonly' } }, }, + { + // jam.js: classic overlay + + diff --git a/src/config.js b/src/config.js index c72a3e6..6e6c3f8 100644 --- a/src/config.js +++ b/src/config.js @@ -29,6 +29,7 @@ const DEFAULTS = { pinnedNote: '', // fixed message pinned above the cat's head ('' = off) notifyOn: true, // also pop a Windows toast for reminders/messages pomodoro: { on: false, focusMin: 25, breakMin: 5 }, // focus/break loops + floating pixel timer + lobbyJam: { on: false, mood: 'cozy' }, // synthesized lo-fi "study music" the cat plays (cozy/dreamy/upbeat) reminders: [], // [{ id, hhmm: 'HH:MM', message, recur, days, lastFired }] email: { on: false, host: '', port: 993, user: '', secure: true, intervalMin: 5 }, // IMAP unread alerts (app-password stored separately, encrypted) calendar: { on: false, icsUrl: '', leadMin: 10 }, // nudge before events from a secret .ics URL @@ -81,6 +82,10 @@ function normalize(cfg) { const p = (c.pomodoro && typeof c.pomodoro === 'object') ? c.pomodoro : {}; return { on: !!p.on, focusMin: clampInt(p.focusMin, 5, 120, 25), breakMin: clampInt(p.breakMin, 1, 60, 5) }; })(), + lobbyJam: (() => { + const lj = (c.lobbyJam && typeof c.lobbyJam === 'object') ? c.lobbyJam : {}; + return { on: !!lj.on, mood: ['cozy', 'dreamy', 'upbeat'].includes(lj.mood) ? lj.mood : 'cozy' }; + })(), email: (() => { const e = (c.email && typeof c.email === 'object') ? c.email : {}; const port = clampInt(e.port, 1, 65535, 993); diff --git a/src/effects.js b/src/effects.js index d8aff76..0979277 100644 --- a/src/effects.js +++ b/src/effects.js @@ -2,7 +2,7 @@ // spinner, "done!" burst, love heart). Classic + diff --git a/src/jam.js b/src/jam.js new file mode 100644 index 0000000..82b2a5a --- /dev/null +++ b/src/jam.js @@ -0,0 +1,168 @@ +// src/jam.js — "Lobby Jam": a synthesized, improvising lo-fi study-music loop the cat +// plays. 100% Web Audio (no asset files): Karplus-Strong plucked guitar over lazy jazzy +// voicings + soft bass + brushed percussion, tape-warmed. Classic overlay