Skip to content

feat(signup): add --ref to attribute signups to the originating site visit - #43

Open
get-linqed wants to merge 1 commit into
mainfrom
nate/signup-ref-attribution
Open

feat(signup): add --ref to attribute signups to the originating site visit#43
get-linqed wants to merge 1 commit into
mainfrom
nate/signup-ref-attribution

Conversation

@get-linqed

Copy link
Copy Markdown
Contributor

Why

The browser and the terminal share no identifier. A linq signup run after reading linqapp.com/cli arrives at the backend with nothing but an email, so growth reporting can count CLI signups but never tie one to the page, campaign, or channel that produced it.

What

--ref carries the visitor's PostHog distinct_id across that gap. It is baked into the quickstart copied from the CLI page, so it arrives pre-filled rather than typed — the flag is hidden in --help for that reason. The value is forwarded verbatim to /cli/signup as webDistinctId, where the backend validates its age and aliases the anonymous site history onto the new account.

Nothing here interprets the token's format, so a stale or malformed value costs only attribution, never the signup.

The install command is untouched. The ref rides the signup step, so npm install -g @linqapp/cli stays clean and attribution works regardless of install method. An npm-side token would have needed a postinstall hook, which --ignore-scripts, CI, and pnpm skip silently — partial data with no signal that it's partial.

Payload compatibility

When --ref is absent the key is omitted entirely, leaving the request byte-identical to what earlier clients send. Covered by a test.

Tests

npm test — 182 pass, 1 skipped. Two new cases: the flag forwards as webDistinctId, and its absence omits the key.

Release ordering

This must be published to npm before the linqapp.com side ships, because oclif rejects unknown flags outright — an older CLI receiving --ref fails signup. The site PR bumps the quickstart's stated minimum to 2.6.0 so agents upgrade first, but that only protects users who follow the upgrade step.

The feat: commit yields 2.6.0 via semantic-release.

Backend counterpart: linq-team/zero-service branch nate/cli-signup-posthog

🤖 Generated with Claude Code

…visit

The browser and the terminal share no identifier, so a `linq signup` run
after reading linqapp.com/cli arrives at the backend with nothing but an
email. Growth reporting could count CLI signups but never tie one to the
page, campaign or channel that produced it.

`--ref` carries the visitor's PostHog distinct_id across that gap. It is
baked into the quickstart copied from the CLI page, so it arrives
pre-filled rather than being something anyone types; the flag is hidden
from --help for the same reason. The value is forwarded verbatim to
/cli/signup as webDistinctId, where the backend validates its age and
aliases the anonymous site history onto the new account.

Nothing here interprets the token's format, so a stale or malformed value
costs only attribution, never the signup. When the flag is absent the key
is omitted from the payload entirely, leaving the request byte-identical
to what earlier clients send.

Note for the site side: linqapp.com must not inject --ref until this ships,
since oclif rejects unknown flags outright. The quickstart's stated minimum
version is bumped to 2.6.0 in the same change so agents upgrade first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@get-linqed
get-linqed requested a review from jflayhart as a code owner August 7, 2026 15:07
@devin-ai-integration

Copy link
Copy Markdown

Review — looks good, nothing blocking.

Forwarding the token verbatim with no format assumptions is the right split of responsibility (the backend already owns the 30-day window), hidden matches how the flag actually reaches users, and the omit-the-key-entirely test is the one I'd have asked for.

Two notes, both about the surrounding rollout rather than this diff:

  • The deploy-order constraint is real and one-directional: 2.6.0 must be on npm before skywalker-next#844 ships, or --ref hits an oclif "Nonexistent flag" and signup fails outright. Flagged separately on #844 — the quickstart's verification block still tells agents that 2.5.0 is acceptable, which weakens the upgrade gate you're relying on.
  • Since the flag is trimmed but otherwise unvalidated, a whitespace-only --ref " " becomes '' and is correctly omitted. Good.

Confirmed the payload stays byte-identical without the flag, so older-server compatibility is a non-issue in the other direction.

@devin-ai-integration devin-ai-integration 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.

Re-review — approving. Nothing changed since my first pass and nothing new to raise.

Head is still a642551: --ref trimmed, forwarded verbatim as webDistinctId, key omitted entirely when absent, both behaviors pinned by tests. CI green (4/4).

The one constraint that outlives this review is release ordering: 2.6.0 has to be on npm before skywalker-next#844 ships, or an older CLI hits an oclif "Nonexistent flag" and signup fails outright. #844's version gate now consistently says 2.6.0, so the guide no longer undercuts it.

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.

1 participant