Skip to content

feat: add User-Agent header to all HTTP requests (DIS-41)#34

Merged
ckorhonen merged 5 commits intomainfrom
devin/1772484974-add-user-agent-header
Mar 4, 2026
Merged

feat: add User-Agent header to all HTTP requests (DIS-41)#34
ckorhonen merged 5 commits intomainfrom
devin/1772484974-add-user-agent-header

Conversation

@ckorhonen
Copy link
Collaborator

@ckorhonen ckorhonen commented Mar 2, 2026

Add User-Agent header to all HTTP requests

Summary

Adds a User-Agent: opensea-cli/<version> header to every HTTP request made by OpenSeaClient, enabling server-side traffic segmentation by channel (CLI vs MCP vs other consumers) in Datadog/analytics.

  • Version is injected at build time via tsup's define option (__VERSION__), avoiding any runtime dependency on file-system layout
  • Both tsup.config.ts and vitest.config.ts read package.json and define __VERSION__ so the constant is available in builds and tests
  • A private defaultHeaders getter centralizes the shared header set (Accept, User-Agent, x-api-key), used by both get() and post()
  • Test assertions use expect.objectContaining with a strictly-anchored regex (/^opensea-cli\/\d+\.\d+\.\d+$/) to validate the header value

Confidence: 🟢 High — small, well-scoped change. Lint, type-check, and all 151 tests pass locally.

Updates since last revision

Addressed review feedback from @ckorhonen:

  1. Build-time version injection — replaced createRequire/require("../package.json") with tsup define: { __VERSION__: JSON.stringify(pkg.version) }. Eliminates the CJS require() call in an ESM-only codebase and removes runtime dependency on dist/package.json relative path.
  2. Anchored test regex — added $ to regex end (/^opensea-cli\/\d+\.\d+\.\d+$/) to reject malformed values like opensea-cli/1.2.3-garbage.
  3. Extracted defaultHeaders getter — private getter on OpenSeaClient removes header duplication between get() and post().

Review & Testing Checklist for Human

  • Verify __VERSION__ is correctly inlined after build: run npm run build && grep 'opensea-cli/' dist/index.js — should show the literal version string (e.g. opensea-cli/0.4.1), not __VERSION__
  • Confirm the post() spread ({ ...this.defaultHeaders }) correctly includes Content-Type when a body is provided — the test covers this but worth a quick manual check of the logic

Notes

  • Test assertions use expect.objectContaining instead of exact header matching to accommodate the new header without breaking if header order changes. This is marginally less strict than before.
  • The $-anchored regex means pre-release versions (e.g. 1.2.3-beta.1) would fail the test assertion — this is intentional per reviewer preference for strict semver matching.
  • Linear ticket: DIS-41
  • Devin Session
  • Requested by: @ckorhonen

Open with Devin

Add User-Agent: opensea-cli/<version> header to all requests made by
OpenSeaClient. Version is dynamically read from package.json using
createRequire. Updates both get() and post() methods and corresponding
test assertions.

Co-Authored-By: Chris K <ckorhonen@gmail.com>
@devin-ai-integration
Copy link
Contributor

Original prompt from Chris K
Please work on ticket "[Tracking] Add User-Agent header to opensea-cli" ([DIS-41](https://linear.app/opensea/issue/DIS-41/tracking-add-user-agent-header-to-opensea-cli))

PLAYBOOK_md:
# Ticket to PR

## Overview

This playbook guides the process of taking a Linear ticket from initial scoping through implementation to final review. The workflow ensures proper context gathering, quality implementation, and thorough code review before delivery. The agent uses the Linear MCP to manage ticket status and communication throughout.

## What's Needed From User

- Linear ticket URL or ticket ID (e.g., `ENG-123` or `https://linear.app/team/issue/ENG-123/...`)
- Repository access for the codebase where changes will be made

<phase name="Disambiguation" id="1">
## Disambiguation Phase

Think about the full user intent. Tickets are sometimes sparse. Make sure you disambiguate to the full scope that the user intended.

1. Fetch the ticket details using the Linear MCP `get_issue` tool with the ticket ID
2. Before diving into code: use the devin MCP to get a high-level understanding of the relevant systems and architecture. Use `ask_question` to learn about the relevant systems – send queries for multiple repos that could be relevant to get the full picture. Use `read_wiki_contents` to then get a better understanding how different parts of the codebase connect to each other.
3. Gather additional context to understand what the ticket means and refers to:
   - Look at past tickets in the same project and from the same author to understand patterns and terminology
   - Search for related commits and PRs (by author and content) that may provide context on the affected systems
   - Check any linked documents, designs, or parent tickets
   - Investigate the actual code
4. Identify any ambiguity in what the ticket refers to or asks for, including jargon or project-specific terms and use all means necessary to answer this yourself
5. Consult your smart friend: pass in the raw content of the... (8092 chars truncated...)

@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@devin-ai-integration devin-ai-integration bot marked this pull request as ready for review March 2, 2026 20:58
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

Co-Authored-By: Chris K <ckorhonen@gmail.com>
@ckorhonen ckorhonen requested a review from CodySearsOS March 2, 2026 21:19
Copy link
Collaborator Author

@ckorhonen ckorhonen left a comment

Choose a reason for hiding this comment

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

Code Review

Overall: Approve with suggestions — All 151 tests pass. Clean, well-scoped change.

Suggestions

  1. Replace createRequire with build-time version injection. The createRequire(import.meta.url) + require("../package.json") pattern works, but introduces a synchronous CJS require() in an ESM-only codebase and depends on file-system layout. Recommend using tsup's define option instead:

    // tsup.config.ts
    define: { __VERSION__: JSON.stringify(pkg.version) }
    
    // client.ts
    declare const __VERSION__: string
    const USER_AGENT = `opensea-cli/${__VERSION__}`

    This eliminates the runtime dependency on file layout and is zero-cost (inlined at build time).

  2. Test regex should anchor the end/^opensea-cli\/\d+\.\d+\.\d+/ should be /^opensea-cli\/\d+\.\d+\.\d+$/ to prevent matching malformed values like opensea-cli/1.2.3-garbage.

  3. Minor: Header duplication — Both get() and post() now have identical header sets. Consider extracting a private defaultHeaders getter for maintainability.

I've pushed a commit with fixes 1 and 2.

ckorhonen and others added 3 commits March 4, 2026 11:25
Replace the runtime createRequire/package.json pattern with tsup's
define option for compile-time version injection. Also anchors the
test regex with $ to prevent false-positive matches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace createRequire with build-time __VERSION__ via tsup define
- Add __VERSION__ define to vitest config for test compatibility
- Anchor test regex with $ to prevent matching malformed versions
- Extract private defaultHeaders getter to reduce header duplication

Co-Authored-By: Chris K <ckorhonen@gmail.com>
Co-Authored-By: Chris K <ckorhonen@gmail.com>
@ckorhonen ckorhonen merged commit c7d51b9 into main Mar 4, 2026
5 checks passed
@ckorhonen ckorhonen deleted the devin/1772484974-add-user-agent-header branch March 4, 2026 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants