Skip to content
SlashClone

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.

SkillDatav1.0.0 (latest)Tested
Activity
New: be the first to try it
  1. 1{
  2. 2 "name": "activation-funnel",
  3. 3 "owner": "usagemetrics",
  4. 4 "version": "1.0.0",
  5. 5 "type": "skill",
  6. 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. 7 "category": "data",
  8. 8 "license": "MIT",
  9. 9 "compat": ["claude-code"],
  10. 10 "permissions": {
  11. 11 "shell": ["node scripts/funnel.mjs"],
  12. 12 "files": { "read": ["./data/**"], "write": ["./out/funnel*"] }
  13. 13 },
  14. 14 "tests": {
  15. 15 "cases": [
  16. 16 {
  17. 17 "name": "four-step funnel with plan segments from the example",
  18. 18 "inputs": {},
  19. 19 "checks": [
  20. 20 {
  21. 21 "type": "command_exits_zero",
  22. 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. 23 },
  24. 24 { "type": "file_exists", "path": "out/funnel-stuck.csv" },
  25. 25 { "type": "file_contains", "path": "out/funnel.md", "text": "| connected_source | 122 | 77% | 77% | 36 | 4.0 h |" },
  26. 26 {
  27. 27 "type": "output_matches_schema",
  28. 28 "path": "out/funnel.json",
  29. 29 "schema": {
  30. 30 "type": "object",
  31. 31 "required": ["entered", "completed", "funnel", "segments", "biggest_drop"],
  32. 32 "properties": {
  33. 33 "entered": { "const": 158 },
  34. 34 "completed": { "const": 44 },
  35. 35 "excluded_too_recent": { "const": 22 },
  36. 36 "biggest_drop": { "type": "object", "properties": { "into_step": { "const": "shared_dashboard" } } },
  37. 37 "segments": { "type": "object", "required": ["business", "free", "team"] }
  38. 38 }
  39. 39 }
  40. 40 }
  41. 41 ]
  42. 42 },
  43. 43 {
  44. 44 "name": "respects step order unless any-order is set",
  45. 45 "inputs": {
  46. 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. 47 },
  48. 48 "checks": [
  49. 49 { "type": "command_exits_zero", "command": "node scripts/funnel.mjs data/events.csv --steps signed_up,a,b --out out/funnel" },
  50. 50 { "type": "output_matches_schema", "path": "out/funnel.json", "schema": { "type": "object", "properties": { "entered": { "const": 2 }, "completed": { "const": 1 } } } },
  51. 51 { "type": "command_exits_zero", "command": "node scripts/funnel.mjs data/events.csv --steps signed_up,a,b --any-order --out out/funnel" },
  52. 52 { "type": "output_matches_schema", "path": "out/funnel.json", "schema": { "type": "object", "properties": { "completed": { "const": 2 }, "ordered": { "const": false } } } }
  53. 53 ]
  54. 54 }
  55. 55 ]
  56. 56 }