Activation funnel
@usagemetrics/activation-funnel
Measure an activation funnel from an events CSV: how many users or accounts reach each step within a time window, conversion step to step, median time between steps, the biggest drop, and splits by plan or any segment. Writes markdown, CSV, JSON, and a list of who got stuck.
- Activity
- New: be the first to try it
- Installs
- 0 installs
- Likes
- 0 likes
- Clones
- 0 clones
- 1{
- 2 "name": "activation-funnel",
- 3 "owner": "usagemetrics",
- 4 "version": "1.0.0",
- 5 "type": "skill",
- 6 "description": "Measure an activation funnel from an events CSV: how many users or accounts reach each step within a time window, conversion step to step, median time between steps, the biggest drop, and splits by plan or any segment. Writes markdown, CSV, JSON, and a list of who got stuck.",
- 7 "category": "data",
- 8 "license": "MIT",
- 9 "compat": ["claude-code"],
- 10 "permissions": {
- 11 "shell": ["node scripts/funnel.mjs"],
- 12 "files": { "read": ["./data/**"], "write": ["./out/funnel*"] }
- 13 },
- 14 "tests": {
- 15 "cases": [
- 16 {
- 17 "name": "four-step funnel with plan segments from the example",
- 18 "inputs": {},
- 19 "checks": [
- 20 {
- 21 "type": "command_exits_zero",
- 22 "command": "node scripts/funnel.mjs examples/events.csv --steps signed_up,connected_source,created_report,shared_dashboard --window-days 14 --as-of 2026-10-31 --segments examples/accounts.csv --segment-column plan --out out/funnel"
- 23 },
- 24 { "type": "file_exists", "path": "out/funnel-stuck.csv" },
- 25 { "type": "file_contains", "path": "out/funnel.md", "text": "| connected_source | 122 | 77% | 77% | 36 | 4.0 h |" },
- 26 {
- 27 "type": "output_matches_schema",
- 28 "path": "out/funnel.json",
- 29 "schema": {
- 30 "type": "object",
- 31 "required": ["entered", "completed", "funnel", "segments", "biggest_drop"],
- 32 "properties": {
- 33 "entered": { "const": 158 },
- 34 "completed": { "const": 44 },
- 35 "excluded_too_recent": { "const": 22 },
- 36 "biggest_drop": { "type": "object", "properties": { "into_step": { "const": "shared_dashboard" } } },
- 37 "segments": { "type": "object", "required": ["business", "free", "team"] }
- 38 }
- 39 }
- 40 }
- 41 ]
- 42 },
- 43 {
- 44 "name": "respects step order unless any-order is set",
- 45 "inputs": {
- 46 "data/events.csv": "timestamp,account_id,user_id,event\n2026-09-01T10:00:00Z,a1,u1,signed_up\n2026-09-01T11:00:00Z,a1,u1,b\n2026-09-01T12:00:00Z,a1,u1,a\n2026-09-02T10:00:00Z,a1,u2,signed_up\n2026-09-02T11:00:00Z,a1,u2,a\n2026-09-02T12:00:00Z,a1,u2,b\n2026-10-30T10:00:00Z,a1,u3,login\n"
- 47 },
- 48 "checks": [
- 49 { "type": "command_exits_zero", "command": "node scripts/funnel.mjs data/events.csv --steps signed_up,a,b --out out/funnel" },
- 50 { "type": "output_matches_schema", "path": "out/funnel.json", "schema": { "type": "object", "properties": { "entered": { "const": 2 }, "completed": { "const": 1 } } } },
- 51 { "type": "command_exits_zero", "command": "node scripts/funnel.mjs data/events.csv --steps signed_up,a,b --any-order --out out/funnel" },
- 52 { "type": "output_matches_schema", "path": "out/funnel.json", "schema": { "type": "object", "properties": { "completed": { "const": 2 }, "ordered": { "const": false } } } }
- 53 ]
- 54 }
- 55 ]
- 56 }
- 57}
