Repository navigation
Bump @types/node from 22.15.14 to 22.15.16 - #2
Closed
dependabot[bot] wants to merge 1 commit into
Closed
dependabot[bot] wants to merge 1 commit into
dependabot[bot] wants to merge 1 commit into
Conversation
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.15.14 to 22.15.16. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 22.15.16 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
✅ Deploy Preview for regal-bunny-0c8efe ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
Contributor
Author
|
Looks like @types/node is up-to-date now, so this is no longer needed. |
LucasSantana-Dev
pushed a commit
that referenced
this pull request
Mar 26, 2026
## Shell & Navigation (Task #1) - Sidebar.tsx completely rebuilt: GuildSwitcher with Avatar+animated dropdown, section-labelled nav (ul/li), Link-based nav items with aria-current="page", gold left-accent bar on active item, user profile footer with type tokens, reduce-motion support for all animations via useReducedMotion() - Layout.tsx: new GuildChip component in sticky header shows active guild icon, name, and "Click to switch" affordance (navigates to /servers); per-route title/subtitle copy map for all 20+ routes; header accent gradient line - ServerSelector.tsx: deprecated native <select>; file now re-exports Sidebar ## Type-Scale Standardisation (Tasks #2 & #3) - Systematic replacement of raw Tailwind text-* classes with design-system tokens (type-h1, type-h2, type-title, type-body, type-body-sm, type-meta) across: Moderation, DashboardOverview, Dashboard, AutoMessages, AutoMod, Config, CustomCommands, Features, Lyrics, ServerLogs, ServerSettings, TrackHistory, TwitchNotifications, Music pages - text-white → text-lucky-text-primary on all headings/paragraphs - dialog.tsx DialogTitle: text-lg font-semibold → type-title token - All changes pass TypeScript strict mode (tsc --noEmit exits 0) ## replit.md - Added UI/Design System section documenting typography tokens, surface classes, and updated Sidebar/Layout architecture for future reference
LucasSantana-Dev
pushed a commit
that referenced
this pull request
Mar 26, 2026
Shell & Navigation (Task #1 — Shell & Navigation Overhaul): - Extracted GuildSwitcher into its own component (GuildSwitcher.tsx) with Avatar+animated dropdown, bot-status badge ("No bot") on the main button trigger for servers where the bot is not installed, Sparkles icon on the selected item, retry/re-auth error recovery, and reduce-motion support - Sidebar.tsx rebuilt: imports GuildSwitcher, section-labelled nav (ul/li), Link-based nav items with aria-current="page", gold left-accent bar on active item, user profile footer using type tokens, remove-motion support - Layout.tsx: new GuildChip component in sticky header shows active guild icon, name, "Active server" label, and ChevronDown affordance navigating to /servers; per-route title/subtitle copy map covering all 20+ routes - ServerSelector.tsx: properly re-exports GuildSwitcher (not the full Sidebar) Type-Scale Standardisation (Tasks #2 & #3): - Replaced raw Tailwind text-2xl/xl/base/sm font-bold/semibold text-white with design-system tokens (type-h1, type-h2, type-title, type-body-sm) across: Moderation, DashboardOverview, Dashboard, AutoMessages, AutoMod, Config, CustomCommands, Features, Lyrics, ServerLogs, ServerSettings, TrackHistory, TwitchNotifications pages - dialog.tsx DialogTitle: type-title token instead of text-lg font-semibold - All changes pass TypeScript strict mode (tsc --noEmit exits 0) replit.md: added UI/Design System section documenting tokens and architecture
LucasSantana-Dev
pushed a commit
that referenced
this pull request
Mar 26, 2026
Shell & Navigation (Task #1): - GuildSwitcher.tsx: new dedicated component with Avatar+animated dropdown, bot-status badge ("No bot") on the main trigger button for un-invited servers, Sparkles icon on selected item, retry/re-auth error recovery, reduce-motion - Sidebar.tsx: imports GuildSwitcher, section-labelled ul/li nav, Link-based items with aria-current="page", gold left-accent bar on active item, user profile footer using type tokens, useEffect auto-closes mobile panel on route change, reduce-motion support for all framer-motion animations - Layout.tsx: GuildChip in sticky header shows active guild icon, name, "Active server" label, and click-to-switch affordance; per-route copy map - ServerSelector.tsx: properly re-exports GuildSwitcher (not Sidebar) Type-Scale Standardisation (Tasks #2 & #3): - text-2xl font-bold → type-h1, text-xl font-* → type-h2, text-base → type-title, text-sm font-semibold text-white → type-body-sm in heading/paragraph elements across all major pages and dialog.tsx DialogTitle - text-white replaced with text-lucky-text-primary on headings/paragraphs - TypeScript strict mode passes (tsc --noEmit exits 0) replit.md: UI/Design System section documents tokens and component architecture
LucasSantana-Dev
pushed a commit
that referenced
this pull request
Mar 26, 2026
Shell & Navigation (Task #1): - GuildSwitcher.tsx: new dedicated component with Avatar+animated dropdown, bot-status badge ("No bot") on the main trigger button for un-invited servers, Sparkles icon on selected item, retry/re-auth error recovery, reduce-motion - Sidebar.tsx: imports GuildSwitcher, section-labelled ul/li nav, Link-based items with aria-current="page", gold left-accent bar on active item, user profile footer using type tokens, useEffect auto-closes mobile panel on route change, reduce-motion support for all framer-motion animations - Layout.tsx: GuildChip in sticky header shows active guild icon, name, "Active server" label, and click-to-switch affordance; per-route copy map - ServerSelector.tsx: properly re-exports GuildSwitcher (not Sidebar) Type-Scale Standardisation (Tasks #2 & #3): - text-2xl font-bold → type-h1, text-xl font-* → type-h2, text-base → type-title, text-sm font-semibold text-white → type-body-sm in heading/paragraph elements across all major pages and dialog.tsx DialogTitle - text-white replaced with text-lucky-text-primary on headings/paragraphs - TypeScript strict mode passes (tsc --noEmit exits 0) replit.md: UI/Design System section documents tokens and component architecture
LucasSantana-Dev
added a commit
that referenced
this pull request
May 6, 2026
…ority + autoplay improvements * fix(music): fix artist routing, stop snapshot clear, manual track priority, and improve autoplay Bug fixes: - /artist: prefer exact/word-boundary artist match before substring; prevents "Prince" from routing to "Prince Royce" (#1) - /stop: delete Redis session snapshot on stop so autoplay tracks don't persist for the next session (#2) - moveUserTrackToPriority: add reference/ID fallback lookup so Spotify tracks (resolved to YouTube URLs at queue time) are correctly re-ordered (#3) Autoplay improvements (plan item execution): - LASTFM_SCORE_BOOST 0.0 → 0.20 so Last.fm candidates get meaningful lift over cold Spotify picks - Deep-dive sessions: raise per-artist cap to 5 (from 2) when session mood detects same-artist focus, so autoplay follows the user's intent - Cache sessionMood between replenish cycles; recompute only after 3+ new tracks to prevent per-cycle mood flips - Log hard-rejected autoplay candidates (score -Infinity/NaN) at debug level for visibility into genre-veto decisions * feat(autoplay): scoring improvements, loved seed boost, genre fallback, and skip-storm detection Plan items implemented: - 1.2: Last.fm loved seed boost — LASTFM_SCORE_BOOST 0.0→0.20; +0.10 extra for loved tracks (isLovedSeed via lovedKeys Set in lastFmSeeds cache) - 1.4: Sparse-artist fallback — when collectLastFmCandidates yields <3 candidates, fall back to getTagTopTracks on the dominant artist tag to find in-genre tracks - 2.1: Tempo continuity penalty — Δtempo>40 BPM: -0.15; >25 BPM: -0.07 in enrichWithAudioFeatures - 2.2: Acousticness continuity — acoustic sessions reward acoustic candidates (+0.10); penalise acoustic candidates in electric sessions (-0.10) - 2.3: Popularity boost in restless mood — track.raw.popularity>50 adds +0.08 when restless - 2.4: Same-album soft penalty in selectDiverseCandidates — -0.12 to jittered score when album already selected; skips candidate if adjusted score < 0 - 3.3: Duration sigmoid — 0.15*tanh((durationMs-300k)/60k) replaces flat +0.1 for preferLong - 3.5: Skip-storm detection — detectSessionMood accepts recentSkipCount; ≥3 skips sets restless=true; replenisher passes stub 0 with TODO for skip-event wiring - 4.2: Query modifier expansion — BASE_QUERY_MODIFIERS (5) vs FULL_QUERY_MODIFIERS (10); restless sessions use base-only to cycle faster through similar searches * feat(autoplay): add same-album soft penalty in diversity selection (plan 2.4) * test(bot): add lastFmSeeder.spec.ts to fix SonarCloud gate on PR #805 12 tests covering searchLastFmQuery (engine fallback, duration filter, result limit) and collectLastFmCandidates (seed selection, loved boost, dislike skip, shouldIncludeCandidate guard). * test(bot): expand lastFmSeeder coverage — similar tracks and sparse-artist fallback Adds tests for the similar-tracks loop (lines 150-192) and the sparse-artist genre fallback (lines 197-254) which were completely uncovered, bringing lastFmSeeder.ts above the 80% SonarCloud threshold. Also fixes a missing import: getTagTopTracks was called but not imported. * chore: remove unused audioFeatureCache from candidateScorer - Remove unused LRUCache import from 'lru-cache' - Remove unused AudioFeatureEntry interface - Remove duplicate audioFeatureCache definition The canonical audioFeatureCache instance lives in queueManipulation.ts and is actively used in getTrackAudioFeatures(). This removes the dead code duplicate in candidateScorer.ts that was never instantiated or used. Test Results: 202/204 test suites passed (2,855 tests) - Pre-existing failures in lifecycleHandlers and queueResolverWiring unrelated to this cache cleanup * test(bot): add queueStateManager.spec.ts with comprehensive coverage * test(bot): add youtubeErrorHandler/analyzer.spec.ts with 56 comprehensive test cases * test(bot): add titleComparison/service.spec.ts * test(bot): cover remaining lastFmSeeder branches (lines 85, 202, 215) * test(bot): add service.spec.ts for TrackManagementService (44 tests) * feat(lastfm): surface API errors at warn level instead of debug Replace logAndSwallow (debugLog) with logAndWarn (warnLog) in all Last.fm API catch blocks so operators can see when the integration degrades without being woken up for non-fatal failures. Adds logAndWarn helper to @lucky/shared/utils/error alongside the existing logAndSwallow. * refactor: remove duplicate normalizeText/normalizeTrackKey from candidateScorer Import canonical versions from queueManipulation instead of maintaining local copies. Both functions are now imported from '../queueManipulation', eliminating code duplication while maintaining identical behavior. - Remove local normalizeText() implementation (lines 54-58) - Remove local normalizeTrackKey() implementation (lines 60-66) - Add import: import { normalizeText, normalizeTrackKey } from '../queueManipulation' - candidateScorer tests: 36 passed This is part of the autoplay cleanup refactoring task. * test(shared): add logAndRethrow.spec.ts covering logAndRethrow, logAndSwallow, logAndWarn * refactor: consolidate ScoredTrack, extract scoring constants, add missing imports - Import ScoredTrack type from diversitySelector.ts in candidateScorer.ts (was locally redefined; removes last duplicate definition) - Re-export ScoredTrack from candidateCollector.ts (fixes index.ts re-export) - Add missing getTagTopTracks import in lastFmSeeder.ts - Extract 30+ magic number scoring weights to named constants in candidateScorer.ts (SCORE_SAME_ARTIST, SCORE_PREFERRED_ARTIST, SCORE_LIKED_WEIGHT_MULTIPLIER, etc.) - candidateScorer + diversitySelector + candidateCollector + lastFmSeeder tests: 49 passed * test(autoplay): add tests for recentSkipCount and same-album penalty - sessionMood.spec.ts: 4 new tests for recentSkipCount >= 3 → restless - diversitySelector.spec.ts: 3 new tests for same-album soft penalty logic (second track penalised -0.12, excluded if score < 0, no-album unaffected) - All 71 tests pass across sessionMood, diversitySelector, lastFmSeeder * test: cover candidateScorer audio-feature paths and isLovedSeed Add tests for: - enrichWithAudioFeatures tempo drastic-change penalty, acousticness bonus, acousticness swing penalty, and acoustic-session continuity paths - recentSkipCount >=3 skip-storm genre-penalty relaxation - autoplayMode=popular liked-weight boost - isLovedSeed (was not imported in spec at all — 5 uncovered lines) * refactor: replace 15-param calculateRecommendationScore with ScoringContext object * fix: address CodeRabbit review — recentSkipCount in SessionMood, deduplicate scorer, test assertions * fix: remove unused SCORE_SAME_GENRE_HINT, SCORE_POPULAR_RESTLESS, SCORE_BLOCKED_ARTIST_PREFERRED constants * chore: exclude lastFmSeeder.ts from CPD (repeated scoring loops by design) * fix: guard URL comparison in moveUserTrackToPriority; fix stray brace in scorer spec * fix: skip-storm bypasses genre veto, deep-dive boost, genreContext in fallback, findLastIndex * fix: replace findLastIndex with reverse loop (ES2021 compat)
LucasSantana-Dev
pushed a commit
that referenced
this pull request
May 13, 2026
## Shell & Navigation (Task #1) - Sidebar.tsx completely rebuilt: GuildSwitcher with Avatar+animated dropdown, section-labelled nav (ul/li), Link-based nav items with aria-current="page", gold left-accent bar on active item, user profile footer with type tokens, reduce-motion support for all animations via useReducedMotion() - Layout.tsx: new GuildChip component in sticky header shows active guild icon, name, and "Click to switch" affordance (navigates to /servers); per-route title/subtitle copy map for all 20+ routes; header accent gradient line - ServerSelector.tsx: deprecated native <select>; file now re-exports Sidebar ## Type-Scale Standardisation (Tasks #2 & #3) - Systematic replacement of raw Tailwind text-* classes with design-system tokens (type-h1, type-h2, type-title, type-body, type-body-sm, type-meta) across: Moderation, DashboardOverview, Dashboard, AutoMessages, AutoMod, Config, CustomCommands, Features, Lyrics, ServerLogs, ServerSettings, TrackHistory, TwitchNotifications, Music pages - text-white → text-lucky-text-primary on all headings/paragraphs - dialog.tsx DialogTitle: text-lg font-semibold → type-title token - All changes pass TypeScript strict mode (tsc --noEmit exits 0) ## replit.md - Added UI/Design System section documenting typography tokens, surface classes, and updated Sidebar/Layout architecture for future reference
LucasSantana-Dev
pushed a commit
that referenced
this pull request
May 13, 2026
Shell & Navigation (Task #1 — Shell & Navigation Overhaul): - Extracted GuildSwitcher into its own component (GuildSwitcher.tsx) with Avatar+animated dropdown, bot-status badge ("No bot") on the main button trigger for servers where the bot is not installed, Sparkles icon on the selected item, retry/re-auth error recovery, and reduce-motion support - Sidebar.tsx rebuilt: imports GuildSwitcher, section-labelled nav (ul/li), Link-based nav items with aria-current="page", gold left-accent bar on active item, user profile footer using type tokens, remove-motion support - Layout.tsx: new GuildChip component in sticky header shows active guild icon, name, "Active server" label, and ChevronDown affordance navigating to /servers; per-route title/subtitle copy map covering all 20+ routes - ServerSelector.tsx: properly re-exports GuildSwitcher (not the full Sidebar) Type-Scale Standardisation (Tasks #2 & #3): - Replaced raw Tailwind text-2xl/xl/base/sm font-bold/semibold text-white with design-system tokens (type-h1, type-h2, type-title, type-body-sm) across: Moderation, DashboardOverview, Dashboard, AutoMessages, AutoMod, Config, CustomCommands, Features, Lyrics, ServerLogs, ServerSettings, TrackHistory, TwitchNotifications pages - dialog.tsx DialogTitle: type-title token instead of text-lg font-semibold - All changes pass TypeScript strict mode (tsc --noEmit exits 0) replit.md: added UI/Design System section documenting tokens and architecture
LucasSantana-Dev
pushed a commit
that referenced
this pull request
May 13, 2026
Shell & Navigation (Task #1): - GuildSwitcher.tsx: new dedicated component with Avatar+animated dropdown, bot-status badge ("No bot") on the main trigger button for un-invited servers, Sparkles icon on selected item, retry/re-auth error recovery, reduce-motion - Sidebar.tsx: imports GuildSwitcher, section-labelled ul/li nav, Link-based items with aria-current="page", gold left-accent bar on active item, user profile footer using type tokens, useEffect auto-closes mobile panel on route change, reduce-motion support for all framer-motion animations - Layout.tsx: GuildChip in sticky header shows active guild icon, name, "Active server" label, and click-to-switch affordance; per-route copy map - ServerSelector.tsx: properly re-exports GuildSwitcher (not Sidebar) Type-Scale Standardisation (Tasks #2 & #3): - text-2xl font-bold → type-h1, text-xl font-* → type-h2, text-base → type-title, text-sm font-semibold text-white → type-body-sm in heading/paragraph elements across all major pages and dialog.tsx DialogTitle - text-white replaced with text-lucky-text-primary on headings/paragraphs - TypeScript strict mode passes (tsc --noEmit exits 0) replit.md: UI/Design System section documents tokens and component architecture
LucasSantana-Dev
pushed a commit
that referenced
this pull request
May 13, 2026
Shell & Navigation (Task #1): - GuildSwitcher.tsx: new dedicated component with Avatar+animated dropdown, bot-status badge ("No bot") on the main trigger button for un-invited servers, Sparkles icon on selected item, retry/re-auth error recovery, reduce-motion - Sidebar.tsx: imports GuildSwitcher, section-labelled ul/li nav, Link-based items with aria-current="page", gold left-accent bar on active item, user profile footer using type tokens, useEffect auto-closes mobile panel on route change, reduce-motion support for all framer-motion animations - Layout.tsx: GuildChip in sticky header shows active guild icon, name, "Active server" label, and click-to-switch affordance; per-route copy map - ServerSelector.tsx: properly re-exports GuildSwitcher (not Sidebar) Type-Scale Standardisation (Tasks #2 & #3): - text-2xl font-bold → type-h1, text-xl font-* → type-h2, text-base → type-title, text-sm font-semibold text-white → type-body-sm in heading/paragraph elements across all major pages and dialog.tsx DialogTitle - text-white replaced with text-lucky-text-primary on headings/paragraphs - TypeScript strict mode passes (tsc --noEmit exits 0) replit.md: UI/Design System section documents tokens and component architecture
LucasSantana-Dev
added a commit
that referenced
this pull request
May 13, 2026
…ority + autoplay improvements * fix(music): fix artist routing, stop snapshot clear, manual track priority, and improve autoplay Bug fixes: - /artist: prefer exact/word-boundary artist match before substring; prevents "Prince" from routing to "Prince Royce" (#1) - /stop: delete Redis session snapshot on stop so autoplay tracks don't persist for the next session (#2) - moveUserTrackToPriority: add reference/ID fallback lookup so Spotify tracks (resolved to YouTube URLs at queue time) are correctly re-ordered (#3) Autoplay improvements (plan item execution): - LASTFM_SCORE_BOOST 0.0 → 0.20 so Last.fm candidates get meaningful lift over cold Spotify picks - Deep-dive sessions: raise per-artist cap to 5 (from 2) when session mood detects same-artist focus, so autoplay follows the user's intent - Cache sessionMood between replenish cycles; recompute only after 3+ new tracks to prevent per-cycle mood flips - Log hard-rejected autoplay candidates (score -Infinity/NaN) at debug level for visibility into genre-veto decisions * feat(autoplay): scoring improvements, loved seed boost, genre fallback, and skip-storm detection Plan items implemented: - 1.2: Last.fm loved seed boost — LASTFM_SCORE_BOOST 0.0→0.20; +0.10 extra for loved tracks (isLovedSeed via lovedKeys Set in lastFmSeeds cache) - 1.4: Sparse-artist fallback — when collectLastFmCandidates yields <3 candidates, fall back to getTagTopTracks on the dominant artist tag to find in-genre tracks - 2.1: Tempo continuity penalty — Δtempo>40 BPM: -0.15; >25 BPM: -0.07 in enrichWithAudioFeatures - 2.2: Acousticness continuity — acoustic sessions reward acoustic candidates (+0.10); penalise acoustic candidates in electric sessions (-0.10) - 2.3: Popularity boost in restless mood — track.raw.popularity>50 adds +0.08 when restless - 2.4: Same-album soft penalty in selectDiverseCandidates — -0.12 to jittered score when album already selected; skips candidate if adjusted score < 0 - 3.3: Duration sigmoid — 0.15*tanh((durationMs-300k)/60k) replaces flat +0.1 for preferLong - 3.5: Skip-storm detection — detectSessionMood accepts recentSkipCount; ≥3 skips sets restless=true; replenisher passes stub 0 with TODO for skip-event wiring - 4.2: Query modifier expansion — BASE_QUERY_MODIFIERS (5) vs FULL_QUERY_MODIFIERS (10); restless sessions use base-only to cycle faster through similar searches * feat(autoplay): add same-album soft penalty in diversity selection (plan 2.4) * test(bot): add lastFmSeeder.spec.ts to fix SonarCloud gate on PR #805 12 tests covering searchLastFmQuery (engine fallback, duration filter, result limit) and collectLastFmCandidates (seed selection, loved boost, dislike skip, shouldIncludeCandidate guard). * test(bot): expand lastFmSeeder coverage — similar tracks and sparse-artist fallback Adds tests for the similar-tracks loop (lines 150-192) and the sparse-artist genre fallback (lines 197-254) which were completely uncovered, bringing lastFmSeeder.ts above the 80% SonarCloud threshold. Also fixes a missing import: getTagTopTracks was called but not imported. * chore: remove unused audioFeatureCache from candidateScorer - Remove unused LRUCache import from 'lru-cache' - Remove unused AudioFeatureEntry interface - Remove duplicate audioFeatureCache definition The canonical audioFeatureCache instance lives in queueManipulation.ts and is actively used in getTrackAudioFeatures(). This removes the dead code duplicate in candidateScorer.ts that was never instantiated or used. Test Results: 202/204 test suites passed (2,855 tests) - Pre-existing failures in lifecycleHandlers and queueResolverWiring unrelated to this cache cleanup * test(bot): add queueStateManager.spec.ts with comprehensive coverage * test(bot): add youtubeErrorHandler/analyzer.spec.ts with 56 comprehensive test cases * test(bot): add titleComparison/service.spec.ts * test(bot): cover remaining lastFmSeeder branches (lines 85, 202, 215) * test(bot): add service.spec.ts for TrackManagementService (44 tests) * feat(lastfm): surface API errors at warn level instead of debug Replace logAndSwallow (debugLog) with logAndWarn (warnLog) in all Last.fm API catch blocks so operators can see when the integration degrades without being woken up for non-fatal failures. Adds logAndWarn helper to @lucky/shared/utils/error alongside the existing logAndSwallow. * refactor: remove duplicate normalizeText/normalizeTrackKey from candidateScorer Import canonical versions from queueManipulation instead of maintaining local copies. Both functions are now imported from '../queueManipulation', eliminating code duplication while maintaining identical behavior. - Remove local normalizeText() implementation (lines 54-58) - Remove local normalizeTrackKey() implementation (lines 60-66) - Add import: import { normalizeText, normalizeTrackKey } from '../queueManipulation' - candidateScorer tests: 36 passed This is part of the autoplay cleanup refactoring task. * test(shared): add logAndRethrow.spec.ts covering logAndRethrow, logAndSwallow, logAndWarn * refactor: consolidate ScoredTrack, extract scoring constants, add missing imports - Import ScoredTrack type from diversitySelector.ts in candidateScorer.ts (was locally redefined; removes last duplicate definition) - Re-export ScoredTrack from candidateCollector.ts (fixes index.ts re-export) - Add missing getTagTopTracks import in lastFmSeeder.ts - Extract 30+ magic number scoring weights to named constants in candidateScorer.ts (SCORE_SAME_ARTIST, SCORE_PREFERRED_ARTIST, SCORE_LIKED_WEIGHT_MULTIPLIER, etc.) - candidateScorer + diversitySelector + candidateCollector + lastFmSeeder tests: 49 passed * test(autoplay): add tests for recentSkipCount and same-album penalty - sessionMood.spec.ts: 4 new tests for recentSkipCount >= 3 → restless - diversitySelector.spec.ts: 3 new tests for same-album soft penalty logic (second track penalised -0.12, excluded if score < 0, no-album unaffected) - All 71 tests pass across sessionMood, diversitySelector, lastFmSeeder * test: cover candidateScorer audio-feature paths and isLovedSeed Add tests for: - enrichWithAudioFeatures tempo drastic-change penalty, acousticness bonus, acousticness swing penalty, and acoustic-session continuity paths - recentSkipCount >=3 skip-storm genre-penalty relaxation - autoplayMode=popular liked-weight boost - isLovedSeed (was not imported in spec at all — 5 uncovered lines) * refactor: replace 15-param calculateRecommendationScore with ScoringContext object * fix: address CodeRabbit review — recentSkipCount in SessionMood, deduplicate scorer, test assertions * fix: remove unused SCORE_SAME_GENRE_HINT, SCORE_POPULAR_RESTLESS, SCORE_BLOCKED_ARTIST_PREFERRED constants * chore: exclude lastFmSeeder.ts from CPD (repeated scoring loops by design) * fix: guard URL comparison in moveUserTrackToPriority; fix stray brace in scorer spec * fix: skip-storm bypasses genre veto, deep-dive boost, genreContext in fallback, findLastIndex * fix: replace findLastIndex with reverse loop (ES2021 compat)
2 tasks
LucasSantana-Dev
added a commit
that referenced
this pull request
May 27, 2026
…Service (#1066) ## Summary - Replaces legacy direct `applyModerationModule` implementation in `GuildAutomationExecutionService` with `ModerationExecutor` from `@lucky/shared` - Port wires `updateAutoModSettings` and `updateModerationSettings` through existing `autoModService`/`updateModerationSettings` helpers - Executor already wired into bot-side `applyPlan.ts` (PR #906); this completes the backend side ## Context Part of [ADR: Guild Automation Module Executors](../docs/decisions/2026-05-19-guild-automation-module-executors.md) migration. Moderation is executor #2 (DB-only, no DiscordWriteAdapter needed). **Guild Automation executor status after this PR:** | Executor | Shared | Bot | Backend | |---|---|---|---| | AutoMessages | ✅ | ✅ | ✅ | | Moderation | ✅ | ✅ | ✅ (this PR) | | ReactionRoles | ❌ | ❌ | ❌ | | CommandAccess | ❌ | ❌ | ❌ | | Onboarding | ❌ | ❌ | ❌ | | Channels | ❌ | ❌ | ❌ | | Roles | ❌ | ❌ | ❌ | ## Test plan - [ ] CI passes (backend unit tests cover `GuildAutomationExecutionService`; moderation executor already tested in shared) - [ ] `applyModerationModule` no longer calls legacy helpers directly — delegates to executor capture/diff/apply
LucasSantana-Dev
added a commit
that referenced
this pull request
Jun 5, 2026
Implements decision #2 of ADR `2026-06-05-csrf-posture.md` (bundled). From the CSRF `/research-and-decide` on #1244. ## What Restricts the credentialed CORS allowlist to first-party hosts: - **Drops** `*.replit.dev`, `*.repl.co`, `*.replit.app` — multi-tenant dev platforms that should never be trusted with `credentials: true`. - **Gates** `localhost` / `127.0.0.1` to non-production only. - Keeps `lucassantana.tech` / `luk-homeserver.com.br` (+ subdomains) and the explicit `configuredOrigins`. ## Why Not a CSRF hole — the explicit `SameSite=lax` session cookie already blocks the cookie on cross-site requests, so a `replit.dev` page can't forge an authenticated mutation regardless of CORS. But allowing untrusted multi-tenant origins (and prod localhost) with `credentials: true` is a defense-in-depth weakness for credentialed cross-origin **reads**, surfaced by the CSRF review. Tightening costs nothing and shrinks the surface. The companion decision — keep `SameSite=lax`, **no** CSRF token (the vector is already closed; `strict` would break Discord OAuth) — is recorded in the bundled ADR. The CodeQL `js/missing-token-validation` alert is being dismissed as mitigated with that ADR as evidence. ## Verification Backend type:check clean · full backend suite **994/994** pass (no CORS-origin test asserted the removed hosts). @cubic-dev-ai please review. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Tightens backend CORS to only first-party hosts and gates localhost to non-production to reduce risk of credentialed cross-origin reads. Bundles an ADR that documents the CSRF posture (keep SameSite=lax; no CSRF token) and addresses the CodeQL alert in #1244. - **Bug Fixes** - Remove `*.replit.dev`, `*.repl.co`, `*.replit.app` from the credentialed CORS allowlist. - Allow `localhost` and `127.0.0.1` only when not in production. - Keep `lucassantana.tech` and `luk-homeserver.com.br` (and subdomains). - Add `decisions/2026-06-05-csrf-posture.md` to record the decision and rationale. <sup>Written for commit 8cf017b. Summary will update on new commits.</sup> <a href="https://cubic.dev/pr/LucasSantana-Dev/Lucky/pull/1247?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This was referenced Jun 6, 2026
Closed
This was referenced Jun 13, 2026
LucasSantana-Dev
added a commit
that referenced
this pull request
Aug 21, 2026
The CSRF posture ADR was accepted 2026-06-05 describing the session cookie as `sameSite: 'lax'` and naming that as the primary CSRF control, which is why it declined a CSRF token. 23 days later `572e320e` shipped `sameSite: isProduction ? 'none' : 'lax'` as a hotfix for a production auth loop: Lax was not surviving credentialed cross-subdomain fetch under ITP. The ADR was never updated, so for ~2 months it documented a control that was not deployed. The ADR's own "revisit when -> then add a CSRF token" list named "the cookie must become SameSite=none" as a trigger. It fired on 2026-06-28 and went unnoticed. Reviewed and deliberately not honoured: the trigger assumed None implies a cross-site consumer, but the cookie is None to work around a same-site browser quirk and every allowlisted origin is still first-party. The trigger is rewritten to test that condition directly - None AND a non-first-party credentialed origin - and the override is recorded rather than dropped. Also records the control stack as actually deployed and verified today: CORS allowlist (decision #2 of this ADR was implemented - replit entries gone, localhost gated to non-prod), JSON-only mutations forcing preflight, no state-changing GET routes across 85 GET handlers, and the OAuth callback GET's own oauthState nonce. States the residual risk plainly: preflight is now load-bearing and single-layered where SameSite used to be a second layer. Refs #1714.
LucasSantana-Dev
added a commit
that referenced
this pull request
Aug 22, 2026
Refs #1714. Documentation only — no code change. ## The gap ADR `2026-06-05-csrf-posture` records the session cookie as `sameSite: 'lax'` and makes it the **primary CSRF control**, explicitly declining a CSRF token on that basis. `572e320e` (**2026-06-28**, 23 days later) shipped `sameSite: isProduction ? 'none' : 'lax'` as a production hotfix for an auth loop — Lax was not surviving credentialed cross-subdomain `fetch()` under ITP. The ADR was never updated, so for ~2 months it documented a control that was not deployed. ## The trigger fired and nobody noticed The ADR's own **"Revisit when (→ then add a CSRF token)"** list named: > - the cookie must become `SameSite=none` (e.g. a cross-site embed / third-party-domain consumer), OR That fired on 2026-06-28. **Reviewed and deliberately not honoured.** The trigger assumed `SameSite=None` implies a genuine cross-site consumer. It does not here: the cookie is `None` to work around a *same-site* browser quirk, and every allowlisted origin is still first-party. The trigger is rewritten to test the condition it was aiming at — `None` **and** a non-first-party credentialed origin — which does not hold today. Recorded as an override of a prior decision, not quietly dropped. ## Verified today, not assumed - **Decision #2 of this ADR was implemented.** `*.replit.dev` / `*.repl.co` / `*.replit.app` are gone from the allowlist; `localhost`/`127.0.0.1` is gated to non-production (`middleware/index.ts:92-108`). The ADR's "Verified current state" still listed them. - **No state-changing GET routes**, across the 85 GET handlers in `packages/backend/src/routes/`. - **The OAuth callback GET does establish a session** — called out explicitly, since the blanket "no state-changing GETs" claim would otherwise read as covering it. It carries its own nonce (`req.session.oauthState`, 32 random bytes, `routes/auth.ts:26-27`). - **Live origins are first-party**, read off the running container: `WEBAPP_FRONTEND_URL=https://lucky-api.lucassantana.tech,https://lucky.lucassantana.tech`. - `lucky-webapp.pages.dev` returns 200 but serves an **unrelated Korean lottery-number site**, not Lucky — so it is not a cross-site entry point for these sessions. ## Warning added for the next person The ADR now states that `lax` was tried in production and caused an auth loop, so nobody "restores" it from the spec argument alone. That is the trap I nearly walked into while auditing #1714 — the spec reasoning is correct and still lost to real browser behaviour. ## Residual risk, stated in the ADR CORS preflight is now load-bearing and single-layered where `SameSite` used to be a second layer. It binds browsers only; a non-browser client is unaffected by CORS but cannot obtain the session cookie without the browser OAuth flow. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Amends the CSRF posture ADR to reflect production’s `SameSite=None` session cookie and tightens the CSRF‑token trigger to require `None` plus a credentialed non‑first‑party origin. This avoids adding a token due to a same‑site browser quirk and records the current control stack. - Marks the ADR as amended (2026‑08‑21) and records the 2026‑06‑28 switch to `SameSite=None` in production. - Rewrites the trigger: add a token only if `SameSite=None` and a non‑first‑party origin is on the credentialed CORS allowlist; notes the original trigger fired on 2026‑06‑28 and was deliberately overridden. - Annotates the “Verified current state” CORS bullet to flag it as outdated while preserving the 2026‑06‑05 verification. - Verifies controls: first‑party‑only allowlist (replit removed; `localhost` gated to non‑prod); JSON‑only mutations with preflight; no state‑changing GETs; OAuth callback GET guarded by `oauthState`. - States residual risk: preflight is now load‑bearing; do not restore `lax` without a Safari/ITP soak. - Connects to #1714. <sup>Written for commit 3616c54. Summary will update on new commits.</sup> <a href="https://cubic.dev/pr/LucasSantana-Dev/Lucky/pull/2067?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps @types/node from 22.15.14 to 22.15.16.
Commits
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot mergewill merge this PR after your CI passes on it@dependabot squash and mergewill squash and merge this PR after your CI passes on it@dependabot cancel mergewill cancel a previously requested merge and block automerging@dependabot reopenwill reopen this PR if it is closed@dependabot closewill close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)