Skip to content

feat: Twitter share referral UI for credit rewards#729

Merged
Felarof (felarof99) merged 3 commits intomainfrom
feat/referral-system
Apr 16, 2026
Merged

feat: Twitter share referral UI for credit rewards#729
Felarof (felarof99) merged 3 commits intomainfrom
feat/referral-system

Conversation

@felarof99
Copy link
Copy Markdown
Contributor

Summary

  • Adds a "Share on Twitter" CTA when credits are exhausted, letting users earn more credits by tweeting about BrowserOS
  • Introduces reusable ShareForCredits component used in both ChatError and UsagePage
  • Exposes browserosId via GET /credits so the extension can pass it to the referral service
  • Rebuilds chat session on provider change to prevent stale provider state

Test plan

  • Trigger credits-exhausted state and verify the Twitter share CTA renders
  • Submit a tweet URL and confirm it reaches the referral endpoint with the correct browserosId
  • Switch LLM providers mid-session and confirm the chat session rebuilds cleanly
  • Verify GET /credits response includes browserosId
  • Run bun run typecheck and bun run lint

🤖 Generated with Claude Code

Felarof (felarof99) and others added 2 commits April 14, 2026 18:41
When credits are exhausted, users now see a "Share on Twitter" CTA with
a pre-filled tweet URL and an input to paste their tweet link. Reusable
ShareForCredits component used in both ChatError and UsagePage. Server's
GET /credits now includes browserosId for the extension to pass to the
referral service.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 16, 2026

Greptile Summary

This PR adds a Twitter share-for-credits referral flow: a reusable ShareForCredits component shown when credits are exhausted (in ChatError) and on the UsagePage, backed by a new submit-referral.ts client and a browserosId field exposed via GET /credits. It also fixes stale-provider state by adding LLM config change detection to ChatService, mirroring the existing MCP-server and workspace rebuild patterns, with a matching test.

Confidence Score: 5/5

Safe to merge; all remaining findings are P2 style and convention improvements.

No P0 or P1 issues found. The server-side changes (credits endpoint, session rebuild) are well-scoped and tested. The frontend component handles loading, success, and error states correctly. The only gaps are convention-level: the referral service URL belongs in shared constants, analytics events are missing, and the TODO comment should be tracked externally.

packages/browseros-agent/apps/agent/lib/referral/submit-referral.ts — hardcoded URL, missing response.ok guard, TODO comment.

Important Files Changed

Filename Overview
packages/browseros-agent/apps/agent/components/referral/ShareForCredits.tsx New reusable component for Twitter share-for-credits flow; clean state management and graceful error handling, but missing analytics tracking for share/submit events per project conventions.
packages/browseros-agent/apps/agent/lib/referral/submit-referral.ts New referral service client; hardcoded URL should be in @browseros/shared/constants/urls, missing response.ok check before JSON parsing, and a TODO comment left in production code.
packages/browseros-agent/apps/server/src/api/routes/credits.ts Cleanly exposes browserosId in the GET /credits response by spreading credits and appending the ID; no issues found.
packages/browseros-agent/apps/server/src/api/services/chat-service.ts Adds LLM provider/model change detection (llmConfigKey) to trigger session rebuild, consistent with existing MCP-server and workspace change detection patterns; well-tested.
packages/browseros-agent/apps/server/tests/api/services/chat-service.test.ts Adds a clear test for LLM provider change mid-session triggering a rebuild; covers agent disposal and new agent creation correctly.

Sequence Diagram

sequenceDiagram
    participant User
    participant ShareForCredits
    participant CreditsEndpoint as GET /credits
    participant ReferralService as browseros-referral.fly.dev
    participant useCredits

    User->>ShareForCredits: Open (credits exhausted)
    ShareForCredits->>useCredits: useCredits()
    useCredits->>CreditsEndpoint: fetch /credits
    CreditsEndpoint-->>useCredits: { credits, dailyLimit, browserosId }
    useCredits-->>ShareForCredits: data.browserosId

    User->>ShareForCredits: Click "Share on Twitter"
    ShareForCredits-->>User: Opens x.com/intent/tweet

    User->>ShareForCredits: Paste tweet URL + Submit
    ShareForCredits->>ReferralService: POST /referral/submit { tweetUrl, browserosId }
    ReferralService-->>ShareForCredits: { success, creditsAdded?, reason? }
    alt success
        ShareForCredits->>useCredits: invalidateCredits()
        ShareForCredits-->>User: "200 credits added!"
    else failure
        ShareForCredits-->>User: reason or "Submission failed"
    end
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: packages/browseros-agent/apps/agent/lib/referral/submit-referral.ts
Line: 1

Comment:
**Hardcoded URL should live in shared constants**

`REFERRAL_SERVICE_URL` is a magic constant that belongs in `EXTERNAL_URLS` in `packages/shared/src/constants/urls.ts`, which is the designated home for all external service URLs (see `KLAVIS_PROXY`, `POSTHOG_DEFAULT`, `CODEGEN_SERVICE`, etc. already there). Scattering URLs in individual files makes future base-URL changes error-prone.

```suggestion
import { EXTERNAL_URLS } from '@browseros/shared/constants/urls'
```

Then reference `EXTERNAL_URLS.REFERRAL_SERVICE` (after adding it to the shared file) instead of the inline string.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: packages/browseros-agent/apps/agent/lib/referral/submit-referral.ts
Line: 13-18

Comment:
**Missing `response.ok` guard before parsing JSON**

If the referral service returns a non-2xx status with a non-JSON body (e.g. a CDN 503 HTML error page), `response.json()` will throw a `SyntaxError`. The catch block in the component will surface this as "Network error. Please try again." rather than giving the user a clear "service unavailable" message. Checking `response.ok` first makes the failure path explicit.

```suggestion
  if (!response.ok) {
    return { success: false, reason: `Request failed with status ${response.status}` }
  }
  return response.json()
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: packages/browseros-agent/apps/agent/lib/referral/submit-referral.ts
Line: 21-24

Comment:
**TODO comment left in production code**

The `// TODO: Rotate between 20-30 variations` comment signals intentional future work but per the project's coding guidelines, comments should only be present for non-obvious logic. If this rotation is planned, track it in the issue tracker rather than leaving a TODO in source.

```suggestion
export function getShareOnTwitterUrl(): string {
  const text = 'I use @browseros_ai to browse the web with AI. Check it out!'
  return `https://x.com/intent/tweet?text=${encodeURIComponent(text)}`
}
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: packages/browseros-agent/apps/agent/components/referral/ShareForCredits.tsx
Line: 27

Comment:
**No analytics tracking for referral interactions**

Per the project's analytics conventions (`apps/agent/CLAUDE.md`), all user-facing events should be tracked via `track()` with constants from `analyticsEvents.ts`. The "Share on Twitter" button click and successful/failed referral submissions are meaningful conversion events that are currently untracked, making it impossible to measure the feature's effectiveness.

Consider adding events like `referral.twitter_share.clicked`, `referral.submit.success`, and `referral.submit.failed` around the relevant actions.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "chore: merge dev into feat/referral-syst..." | Re-trigger Greptile

@felarof99 Felarof (felarof99) changed the base branch from dev to main April 16, 2026 22:23
- Move referral service URL to EXTERNAL_URLS
- Guard submitReferral on !response.ok
- Remove stale TODO comment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@felarof99 Felarof (felarof99) merged commit b6d6d4e into main Apr 16, 2026
6 of 8 checks passed
@felarof99 Felarof (felarof99) deleted the feat/referral-system branch April 16, 2026 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant