Skip to content

Add affiliate: a cursor over a list of signup pages - #18

Merged
ralyodio merged 1 commit into
masterfrom
worktree-affiliate-cli
Aug 21, 2026
Merged

Add affiliate: a cursor over a list of signup pages#18
ralyodio merged 1 commit into
masterfrom
worktree-affiliate-cli

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Point it at any text file with links in it. It walks them one at a time, remembers which you have dealt with, and keeps the referral link each one hands back.

affiliate list --file programs.md
affiliate next --open
affiliate join elevenlabs https://try.elevenlabs.io/abc123
affiliate links --format markdown

Nothing in it knows what an affiliate program is — the list is the input, so it works for any batch of signup pages.

Parsing

A bare column of URLs, a markdown table, a bullet list, a CSV. Rather than asking which format it is, it takes the first URL on the line and works the name out from context: the bracketed text of a markdown link, the first cell of a table row, or the host when there is nothing else. A line with no URL is a heading, not an error.

The URL pattern deliberately does not treat ) as a terminator. Doing so truncates any path containing a bracket (/wiki_(disambiguation)); it over-matches and balances back instead, which handles that and markdown links with the same code.

The parts worth reviewing

  • utm_* collapses to one entry. The same page shared from a newsletter and from a tweet would otherwise ask you to sign up twice.
  • A joined entry survives being dropped from the list — it moves to the end rather than disappearing. Losing a referral link because somebody tidied the source file would be the worst thing this could do.
  • A recorded referral link survives a later status change, so skip typed at the wrong index is not unrecoverable.
  • Contact address resolves --email$AFFILIATE_EMAIL → profile file → moshcode whoami. The account is last because it is the one you cannot override in the moment, and signing up as the wrong identity does not undo.
  • answers prints gaps as (not set) rather than inventing them. A form that asks for audience size and receives an unchecked number is the fastest way to lose the account it was meant to open.
  • ListError vs UsageError so a bad index exits 1 ("you typed it wrong") and 2 stays "this broke".

It does not submit anything

Signing up accepts terms and hands over payout identity as a named person, and every one of these is behind an email-verification loop regardless — a form-filler would stop at the same wall with one more moving part. Opening the next page, having the answers ready to paste, and keeping the links in one place is the part that was actually tedious.

Verification

  • 253 tests pass (29 new), pnpm typecheck clean.
  • Exercised end to end against a real markdown list: parsed 9 entries out of a document (tables, bullets and prose links), joined one with a link, emitted markdown, and resolved the contact email from moshcode whoami.

🤖 Generated with Claude Code

Point it at any text file with links in it and it walks them one at a
time, remembers which you have dealt with, and keeps the referral link
each one hands back.

  affiliate list --file programs.md
  affiliate next --open
  affiliate join elevenlabs https://try.elevenlabs.io/abc123
  affiliate links --format markdown

Nothing here knows what an affiliate program is. The list is the input:
a bare column of URLs, a markdown table, a bullet list, a CSV. Rather
than asking which format it is, take the first URL on the line and work
the name out from context — the bracketed text of a markdown link, the
first cell of a table row, or the host. A line with no URL is a heading,
not an error.

Details that are deliberate:

- Entries differing only by utm_* are one program. The same page shared
  from a newsletter and from a tweet would otherwise ask you to sign up
  twice.
- A joined entry survives being dropped from the list — it moves to the
  end. Losing a referral link because somebody tidied the source file
  would be the worst thing this could do.
- A referral link already recorded survives a later status change, so
  `skip` typed at the wrong index is not unrecoverable.
- The contact address resolves --email, then $AFFILIATE_EMAIL, then the
  profile file, then `moshcode whoami`. The account is last because it
  is the one you cannot override in the moment.
- `answers` prints gaps as (not set) rather than inventing them. A form
  that asks for audience size and gets an unchecked number is the
  fastest way to lose the account it was meant to open.

It does not fill the forms in. Signing up accepts terms and hands over
payout identity as a named person, and it is behind an email
verification loop regardless — so a filler would stop at the same wall
with one more thing that can break. Opening the next one and keeping the
links in one place is the part that was tedious.

The URL pattern deliberately does not treat ")" as a terminator: doing
so truncates any path containing a bracket. It over-matches and balances
back, which handles both that and a markdown link.

Suite is 253 tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

ThreatCrush Security Scan

6 finding(s)

MEDIUM: 1 | LOW: 5

Severity Rule Location
MEDIUM redos-nested-quantifier src/domain-free.ts:56
LOW insecure-temp-file test/blog.test.ts:73
LOW insecure-temp-file test/blog.test.ts:74
LOW insecure-temp-file test/credentials.test.ts:43
LOW insecure-temp-file test/credentials.test.ts:44
LOW secret-generic-api-key test/credentials.test.ts:208

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit ed39d55 into master Aug 21, 2026
5 checks passed
@ralyodio
ralyodio deleted the worktree-affiliate-cli branch August 21, 2026 14:43
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