Skip to main content

Installer and license manager for the marketr-* family of Claude Code skills

Project description

marketr-installer

Installer and license manager for the marketr-* family of Claude Code skills.

What's in this pack → INDEX.md · Skills · Agents · Workflows · Scripts

What this does

marketr-installer is the bridge between a customer's purchased licenses and a working installation of marketr skills in their Claude Code environment. It:

  1. Reads per-purchase license files from ~/.marketr/licenses/
  2. Computes the merged entitlement (union by SKU)
  3. Installs each owned SKU as a Python package via pip
  4. Copies each SKU's SKILL.md + references into ~/.claude/skills/marketr/<sku>/ so Claude Code discovers them

It is also the home of the marketr CLI (install, update, add-license, status, setup, auth, init, doctor).

marketr update enforces the per-license updates_until field, and marketr status shows days-until-expiry per SKU. Lapsed-window SKUs skip the wheel fetch with a friendly renewal nudge; the installed version keeps working. See docs/plans/2026-05-10-perpetual-license-launch.md §6.1 to §6.3 for the full runtime contract, the 7-day signed-URL footgun, and the manual renewal flow.

Status

Alpha. Phase 1 of the marketplace launch plan (docs/plans/2026-05-09-marketplace-launch.md). R2 URL signing wired 2026-05-09 (see "Operator setup — R2 signing" below).

Operator setup — R2 signing

mkt-admin license issue --method wheel signs R2 URLs at issuance time so the customer's marketr install can pip install the wheel directly. Only the operator needs R2 credentials — the signed URL embedded in the license YAML is self-authenticating until expiry.

One-time install

pip install 'marketr-installer[r2]'   # adds boto3

Required environment variables

Set these in your shell rc (~/.zshrc / ~/.bash_profile) so mkt-admin can read them. They never end up in git, license YAMLs, or customer artifacts.

Var Example Where to find it
MARKETR_R2_ACCOUNT_ID 2f6b6043df01b12524c5752df11ffb22 Cloudflare Dashboard → R2 → bucket details (or the hex prefix in the bucket URL)
MARKETR_R2_BUCKET skillsformarketing The bucket name
MARKETR_R2_ENDPOINT https://2f6b6043df01b12524c5752df11ffb22.r2.cloudflarestorage.com The S3 API endpoint URL without the bucket suffix
MARKETR_R2_ACCESS_KEY (redacted) Cloudflare Dashboard → R2 → Manage API Tokens → create with "Object Read & Write" scoped to the bucket
MARKETR_R2_SECRET_KEY (redacted) Same step as above. Cloudflare shows the secret once at creation — save to a password manager immediately.

How it behaves

Scenario Result
All 5 env vars set, URL bucket matches MARKETR_R2_BUCKET URL signed with X-Amz-Signature=… query string, valid 7 days (AWS Sig v4 max)
Any env var missing/empty Unsigned URL emitted + WARNING printed to stderr. License YAML is still issuable for dev/testing; install will fail at the actual download step.
URL bucket prefix doesn't match MARKETR_R2_BUCKET R2SigningError — operator misconfigured something. Update skus.yaml URL templates or the env var.

Customer perspective

Customers don't install [r2] and don't set any env vars. Their license YAML contains a pre-signed URL; marketr install runs pip install <url> and that's it.

URL expiry

Signed URLs are valid for 7 days (the AWS Sig v4 maximum for static credentials). If a customer takes longer than 7 days to install after receiving a license, run mkt-admin license issue again for the same SKU and re-email the YAML.

Customer install (eventually)

curl -L https://marketr.<tld>/install | sh

This script will install marketr-installer (currently from a private wheel URL or git+ssh) and run marketr setup to drop the Claude Code skill into ~/.claude/skills/marketr/.

To opt into voice/sound feedback during install:

curl -L https://marketr.<tld>/install | MARKETR_WITH_VOICE=1 sh

To skip the third-party bundles entirely (minimal install):

curl -L https://marketr.<tld>/install | MARKETR_SKIP_BUNDLES=1 sh

License redemption

After a paid purchase, the operator (or, eventually, the marketr-store backend) issues a signed license YAML and uploads it to R2 under marketr/_redeem/<token>/license.yaml. The customer receives a presigned GET URL (AWS Sig v4, 7-day max TTL) by email and redeems it with one command:

marketr install --redeem 'https://<account>.r2.cloudflarestorage.com/marketr/_redeem/<token>/license.yaml?X-Amz-Signature=...'

This:

  1. Downloads the YAML over HTTPS (30s timeout, identifies as User-Agent: marketr-installer/<version> so we're greppable in R2 access logs).
  2. Verifies the embedded Ed25519 signature locally against the bundled public keys (dev + prod). The URL alone is NOT trusted — a compromised email or a typo'd URL must not be able to plant arbitrary YAML on the customer's machine.
  3. Writes the file atomically to ~/.marketr/licenses/<license_id>.yaml.
  4. Continues with the normal install (same code path as bare marketr install).

If anything fails (HTTP error, expired URL, bad signature, a license with the same license_id is already redeemed) the command exits with status 1 and does not run any pip install — redemption is all-or-nothing.

The 7-day TTL is the operator's policy; if a customer's URL has expired, the operator re-issues a fresh one (mkt-admin license issue or, eventually, the store-backend re-signs). The redeem flow does NOT extend or refresh URLs on its own.

Security model in one paragraph

The presigned URL is just a delivery mechanism — the trust anchor is the Ed25519 signature inside the YAML, verified against public keys shipped in the wheel under marketr_installer/_keys/. As long as the operator's private key stays vaulted (~/.marketr/signing/ by convention), any tampering anywhere along the email/network path fails the signature check at redeem time, so the customer cannot end up with an unauthorized license.

What marketr setup installs

Component Source Lands at Default
marketr CLI + installer skill this package ~/.claude/skills/marketr-installer/ + pip user bin always
~/.marketr/ scaffold this package ~/.marketr/{licenses,credentials,vendor,templates}/ always
Best-practice agents/commands/rules/skills shanraisshan/claude-code-best-practice ~/.claude/{agents,commands,rules,skills}/best-practice/ on, --skip-bundles to opt out
Best-practice CLAUDE.md template same ~/.marketr/templates/best-practice-CLAUDE.md (staged, never auto-applied) on
Voice/sound hooks shanraisshan/claude-code-hooks ~/.claude/hooks/marketr-voice/ off, --with-voice to enable

Bundles are namespaced under best-practice/ and marketr-voice/ subdirs so we never collide with files the user has already authored.

Voice feedback (opt-in)

marketr voice enable    # fetch + install hooks, merge bindings into ~/.claude/settings.json
marketr voice status    # show enabled/disabled + binding count
marketr voice disable   # remove bindings (keeps files cached, fast re-enable)

Bindings are tagged marketr-voice:<HookEvent> so disable removes only our entries — your other hooks stay intact.

Activation (online seat enforcement)

A license can grant N concurrent machine activations. The mechanism:

  1. The license YAML carries a seats: N field (default 1; bundles like agency_multi_client ship seats: 5).
  2. On marketr install, the CLI POSTs {license_id, fingerprint} to ${MARKETR_ACTIVATION_URL}/activate. The server records the activation if the cap allows, refuses with HTTP 409 if full.
  3. Successful activations are cached at ~/.marketr/activation_<license_id>.json for 30 days by default, so subsequent installs on the SAME machine don't re-call. The cache stores ONLY the activation token + seat metadata — never license content. Operators who want a tighter window (e.g. faster seat-revocation propagation) set MARKETR_ACTIVATION_CACHE_DAYS=<N> where N is an integer in [1, 90]. Out-of-range values raise a clear error at ActivationClient() construction time — a typo in a deployment env file fails loud at startup instead of silently leaking seats.
  4. The machine fingerprint is the install_id already used for telemetry (~/.marketr/telemetry/.install-id). No new per-machine identifier is introduced; if you opted out of telemetry, the activation flow still uses this anonymous random id but doesn't send any telemetry events.

Backwards-compat

If MARKETR_ACTIVATION_URL is unset, activation is skipped and marketr install prints a stderr note: "activation skipped (MARKETR_ACTIVATION_URL not set)". Customer flows keep working until the operator deploys the activation server. Once deployed, the env var flips enforcement on with no client-side code change.

Customer commands

# Start using the license on this machine — happens automatically
# inside `marketr install`, no manual activation step required.
marketr install

# Free up a seat (e.g. retiring an old laptop):
marketr deactivate MKT-AGCY-MULT-CLNT
# Or release a different machine's seat (you'll need its fingerprint;
# the cap-exceeded message lists the active ones):
marketr deactivate MKT-AGCY-MULT-CLNT --fingerprint <fp>

# Inspect current usage:
marketr seats MKT-AGCY-MULT-CLNT

Cap-exceeded message

When the seat cap is full and you try to activate a new machine, marketr install exits with:

Seat limit reached for MKT-AGCY-MULT-CLNT: 5/5 in use.
Deactivate one of: <fp_a, fp_b, fp_c, fp_d, fp_e> via
`marketr deactivate MKT-AGCY-MULT-CLNT --fingerprint <fp>`, or
contact sales for a higher-seat license.

Cache, rotation, and growth

The customer-side cache is a single small JSON file per license. The server-side log is one <DATA_DIR>/activations/<license_id>.jsonl per license that grows by one line per (re)activation or deactivation. At v1 scale (a handful of machines per license over a multi-year window) growth is negligible. Operators who want hard caps on file size can run marketr_store.activation._compact_inplace on a daily cron — it rewrites each file with only the live records.

Vendored bundles

Third-party content is fetched into ~/.marketr/vendor/<bundle-name>/ at frozen SHAs (see marketr_installer/bundle_fetcher.py for current pins). We don't ship the 100MB+ payload in the wheel — it's pulled at marketr setup time. Bumping a pin in code requires customers to re-run marketr setup to pick up the change.

Local development

cd marketr-installer
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest

Layout

marketr-installer/
├── pyproject.toml
├── marketr_installer/        # the Python package
│   ├── cli.py                # `marketr` CLI
│   ├── admin.py              # `mkt-admin` operator CLI
│   ├── schema.py             # Pydantic models for license YAML
│   ├── license_loader.py     # reads + merges ~/.marketr/licenses/
│   ├── pip_runner.py         # subprocess wrapper for pip
│   ├── skill_copier.py       # copies SKILL.md from installed packages
│   ├── bundle_fetcher.py     # clones third-party bundles to ~/.marketr/vendor/
│   └── bundle_installer.py   # deploys bundles into ~/.claude/ (namespaced)
├── skill/
│   └── SKILL.md              # the Claude Code skill that delegates to `marketr`
├── scripts/
│   ├── install.sh            # the curl|sh one-liner
│   └── skus.yaml             # SKU registry (operator-side)
└── tests/
    ├── conftest.py
    ├── fixtures/licenses/    # sample license YAMLs for tests
    └── test_*.py

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

marketr_installer-0.1.11.tar.gz (412.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

marketr_installer-0.1.11-py3-none-any.whl (428.9 kB view details)

Uploaded Python 3

File details

Details for the file marketr_installer-0.1.11.tar.gz.

File metadata

  • Download URL: marketr_installer-0.1.11.tar.gz
  • Upload date:
  • Size: 412.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for marketr_installer-0.1.11.tar.gz
Algorithm Hash digest
SHA256 a5af60aa0ce5607198ac0a92a11dd8e75224e5ba6b8b814b71aeac4aff237115
MD5 19afd81ebe7891267c02f2507f22d1fc
BLAKE2b-256 b6fa5f08e9b33e94a2f742e4caaecad6f594bdf88d8e6292d9ed8b61f9bffb88

See more details on using hashes here.

Provenance

The following attestation bundles were made for marketr_installer-0.1.11.tar.gz:

Publisher: publish-installer.yml on don-devo/skillsformarketing

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file marketr_installer-0.1.11-py3-none-any.whl.

File metadata

File hashes

Hashes for marketr_installer-0.1.11-py3-none-any.whl
Algorithm Hash digest
SHA256 ca93a28ecd2e54b5e75db0e235bd3fff50c2679c17ade695fb586b0f2062ed49
MD5 7bb6bd842a1483fea8cdd6db4c2c92a4
BLAKE2b-256 3ece197be57bafed4dba9e57a2aff19345332dcc312d2bc79c679ca70b7d0125

See more details on using hashes here.

Provenance

The following attestation bundles were made for marketr_installer-0.1.11-py3-none-any.whl:

Publisher: publish-installer.yml on don-devo/skillsformarketing

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page