Skip to content

Add feature switches and new survey#265

Merged
wonderwhy-er merged 3 commits into
mainfrom
new-survey
Oct 22, 2025
Merged

Add feature switches and new survey#265
wonderwhy-er merged 3 commits into
mainfrom
new-survey

Conversation

@wonderwhy-er

@wonderwhy-er wonderwhy-er commented Oct 22, 2025

Copy link
Copy Markdown
Owner

CodeAnt-AI Description

Add remote feature flags and tighten feedback survey prompts

What Changed

  • A remote feature-flag system was added and initialized at startup; feature flag values are now included in the server config so remote toggles are visible to users.
  • Feedback survey behavior updated:
    • The fallback survey link was replaced with the new Tally form URL so users get a working form when the embedded form fails.
    • Survey prompts only appear when the "user_surveys" flag is enabled; prompts will not show for the desktop-commander client.
    • Prompts are shown much less often: only at the start of a session, only after at least 3 days of use and 10 total tool calls, at most once per day, and stop after 3 attempts total.
    • Prompt attempts are recorded and a session-level flag prevents repeated prompts in the same session; prompt text variants were refreshed to three new, clearer messages.
  • Onboarding checks were tightened to avoid showing invites to established users and to skip onboarding for the desktop-commander client.
  • Feature flags are fetched in the background, cached to disk, and used if remote fetch fails so users see consistent behavior even offline.

Impact

✅ Remote feature toggles visible in config
✅ Fewer unwanted feedback prompts
✅ Reachable feedback form via updated link

💡 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.

Summary by CodeRabbit

  • New Features

    • Introduced a feature flags system with startup initialization, local caching and periodic remote refresh for dynamic feature control.
  • Improvements

    • Enhanced feedback prompting with per-session, per-day, and attempt limits plus feature-flag gating and richer prompt variants.
    • Updated the pre-filled feedback form URL.
    • Expanded usage tracking to capture additional session and prompt metadata for better analytics.

@codeant-ai

codeant-ai Bot commented Oct 22, 2025

Copy link
Copy Markdown
Contributor

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

@coderabbitai

coderabbitai Bot commented Oct 22, 2025

Copy link
Copy Markdown
Contributor

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a FeatureFlagManager (cache + remote refresh), initializes it at server startup, exposes flags via the config endpoint, updates the Tally survey base URL, and extends usage-tracking with feature-flag gating, per-session/day limits, attempt caps, new tracking fields, and multiple prompt variants.

Changes

Cohort / File(s) Summary
Feature flag infra & startup init
src/index.ts, src/utils/feature-flags.ts
New FeatureFlagManager singleton implemented (cache file, remote fetch with 5s timeout, periodic refresh, load/save cache, refresh/destroy API). Initialized during server startup via await featureFlagManager.initialize() (logged).
Config exposure
src/tools/config.ts
Added featureFlags field to the config response populated from featureFlagManager.getAll().
Feedback URL update
src/tools/feedback.ts
Updated pre-filled Tally survey base URL from mYB6av to mKqoKg (error text and URL construction).
Usage tracking & feedback gating
src/utils/usageTracker.ts
Extended ToolUsageStats and UsageSession with lastFeedbackPromptDate, feedbackAttempts, and promptedThisSession. shouldPromptForFeedback now respects user_surveys flag, excludes desktop-commander, caps attempts to 3, enforces per-session/ per-day dedupe, requires ≥3 days since first use and ≥10 total tool calls. New prompt variants and updated markFeedbackPrompted.

Sequence Diagram(s)

sequenceDiagram
    participant Server as Server Startup
    participant FM as FeatureFlagManager
    participant Cache as feature-flags.json
    participant Remote as Remote Flag Service

    Server->>FM: initialize()
    activate FM
    FM->>Cache: loadFromCache()
    alt cache present
        Cache-->>FM: return flags
        FM->>FM: set internal flags
    else cache missing/invalid
        FM->>FM: continue with empty/defaults
    end
    Note over FM: start background fetch & schedule periodic refresh (interval)
    FM->>Remote: fetchFlags() [async, 5s timeout]
    alt success
        Remote-->>FM: flags JSON
        FM->>Cache: saveToCache()
        FM->>FM: update internal flags
    else timeout/error
        FM-->>FM: log debug/warn, keep cached flags
    end
    deactivate FM
    Server->>Server: continue startup
Loading
sequenceDiagram
    participant User as User Session
    participant Tracker as UsageTracker
    participant FM as FeatureFlagManager
    participant Feedback as Feedback System

    User->>Tracker: newSession()
    Tracker->>Tracker: promptedThisSession = false

    loop each tool invocation
        User->>Tracker: recordToolUse()
        Tracker->>Tracker: increment counters

        alt commandsInSession == 1
            Tracker->>FM: getAll() (check user_surveys)
            alt user_surveys enabled
                Tracker->>Tracker: evaluate gating (client, attempts≤3, not prompted today, promptedThisSession=false, 3+ days, ≥10 calls)
                alt all gates pass
                    Tracker->>Feedback: getFeedbackPromptMessage()
                    Feedback-->>Tracker: prompt variant
                    Tracker->>Tracker: markFeedbackPrompted()
                    Tracker->>User: show prompt
                else any gate fails
                    Tracker->>User: no prompt
                end
            else flag disabled
                Tracker->>User: no prompt
            end
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hid the flags beneath a log so neat,
I fetch at dusk and save them off to sleep.
When sessions start I nudge — but not too much,
Three tries, one day, and prompts that feel just right.
Hop on, click the survey — I’ll cheer with a twitch!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Add feature switches and new survey settings" accurately describes the primary changes in the changeset. The PR adds a remote feature-flag system (feature-flags.ts) that is initialized at startup and exposed through the config, which corresponds to "feature switches." The "new survey settings" refers to the updated feedback survey behavior including the new Tally URL, the user_surveys feature flag integration, and refined prompt frequency logic. The title is concise, specific, and free of vague terms or noise. While it doesn't enumerate every detail (such as caching behavior or onboarding changes), which is expected per the guidelines, it successfully conveys the main changes a teammate would need to understand from scanning the PR history.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch new-survey

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 Oct 22, 2025
Comment thread src/utils/feature-flags.ts Outdated
private flags: Record<string, any> = {};
private lastFetch: number = 0;
private cachePath: string;
private cacheMaxAge: number = 0.5 * 60 * 1000; // 5 minutes - hardcoded refresh interval

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: Fix the incorrect milliseconds calculation for the cache refresh interval so the comment and value match (use 5 * 60 * 1000 for five minutes). [possible bug]

Severity Level: Critical 🚨

Suggested change
private cacheMaxAge: number = 0.5 * 60 * 1000; // 5 minutes - hardcoded refresh interval
private cacheMaxAge: number = 5 * 60 * 1000; // 5 minutes - hardcoded refresh interval
Why it matters? ⭐

The current expression 0.5 * 60 * 1000 evaluates to 30_000ms (30 seconds), which contradicts the inline comment and the later logging that reports the refresh interval. Changing to 5 * 60 * 1000 fixes an obvious arithmetic bug so setInterval runs at the intended 5-minute cadence. This is a real bugfix (timing) and has no syntactic risk.

Prompt for AI Agent 🤖
<code>This is a comment left during a code review.

**Path:** src/utils/feature-flags.ts
**Line:** 16:16
**Comment:**
	*Possible Bug: Fix the incorrect milliseconds calculation for the cache refresh interval so the comment and value match (use 5 * 60 * 1000 for five minutes).

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

@codeant-ai

codeant-ai Bot commented Oct 22, 2025

Copy link
Copy Markdown
Contributor

CodeAnt AI finished reviewing your PR.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (5)
src/tools/feedback.ts (1)

91-91: Deduplicate the feedback form URL (single source of truth).

The Tally form URL appears twice. Define one constant and reuse to prevent drift on future updates.

+const FEEDBACK_FORM_URL = 'https://tally.so/r/mKqoKg';
...
-              `You can still access our feedback form directly at: https://tally.so/r/mKqoKg\n\n` +
+              `You can still access our feedback form directly at: ${FEEDBACK_FORM_URL}\n\n` +
...
-  const baseUrl = 'https://tally.so/r/mKqoKg';
+  const baseUrl = FEEDBACK_FORM_URL;

Please confirm mKqoKg is the intended production form ID and whether we should load it from config/env to allow rotation without code changes.

Also applies to: 103-103

src/utils/usageTracker.ts (1)

340-349: Day-based gating uses UTC date; consider local day to match user expectations.

Using toISOString().split('T')[0] gates by UTC. If local time crosses midnight earlier/later than UTC, prompts may repeat or be suppressed unexpectedly.

Compute local “YYYY-MM-DD”:

-const today = new Date().toISOString().split('T')[0];
+const d = new Date();
+const today = `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
src/tools/config.ts (1)

5-5: Expose flags: LGTM, minor hardening optional.

featureFlags: featureFlagManager.getAll() is fine. If some flags are internal, consider filtering or namespacing before exposing. Optionally deep-freeze the object in the response to prevent accidental mutation downstream.

Also applies to: 31-31

src/index.ts (1)

47-49: Initialize flags: LGTM. Consider cleanup on shutdown.

Call featureFlagManager.destroy() on exit signals to clear the refresh interval so it never keeps the process alive in edge cases.

+process.on('SIGINT', () => { try { featureFlagManager.destroy(); } finally { process.exit(0); } });
+process.on('SIGTERM', () => { try { featureFlagManager.destroy(); } finally { process.exit(0); } });
+process.on('exit', () => { featureFlagManager.destroy(); });
src/utils/feature-flags.ts (1)

43-49: Optional: prevent the timer from keeping the process alive.

Call unref() on the interval so Node can exit cleanly when idle.

-      this.refreshInterval = setInterval(() => {
+      this.refreshInterval = setInterval(() => {
         this.fetchFlags().catch(err => {
           logger.debug('Periodic flag fetch failed:', err.message);
         });
-      }, this.cacheMaxAge);
+      }, this.cacheMaxAge);
+      if (this.refreshInterval.unref) this.refreshInterval.unref();
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 252a00d and 0e7be1e.

📒 Files selected for processing (5)
  • src/index.ts (2 hunks)
  • src/tools/config.ts (2 hunks)
  • src/tools/feedback.ts (2 hunks)
  • src/utils/feature-flags.ts (1 hunks)
  • src/utils/usageTracker.ts (10 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
src/index.ts (1)
src/utils/feature-flags.ts (1)
  • featureFlagManager (175-175)
src/utils/feature-flags.ts (1)
src/utils/logger.ts (1)
  • logger (55-64)
src/tools/config.ts (1)
src/utils/feature-flags.ts (1)
  • featureFlagManager (175-175)
src/utils/usageTracker.ts (3)
src/utils/feature-flags.ts (1)
  • featureFlagManager (175-175)
src/server.ts (1)
  • currentClient (148-148)
src/config-manager.ts (1)
  • configManager (219-219)
🔇 Additional comments (3)
src/utils/feature-flags.ts (2)

25-27: Review comment references incorrect lines; CONFIG_FILE is properly exported and available.

The CONFIG_FILE import at line 4 and cache path resolution at lines 21-22 are working correctly. CONFIG_FILE is properly exported from ../config.js and the module path resolves without issues. Lines 25-27 shown in the snippet don't reference CONFIG_FILE, so the review comment points to the wrong location and raises an unfounded concern.

Likely an incorrect or invalid review comment.


115-121: No changes needed—Node version already enforces fetch availability.

The project specifies "engines": { "node": ">=18.0.0" } in package.json, which guarantees native fetch support. Node 18+ includes fetch as a global by default, so no polyfill or guard is required.

src/utils/usageTracker.ts (1)

219-236: No call order gating issue exists—verification confirms proper sequencing.

The code correctly calls trackSuccess/trackFailure at lines 1250/1253 before shouldPromptForFeedback at line 1295 in src/server.ts. Both track methods immediately call updateSession() to increment commandsInSession, ensuring the gating check at line 251 (commandsInSession !== 1) works as intended. Only one call site exists, and it follows the correct order.

Comment thread src/utils/feature-flags.ts Outdated
private flags: Record<string, any> = {};
private lastFetch: number = 0;
private cachePath: string;
private cacheMaxAge: number = 0.5 * 60 * 1000; // 5 minutes - hardcoded refresh interval

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Refresh interval mismatch (30s vs. “5 minutes”).

0.5 * 60 * 1000 = 30,000 ms (30s). The comment and behavior suggest 5 minutes.

-  private cacheMaxAge: number = 0.5 * 60 * 1000; // 5 minutes - hardcoded refresh interval
+  private cacheMaxAge: number = 5 * 60 * 1000; // 5 minutes
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private cacheMaxAge: number = 0.5 * 60 * 1000; // 5 minutes - hardcoded refresh interval
private cacheMaxAge: number = 5 * 60 * 1000; // 5 minutes
🤖 Prompt for AI Agents
In src/utils/feature-flags.ts around line 16, the numeric expression 0.5 * 60 *
1000 evaluates to 30,000ms (30s) but the comment states "5 minutes"; fix by
making the code and comment consistent: either set cacheMaxAge to 5 * 60 * 1000
(for 5 minutes) and keep the comment, or if the intended refresh is 30s, update
the comment to "30 seconds" (or "30s - hardcoded refresh interval"); pick the
correct intended interval and update the value or the comment accordingly.

Comment thread src/utils/usageTracker.ts
Comment on lines +27 to +29
lastFeedbackPrompt: number; // timestamp (deprecated, use lastFeedbackPromptDate)
lastFeedbackPromptDate?: string; // date string like '2025-10-20'
feedbackAttempts?: number; // How many times we've shown feedback prompt (max 3)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Type narrowing bug after adding new fields — getToolCategory return type now too broad.

Adding lastFeedbackPromptDate/feedbackAttempts expands the key union; stats[category]++ may become invalid at compile time or unsafe at runtime.

Use an explicit category key type to ensure only numeric counters are returned.

+type UsageCategoryKey =
+  | 'filesystemOperations'
+  | 'terminalOperations'
+  | 'editOperations'
+  | 'searchOperations'
+  | 'configOperations'
+  | 'processOperations';
...
-  private getToolCategory(toolName: string): keyof Omit<ToolUsageStats, 'totalToolCalls' | 'successfulCalls' | 'failedCalls' | 'toolCounts' | 'firstUsed' | 'lastUsed' | 'totalSessions' | 'lastFeedbackPrompt'> | null {
+  private getToolCategory(toolName: string): UsageCategoryKey | null {

Run tsc to ensure no remaining arithmetic on non‑numeric fields compiles cleanly.


🏁 Script executed:

#!/bin/bash
# Verify category typing and numeric increments compile
rg -nP 'getToolCategory\s*\(' src/utils/usageTracker.ts -n -C2
# Type-check whole project (tsconfig assumed)
npm run -s build || npx tsc -p .

Length of output: 1355


🏁 Script executed:

#!/bin/bash
# Find ToolUsageStats interface definition
rg -nP 'interface\s+ToolUsageStats|type\s+ToolUsageStats' src/utils/usageTracker.ts -A 20

# Find TOOL_CATEGORIES definition
rg -nP 'TOOL_CATEGORIES\s*=' src/utils/usageTracker.ts -A 15

# Check if new fields appear anywhere as category keys
rg -n 'lastFeedbackPromptDate|feedbackAttempts' src/utils/usageTracker.ts | head -20

Length of output: 1747


🏁 Script executed:

#!/bin/bash
# Check the exact type error TypeScript would produce
# by looking at the full getToolCategory function and stats increment usage

rg -nP 'private getToolCategory' src/utils/usageTracker.ts -A 10

# Check if there's a fix already in place (looking for explicit category type or updated Omit)
rg -nP 'type.*CategoryKey|interface.*Category' src/utils/usageTracker.ts

Length of output: 730


🏁 Script executed:

#!/bin/bash
# Check lines around stats[category]++ to see the full context
rg -nP 'stats\[category\]\+\+' src/utils/usageTracker.ts -B 3 -A 3

# Check if there are any tsc errors or type checks in package.json or tsconfig
cat tsconfig.json 2>/dev/null || cat package.json | grep -A 5 '"scripts"'

Length of output: 896


Type narrowing bug confirmed — getToolCategory return type must exclude new feedback fields.

The Omit at line 104 excludes 8 fields but misses lastFeedbackPromptDate and feedbackAttempts. With strict: true in tsconfig, stats[category]++ at lines 171 and 203 will fail TypeScript type-checking if category could be a string field instead of a numeric counter.

Fix: Add the new fields to the Omit exclusion list, or introduce an explicit category key type:

+type UsageCategoryKey =
+  | 'filesystemOperations'
+  | 'terminalOperations'
+  | 'editOperations'
+  | 'searchOperations'
+  | 'configOperations'
+  | 'processOperations';
...
-  private getToolCategory(toolName: string): keyof Omit<ToolUsageStats, 'totalToolCalls' | 'successfulCalls' | 'failedCalls' | 'toolCounts' | 'firstUsed' | 'lastUsed' | 'totalSessions' | 'lastFeedbackPrompt'> | null {
+  private getToolCategory(toolName: string): UsageCategoryKey | null {

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/utils/usageTracker.ts around lines 27 and 29 and the Omit at line 104,
the type narrowing for getToolCategory is incomplete because the new fields
lastFeedbackPromptDate and feedbackAttempts are not excluded; update the Omit to
also exclude "lastFeedbackPromptDate" and "feedbackAttempts" (or replace the
Omit with an explicit type for the category keys) so the returned category type
only contains numeric counters and TypeScript will allow stats[category]++ at
lines 171 and 203 to type-check.

Comment thread src/utils/usageTracker.ts
Comment on lines +142 to 144
commandsInSession: 1,
promptedThisSession: false // Reset for new session
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Session counter likely off-by-one on first run.

Initializing commandsInSession to 1 and incrementing totalSessions when commandsInSession === 1, combined with default totalSessions = 1, yields 2 after the very first command.

Options:

  • Start totalSessions at 0 in getDefaultStats; or
  • Initialize commandsInSession to 0 on new session and increment immediately after; or
  • Increment totalSessions when creating a new session instead of in trackSuccess/Failure.

Minimal change:

-        commandsInSession: 1,
+        commandsInSession: 0,
         promptedThisSession: false

And in trackSuccess/trackFailure, increment before the session check:

-    // Update session count if this is a new session
-    if (this.currentSession?.commandsInSession === 1) {
+    // Update session count if this is the first command of a new session
+    if (this.currentSession && ++this.currentSession.commandsInSession === 1) {
       stats.totalSessions++;
     }

Or increment totalSessions when creating the session (preferred).

🤖 Prompt for AI Agents
In src/utils/usageTracker.ts around lines 142-144, the session counter is
off-by-one because new sessions start with commandsInSession: 1 while
totalSessions is also incremented when commandsInSession === 1 (and default
totalSessions = 1), producing 2 after the first command; fix by initializing new
sessions with commandsInSession: 0 (or set totalSessions default to 0) and move
the totalSessions increment to the session-creation path so a new session
increments totalSessions immediately when created (preferred), ensuring
trackSuccess/trackFailure only increments commandsInSession and does not adjust
totalSessions.

@wonderwhy-er wonderwhy-er changed the title Add feature switches and new survey settings Add feature switches and new survey Oct 22, 2025
@wonderwhy-er wonderwhy-er merged commit cc89540 into main Oct 22, 2025
1 of 2 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/utils/usageTracker.ts (1)

27-29: Type narrowing bug — past review not addressed.

The new fields lastFeedbackPromptDate and feedbackAttempts are not excluded in the Omit at line 104, allowing getToolCategory to potentially return these string/number field names. This causes stats[category]++ at lines 171 and 203 to fail type-checking under strict: true.

Apply the fix from the previous review:

+type UsageCategoryKey =
+  | 'filesystemOperations'
+  | 'terminalOperations'
+  | 'editOperations'
+  | 'searchOperations'
+  | 'configOperations'
+  | 'processOperations';
...
-  private getToolCategory(toolName: string): keyof Omit<ToolUsageStats, 'totalToolCalls' | 'successfulCalls' | 'failedCalls' | 'toolCounts' | 'firstUsed' | 'lastUsed' | 'totalSessions' | 'lastFeedbackPrompt'> | null {
+  private getToolCategory(toolName: string): UsageCategoryKey | null {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 31eda66 and f3d2912.

📒 Files selected for processing (1)
  • src/utils/usageTracker.ts (11 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/utils/usageTracker.ts (3)
src/utils/feature-flags.ts (1)
  • featureFlagManager (175-175)
src/server.ts (1)
  • currentClient (148-148)
src/config-manager.ts (1)
  • configManager (219-219)
🔇 Additional comments (3)
src/utils/usageTracker.ts (3)

80-80: Session counter initialization fix looks correct.

Changing totalSessions from 1 to 0 resolves the off-by-one issue flagged in the previous review. First command now correctly results in totalSessions = 1.


279-306: Variant-based prompt system looks good.

The three message variants with clear CTAs and random selection support effective A/B testing of feedback prompts.


338-352: Tracking updates are correct.

The function properly updates all feedback tracking fields and prevents duplicate prompts in the same session.

Note: Line 340 has the same timezone issue flagged earlier (uses UTC instead of local date).

Comment thread src/utils/usageTracker.ts
}

// Check if client is desktop-commander (disable for this client)
//return true;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove debug artifact.

The commented //return true; line should be removed before merging.

Apply this diff:

-    //return true;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
//return true;
🤖 Prompt for AI Agents
In src/utils/usageTracker.ts around line 227, there is a leftover debug
artifact: a commented line "//return true;". Remove this commented line to clean
up the codebase before merging, ensuring no behavior changes are introduced.

Comment thread src/utils/usageTracker.ts
Comment on lines +260 to +264
// Check if we've already prompted today
const today = new Date().toISOString().split('T')[0]; // '2025-10-20'
if (stats.lastFeedbackPromptDate === today) {
return false;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Timezone mismatch in daily prompt check.

Using toISOString().split('T')[0] produces a UTC date. If the user is in a different timezone (e.g., PST), the "once per day" check may not align with their actual day boundary. For instance, 11 PM PST on Oct 22 is Oct 23 UTC.

Consider using local date:

-    const today = new Date().toISOString().split('T')[0]; // '2025-10-20'
+    const today = new Date().toLocaleDateString('en-CA'); // 'YYYY-MM-DD' in local timezone

And update line 340 similarly.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/utils/usageTracker.ts around lines 260 to 264 (and apply same change at
line ~340), the code uses toISOString().split('T')[0] which yields a UTC date
and causes the daily-prompt check to misalign with the user's local day; replace
that logic to compute the current local date string (e.g., build YYYY-MM-DD from
new Date() using local year/month/day or use toLocaleDateString with a
consistent locale/format) and compare stats.lastFeedbackPromptDate against that
local-date string so the "once per day" check respects the user's timezone; make
the same change at the other occurrence on line ~340.

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.

1 participant