Conversation
- Move all root JS modules to lib/ folder (cleaner structure) - Rename spotify-async.js to lib/spotify.js - Extract add/addalbum/addplaylist/append handlers to lib/add-handlers.js - Add Spotify null guards in search functions - Replace .map() with .forEach() for side effects - Bump posthog-node to 5.24.2 - Add integration tests for addalbum and addplaylist with queue size verification - Fix integration test to detect threaded bot responses - Add rate-limit handling and reduce polling frequency in test runner - Add test retry with 10s backoff on failure
There was a problem hiding this comment.
Pull request overview
This PR restructures the project by moving core modules into lib/, extracting the “add*” command logic into a dedicated module, and expanding/strengthening both unit and integration test coverage around queueing behavior.
Changes:
- Move root JS modules into
lib/and update imports throughout the app and tests. - Extract
add,addalbum,addplaylist, andappendintolib/add-handlers.jsand add a comprehensive unit test suite for it. - Enhance the Slack-based integration test runner with threaded-response detection, rate-limit handling, queue-size assertions, and retry-on-failure behavior.
Reviewed changes
Copilot reviewed 11 out of 22 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| test/voting.test.mjs | Updates module import path to the new lib/ location. |
| test/tools/integration-test-suite.mjs | Improves integration test robustness (threads, rate limits, retries, queue-size assertions, admin posting). |
| test/ai-handler.test.mjs | Updates AI handler import path to the new lib/ location. |
| test/add-handlers.test.mjs | Adds unit tests covering the extracted add/addalbum/addplaylist/append behavior. |
| package.json | Bumps posthog-node dependency. |
| package-lock.json | Locks updated posthog-node and transitive dependencies; updates Node engine constraints. |
| lib/voting.js | New lib/-scoped voting module (gong/vote/flushvote, etc.). |
| lib/utils.js | New lib/-scoped utilities module. |
| lib/telemetry.js | Adds/relocates telemetry module backed by PostHog. |
| lib/spotify.js | Adds/relocates Spotify wrapper used by the app. |
| lib/soundcraft-handler.js | Adds/relocates Soundcraft integration handler. |
| lib/slack.js | Adds/relocates Slack Socket Mode integration and reaction handling. |
| lib/music-helper.js | Adds/relocates music helper logic (search/boosters/theme mixing/queueing). |
| lib/logger.js | Adds/relocates Winston wrapper required by SocketModeClient. |
| lib/discord.js | Adds/relocates Discord integration and reaction handling. |
| lib/command-handlers.js | Refactors queue display iteration and adds Spotify-null guards for search handlers. |
| lib/ai-handler.js | Adds/relocates OpenAI-based natural language parsing + context tracking. |
| lib/add-handlers.js | New extracted add/addalbum/addplaylist/append implementation. |
| index.js | Repoints imports to lib/ and wires extracted add-handlers into the command registry. |
| .github/workflows/feature-request-enhance.yml | Extends automation to generate implementation plans + create PRs from issues. |
| .github/agent/generate-implementation.mjs | Adds a Claude-based implementation-plan generator script. |
| .github/AI_PR_SETUP.md | Documents how to configure and use the AI PR automation. |
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 20 | ||
| cache: npm |
There was a problem hiding this comment.
actions/setup-node is configured with node-version: 20, but posthog-node declares an engine requirement of ^20.20.0 || >=22.22.0 (per package-lock). Pin the workflow to 20.20.0 (or bump to a supported 22.x/24.x) to avoid CI/runtime incompatibilities as the default "20" changes over time.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
|
|
||
| Project context: | ||
| - Node.js application | ||
| - Uses Slack RTM API and Discord.js |
There was a problem hiding this comment.
The system prompt says the project uses the Slack RTM API, but the codebase uses Socket Mode (@slack/socket-mode). This will mislead the generator and can produce incorrect implementation guidance; update the prompt to reflect Socket Mode / Events API usage.
| - Uses Slack RTM API and Discord.js | |
| - Uses Slack Socket Mode / Events API (via @slack/socket-mode) and Discord.js |
| // If we have blacklisted tracks, add individually; otherwise use playlist URI | ||
| if (blacklistedTracks.length > 0) { | ||
| const allowedTracks = playlistTracks.filter(track => | ||
| !isTrackBlacklisted(track.name, track.artist) | ||
| ); | ||
|
|
||
| for (const track of allowedTracks) { | ||
| await sonos.queue(track.uri); | ||
| } | ||
| logger.info(`Added ${allowedTracks.length} tracks from playlist (filtered ${blacklistedTracks.length})`); | ||
| } else { | ||
| await sonos.queue(result.uri); | ||
| logger.info('Added playlist: ' + result.name); | ||
| } | ||
|
|
There was a problem hiding this comment.
addplaylist queues the playlist twice: once synchronously (either sonos.queue(result.uri) or iterating allowedTracks) and then again in the background IIFE below. This will duplicate tracks in the Sonos queue. Consider choosing one approach (either do all queueing in the background and respond immediately, or keep the synchronous queueing and remove the background queueing block).
| // If we have blacklisted tracks, add individually; otherwise use playlist URI | |
| if (blacklistedTracks.length > 0) { | |
| const allowedTracks = playlistTracks.filter(track => | |
| !isTrackBlacklisted(track.name, track.artist) | |
| ); | |
| for (const track of allowedTracks) { | |
| await sonos.queue(track.uri); | |
| } | |
| logger.info(`Added ${allowedTracks.length} tracks from playlist (filtered ${blacklistedTracks.length})`); | |
| } else { | |
| await sonos.queue(result.uri); | |
| logger.info('Added playlist: ' + result.name); | |
| } | |
| // Queueing is handled asynchronously in the background worker/IIFE below. | |
| // Avoid queueing here to prevent adding the playlist twice. | |
| // (blacklistedTracks and playlistTracks remain available to that code.) | |
| // NOTE: Previously this block synchronously queued the playlist via | |
| // `sonos.queue(result.uri)` or by iterating `allowedTracks`. That logic | |
| // has been removed to eliminate duplicate queuing; the background | |
| // processing now owns all queuing responsibilities. | |
| // Intentionally no direct calls to `sonos.queue` here. |
| # Create commit with heredoc to handle multiline | ||
| git commit -m "$(cat <<'EOF' | ||
| Add implementation plan for issue #$ISSUE_NUMBER | ||
|
|
||
| This is an AI-generated implementation plan created by Claude. | ||
| Please review and adapt as needed. | ||
|
|
||
| Related issue: #$ISSUE_NUMBER | ||
| EOF | ||
| )" |
There was a problem hiding this comment.
The git commit -m heredoc uses a single-quoted delimiter (<<'EOF'), so $ISSUE_NUMBER will not expand and the commit message will literally contain #$ISSUE_NUMBER. Use an unquoted heredoc (or build the message string another way) so variables expand correctly.
index.js
Outdated
| const Spotify = require('./spotify-async'); | ||
| const utils = require('./utils'); | ||
| const Spotify = require('./lib/spotify'); | ||
| const utils = require('./lib/utils'); |
There was a problem hiding this comment.
Unused variable utils.
| const utils = require('./lib/utils'); |
- Pin Node.js to 20.20.0 (meets posthog-node engine requirement) - Fix Slack RTM -> Socket Mode in AI generator prompt - Remove duplicate playlist queueing (was queuing twice) - Fix heredoc variable expansion in workflow - Comment out unused utils import - Add githubToken to setconfig with sensitive masking - Improve featurerequest error message with setup instructions
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| } catch (err) { | ||
| logger.error('Error in background playlist queueing: ' + err.message); | ||
| } | ||
| })(); |
There was a problem hiding this comment.
Duplicate playback calls in addplaylist function
Low Severity
The addplaylist function contains redundant playback logic. Playback is started synchronously at lines 548-570, and then the same playback logic is repeated in a background async task at lines 584-597. Both sections check isStopped and state conditions and call sonos.play(), causing the Sonos speaker to receive duplicate play commands. The comment at line 582 acknowledges that queueing is already done but doesn't account for the fact that playback was also already started above.
Summary
lib/folder for cleaner project structurelib/add-handlers.jswith add/addalbum/addplaylist/append commands.map()with.forEach()for side effectsTest improvements
addalbumandaddplaylistwith queue size verificationChanges
lib/Test plan
npm test)npm run test:integration)Note
Introduces AI-assisted PR creation and refactors command handling.
feature-request-enhance.ymlworkflow adds preprocessing, optional Confluence page, Claude-powered implementation generation, and auto-PR creation againstdevelop; pins Node to20.20.0and adjusts permissions. Adds.github/AI_PR_SETUP.mdandagent/generate-implementation.mjs.lib/*; extractsadd,addalbum,addplaylist,appendinto newlib/add-handlers.jsand wires them intoindex.jscommand registry; cleans up legacy implementations and updates references tolib/discord,lib/slack, etc.githubTokenconfig (masked on save) and improvesfeaturerequestguidance.add-handlers; updates paths for moved modules; enhances Slack integration tests (thread replies, rate-limit handling, queue-size tracking, retry-on-fail).posthog-nodeto5.24.2(and@posthog/core), minorforEach/cosmetic fixes.Written by Cursor Bugbot for commit 005d6bd. This will update automatically on new commits. Configure here.