Skip to content

Claude/plan v3 deployment vp mpw - #114

Merged
gamblecodezcom merged 11 commits into
mainfrom
claude/plan-v3-deployment-VPMpw
Feb 28, 2026
Merged

Claude/plan v3 deployment vp mpw#114
gamblecodezcom merged 11 commits into
mainfrom
claude/plan-v3-deployment-VPMpw

Conversation

@gamblecodezcom

@gamblecodezcom gamblecodezcom commented Feb 28, 2026

Copy link
Copy Markdown
Owner

User description

Summary by Sourcery

Harden tooltip generation and align onboarding documentation with the expanded step range.

Enhancements:

  • Add a sanity check to the tooltip generation script before evaluating DEFAULT_TIPS_LIST to prevent processing unexpectedly large or malformed data.
  • Update onboarding prompt documentation to reflect support for up to five onboarding steps.

CodeAnt-AI Description

Redirect group commands to DM; show onboarding progress and one-time completion card; add batch tooltip import and safer startup flows

What Changed

  • Commands sent in group/supergroup chats are intercepted: most commands are suppressed and the user sees a "This command works in DM" message with a deep-link to the bot; a small set of group-aware commands (link, giveaway, start_giveaway, admin) still work in-group.
  • Onboarding now shows a short visual progress header before each step (auto-deletes), supports five steps, and displays a one-time completion card the first time a user reaches the main menu after finishing onboarding.
  • Admins can batch-import helpful-tooltips via a JSON-array paste flow in the admin tips import action; the flow validates input and returns the IDs of imported entries.
  • Admin System Tools adds a top-level "🔗 Group Linking" entry that opens group linking tools and returns to System Tools.
  • Dev/deploy/start/rollback scripts proactively free the configured bot port (SIGTERM then SIGKILL) and refresh tooltips before starting to reduce failed starts from stale processes.
  • Tests extended: catch-all regex detection now recognizes multiline and stripped-newline forms; command extraction tests include let/var/no-semicolon cases so detection matches more real code patterns.

Impact

✅ Fewer accidental group-triggered commands
✅ Clearer onboarding progress and a visible welcome after setup
✅ Fewer failed starts due to blocked bot ports

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

…urity, 23 Block 1 fixes

Menu lifecycle overhaul:
- replyMenu() TTL auto-vanish via ttlMs parameter
- clearStaleMenuIds() on startup (24h threshold)
- mainMenuSentAt / adminMenuSentAt timestamps on user schema
- sendHelpMenu() fixed: bare ctx.reply() → replyMenu() (panel stacking bug)
- replaceCallbackPanel() fallback now tracks message ID in user state
- Admin mode toggle double-fire fixed

Feature upgrades:
- User giveaway list: sendUserGiveawaysPage() 5/page + 2-min auto-vanish
- Admin giveaway panel: activeGiveawaysKeyboard(page) 5/page pagination
- pmenu_referral sub-menu with share deep-link button
- Admin stats: active window indicator + Refresh button
- Admin health panel: inline memory/errors/users/persist-age/uptime
- Broadcast builder: Preview button sends to admin DM before mass send

Block 1 security & logic fixes:
- getStartAppLink(): encodeURIComponent + regex whitelist
- referralShareHTML(): escapeHtml() on code param
- unwrapTelegramUrl(): safe fallback, scheme whitelist, www.t.me support
- getDiscordLink(): null when not configured (no hardcoded fallback)
- evaluatePendingActionTimeout(): >= boundary, NaN guard, no createdAt mutation
- getPlayLink(): legacy user.playMode fallback restored
- Weighted winner pool: splice-after-pick guarantees termination
- deploy_status + logs: exec() → execFile() (no shell spawn)
- SSHV: rejects null bytes, backticks, $( and ${ before exec
- Startup env warnings: ADMIN_IDS, TELEGRAM_CHANNEL_ID, TELEGRAM_GROUP_ID

Centralized helpers: computeParticipantWeight(), getRealGiveaways(), isNewUserPromoEligible()

Metrics: added runewager_menu_stale_recoveries, pending_actions_timed_out, uptime_seconds

load_tooltips.sh: full rewrite — atomic write, --push/--pull flags, parameterized REPO_DIR,
  HTML-safe tooltips, --dry-run mode, permission checks, guarded git ops

Tests: readdirSync wrapped in try/catch; isCatchAllRegexPattern expanded;
  extractCommandHandlerNames supports let/var/no-semicolon

Infrastructure: pre-deploy-checks gate 3b (menu symbols), CHANGELOG.md created,
  package.json bumped to 3.0.0

All 60 tests pass. node --check clean.

https://claude.ai/code/session_01VijmtzjN63WZJy5gYgJAKs
… during PR merges

Restores 12 categories of codex changes that were incorrectly overwritten by
"current" (main) when resolving merge conflicts across 6 merge commits.

Security / TLS hardening (index.js):
- Restore resolveTlsCertPathIfAllowed(): multi-directory fallback for TLS certs
  (PROJECT_DIR, certs/, /etc/ssl, /etc/letsencrypt) — was collapsed to PROJECT_DIR only
- Restore isHealthTlsEnabled() to use resolveTlsCertPathIfAllowed()
- Restore requestHealthPayload(): centralized HTTP/HTTPS health fetcher with
  dynamic protocol detection — was inlined with hardcoded https in two places
- Update /health command to use requestHealthPayload() (shows protocol label)
- Update pamenu_tools_health to use requestHealthPayload()
- Update startHealthServer() TLS cert read to use resolveTlsCertPathIfAllowed()

Command injection protection (index.js):
- commandNeedsConfirmation(): restore pipe-to-bash/zsh detection,
  destructive-cmd-piped pattern, redirect pattern — main simplified to only catch "sh"
- commandBlocked(): restore explicit pipe-to-shell blocker pattern

Race condition fixes (index.js):
- deleteEphemeralBonusPrompt(): restore runUserMutation guards for safe
  read-delete-write of ephemeralBonusMsgId/ChatId
- sendEphemeralBonusPrompt(): restore guards (claimedPromo check, active promo lookup),
  per-user dynamic promo lookup via getActivePromoCodeForUser() (was hardcoded
  promoStore.code), "I Have Claimed" callback button, mutation-safe writes
- Add promo_confirm_claimed_next callback handler (button was added, handler missing)

Deploy/runtime hardening (deploy.sh, prod-run.sh, runewager.service):
- deploy.sh: restore data/backups/ mkdir, chown -R APP_NAME, chmod 0750/0640/0600
  permission hardening after npm install
- prod-run.sh: restore chmod 0750 for data/data/backups/logs dirs,
  chmod 0640 for log+session files, chown -R to service user after dir creation
- runewager.service: add UMask=0077 (prevents world-readable files from service)

.gitignore:
- Restore legacy root-level data file patterns: users.json, giveaways.json,
  promo.json, env.json, analytics*.json (pre-data/ directory structure)

All 60 tests pass. node --check clean.

https://claude.ai/code/session_01VijmtzjN63WZJy5gYgJAKs
- TDZ fix: move pendingActionsTimedOut/menuStaleRecoveries declarations
  before evaluatePendingActionTimeout to eliminate temporal dead-zone risk
- Timeout boundary: revert < to <= so age exactly equal to 15m is NOT
  expired — aligns with /testall check and unit test expectations
- /logs line count: clamp to [1, 200] (adds Math.max(1,...) lower bound
  to reject negative/zero values from user input)
- Health panel: fix _errorRate.windowErrors → _errorRate.count (field
  did not exist; .count is the correct field on _errorRate object)
- /logs fallback: add execFile('tail') fallback when journalctl errors
  with no output (non-systemd systems); uses BOT_LOG_FILE env or default
- executeSshvCommand: fix comment — said "spawn" but code uses exec();
  updated to accurately describe exec with shell:true (admin-only)
- load_tooltips.sh: remove || true that defeated diff --cached check,
  causing .gitignore changes to never be committed on --push

All 60 tests pass. node --check clean.

https://claude.ai/code/session_01VijmtzjN63WZJy5gYgJAKs
## Helpful Tooltips (was Content Drops)
- Rename all UI strings: Content Drops → Helpful Tooltips throughout
- New settings panel: interval, silent mode, Link Channel/Group
- Target group linking via forwarded message (saves name + ID)
- Dashboard footer shows real group name + ID
- "Show all Helpful Tooltips (N)" button with dynamic count
- Inline button builder: [Label - URL] && [Label2 - URL2] syntax
  - Multiple buttons per row with &&, new line = new row
  - [Open Bot] shorthand for standard Open Bot button
  - Full URL + label validation before save
- postTipToConfiguredTarget uses silentMode flag + parsed buttons
- tipsStore extended with targetGroupTitle and silentMode fields

## Giveaway v3.0+
- Extracted buildGiveawayAnnouncementText + buildGiveawayAnnouncementKeyboard helpers
- scheduleGiveawayRefresh: auto-refresh at 25%, 50%, 75% of duration + re-pin
- scheduleGiveawayReminders overhauled: 10m, 5m, 1min, 30sec, 10→1 countdown
- HTML results format: @handle, SC WON, (2x boost applied), DM tip
- Full admin winner report per winner: TG handle, display name, RW username, prize, boost
- "View Results in Group" deep-link button in admin report
- Winner DMs include SC amount, boost status, RW username
- DM failure tracking with summary count
- giveawayPreflightCheck: validates group linked, warns on missing pin permission
- gwizStart calls preflight before wizard begins

## Scripts
- generate_tooltips.sh: extracts DEFAULT_TIPS_LIST from index.js → data/tooltips.json (atomic, idempotent)
- add_tooltip.sh: appends placeholder tooltip entry, outputs new ID
- deploy.sh: step 3b auto-runs generate_tooltips.sh before service start
- prod-run.sh: step 6b auto-runs generate_tooltips.sh before bot launch

## /testall
- Added Helpful Tooltips System checks (tipsStore shape, count, interval, target, parser)
- Added Giveaway Extended checks (helpers defined, preflight defined)

## Docs
- RUNEWAGER_FUNCTIONALITY_MAP.md: full v3.0+ sync with flowcharts

All 60 tests pass. node --check clean.

https://claude.ai/code/session_01VijmtzjN63WZJy5gYgJAKs
… linking

- Group command guard middleware: bot.use() intercepts all commands in
  group/supergroup chats and redirects to DM with a deep-link button.
  Passthrough commands with own group logic: link, linkrunewager, giveaway,
  start_giveaway, admin. Suppresses handler execution for all others.

- Onboarding progress bar: onboardingProgressBar(step) renders ●●○○○
  Step N of 5 — Label. showOnboardingPrompt() prepends a Markdown progress
  header (auto-deletes after 8s) before each step-specific prompt.

- Onboarding completion card: shown once (user.onboarding.completionCardShown
  flag) when user reaches the main menu after completing all 5 steps.
  Includes feature summary and Open Menu button.

- Admin System Tools: added 🔗 Group Linking button to
  adminSystemToolsKeyboard() with admin_sys_group_linking action handler
  (renders group linking panel with back-to-system-tools navigation).

- Schema: completionCardShown added to onboarding default + migration guard.
- Map: RUNEWAGER_FUNCTIONALITY_MAP.md fully updated; todolist.md updated.
- All 60 tests pass, node --check clean.

https://claude.ai/code/session_01VijmtzjN63WZJy5gYgJAKs
…ates

PR #112 review fixes (sourcery-ai):
- R1: tips_cmd_import_batch now uses await_tip_import_batch pending type
  with dedicated JSON-array router handler; proper MarkdownV2 prompt
- R2: generate_tooltips.sh fixes command substitution pollution; use
  RUNEWAGER_APP env var instead of process.argv[1] (undefined in node -)
- R3: add_tooltip.sh fixes shell injection; TOOLTIP_TEXT passed via
  TOOLTIP_TEXT_ENV env var, heredoc uses <<'EOF', process.argv[2] for file
- R4: extend catchAllCases array with (.|\n)*, (.|\n)+, (\.|[\s\S])*;
  add post-whitespace-strip forms to CATCH_ALL_CORES set
- R5: extractCommandHandlerNames test now covers let/var declarations and
  no-semicolon forms (CMD_FOUR/eta, CMD_FIVE/theta)
- R6: RUNEWAGER_FUNCTIONALITY_MAP.md typo "auto-deletes 8s" → "after 8s"

Codebase audit duplicate removal:
- A1: remove dead buildGiveawayAnnouncementText(giveaway, remainingStr)
  at ~12533; keep dynamic version at ~13795
- A2: remove simplified buildGiveawayAnnouncementKeyboard at ~13817
  (wrong tgw_participants_ callback); restore full 5-row version
- A3+A4: remove first duplicate bot.action registrations for
  admin_cat_system and admin_cat_support (identical bodies)

All 60 tests pass, node --check clean, bash -n clean on both scripts.

https://claude.ai/code/session_01VijmtzjN63WZJy5gYgJAKs
Resolved conflicts in favour of our branch (HEAD) for:
- index.js: keep await_tip_import_batch router + handler, keep A1/A2
  duplicate-function removal, keep Content Drops branding from main
- add_tooltip.sh / generate_tooltips.sh: keep env-var injection fixes
- test/smoke.test.js: keep extended catchAllCases + extractCommand fixtures
- RUNEWAGER_FUNCTIONALITY_MAP.md / todolist.md: keep our updated content

Incoming from origin/main: claude-pr-results-20260228_193756Z.md

https://claude.ai/code/session_01VijmtzjN63WZJy5gYgJAKs
…ry bot start

Every script that starts/restarts the bot now follows the same safe sequence:
  1. git pull origin main (fetch + reset --hard)
  2. generate_tooltips.sh (extracts DEFAULT_TIPS_LIST → data/tooltips.json)
  3. kill any process blocking PORT (default 3000)
  4. start/restart bot

Changes per file:
- prod-run.sh: add step 9c — free_port_if_conflicted() BEFORE step 10 restart
  (port-kill was already present in God-Mode Heal but fired after, not before)
- deploy.sh: add step 3c — inline lsof/fuser port-kill before systemctl start
- start.sh: add git fetch+reset, generate_tooltips, port-kill, stale-PID kill
  before bot launch; replace refuse-on-duplicate with kill-and-continue
- dev-run.sh: add git fetch+reset (best-effort), generate_tooltips, port-kill
  before exec node
- scripts/rollback.sh: add generate_tooltips after npm ci (refreshes from
  rolled-back index.js), add lsof/fuser port-kill before service start
  (no git pull — rollback intentionally targets an older commit)

https://claude.ai/code/session_01VijmtzjN63WZJy5gYgJAKs
- Escape Markdown special chars in runewagerUsername to prevent parse failures
- Add explicit smoke-test assertions for (.|)* and (.|)+ catch-all forms
- Strip inline comments from .env PORT values in deploy.sh, dev-run.sh, start.sh
  (e.g. PORT=3000 # dev now correctly yields 3000)
- Fix showOnboardingPrompt JSDoc: steps documented as 1–4 → 1–5 (matches impl)
- Upgrade all port-block kill loops to SIGTERM-first then SIGKILL after 2s grace
- Add path + shape validation to generate_tooltips.sh Node extraction block
  (validates RUNEWAGER_APP is absolute .js path; checks array literal size/shape)

https://claude.ai/code/session_01VijmtzjN63WZJy5gYgJAKs
@codeant-ai

codeant-ai Bot commented Feb 28, 2026

Copy link
Copy Markdown

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@sourcery-ai

sourcery-ai Bot commented Feb 28, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds group-chat command guard middleware, improves onboarding with progress/completion UX, introduces batch tooltip import via admin tools, and hardens dev/deploy scripts and tooltip generation while cleaning up duplicate giveaway/admin code and extending regex/command extraction tests.

Sequence diagram for group-chat command guard middleware

sequenceDiagram
  actor User
  participant TelegramChat as TelegramGroupOrSupergroup
  participant Bot as TelegrafBot
  participant Guard as GroupCommandGuardMiddleware
  participant Router as CommandRouter
  participant DM as TelegramDirectMessage

  User->>TelegramChat: Send /some_command
  TelegramChat->>Bot: Update with message
  Bot->>Guard: handleUpdate(ctx)

  alt Command in group or supergroup
    Guard->>Guard: isWhitelistedGroupCommand(command)
    alt Command is whitelisted (link, giveaway, start_giveaway, admin)
      Guard-->>Router: next(ctx)
      Router->>Bot: Execute group-aware handler
      Bot-->>TelegramChat: Reply with group-specific response
    else Command is not whitelisted
      Guard-->>TelegramChat: Send message with deep-link button to bot DM
      Guard-->>Router: Skip further group handlers
    end
  else Command in private chat
    Guard-->>Router: next(ctx)
    Router->>Bot: Execute normal DM handler
    Bot-->>DM: Reply in DM
  end
Loading

Class diagram for bot modules: group guard, onboarding, and admin tooltip import

classDiagram
  class BotApp {
    +start()
    +useMiddleware(middleware)
    +registerCommand(name, handler)
  }

  class GroupCommandGuardMiddleware {
    +handleUpdate(ctx)
    -isGroupChat(ctx) bool
    -getCommand(ctx) string
    -isWhitelistedGroupCommand(command) bool
    -buildDeepLink(userId, payload) string
  }

  class OnboardingService {
    +showOnboardingPrompt(ctx, user, step)
    +onStepCompleted(ctx, user, step)
    +maybeShowCompletionCard(ctx, user)
    -onboardingProgressBar(step) string
  }

  class UserState {
    +id string
    +onboarding_step number
    +onboarding_finished boolean
    +completion_card_shown boolean
  }

  class AdminSystemTools {
    +showSystemToolsMenu(ctx)
    +handleSystemToolsCallback(ctx, action)
  }

  class GroupLinkingTools {
    +showGroupLinkingMenu(ctx)
    +handleGroupLinkingCallback(ctx, action)
  }

  class TooltipImportService {
    +importFromJsonArray(ctx, jsonText)
    -parseJsonArray(jsonText) TooltipEntry[]
    -validateEntry(entry) boolean
    -saveEntries(entries) string[]
  }

  class TooltipEntry {
    +id string
    +trigger string
    +text string
    +metadata object
  }

  BotApp --> GroupCommandGuardMiddleware : uses
  BotApp --> OnboardingService : uses
  BotApp --> AdminSystemTools : uses
  AdminSystemTools --> GroupLinkingTools : opens
  AdminSystemTools --> TooltipImportService : uses
  TooltipImportService --> TooltipEntry : creates
  OnboardingService --> UserState : reads_writes
  GroupCommandGuardMiddleware --> UserState : reads
Loading

File-Level Changes

Change Details Files
Guard most bot commands in group chats and route users to DM with a deep-link, while allowing a small set of group-safe commands.
  • Add middleware that inspects incoming updates, detects group and supergroup chats, and short-circuits most command handlers in those contexts
  • Return a standardized "use this in DM" message with an inline deep-link button back to the bot for blocked commands
  • Maintain an allowlist of group-safe commands (e.g., linking and giveaway flows) that still execute in group contexts
index.js
middleware/*
bot/router/*
Enhance onboarding UX to display progress indicators for up to five steps and show a one-time completion card after onboarding finishes.
  • Extend onboarding step handling to support a fifth step and update related documentation/comments (e.g., step range 1–5)
  • Prepend an auto-deleting progress bar/header message before each onboarding prompt to indicate current step and total steps
  • Track in user state whether the completion card has been shown and gate sending a new completion card at first entry to the main menu post-onboarding
index.js
state/user/*
docs/*
Add admin flows for batch tooltip import and expand the System Tools navigation with a Group Linking entry.
  • Introduce an admin handler that parses a pasted JSON array of tooltip definitions, validates shape, and bulk-inserts them into storage, returning their IDs or errors
  • Wire a new "Group Linking" top-level menu item into Admin System Tools and add the callback handler to route into existing group-linking utilities
  • Adjust admin replies/navigation so returning from Group Linking drops the admin back into System Tools rather than exiting the admin panel
index.js
admin/*
views/admin/*
Harden tooltip generation and shell tooling for dev, deploy, and rollback flows to be safer and more robust.
  • Tighten generate_tooltips.js to sanity-check the DEFAULT_TIPS_LIST match (size and array-like shape) before evaluating with Function, and clarify its use as isolated literal evaluation
  • Update generate_tooltips.sh and add_tooltip.sh to avoid unsafe command substitution, validate paths, and pass parameters via environment variables
  • Modify start/dev-run/deploy/rollback scripts to kill processes on the configured bot port (SIGTERM then SIGKILL) and regenerate tooltips from the current index.js before starting or restarting the bot
generate_tooltips.sh
generate_tooltips.js
add_tooltip.sh
scripts/start.sh
scripts/dev-run.sh
scripts/deploy.sh
scripts/rollback.sh
Remove obsolete giveaway/admin helpers and extend tests for regex-based detection and command extraction.
  • Delete duplicate or outdated giveaway UI builders and redundant admin action handlers discovered during code audit
  • Update documentation (functionality map, TODO board, audit notes) to reflect group guard behavior, onboarding updates, admin navigation, and audit outcomes
  • Expand tests to cover multiline and stripped-newline regex patterns for catch-all detection and let/var/no-semicolon command declarations for handler extraction
giveaway/*
admin/*
tests/*
docs/*

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Feb 28, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@gamblecodezcom has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 49 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 92f1579 and 9aeab81.

📒 Files selected for processing (2)
  • generate_tooltips.sh
  • index.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/plan-v3-deployment-VPMpw

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Feb 28, 2026
@gamblecodezcom
gamblecodezcom merged commit abce25d into main Feb 28, 2026
4 checks passed
@gamblecodezcom
gamblecodezcom deleted the claude/plan-v3-deployment-VPMpw branch February 28, 2026 20:58

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The tooltip generator still relies on new Function to evaluate DEFAULT_TIPS_LIST; if possible, consider requiring this literal to be valid JSON (or parsing via a JS parser/AST and extracting the array) to avoid executing arbitrary code from a compromised index.js.
  • For the onboarding flow, now that you support 5 steps, it may be worth centralizing the total step count in a single constant used by both the progress bar rendering and any step-transition logic to avoid future off-by-one or mismatch issues.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The tooltip generator still relies on `new Function` to evaluate `DEFAULT_TIPS_LIST`; if possible, consider requiring this literal to be valid JSON (or parsing via a JS parser/AST and extracting the array) to avoid executing arbitrary code from a compromised `index.js`.
- For the onboarding flow, now that you support 5 steps, it may be worth centralizing the total step count in a single constant used by both the progress bar rendering and any step-transition logic to avoid future off-by-one or mismatch issues.

## Individual Comments

### Comment 1
<location path="generate_tooltips.sh" line_range="44-45" />
<code_context>
 const m = src.match(/const DEFAULT_TIPS_LIST\s*=\s*(\[[\s\S]+?\]);/);
 if (!m) { process.stderr.write('DEFAULT_TIPS_LIST not found\n'); process.exit(1); }
+// Sanity-check the matched literal before evaluating (must look like an array)
+if (m[1].length > 500000 || !/^\s*\[/.test(m[1])) {
+  process.stderr.write('Unexpected DEFAULT_TIPS_LIST shape — aborting\n');
+  process.exit(1);
+}
</code_context>
<issue_to_address>
**suggestion:** Consider making the size guard more intentional and visible rather than a hard‑coded magic number.

The `500000` byte limit works as a safeguard, but as a bare literal it’s hard to understand and adjust later. Consider extracting it to a named constant (e.g. `MAX_TIPS_LITERAL_LENGTH`) or basing it on `src.length` so future tuning and debugging of “shape” failures is clearer.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread generate_tooltips.sh
Comment on lines +44 to +45
if (m[1].length > 500000 || !/^\s*\[/.test(m[1])) {
process.stderr.write('Unexpected DEFAULT_TIPS_LIST shape — aborting\n');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider making the size guard more intentional and visible rather than a hard‑coded magic number.

The 500000 byte limit works as a safeguard, but as a bare literal it’s hard to understand and adjust later. Consider extracting it to a named constant (e.g. MAX_TIPS_LITERAL_LENGTH) or basing it on src.length so future tuning and debugging of “shape” failures is clearer.

@codeant-ai

codeant-ai Bot commented Feb 28, 2026

Copy link
Copy Markdown

Nitpicks 🔍

🔒 No security issues identified
⚡ Recommended areas for review

  • Code-eval Risk
    The Node helper extracts a source snippet from index.js and then evaluates it with the Function constructor. Although there are new size/shape checks and a path validation, evaluating text from a project file can still execute unexpected code if the regex match is tricked or the index.js format changes. Consider replacing or further hardening this evaluation step.

  • Port prestart handling
    New logic frees any process listening on the configured port before restart. Verify free_port_if_conflicted correctly ignores the intended bot PID and that there are no race conditions between freeing the port and restarting the service.

  • Kill semantics on rollback
    Rollback now forcibly kills processes found by lsof/fuser on the target port. Confirm the candidate processes are correctly identified (no false positives) and consider a gentler shutdown sequence or admin notification before hard kills.

  • Fuser output parsing
    The block uses fuser -n tcp "$DEPLOY_PORT" and then pipes to tr/sed but does not strip the possible "/tcp" suffix that many fuser implementations append (e.g. "1234/tcp"). Passing those values directly to kill will fail. Normalize/validate PIDs before attempting to kill them.

  • Fuser output parsing (dev)
    The dev-run kill logic mirrors the deploy script and also uses fuser -n tcp ... output directly. If fuser emits values like "1234/tcp" the subsequent kill calls will fail. Also consider robust splitting/iteration to avoid accidental word-splitting issues.

Comment thread deploy.sh Outdated
# 3c) Kill anything blocking the bot port before starting
# ---------------------------------------------------------
DEPLOY_PORT="$(grep -E '^PORT=' "$PROJECT_DIR/.env" 2>/dev/null | head -1 | cut -d= -f2 | tr -d '"' | tr -d "'" | tr -d $'\r')"
DEPLOY_PORT="$(grep -E '^PORT=' "$PROJECT_DIR/.env" 2>/dev/null | head -1 | cut -d= -f2 | cut -d'#' -f1 | tr -d '"' | tr -d "'" | tr -d ' ' | tr -d $'\r')"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: In the new port-unblocking step, grep is run unconditionally on $PROJECT_DIR/.env under set -euo pipefail, so if .env is missing or unreadable the command substitution can abort the entire deploy script before the service is restarted, potentially leaving the bot down instead of cleanly defaulting to port 3000. [possible bug]

Severity Level: Major ⚠️
- ⚠️ Deploy script can fail if .env is absent.
- ⚠️ Admins receive failure alerts despite code updating successfully.
- ⚠️ Port-unblocking becomes a hard dependency on .env presence.
Suggested change
DEPLOY_PORT="$(grep -E '^PORT=' "$PROJECT_DIR/.env" 2>/dev/null | head -1 | cut -d= -f2 | cut -d'#' -f1 | tr -d '"' | tr -d "'" | tr -d ' ' | tr -d $'\r')"
if [[ -f "$PROJECT_DIR/.env" ]]; then
DEPLOY_PORT="$(grep -E '^PORT=' "$PROJECT_DIR/.env" 2>/dev/null | head -1 | cut -d= -f2 | cut -d'#' -f1 | tr -d '"' | tr -d "'" | tr -d ' ' | tr -d $'\r')"
fi
Steps of Reproduction ✅
1. On the VPS where `deploy.sh` runs, go to the project directory `"$PROJECT_DIR"`
referenced at `deploy.sh:26` and temporarily remove or rename `.env` so that
`$PROJECT_DIR/.env` does not exist or is unreadable.

2. Trigger a deploy using this script (per usage comment at `deploy.sh:5-11`), for example
by running `bash /var/www/html/Runewager/deploy.sh bot` or invoking the GitHub/bot
integration that calls this script.

3. The script proceeds through step 1 (service stop at `deploy.sh:136-143`), step 2 (git
update at `deploy.sh:153-174`), and step 3 (npm install at `deploy.sh:183-212`)
successfully.

4. When it reaches the port-unblocking block at `deploy.sh:232-251`, the unguarded command
substitution `DEPLOY_PORT="$(grep -E '^PORT=' "$PROJECT_DIR/.env" …)"` at `deploy.sh:235`
executes; because `.env` is missing, `grep` exits with status 2, which under `set -euo
pipefail` (line `24`) triggers the `ERR` trap `_on_error` at `deploy.sh:88-102`, causing
the main deploy flow to abort before the normal "Step 4/4 — Starting bot via systemctl…"
path at `deploy.sh:256-261` runs and leading to a deploy reported as failed due solely to
the missing `.env` file.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** deploy.sh
**Line:** 235:235
**Comment:**
	*Possible Bug: In the new port-unblocking step, `grep` is run unconditionally on `$PROJECT_DIR/.env` under `set -euo pipefail`, so if `.env` is missing or unreadable the command substitution can abort the entire deploy script before the service is restarted, potentially leaving the bot down instead of cleanly defaulting to port 3000.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

@codeant-ai

codeant-ai Bot commented Feb 28, 2026

Copy link
Copy Markdown

CodeAnt AI finished reviewing your PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants