
Customer Lifetime Value
- 68 installs
- 41 repo stars
- Updated March 13, 2026
- finsilabs/awesome-ecommerce-skills
Calculate historical and predicted customer lifetime value and churn risk, then trigger retention automation for high-value segments.
About
Guides measuring historical and predictive CLV across Shopify, WooCommerce, BigCommerce, or a custom store, and scoring churn to drive win-back flows. A developer uses it when setting CAC targets, building VIP tiers, or predicting which customers will churn.
- Platform table for historical vs predictive CLV tooling (Klaviyo, Metorik, Triple Whale)
- Custom parametric CLV, churn-probability code, and BG/NBD lifetimes model for 100k+ customers
Customer Lifetime Value by the numbers
- 68 all-time installs (skills.sh)
- Ranked #879 of 2,064 Data Science & ML skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill customer-lifetime-valueAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 68 |
|---|---|
| repo stars | ★ 41 |
| Last updated | March 13, 2026 |
| Repository | finsilabs/awesome-ecommerce-skills ↗ |
What it does
Calculate historical and predicted customer lifetime value and churn risk, then trigger retention automation for high-value segments.
Files
Customer Lifetime Value
Overview
Customer Lifetime Value (CLV) tells you the total net revenue expected from a customer over their relationship with your store, enabling smarter decisions on acquisition spend, retention investment, and customer tier management. Most platforms calculate historical CLV (total spent to date) natively. For predictive CLV and churn risk scoring, use a dedicated analytics app (Klaviyo, Metorik, Triple Whale) or build a custom model for stores with 10k+ customers.
When to Use This Skill
- When setting CAC targets for acquisition channels based on expected return
- When building a VIP tier program that needs a quantitative threshold
- When predicting which customers are likely to churn and triggering win-back automation
- When calculating the ROI of retention programs (loyalty points, VIP benefits)
- When segmenting customers by predicted future value rather than historical spend alone
Core Instructions
Step 1: Determine platform and choose the right CLV tool
| Platform | Historical CLV | Predictive CLV |
|---|---|---|
| Shopify | Built-in: Admin → Analytics → Customers (shows lifetime spend) | Triple Whale, Lifetimely, or Klaviyo for predictive scoring |
| WooCommerce | Metorik or WooCommerce Analytics → Customers report | Metorik Pro for churn prediction; Klaviyo integration for CLV-based flows |
| BigCommerce | Built-in customer analytics; Google Analytics 4 for cohort analysis | Klaviyo or Metorik for predictive CLV |
| Custom / Headless | Build SQL queries against your order database | Build a parametric or BG/NBD model against your historical data |
---
Step 2: Access and track historical CLV
Historical CLV is the sum of all revenue from a customer. Platforms show this natively.
Shopify
1. Go to Admin → Analytics → Reports → Customers over time — shows total customers, orders, and revenue by cohort 2. Go to Admin → Customers → [Customer] — each customer profile shows total spent, order count, and last order date 3. For bulk export: go to Customers → Export — the CSV includes Total Spent and Number of Orders per customer
More advanced CLV reporting:
- Install Lifetimely from the App Store — provides cohort-based LTV curves, payback period by acquisition channel, and predicted future spend
- Install Triple Whale — includes CLV by acquisition source, cohort analysis, and attribution modeling
WooCommerce
1. Go to WooCommerce → Analytics → Customers — shows lifetime value, order count, and average order value per customer 2. Sort by Lifetime value descending to see your top customers 3. Filter by date range to see CLV for specific acquisition cohorts
Metorik for deeper analytics:
- Install Metorik (connects via WooCommerce REST API)
- Metorik's customer dashboard shows CLV distributions, cohort retention, and automatically flags at-risk customers
- Metorik Pro adds churn probability scoring and automated win-back email triggers
BigCommerce
1. Go to Analytics → Customers for a summary of customer spending 2. Individual customer profiles show total orders and lifetime spend 3. For cohort analysis: connect Google Analytics 4 and use the User Lifetime reports
---
Step 3: Set up CLV-based customer segments
Once you can measure CLV, create segments to target different value tiers with different messaging.
Shopify + Klaviyo
1. In Klaviyo, go to Lists & Segments → Create Segment 2. Create a "VIP Customers" segment: Customer → Predicted CLV is greater than $500 (Klaviyo calculates predicted CLV automatically for Shopify stores) 3. Create an "At Risk - High Value" segment: Customer → Predicted CLV > $200 AND Last order date is more than 90 days ago 4. Use these segments as audiences for targeted email flows
Klaviyo's predictive analytics (available on paid plans):
- Klaviyo shows Predicted CLV, Churn Risk, and Predicted Next Order Date per profile
- Find these under Analytics → Predictive Analytics or on individual customer profiles
- Use these predictions as segment filters without any custom code
WooCommerce + Klaviyo
1. Install Klaviyo for WooCommerce from WordPress.org 2. Klaviyo syncs customer purchase history automatically 3. Create the same CLV-based segments as described above
---
Step 4: Automate retention based on CLV and churn risk
Once segments are defined, create automated flows for each tier.
Win-back flow for high-value at-risk customers:
Klaviyo (all platforms): 1. Go to Flows → Create Flow → Win-Back 2. Set trigger: customer enters the "At Risk - High Value" segment 3. Configure the sequence:
- Day 0: personalized email — "We miss you" with product recommendations based on purchase history
- Day 7: email with a small incentive (free shipping or 10% off)
- Day 14: final email from the "founder" or customer success team
4. Stop the flow if the customer makes a purchase (add a flow filter: "Ordered zero times since starting this flow")
VIP tier recognition: 1. Create a VIP segment (CLV > $500 or 5+ orders) 2. When a customer enters the segment, send a personalized "You're now a VIP" email with exclusive benefits 3. On Shopify: tag the customer with vip automatically using Shopify Flow (Plus) or a tagging app; use the tag to show VIP-specific content on the storefront
---
Custom / Headless
For stores building their own CLV calculations:
// lib/clv.ts
// Simple parametric CLV prediction — practical for most stores
export function calculatePredictedCLV(inputs: {
avgOrderValue: number;
avgOrderFrequencyPerYear: number;
avgCustomerLifespanYears: number;
grossMarginRate: number;
}): number {
const { avgOrderValue, avgOrderFrequencyPerYear, avgCustomerLifespanYears, grossMarginRate } = inputs;
return avgOrderValue * avgOrderFrequencyPerYear * avgCustomerLifespanYears * grossMarginRate;
}
// Per-customer prediction from their actual order history
export async function predictCustomerCLV(customerId: string, projectionYears = 2): Promise<number> {
const orders = await db.orders.findMany({
where: { customerId, status: { notIn: ['cancelled', 'refunded'] } },
orderBy: { createdAt: 'asc' },
});
if (orders.length < 2) return 0; // Not enough history
const dates = orders.map(o => o.createdAt.getTime());
const tenureDays = (dates[dates.length - 1] - dates[0]) / 86400000;
const avgIntervalDays = tenureDays / (orders.length - 1);
const purchasesPerYear = 365 / avgIntervalDays;
const aov = orders.reduce((sum, o) => sum + o.subtotalCents / 100, 0) / orders.length;
// Reduce projection for customers who haven't ordered recently
const daysSinceLast = (Date.now() - dates[dates.length - 1]) / 86400000;
const effectiveYears = daysSinceLast < 90 ? projectionYears : projectionYears * 0.5;
return aov * purchasesPerYear * effectiveYears * 0.50; // 50% gross margin
}
// Churn probability based on recency vs. typical purchase cadence
export async function calculateChurnProbability(customerId: string): Promise<number> {
const orders = await db.orders.findMany({
where: { customerId, status: { notIn: ['cancelled', 'refunded'] } },
orderBy: { createdAt: 'desc' },
});
if (orders.length === 0) return 0.95;
if (orders.length === 1) return 0.65;
const daysSinceLast = (Date.now() - orders[0].createdAt.getTime()) / 86400000;
const avgInterval = orders.slice(0, -1).reduce((sum, o, i) =>
sum + (o.createdAt.getTime() - orders[i + 1].createdAt.getTime()) / 86400000, 0) / (orders.length - 1);
// Sigmoid: churn probability rises as recency exceeds 2× typical interval
const recencyRatio = daysSinceLast / avgInterval;
return Math.min(0.99, Math.max(0.01, 1 / (1 + Math.exp(-2 * (recencyRatio - 2)))));
}
// Nightly job: update CLV scores and trigger win-back automation
export async function runChurnPreventionNightly() {
const activeCustomers = await db.customers.findMany({ where: { orderCount: { gte: 2 } } });
for (const customer of activeCustomers) {
const [churnProbability, predictedCLV] = await Promise.all([
calculateChurnProbability(customer.id),
predictCustomerCLV(customer.id),
]);
await db.customers.update({ where: { id: customer.id }, data: { churnProbability, predictedCLV } });
// High-value, high-churn-risk: trigger win-back
if (churnProbability > 0.70 && predictedCLV > 200) {
const alreadyTriggered = await db.winBackTriggers.findFirst({
where: { customerId: customer.id, createdAt: { gte: new Date(Date.now() - 90 * 86400000) } },
});
if (!alreadyTriggered) {
await klaviyo.triggerFlow(customer.email, 'win-back-high-value');
await db.winBackTriggers.create({ data: { customerId: customer.id } });
}
}
}
}For stores with 100k+ customers: Use the BG/NBD probabilistic model (Python lifetimes library) for significantly more accurate predictions than the parametric approach:
from lifetimes import BetaGeoFitter, GammaGammaFitter
from lifetimes.utils import summary_data_from_transaction_data
# Build RFM summary and fit BG/NBD model
rfm = summary_data_from_transaction_data(orders_df, 'customer_id', 'created_at', 'subtotal_cents')
bgf = BetaGeoFitter(penalizer_coef=0.001)
bgf.fit(rfm['frequency'], rfm['recency'], rfm['T'])
ggf = GammaGammaFitter(penalizer_coef=0.001)
ggf.fit(rfm[rfm['frequency'] > 0]['frequency'], rfm[rfm['frequency'] > 0]['monetary_value'])
rfm['predicted_clv_12mo'] = ggf.customer_lifetime_value(bgf, rfm['frequency'], rfm['recency'], rfm['T'], rfm['monetary_value'], time=12, discount_rate=0.01)Best Practices
- Use Klaviyo's predictive CLV for Shopify/WooCommerce before building anything custom — their model is well-calibrated and works out of the box
- Refresh CLV scores weekly at minimum — customer behavior changes; stale scores lead to mistargeted retention campaigns
- Separate predicted CLV from historical spend in your segments — they answer different questions: historical shows past value, predicted shows where to invest
- Set CAC ceilings per acquisition channel based on CLV — if average CLV from Google Ads customers is $80 at 50% margin, your maximum sustainable CAC is $40
- Calibrate churn probability against actual outcomes — compare predictions from 6 months ago to who actually churned; adjust thresholds if the model is over- or under-predicting
Common Pitfalls
| Problem | Solution |
|---|---|
| CLV model inflated by a few very large orders | Use median order value rather than mean AOV for parametric models; single outlier orders skew the mean significantly |
| Win-back emails trigger for customers who took a vacation | Set a minimum "days since last purchase" threshold of 60+ days before triggering win-back; short gaps are normal, not churn signals |
| CLV calculation includes cancelled orders | Always filter status NOT IN ('cancelled', 'refunded') — cancelled orders overstate revenue |
| Predicted CLV lower than historical for loyal customers | In BG/NBD, verify that the tenure variable (T) is measured from first purchase, not account creation date |
Related Skills
- @customer-segmentation
- @referral-program
- @personalization-engine
{
"context": "Tests whether the agent uses the lifetimes Python library with BetaGeoFitter and GammaGammaFitter, applies the correct utility function for RFM preparation, filters out zero-frequency customers for the monetary model, uses penalizer_coef=0.001, and applies the correct discount rate and time horizon.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Uses lifetimes library",
"max_score": 8,
"description": "clv_model.py imports from the lifetimes package (not a different CLV library like pymc-marketing or lifetimes2)"
},
{
"name": "BetaGeoFitter used",
"max_score": 8,
"description": "clv_model.py instantiates and fits a BetaGeoFitter model (from lifetimes)"
},
{
"name": "GammaGammaFitter used",
"max_score": 8,
"description": "clv_model.py instantiates and fits a GammaGammaFitter model (from lifetimes)"
},
{
"name": "summary_data_from_transaction_data",
"max_score": 10,
"description": "clv_model.py uses summary_data_from_transaction_data (from lifetimes.utils) to build the RFM summary, rather than computing recency/frequency/T manually"
},
{
"name": "GGF zero-frequency filter",
"max_score": 10,
"description": "GammaGammaFitter is fitted only on customers where frequency > 0 (i.e., the rfm dataframe is filtered before fitting GGF)"
},
{
"name": "penalizer_coef=0.001",
"max_score": 10,
"description": "Both BetaGeoFitter and GammaGammaFitter are initialized with penalizer_coef=0.001"
},
{
"name": "12-month prediction window",
"max_score": 8,
"description": "ggf.customer_lifetime_value is called with time=12 (months)"
},
{
"name": "Monthly discount rate 0.01",
"max_score": 8,
"description": "ggf.customer_lifetime_value is called with discount_rate=0.01"
},
{
"name": "Cancelled orders excluded",
"max_score": 8,
"description": "Transaction data is filtered to exclude non-completed orders before being passed to the model (e.g., only status='completed' rows are used)"
},
{
"name": "Notes explain GGF filter",
"max_score": 8,
"description": "model-notes.md explains why customers with zero repeat purchases (frequency=0) are excluded from GammaGammaFitter fitting"
},
{
"name": "Notes state penalizer and discount",
"max_score": 14,
"description": "model-notes.md states the penalizer_coef value (0.001) AND the monthly discount rate used (0.01)"
}
]
}
Probabilistic Customer Lifetime Value Prediction
Problem/Feature Description
FreshCart, an online grocery platform with over 80,000 repeat customers, wants to move beyond rule-based customer segmentation and adopt a statistically rigorous approach to predicting which customers are most valuable over the next year. Their head of analytics has heard about probabilistic models that account for both purchase frequency and order value separately, and wants to evaluate one for use in their annual customer value report.
The data team has an export of completed orders from the last 3 years. They want a Python script that ingests this transaction data, fits a probabilistic model, and outputs a 12-month predicted CLV for each customer — ready to be imported back into their data warehouse. The script should be production-quality: documented, reproducible, and designed to be rerun monthly without overfitting on any particular data slice.
Output Specification
Produce a Python script clv_model.py that:
1. Loads transaction data from the provided CSV file (see Input Files below) 2. Prepares the RFM (recency, frequency, monetary) summary needed for model fitting 3. Fits the appropriate probabilistic models for purchase frequency and monetary value 4. Generates 12-month CLV predictions for all customers 5. Saves predictions to clv_predictions.csv with columns: customer_id, predicted_clv_12mo
Also produce a model-notes.md file that explains:
- Which Python library and model classes are used
- The regularization approach and the coefficient value chosen
- Why customers with zero repeat purchases are handled separately in one of the model fitting steps
- The discount rate assumption used for the time-value calculation
Input Files
The following files are provided as inputs. Extract them before beginning.
=============== FILE: inputs/orders.csv =============== customer_id,created_at,subtotal_cents,status C001,2022-01-15,4500,completed C001,2022-04-20,5200,completed C001,2022-09-10,4800,completed C001,2023-02-14,5100,completed C001,2023-08-22,4900,completed C002,2022-03-01,12000,completed C002,2022-06-15,9800,completed C002,2023-01-10,11500,completed C002,2023-07-20,10200,completed C002,2024-02-08,11000,completed C003,2022-05-20,3200,completed C003,2023-11-30,2900,completed C004,2022-02-10,6700,completed C004,2022-05-18,7200,completed C004,2022-11-25,6900,completed C004,2023-04-12,7100,completed C004,2023-10-08,6800,completed C004,2024-03-15,7300,completed C005,2022-07-01,2100,completed C005,2022-10-15,1950,completed C005,2023-03-22,2200,completed C006,2022-08-10,15000,completed C006,2023-02-28,14500,completed C006,2023-09-14,16000,completed C006,2024-01-20,15500,completed C007,2022-04-05,890,completed C007,2023-12-01,920,completed C008,2022-06-20,5500,completed C008,2022-09-30,5800,completed C008,2023-01-15,5300,completed C008,2023-06-10,5600,completed C008,2023-12-05,5400,completed C008,2024-04-01,5700,completed C009,2022-11-01,3400,completed C010,2022-03-15,8900,completed C010,2022-07-22,9200,completed C010,2023-01-08,8700,completed C010,2023-08-14,9100,completed C010,2024-02-20,8800,completed
{
"context": "Tests whether the agent implements the parametric CLV prediction formula correctly, applies the recency-based lifespan adjustment, uses the correct churn probability sigmoid, handles edge cases for customers with 0 or 1 orders, and applies the 50% gross margin assumption.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Parametric CLV formula",
"max_score": 12,
"description": "calculatePredictedCLV uses the formula: (AOV × purchaseFrequency × grossMarginRate) / (1 + discountRate - repeatPurchaseRate), where repeatPurchaseRate = 1 - 1/avgCustomerLifespanYears"
},
{
"name": "Cold-start fallback",
"max_score": 8,
"description": "predictCustomerCLV falls back to a cold-start calculation (calls a separate function or returns a default) when the customer has fewer than 2 orders"
},
{
"name": "Recency-based lifespan adjustment",
"max_score": 10,
"description": "predictCustomerCLV uses full projectionYears for customers inactive less than 90 days, and half projectionYears (projectionYears * 0.5) for customers inactive 90 or more days"
},
{
"name": "50% gross margin applied",
"max_score": 8,
"description": "predictCustomerCLV multiplies projected revenue by 0.50 (50% gross margin rate) when computing the final CLV value"
},
{
"name": "Filter cancelled orders",
"max_score": 8,
"description": "Order queries in predictCustomerCLV and/or calculateChurnProbability exclude cancelled orders (e.g., status not equal to 'cancelled')"
},
{
"name": "Churn edge case: no purchases",
"max_score": 8,
"description": "calculateChurnProbability returns 0.95 when the customer has no orders"
},
{
"name": "Churn edge case: single purchase",
"max_score": 8,
"description": "calculateChurnProbability returns 0.65 when the customer has exactly one order"
},
{
"name": "Sigmoid churn formula",
"max_score": 12,
"description": "calculateChurnProbability uses a sigmoid function: 1 / (1 + exp(-2 * (recencyRatio - 2))), where recencyRatio = daysSinceLastOrder / avgInterval"
},
{
"name": "Churn probability clamped",
"max_score": 8,
"description": "calculateChurnProbability clamps the returned value to the range [0.01, 0.99] (i.e., uses Math.min(0.99, Math.max(0.01, ...)))"
},
{
"name": "README documents assumptions",
"max_score": 8,
"description": "README.md mentions the 50% gross margin assumption and the 90-day recency threshold for lifespan adjustment"
},
{
"name": "Purchase frequency calculation",
"max_score": 10,
"description": "Per-customer purchase frequency is computed as 365 / avgPurchaseIntervalDays, where avgPurchaseIntervalDays = tenureDays / (orders.length - 1)"
}
]
}
Customer Value Prediction Engine
Problem/Feature Description
Petal & Co., a growing direct-to-consumer flower subscription service, wants to prioritize customer support and marketing spend more intelligently. Their current approach treats all customers equally, but the team suspects a small segment of loyal customers generates the majority of revenue. Before investing in a full data science platform, they want a lightweight TypeScript utility that predicts how much each customer is worth going forward and how likely they are to stop buying.
The engineering team has access to each customer's order history (order IDs, timestamps, amounts) and wants two things: a function that computes a forward-looking predicted lifetime value per customer, and a function that produces a churn probability score between 0 and 1. Both functions will be called from a nightly background job that processes the entire active customer base.
Output Specification
Produce a single TypeScript file clv.ts that exports:
1. calculatePredictedCLV(inputs) — a pure function that takes aggregate statistics and returns a numeric CLV prediction 2. predictCustomerCLV(customerId, projectionYears?) — an async function that queries order history from a db object and returns a predicted CLV value 3. calculateChurnProbability(customerId) — an async function that queries order history from a db object and returns a churn probability score
The db object is assumed to be available in scope (you can declare it as a module-level import or constant). Write the logic so another developer can read it and understand the calculation approach.
Also produce a README.md that:
- Describes the formulas and thresholds used in each function
- Lists the key assumptions (e.g., gross margin rate used, how recency affects projections)
Input Files
No additional input files are provided. Implement the functions based on your knowledge of CLV modeling best practices.
{
"context": "Tests whether the agent implements the correct churn risk thresholds for win-back vs nurture routing, the duplicate win-back check, intervention logging, the minimum recency guard, blended CLV tier calculation, and the correct tier thresholds.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Win-back churn threshold",
"max_score": 8,
"description": "Win-back flow is triggered only when churnProbability > 0.70 (not >= 0.70, not a different value like 0.60 or 0.80)"
},
{
"name": "Win-back CLV threshold",
"max_score": 8,
"description": "Win-back flow is triggered only when predictedCLV > 200 (combined with the churn threshold, not just churn alone)"
},
{
"name": "Win-back discount parameters",
"max_score": 8,
"description": "triggerWinBackFlow is called with discountPct: 20 and expiresInDays: 7"
},
{
"name": "Duplicate win-back prevention",
"max_score": 10,
"description": "Code checks whether the customer is already in a win-back flow (e.g., via db.emailQueue.has or equivalent) before triggering a new win-back"
},
{
"name": "Intervention logging",
"max_score": 8,
"description": "A record is written to a churn interventions store/table (e.g., db.churnInterventions.create) including customerId, churnProbability, predictedCLV, and a timestamp"
},
{
"name": "Nurture email threshold",
"max_score": 8,
"description": "Personalized nurture email is sent for customers with churnProbability > 0.40 AND churnProbability <= 0.70"
},
{
"name": "Minimum recency guard",
"max_score": 8,
"description": "Win-back or churn automation only triggers for customers who have been inactive for at least 60 days (days since last purchase >= 60)"
},
{
"name": "Blended CLV formula",
"max_score": 12,
"description": "assignCustomerTier computes blendedCLV = predictedCLV * 0.7 + historicalCLV * 0.3"
},
{
"name": "Tier thresholds",
"max_score": 10,
"description": "Tier assignments are: platinum >= 1000, gold >= 500, silver >= 200, standard below 200 (all based on blended CLV)"
},
{
"name": "Tier persisted",
"max_score": 8,
"description": "assignCustomerTier updates the customer record with the computed tier (e.g., db.customers.update with loyaltyTier)"
},
{
"name": "Design doc covers logic",
"max_score": 12,
"description": "retention-design.md documents the churn probability routing thresholds (0.40, 0.70) and the CLV blend weights (0.7/0.3)"
}
]
}
Nightly Retention Engine and Loyalty Tier System
Problem/Feature Description
Nomad Outfitters, an outdoor gear retailer with 50,000 active customers, is losing roughly 12% of their mid-tier customers each quarter — mostly to a competitor running aggressive promotions. The retention team has identified that timely, targeted outreach is the difference between winning back a lapsing customer and losing them permanently, but right now all outreach is manual and sporadic.
They want two things built: First, a nightly automated job that evaluates each customer's predicted CLV and churn risk and routes them into the appropriate action — high-risk, high-value customers should receive a win-back campaign while moderately at-risk customers should get a personalized nurture touch. Second, a loyalty tier assignment function that segments customers into named tiers (platinum, gold, silver, standard) based on their predicted and historical value, so the merchandising team can adjust offers accordingly.
The existing codebase already has calculateChurnProbability(customerId), predictCustomerCLV(customerId), and db.customers.findActiveWithOrders({ minOrders }) available. The email/action triggers triggerWinBackFlow(customerId, opts) and triggerPersonalizedNurtureEmail(customerId) are also available as imported functions.
Output Specification
Produce a TypeScript file retention.ts that exports:
1. runChurnPreventionAutomation() — the nightly job function 2. assignCustomerTier(customerId) — tier assignment based on CLV values
Also write a retention-design.md file documenting:
- The churn probability thresholds used to route customers into different actions
- The CLV threshold used to decide whether a win-back discount is justified
- How the tier thresholds and blending weights are determined
- Any idempotency or duplicate-prevention logic used
Input Files
No additional input files are provided. The functions listed above (db, triggerWinBackFlow, etc.) can be treated as available in scope.
{
"name": "finsi/customer-lifetime-value",
"version": "0.1.0",
"summary": "CLV calculation models, prediction, and retention strategy automation",
"skills": {
"customer-lifetime-value": {
"path": "SKILL.md"
}
}
}