rc-pulse 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # rc-pulse
2
+
3
+ **RevenueCat subscription health monitor. Pull your key metrics from the Charts API and get a clear pulse report — in the terminal, as Markdown, JSON, or a visual HTML dashboard.**
4
+
5
+ Two interfaces for two audiences:
6
+ - **CLI** — for agents, scripts, GitHub Actions, and developers who want composable JSON output
7
+ - **Dashboard** — a visual HTML report for humans, with MRR trend charts, a health score gauge, and signal cards
8
+
9
+ ```
10
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
11
+ rc-pulse · Dark Noise 2026-03-16
12
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
13
+
14
+ Health Score: 72/100 🟡 Good
15
+
16
+ OVERVIEW
17
+ Active Subscribers 2529
18
+ Active Trials 65
19
+ Active Users (28d) 14.0k
20
+ New Customers (28d) 1.6k
21
+
22
+ KEY METRICS
23
+ MRR $4.6k ↑ +3.2% MoM
24
+ Revenue/mo $5.1k ↑ +2.8% MoM
25
+ Churn Rate 4.1% (avg: 4.8%)
26
+ Trial Conv. 38.2% → flat MoM
27
+
28
+ SIGNALS
29
+ ✓ MRR Growth +3.2% MoM
30
+ ✓ Churn 4.1% (below avg 4.8%)
31
+ ✓ Revenue +2.8% MoM
32
+ ~ Trial Conversion 38.2% (stable)
33
+
34
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
35
+ ```
36
+
37
+ ## What It Does
38
+
39
+ `rc-pulse` calls the [RevenueCat Charts API v2](https://www.revenuecat.com/docs/api-v2) and returns a subscription health report with:
40
+
41
+ - **MRR** and month-over-month trend
42
+ - **Churn rate** vs. historical average
43
+ - **Revenue** per month with trend
44
+ - **Trial conversion rate** trend
45
+ - **Overview snapshot**: active subscribers, trials, users, new customers
46
+ - **Health score** (0–100) with graded signals
47
+
48
+ Use it locally for quick checks, or automate it as a weekly digest in GitHub Actions, Slack, or any CI pipeline.
49
+
50
+ ## Quickstart
51
+
52
+ ### npx (no install)
53
+
54
+ ```bash
55
+ npx rc-pulse --api-key sk_YOUR_KEY --project-id proj_YOUR_ID
56
+ ```
57
+
58
+ ### Global install
59
+
60
+ ```bash
61
+ npm install -g rc-pulse
62
+ rc-pulse --api-key sk_YOUR_KEY --project-id proj_YOUR_ID
63
+ ```
64
+
65
+ ### With environment variables
66
+
67
+ ```bash
68
+ export RC_API_KEY=sk_YOUR_KEY
69
+ export RC_PROJECT_ID=proj_YOUR_ID
70
+ rc-pulse
71
+ ```
72
+
73
+ ## Output Formats
74
+
75
+ ### Terminal (default)
76
+ ```bash
77
+ rc-pulse --api-key sk_xxx --project-id proj_xxx
78
+ ```
79
+
80
+ ### Dashboard — Visual HTML report
81
+ ```bash
82
+ # Open an interactive dashboard in your browser (auto-launches)
83
+ rc-pulse serve --api-key sk_xxx --project-id proj_xxx
84
+
85
+ # Or generate a standalone HTML file to share or deploy
86
+ rc-pulse --api-key sk_xxx --project-id proj_xxx --output html > report.html
87
+ open report.html
88
+ ```
89
+
90
+ The dashboard includes:
91
+ - Animated health score gauge (0–100)
92
+ - MRR trend chart (12-month history)
93
+ - Churn rate vs. historical average (bar chart)
94
+ - Overview metric cards with trend badges
95
+ - Color-coded signals section
96
+
97
+ ### Markdown (for Notion, GitHub, Slack bots)
98
+ ```bash
99
+ rc-pulse --api-key sk_xxx --project-id proj_xxx --output markdown
100
+ rc-pulse --output markdown > weekly-report.md
101
+ ```
102
+
103
+ ### JSON (for agents, scripts, custom integrations)
104
+ ```bash
105
+ rc-pulse --output json | jq '.metrics.mrr'
106
+ rc-pulse --output json > report.json
107
+ ```
108
+
109
+ ## Finding Your Project ID
110
+
111
+ ```bash
112
+ rc-pulse --api-key sk_YOUR_KEY --list-projects
113
+ ```
114
+
115
+ This lists all projects accessible with the key:
116
+
117
+ ```
118
+ Projects:
119
+ proj058a6330 Dark Noise
120
+ proj1234abcd My Other App
121
+ ```
122
+
123
+ ## GitHub Actions: Weekly Pulse
124
+
125
+ Add this to your repo and configure `RC_API_KEY` + `RC_PROJECT_ID` as repository secrets:
126
+
127
+ ```yaml
128
+ # .github/workflows/weekly-pulse.yml
129
+ name: Weekly Subscription Pulse
130
+
131
+ on:
132
+ schedule:
133
+ - cron: "0 9 * * 1" # Every Monday at 9am UTC
134
+ workflow_dispatch:
135
+
136
+ jobs:
137
+ pulse:
138
+ runs-on: ubuntu-latest
139
+ steps:
140
+ - name: Run rc-pulse
141
+ run: npx rc-pulse --output markdown >> $GITHUB_STEP_SUMMARY
142
+ env:
143
+ RC_API_KEY: ${{ secrets.RC_API_KEY }}
144
+ RC_PROJECT_ID: ${{ secrets.RC_PROJECT_ID }}
145
+ ```
146
+
147
+ The Markdown output renders directly in GitHub's workflow summary view — no external service needed.
148
+
149
+ ## API Requirements
150
+
151
+ - A **secret API key** from your RevenueCat dashboard (Settings → API Keys)
152
+ - The key needs `charts_metrics:charts:read` permission
153
+ - Works with the RevenueCat Charts API v2
154
+
155
+ ## Health Score
156
+
157
+ The health score (0–100) is computed from:
158
+
159
+ | Signal | Good | Warning | Bad |
160
+ |--------|------|---------|-----|
161
+ | MRR trend | > +5% MoM | 0–5% MoM | Negative |
162
+ | Churn vs avg | > 1% below avg | ±1% of avg | > 1% above avg |
163
+ | Revenue trend | > +3% MoM | Flat | < -5% MoM |
164
+ | Trial conversion | > +5% MoM | ±5% | < -5% MoM |
165
+
166
+ **Grades:**
167
+ - 80–100: A (Healthy 💚)
168
+ - 65–79: B (Good 🟡)
169
+ - 50–64: C (Needs attention 🟠)
170
+ - 35–49: D (At risk 🔴)
171
+ - 0–34: F (Warning 🔴)
172
+
173
+ ## Development
174
+
175
+ ```bash
176
+ git clone https://github.com/dimitriharding/rc-pulse
177
+ cd rc-pulse
178
+ npm install
179
+ npm run build
180
+
181
+ # Run in dev mode
182
+ npm run dev -- --api-key sk_xxx --project-id proj_xxx
183
+ ```
184
+
185
+ ## License
186
+
187
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env node
2
+ import { createServer } from "node:http";
3
+ import { RCChartsClient } from "./client.js";
4
+ import { fetchPulseMetrics } from "./metrics.js";
5
+ import { formatTerminal, formatMarkdown, formatJson } from "./report.js";
6
+ import { generateDashboardHtml } from "./dashboard.js";
7
+ const VERSION = "1.1.0";
8
+ function usage() {
9
+ console.log(`
10
+ rc-pulse v${VERSION} — RevenueCat subscription health monitor
11
+
12
+ Usage:
13
+ rc-pulse [options]
14
+ rc-pulse serve [options]
15
+
16
+ Commands:
17
+ (default) Output a health report to stdout
18
+ serve Start a local dashboard server and open in browser
19
+
20
+ Options:
21
+ --api-key <key> RevenueCat secret API key (or RC_API_KEY env var)
22
+ --project-id <id> RevenueCat project ID (or RC_PROJECT_ID env var)
23
+ --output <format> Output format: terminal (default), markdown, json, html
24
+ --port <port> Port for serve command (default: 3847)
25
+ --list-projects List all projects for the given API key and exit
26
+ --version Print version
27
+ --help Show this help
28
+
29
+ Examples:
30
+ rc-pulse --api-key sk_xxx --project-id proj_xxx
31
+ rc-pulse --api-key sk_xxx --project-id proj_xxx --output markdown
32
+ rc-pulse --api-key sk_xxx --project-id proj_xxx --output html > report.html
33
+ rc-pulse --api-key sk_xxx --project-id proj_xxx --output json > data.json
34
+ rc-pulse serve --api-key sk_xxx --project-id proj_xxx
35
+
36
+ Environment variables:
37
+ RC_API_KEY RevenueCat secret API key
38
+ RC_PROJECT_ID RevenueCat project ID
39
+ `);
40
+ }
41
+ async function run() {
42
+ const args = process.argv.slice(2);
43
+ if (args.includes("--help") || args.includes("-h")) {
44
+ usage();
45
+ process.exit(0);
46
+ }
47
+ if (args.includes("--version") || args.includes("-v")) {
48
+ console.log(`rc-pulse v${VERSION}`);
49
+ process.exit(0);
50
+ }
51
+ function getArg(flag) {
52
+ const idx = args.indexOf(flag);
53
+ return idx !== -1 ? args[idx + 1] : undefined;
54
+ }
55
+ const isServe = args[0] === "serve";
56
+ const apiKey = getArg("--api-key") ?? process.env.RC_API_KEY;
57
+ const projectId = getArg("--project-id") ?? process.env.RC_PROJECT_ID;
58
+ const output = (getArg("--output") ?? "terminal");
59
+ const port = parseInt(getArg("--port") ?? "3847", 10);
60
+ if (!apiKey) {
61
+ console.error("Error: --api-key or RC_API_KEY required");
62
+ process.exit(1);
63
+ }
64
+ const client = new RCChartsClient(apiKey, projectId ?? "");
65
+ // List projects mode
66
+ if (args.includes("--list-projects")) {
67
+ const projects = await client.getProjects();
68
+ console.log("\nProjects:");
69
+ for (const p of projects.items) {
70
+ console.log(` ${p.id} ${p.name}`);
71
+ }
72
+ console.log();
73
+ process.exit(0);
74
+ }
75
+ if (!projectId) {
76
+ console.error("Error: --project-id or RC_PROJECT_ID required.\n" +
77
+ "Use --list-projects to discover your project ID.");
78
+ process.exit(1);
79
+ }
80
+ // Fetch project name
81
+ let projectName;
82
+ try {
83
+ const projects = await client.getProjects();
84
+ projectName = projects.items.find((p) => p.id === projectId)?.name;
85
+ }
86
+ catch {
87
+ // non-fatal
88
+ }
89
+ if (output !== "json") {
90
+ process.stderr.write("Fetching metrics from RevenueCat Charts API...\n");
91
+ }
92
+ const metrics = await fetchPulseMetrics(client);
93
+ // Serve mode: start local server and open browser
94
+ if (isServe) {
95
+ const html = generateDashboardHtml(metrics, projectName);
96
+ const server = createServer((_req, res) => {
97
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
98
+ res.end(html);
99
+ });
100
+ server.listen(port, () => {
101
+ const url = `http://localhost:${port}`;
102
+ process.stderr.write(`\nrc-pulse dashboard running at ${url}\n`);
103
+ process.stderr.write("Press Ctrl+C to stop.\n\n");
104
+ // Open in browser (best-effort)
105
+ const open = process.platform === "darwin" ? "open" :
106
+ process.platform === "win32" ? "start" : "xdg-open";
107
+ import("node:child_process").then(({ exec }) => exec(`${open} ${url}`)).catch(() => { });
108
+ });
109
+ return; // keep server alive
110
+ }
111
+ switch (output) {
112
+ case "terminal":
113
+ console.log(formatTerminal(metrics, projectName));
114
+ break;
115
+ case "markdown":
116
+ console.log(formatMarkdown(metrics, projectName));
117
+ break;
118
+ case "json":
119
+ console.log(formatJson(metrics, projectName));
120
+ break;
121
+ case "html":
122
+ console.log(generateDashboardHtml(metrics, projectName));
123
+ break;
124
+ default:
125
+ console.error(`Unknown output format: ${output}`);
126
+ process.exit(1);
127
+ }
128
+ }
129
+ run().catch((err) => {
130
+ console.error("Error:", err.message);
131
+ process.exit(1);
132
+ });
133
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ChartData, OverviewData } from "./types.js";
2
+ export declare class RCChartsClient {
3
+ private apiKey;
4
+ private projectId;
5
+ constructor(apiKey: string, projectId: string);
6
+ private get;
7
+ getOverview(): Promise<OverviewData>;
8
+ getChart(chartName: string, resolution?: "day" | "week" | "month"): Promise<ChartData>;
9
+ getProjects(): Promise<{
10
+ items: Array<{
11
+ id: string;
12
+ name: string;
13
+ }>;
14
+ }>;
15
+ }
16
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1D,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;YAK/B,GAAG;IAuBX,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC;IAIpC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,KAAK,GAAG,MAAM,GAAG,OAAiB,GAAG,OAAO,CAAC,SAAS,CAAC;IAM/F,WAAW,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CAG7E"}
package/dist/client.js ADDED
@@ -0,0 +1,38 @@
1
+ const BASE_URL = "https://api.revenuecat.com/v2";
2
+ export class RCChartsClient {
3
+ apiKey;
4
+ projectId;
5
+ constructor(apiKey, projectId) {
6
+ this.apiKey = apiKey;
7
+ this.projectId = projectId;
8
+ }
9
+ async get(path, params) {
10
+ const url = new URL(`${BASE_URL}${path}`);
11
+ if (params) {
12
+ Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
13
+ }
14
+ const res = await fetch(url.toString(), {
15
+ headers: {
16
+ Authorization: `Bearer ${this.apiKey}`,
17
+ "Content-Type": "application/json",
18
+ },
19
+ });
20
+ if (!res.ok) {
21
+ const error = await res.json().catch(() => ({ message: res.statusText }));
22
+ throw new Error(`RC API error ${res.status}: ${error.message || res.statusText}`);
23
+ }
24
+ return res.json();
25
+ }
26
+ async getOverview() {
27
+ return this.get(`/projects/${this.projectId}/metrics/overview`);
28
+ }
29
+ async getChart(chartName, resolution = "month") {
30
+ return this.get(`/projects/${this.projectId}/charts/${chartName}`, {
31
+ resolution,
32
+ });
33
+ }
34
+ async getProjects() {
35
+ return this.get("/projects");
36
+ }
37
+ }
38
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAG,+BAA+B,CAAC;AAEjD,MAAM,OAAO,cAAc;IACjB,MAAM,CAAS;IACf,SAAS,CAAS;IAE1B,YAAY,MAAc,EAAE,SAAiB;QAC3C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,GAAG,CAAI,IAAY,EAAE,MAA+B;QAChE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,QAAQ,GAAG,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;YACtC,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;gBACtC,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YAC1E,MAAM,IAAI,KAAK,CACb,gBAAgB,GAAG,CAAC,MAAM,KAAM,KAAa,CAAC,OAAO,IAAI,GAAG,CAAC,UAAU,EAAE,CAC1E,CAAC;QACJ,CAAC;QAED,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC,GAAG,CAAe,aAAa,IAAI,CAAC,SAAS,mBAAmB,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,SAAiB,EAAE,aAAuC,OAAO;QAC9E,OAAO,IAAI,CAAC,GAAG,CAAY,aAAa,IAAI,CAAC,SAAS,WAAW,SAAS,EAAE,EAAE;YAC5E,UAAU;SACX,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ import type { PulseMetrics } from "./types.js";
2
+ export declare function generateDashboardHtml(metrics: PulseMetrics, projectName?: string): string;
3
+ //# sourceMappingURL=dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,YAAY,CAAC;AAG5D,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,YAAY,EACrB,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAwaR"}