Agent skill

Polar Migration

by chmonitor in chmonitor/chmonitor

Guide for migrating to Polar from other payment platforms (Stripe Billing, Paddle, Lemon Squeezy, Gumroad).

GPL-3.0Auto-check passedData & Analytics

Install Polar Migration

skills CLI
$ npx skills add chmonitor/chmonitor --skill polar-migration -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install chmonitor/chmonitor polar-migration --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/chmonitor/chmonitor.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/polar-migration .claude/skills/polar-migration && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
polar-migration
GitHub stars
299
Token cost
~3.8k tokens
SKILL.md length
365 words
Files
1
Skills in repo
53
Repo updated
First seen
Licence
GPL-3.0

At a glance

Guide for migrating to Polar from other payment platforms (Stripe Billing, Paddle, Lemon Squeezy, Gumroad).

  • Works in 4 steps: Set Up Polar → Map Your Products → Map Benefits/Entitlements → …
  • Planning a migration from another payment provider to Polar
  • SKILL.md covers Migration Overview, Pre-Migration Checklist, Migration from Stripe Billing and Migration from Paddle, plus 5 more sections
  • Calls npm; reaches sandbox.polar.sh and vendors.paddle.com; needs POLAR_ACCESS_TOKEN and POLAR_WEBHOOK_SECRET

What it does

Polar Migration is an agent skill from chmonitor/chmonitor. Guide for migrating to Polar from other payment platforms (Stripe Billing, Paddle, Lemon Squeezy, Gumroad). Use this skill when: (1) Planning a migration from another payment provider to Polar; (2) Migrating customer data and subscriptions; (3) Running parallel systems during transition; (4) Mapping products and pricing between platforms; (5) Handling payment method migration; (6) Communicating migration to customers; (7) Testing migration in sandbox before production.

Its SKILL.md is about 3.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Data & Analytics, covering DataFrames. It works with Stripe. The repository describes itself as: Open-source operational advisor for ClickHouse — real-time monitoring plus AI-driven index/partition/materialized-view recommendations. The licence is GPL-3.0.

When your agent uses it

  • Planning a migration from another payment provider to Polar
  • Migrating customer data and subscriptions
  • Running parallel systems during transition
  • Mapping products and pricing between platforms

Example prompts

  • “/polar-migration”

Requirements

  • Node.js
  • A credential in POLAR_ACCESS_TOKEN
  • A credential in POLAR_WEBHOOK_SECRET

Workflow steps

4 steps, taken from the step headings in SKILL.md.

  1. Set Up Polar
  2. Map Your Products
  3. Map Benefits/Entitlements
  4. Set Up Webhooks

What it can do on your machine

Read from SKILL.md and the folder at commit fc39ef0. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • sandbox.polar.sh
    • vendors.paddle.com
    • api.lemonsqueezy.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • POLAR_ACCESS_TOKEN
    • POLAR_WEBHOOK_SECRET
    • STRIPE_SECRET_KEY
    • LEMON_SQUEEZY_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Polar Migration loads about 3.8k tokens when it runs. Until then it costs about 122 tokens; SKILL.md has 365 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~122
When it runs · the whole SKILL.md, loaded when a task matches
~3.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from chmonitor/chmonitor at commit fc39ef0, republished under its GPL-3.0 licence (© chmonitor). 365 words, ~3,823 tokens.

Download SKILL.mdSave it as .claude/skills/polar-migration/SKILL.md (or your agent's skills folder).
name
polar-migration
description
Guide for migrating to Polar from other payment platforms (Stripe Billing, Paddle, Lemon Squeezy, Gumroad). Use this skill when: (1) Planning a migration from another payment provider to Polar; (2) Migrating customer data and subscriptions; (3) Running parallel systems during transition; (4) Mapping products and pricing between platforms; (5) Handling payment method migration; (6) Communicating migration to customers; (7) Testing migration in sandbox before production.

Polar Migration Guide

Migrate to Polar from other payment platforms while minimizing disruption to your customers and revenue.

Migration Overview

What Can Be Migrated
Data TypeMigration Method
Customer emails/namesAPI import
Product catalogManual recreation
Active subscriptionsNew subscription creation
Payment methodsCustomer re-entry required*
Historical ordersNot migrated (keep in old system)
License keysNew keys generated

*Payment method tokens cannot be transferred between processors due to PCI compliance. Customers will need to re-enter payment details.

Migration Strategies

1. Hard Cutover

  • Cancel all subscriptions in old system
  • Create new subscriptions in Polar
  • Best for: Small customer base, simple products

2. Gradual Migration

  • Run both systems in parallel
  • Migrate customers as they renew
  • Best for: Large customer base, minimizing risk

3. New Customers Only

  • Keep existing customers on old system
  • New customers use Polar
  • Best for: Testing Polar before full commitment

Pre-Migration Checklist

1. Set Up Polar
bash
# Test in sandbox first
# https://sandbox.polar.sh

# Install SDK
npm install @polar-sh/sdk
2. Map Your Products

Create equivalent products in Polar:

typescript
import { Polar } from "@polar-sh/sdk";

const polar = new Polar({
  accessToken: process.env.POLAR_ACCESS_TOKEN,
  server: "sandbox", // Test first!
});

// Create products matching your old catalog
const basicPlan = await polar.products.create({
  name: "Basic Plan",
  organizationId: "org_xxx",
  description: "Basic features",
  prices: [
    {
      type: "recurring",
      recurringInterval: "month",
      amountType: "fixed",
      priceAmount: 900, // $9.00
      priceCurrency: "usd",
    },
    {
      type: "recurring",
      recurringInterval: "year",
      amountType: "fixed",
      priceAmount: 9000, // $90.00
      priceCurrency: "usd",
    },
  ],
});
3. Map Benefits/Entitlements
typescript
// Create benefits in Polar
const licenseBenefit = await polar.benefits.create({
  type: "license_keys",
  description: "Software License",
  organizationId: "org_xxx",
  properties: {
    prefix: "PRO",
    activations: { limit: 3 },
  },
});

// Attach the benefit to the product in the Polar dashboard
// (Organization → Products → [product] → Benefits).
4. Set Up Webhooks
typescript
import { validateEvent, WebhookVerificationError } from "@polar-sh/sdk/webhooks";

export async function POST(request: Request): Promise<Response> {
  const body = await request.text();

  let event: ReturnType<typeof validateEvent>;
  try {
    event = validateEvent(
      body,
      {
        "webhook-id": request.headers.get("webhook-id") ?? "",
        "webhook-timestamp": request.headers.get("webhook-timestamp") ?? "",
        "webhook-signature": request.headers.get("webhook-signature") ?? "",
      },
      process.env.POLAR_WEBHOOK_SECRET!,
    );
  } catch (error) {
    if (error instanceof WebhookVerificationError) {
      return Response.json({ received: false }, { status: 403 });
    }
    throw error;
  }

  switch (event.type) {
    case "order.paid":
      // Grant access in your system
      await grantAccess(event.data.customer.externalId, event.data.productId);
      break;

    case "subscription.canceled":
      // Schedule access removal
      await scheduleAccessRemoval(event.data.customer.externalId, event.data.endsAt);
      break;
  }

  return Response.json({ received: true });
}

See the polar-integration skill for the full webhook recipe (event types, framework variations, raw-body requirement, idempotency).

Migration from Stripe Billing

Export Customer Data
typescript
import Stripe from "stripe";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

// Export customers with active subscriptions
async function exportStripeCustomers() {
  const customers: ExportedCustomer[] = [];

  for await (const subscription of stripe.subscriptions.list({ status: "active" })) {
    const customer = await stripe.customers.retrieve(subscription.customer as string);

    if (customer.deleted) continue;

    customers.push({
      stripeCustomerId: customer.id,
      email: customer.email!,
      name: customer.name || undefined,
      subscriptionId: subscription.id,
      productId: subscription.items.data[0].price.product as string,
      priceId: subscription.items.data[0].price.id,
      currentPeriodEnd: new Date(subscription.current_period_end * 1000),
      cancelAtPeriodEnd: subscription.cancel_at_period_end,
    });
  }

  return customers;
}
Create Customers in Polar
typescript
// Map Stripe products to Polar products
const productMap: Record<string, string> = {
  "prod_stripe_basic": "prod_polar_basic",
  "prod_stripe_pro": "prod_polar_pro",
};

async function createPolarCustomers(customers: ExportedCustomer[]) {
  for (const customer of customers) {
    // Create customer in Polar with external ID for linking
    const polarCustomer = await polar.customers.create({
      organizationId: "org_xxx",
      email: customer.email,
      name: customer.name,
      externalId: customer.stripeCustomerId, // Link to Stripe ID
    });

    console.log(`Created Polar customer: ${polarCustomer.id} for ${customer.email}`);
  }
}
Migrate Subscriptions (Gradual)
typescript
async function migrateSubscription(customer: ExportedCustomer) {
  const polarProductId = productMap[customer.productId];

  // Create checkout for customer to enter new payment method
  const checkout = await polar.checkouts.create({
    products: [polarProductId],
    customerEmail: customer.email,
    externalCustomerId: customer.stripeCustomerId,
    successUrl: `https://yoursite.com/migration-complete?customer=${customer.stripeCustomerId}`,
    // Allow discount for migration
    discountId: "migration_discount_xxx",
  });

  // Send migration email to customer
  await sendMigrationEmail(customer.email, {
    checkoutUrl: checkout.url,
    currentPeriodEnd: customer.currentPeriodEnd,
  });

  return checkout;
}
Handle Migration Completion
typescript
// Inside the validateEvent switch in your webhook handler:
case "order.paid": {
  const order = event.data;
  const stripeCustomerId = order.customer.externalId;

  if (stripeCustomerId?.startsWith("cus_")) {
    // Cancel Stripe subscription at period end
    const stripeSubscriptions = await stripe.subscriptions.list({
      customer: stripeCustomerId,
      status: "active",
    });

    for (const sub of stripeSubscriptions.data) {
      await stripe.subscriptions.update(sub.id, {
        cancel_at_period_end: true,
      });
    }

    // Mark customer as migrated in your database
    await db.customer.update({
      where: { stripeId: stripeCustomerId },
      data: {
        migratedToPolar: true,
        polarCustomerId: order.customer.id,
      },
    });
  }
  break;
}

Migration from Paddle

Export Paddle Data
typescript
// Paddle API to export subscribers
async function exportPaddleSubscribers() {
  const response = await fetch("https://vendors.paddle.com/api/2.0/subscription/users", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      vendor_id: process.env.PADDLE_VENDOR_ID,
      vendor_auth_code: process.env.PADDLE_AUTH_CODE,
      state: "active",
    }),
  });

  const data = await response.json();
  return data.response;
}
Map Paddle to Polar
typescript
const paddleToPolar = {
  products: {
    "paddle_12345": "polar_basic",
    "paddle_12346": "polar_pro",
  },
};

async function migratePaddleCustomer(paddleUser: PaddleSubscriber) {
  // Create checkout with Polar
  const checkout = await polar.checkouts.create({
    products: [paddleToPolar.products[paddleUser.plan_id]],
    customerEmail: paddleUser.user_email,
    externalCustomerId: `paddle_${paddleUser.user_id}`,
    successUrl: "https://yoursite.com/migrated",
  });

  return checkout;
}

Migration from Lemon Squeezy

typescript
// Lemon Squeezy API export
async function exportLemonSqueezyCustomers() {
  const response = await fetch("https://api.lemonsqueezy.com/v1/subscriptions", {
    headers: {
      Authorization: `Bearer ${process.env.LEMON_SQUEEZY_API_KEY}`,
    },
  });

  const { data } = await response.json();
  return data.filter((sub: any) => sub.attributes.status === "active");
}

Customer Communication

Migration Email Template
typescript
const migrationEmailTemplate = {
  subject: "Action Required: Update Your Payment Method",
  body: `
Hi {{customer_name}},

We're upgrading our payment system to provide you with a better experience.

**What you need to do:**
Click the link below to update your payment method. This will only take a minute.

[Update Payment Method]({{checkout_url}})

**What's changing:**
- More payment options
- Better invoice management
- Improved customer portal

**What's NOT changing:**
- Your subscription price
- Your features and access
- Your billing date

**Timeline:**
Please complete this by {{deadline}} to ensure uninterrupted service.

Your current subscription will continue until {{current_period_end}}, then
seamlessly transition to our new system.

Questions? Reply to this email.

Thanks,
{{company_name}}
`,
};

async function sendMigrationEmail(email: string, data: MigrationData) {
  // Use your email service (SendGrid, Postmark, etc.)
  await emailService.send({
    to: email,
    subject: migrationEmailTemplate.subject,
    body: renderTemplate(migrationEmailTemplate.body, {
      customer_name: data.name || "there",
      checkout_url: data.checkoutUrl,
      deadline: formatDate(data.deadline),
      current_period_end: formatDate(data.currentPeriodEnd),
      company_name: "Your Company",
    }),
  });
}
Reminder Sequence
typescript
const reminderSchedule = [
  { daysBeforeDeadline: 14, template: "initial" },
  { daysBeforeDeadline: 7, template: "reminder" },
  { daysBeforeDeadline: 3, template: "urgent" },
  { daysBeforeDeadline: 1, template: "final" },
];

async function scheduleReminders(customer: Customer, deadline: Date) {
  for (const reminder of reminderSchedule) {
    const sendAt = subDays(deadline, reminder.daysBeforeDeadline);

    await scheduleEmail({
      to: customer.email,
      template: reminder.template,
      sendAt,
      data: { checkoutUrl: customer.migrationCheckoutUrl },
    });
  }
}
Show full SKILL.md (147 more words)Show less

Parallel Running

Router Pattern
typescript
// Determine which system handles a customer
async function getPaymentSystem(userId: string): Promise<"stripe" | "polar"> {
  const user = await db.user.findUnique({ where: { id: userId } });

  if (user?.polarCustomerId) {
    return "polar";
  }
  return "stripe";
}

// Route subscription checks
async function hasActiveSubscription(userId: string): Promise<boolean> {
  const system = await getPaymentSystem(userId);

  if (system === "polar") {
    const state = await polar.customers.getState({
      customerId: user.polarCustomerId,
    });
    return state.activeSubscriptions.length > 0;
  } else {
    const subscriptions = await stripe.subscriptions.list({
      customer: user.stripeCustomerId,
      status: "active",
    });
    return subscriptions.data.length > 0;
  }
}
Unified Webhook Handler
typescript
// Handle webhooks from both systems during migration
app.post("/webhooks/stripe", stripeWebhookHandler);
app.post("/webhooks/polar", polarWebhookHandler);

// Normalize events to your internal format
interface SubscriptionEvent {
  type: "created" | "canceled" | "renewed";
  customerId: string;
  productId: string;
  source: "stripe" | "polar";
}

function normalizeStripeEvent(event: Stripe.Event): SubscriptionEvent | null {
  // Convert Stripe event to internal format
}

function normalizePolarEvent(event: PolarWebhookEvent): SubscriptionEvent | null {
  // Convert Polar event to internal format
}

Post-Migration Cleanup

Verify Migration
typescript
async function verifyMigration() {
  // Get all customers marked as migrated
  const migratedCustomers = await db.customer.findMany({
    where: { migratedToPolar: true },
  });

  const issues: string[] = [];

  for (const customer of migratedCustomers) {
    // Verify Polar subscription exists
    const polarState = await polar.customers.getState({
      customerId: customer.polarCustomerId,
    });

    if (polarState.activeSubscriptions.length === 0) {
      issues.push(`${customer.email}: No active Polar subscription`);
    }

    // Verify Stripe subscription is canceled
    const stripeSubscriptions = await stripe.subscriptions.list({
      customer: customer.stripeCustomerId,
      status: "active",
    });

    if (stripeSubscriptions.data.length > 0) {
      issues.push(`${customer.email}: Stripe subscription still active`);
    }
  }

  return issues;
}
Cancel Old System
typescript
// After all customers migrated, cancel remaining Stripe subscriptions
async function cancelRemainingStripeSubscriptions() {
  for await (const subscription of stripe.subscriptions.list({ status: "active" })) {
    // Check if customer was migrated
    const customer = await db.customer.findFirst({
      where: { stripeId: subscription.customer as string },
    });

    if (customer?.migratedToPolar) {
      await stripe.subscriptions.cancel(subscription.id);
      console.log(`Canceled Stripe subscription ${subscription.id}`);
    }
  }
}

Migration Checklist

Before Migration
  • Products created in Polar (sandbox)
  • Benefits/entitlements mapped
  • Webhooks configured
  • Email templates ready
  • Customer support informed
  • Rollback plan documented
During Migration
  • Test with small batch first
  • Monitor error rates
  • Track conversion rate
  • Respond to customer issues quickly
  • Send reminder emails on schedule
After Migration
  • Verify all subscriptions migrated
  • Cancel old platform subscriptions
  • Update documentation
  • Remove old platform code
  • Archive old platform data
  • Celebrate! 🎉

Troubleshooting

Customer didn't receive migration email

  • Check spam folder
  • Verify email address in export
  • Resend with different subject line

Customer completed checkout but Stripe not canceled

  • Check webhook logs
  • Verify external_id mapping
  • Manually cancel if needed

Double billing

  • Refund on old platform
  • Apologize to customer
  • Improve timing logic

Customer wants to stay on old platform

  • Respect their choice (if possible)
  • Offer incentive to migrate
  • Set final deadline

© chmonitor, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/polar-migration of chmonitor/chmonitor.

Open the folder on GitHubat commit fc39ef0

Compare with similar skills

Polar Migration next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Polar Migration compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Polar Migration this skillchmonitor/chmonitor299—~3.8kAutomated safety check: PassGPL-3.0
Verifier Webpolarsource/polar10k—~3kAutomated safety check: NotesMIT
Polar Billingfcakyon/claude-codex-settings1.2k—~5.9kAutomated safety check: PassApache-2.0
Chdb Datastorevemetric/vemetric3942 repos~1.4kAutomated safety check: PassApache-2.0
Polar Python SDKpolarsource/polar10k—~1.8kAutomated safety check: PassApache-2.0
Polar Typescript SDKpolarsource/polar10k—~2kAutomated safety check: PassApache-2.0

Similar skills

  • Verifier Web

    polarsource/polar

    Evidence-capture protocol for verifying web/dashboard/backoffice/checkout changes in the Polar local stack by driving the real UI with Playwright.

    10k GitHub stars~3k tokensUpdated today
    Data & AnalyticsAuto-check: notes
  • Polar Billing

    fcakyon/claude-codex-settings

    This skill should be used when working on Polar billing system, Stripe integration, subscription lifecycle, checkout flows, or benefit provisioning.

    1.2k GitHub stars~5.9k tokensUpdated yesterday
    Data & AnalyticsAuto-check passed
  • Chdb Datastore

    vemetric/vemetric

    A skill your agent uses when the user has tabular data (pandas DataFrame, parquet, csv, Arrow, json) and wants to filter, group, aggregate, join, or speed up slow pandas.

    394 GitHub starsUsed in 2 repos~1.4k tokens
    Data & AnalyticsAuto-check passed
  • Polar Python SDK

    polarsource/polar

    Integrate Polar billing in server-side Python applications using the versioned Polar and PolarAsync clients.

    10k GitHub stars~1.8k tokensUpdated today
    Data & AnalyticsAuto-check passed
  • Polar Typescript SDK

    polarsource/polar

    Integrate Polar billing in server-side TypeScript applications using the versioned createPolar and createPolarCore clients.

    10k GitHub stars~2k tokensUpdated today
    Data & AnalyticsAuto-check passed
  • CSV Data Summarizer

    coffeefuelbump/csv-data-summarizer-claude-skill

    Analyzes CSV files, generates summary stats, and plots quick visualizations using Python and pandas.

    468 GitHub starsUsed in 2 repos~1.4k tokens
    Data & AnalyticsAuto-check passed

More from chmonitor/chmonitor

All 53 skills in this repo
  • Hyperframes Creative

    chmonitor/chmonitor

    Non-animation creative direction for HyperFrames videos. An agent skill from chmonitor/chmonitor.

    299 GitHub starsUsed in 5 repos~1.3k tokens
    Auto-check passed
  • Hyperframes Media

    chmonitor/chmonitor

    Audio and media assets for HyperFrames compositions, produced by one shared audio engine (scripts/audio.mjs) — multi-provider TTS (HeyGen / ElevenLabs / Kokoro local), background music + sound…

    299 GitHub starsUsed in 1 repo~2.8k tokens
    Auto-check: notes
  • Remotion To Hyperframes

    chmonitor/chmonitor

    Port an existing Remotion (React) composition to HyperFrames HTML.

    299 GitHub starsUsed in 1 repo~2.5k tokens
    Auto-check passed
  • Music To Video

    chmonitor/chmonitor

    A skill your agent uses when the user has a music track (an audio file, or a video to pull audio from) and wants a beat-synced HyperFrames video, calm to hard-hitting.

    299 GitHub starsUsed in 1 repo~4k tokens
    Auto-check: notes
  • Hyperframes Animation

    chmonitor/chmonitor

    All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus…

    299 GitHub starsUsed in 2 repos~1.8k tokens
    Auto-check passed
  • Faceless Explainer

    chmonitor/chmonitor

    turn arbitrary text — an article, notes, a topic, a brief — into a faceless explainer video, up to ~3 min (sweet spot 30-90s), where every visual is invented (typography, abstract graphics…

    299 GitHub stars~4.5k tokensUpdated 2 days ago
    Auto-check: notes

Works with

Questions about Polar Migration

What does Polar Migration do?

Guide for migrating to Polar from other payment platforms (Stripe Billing, Paddle, Lemon Squeezy, Gumroad). Polar Migration is an agent skill from chmonitor/chmonitor. Guide for migrating to Polar from other payment platforms (Stripe Billing, Paddle, Lemon Squeezy, Gumroad).

When should I use Polar Migration?

Polar Migration fits situations like: planning a migration from another payment provider to Polar; migrating customer data and subscriptions; running parallel systems during transition; mapping products and pricing between platforms.

How do I install Polar Migration in Claude Code?

Run `npx skills add chmonitor/chmonitor --skill polar-migration -a claude-code`. Or copy the skill folder (.agents/skills/polar-migration in chmonitor/chmonitor) into .claude/skills/polar-migration in your project. Claude Code loads it when a task matches its description.

How do I install Polar Migration in Codex?

Run `npx skills add chmonitor/chmonitor --skill polar-migration -a codex`. Or copy the skill folder (.agents/skills/polar-migration in chmonitor/chmonitor) into .agents/skills/polar-migration in your project. Codex loads it when a task matches its description.

Can I use Polar Migration in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add chmonitor/chmonitor --skill polar-migration -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/polar-migration, .gemini/skills/polar-migration, .github/skills/polar-migration and .opencode/skills/polar-migration in your project.

What does Polar Migration need to run?

Going by SKILL.md and its folder, Polar Migration needs the command-line tools its instructions call (npm) and credentials named POLAR_ACCESS_TOKEN, POLAR_WEBHOOK_SECRET, STRIPE_SECRET_KEY and LEMON_SQUEEZY_API_KEY. Our summary lists: Node.js; A credential in POLAR_ACCESS_TOKEN; A credential in POLAR_WEBHOOK_SECRET.

Does Polar Migration access the network?

SKILL.md names 3 domains. In commands or code: sandbox.polar.sh, vendors.paddle.com and api.lemonsqueezy.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.

Is Polar Migration safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Polar Migration use?

Polar Migration is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Polar Migration use?

About 3.8k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Polar Migration?

Skills that share tags, products or a category with Polar Migration: Verifier Web (polarsource/polar, 10k stars), Polar Billing (fcakyon/claude-codex-settings, 1.2k stars), Chdb Datastore (vemetric/vemetric, 394 stars) and Polar Python SDK (polarsource/polar, 10k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Polar Migration?

chmonitor (a GitHub organization) maintains it in chmonitor/chmonitor, which has 299 GitHub stars. The repository holds 53 skills in this directory. The repository was last updated on October 5, 2026.

Source: chmonitor/chmonitor on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.