Skip to content

feat(cli): attribute CLI traffic with e2b-cli and per-command tags#1544

Open
mishushakov wants to merge 1 commit into
mainfrom
cli-connectionconfig-attribution
Open

feat(cli): attribute CLI traffic with e2b-cli and per-command tags#1544
mishushakov wants to merge 1 commit into
mainfrom
cli-connectionconfig-attribution

Conversation

@mishushakov

Copy link
Copy Markdown
Member

Follow-up promised in #1524 (original attempt #1525, closed while blocked on the backend User-Agent parser, since fixed by e2b-dev/infra#3149, which now iterates User-Agent tokens and ignores unrecognized ones — so the extra tags are safe on template builds).

Sets ConnectionConfig.setIntegration('e2b-cli/<version>') at the top of src/api.ts before the shared connection config is built at import time, and a commander preAction hook extends the tag with the canonical invoked command (alias ls reports as list), rebuilding the shared config and client since they capture the User-Agent at construction. Every CLI request then carries:

User-Agent: e2b-js-sdk/2.32.0 e2b-cli/2.13.1 e2b-cli-command/sandbox.list

Tests drive the built CLI (sandbox list and the ls alias) against a local stub API server and assert the received User-Agent, which also guards that the bundle keeps shipping the workspace SDK where setIntegration exists. Includes a patch changeset for @e2b/cli.

🤖 Generated with Claude Code

Call ConnectionConfig.setIntegration('e2b-cli/<version>') at the top of
src/api.ts, before the shared connection config is constructed at import
time, and extend the tag with the invoked command from a commander
preAction hook, rebuilding the shared config and client (they capture
the User-Agent at construction). Every CLI request then carries:

  User-Agent: e2b-js-sdk/2.32.0 e2b-cli/2.13.1 e2b-cli-command/sandbox.list

Command names are canonical (alias 'ls' reports as 'list'). Safe for
template builds: the backend parser iterates User-Agent tokens and
ignores unrecognized ones since e2b-dev/infra#3149, which unblocked
this follow-up promised in #1524 (original attempt: #1525).

Tests drive the built CLI against a local stub API server and assert
the received User-Agent, which also guards that the bundle ships the
workspace SDK where setIntegration exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 13, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Observability-only header changes with no auth or request-body behavior changes; shared client is recreated per command invocation.

Overview
The CLI tags outbound API traffic by setting ConnectionConfig.setIntegration to e2b-cli/<version> before the shared config is created, then extending it in a commander preAction hook with e2b-cli-command/<canonical.path> (aliases resolve to the real subcommand name). Because User-Agent is fixed at ConnectionConfig construction, the shared connectionConfig and client are rebuilt when the command is known. Vitest runs the built CLI against a stub server to assert the User-Agent includes the SDK, CLI version, and command path. Patch changeset for @e2b/cli.

Reviewed by Cursor Bugbot for commit 8de1310. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Jul 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8de1310

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@e2b/cli Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

Package Artifacts

Built from 2fc0416. Download artifacts from this workflow run.

JS SDK (e2b@2.32.1-cli-connectionconfig-attribution.0):

npm install ./e2b-2.32.1-cli-connectionconfig-attribution.0.tgz

CLI (@e2b/cli@2.13.2-cli-connectionconfig-attribution.0):

npm install ./e2b-cli-2.13.2-cli-connectionconfig-attribution.0.tgz

Python SDK (e2b==2.31.0+cli.connectionconfig.attribution):

pip install ./e2b-2.31.0+cli.connectionconfig.attribution-py3-none-any.whl

@claude claude 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.

LGTM — straightforward attribution follow-up to #1524, and the mechanism checks out.

Extended reasoning...

Overview

Adds User-Agent attribution to CLI traffic: packages/cli/src/api.ts calls the SDK's existing ConnectionConfig.setIntegration (added in #1524) with e2b-cli/<version> at module load, and a commander preAction hook in packages/cli/src/commands/index.ts extends it per-invocation with the canonical command path (e.g. sandbox.list), rebuilding the shared connectionConfig/client since the User-Agent is captured at construction time. A new attribution.test.ts spawns the built CLI against a local stub HTTP server and asserts the received User-Agent, covering both the canonical command and an alias (lssandbox.list).

Security risks

None. This only appends informational tags to an outbound header; no auth, parsing of untrusted input, or new attack surface. The description notes the backend User-Agent parser (infra#3149) tolerates unrecognized tokens, so this is safe even for template-build requests that don't expect it.

Level of scrutiny

Low-to-moderate is appropriate: it's an observability/attribution feature with no behavior change to sandbox or auth logic, following a pattern already reviewed and merged in #1524. I verified the two pieces of mechanism this PR leans on rather than taking the description at face value: (1) read connectionConfig.ts to confirm setIntegration/buildUserAgent/applyUserAgent behave as described, and (2) read commander's Command.js to confirm a preAction hook registered on the top-level program fires for nested subcommand actions via _getCommandAndAncestors, and that cmd.name() resolves to the canonical name (not the invoked alias), matching the lssandbox.list test expectation.

Other factors

The new test drives the actual built CLI binary against a real (stub) HTTP server rather than mocking internals, which gives good confidence the wiring works end-to-end, not just in isolation. Diff is small and confined to CLI attribution plumbing plus a changeset; no CODEOWNER-sensitive or critical-path code is touched.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant