Skip to content
SlashClone
Made by@revopslab

Pipeline hygiene

@revopslab/pipeline-hygiene

Check open deals in a CRM export (HubSpot, Salesforce, or any CSV) for past close dates, deals stuck in a stage, no recent activity, missing required fields (also by stage), zero amounts, and close dates too far out. Writes a hygiene score and a fix list per rep you can send out.

SkillRevOpsv1.0.0 (latest)Tested
Activity
New: be the first to try it
  1. 1{
  2. 2 "name": "pipeline-hygiene",
  3. 3 "owner": "revopslab",
  4. 4 "version": "1.0.0",
  5. 5 "type": "skill",
  6. 6 "description": "Check open deals in a CRM export (HubSpot, Salesforce, or any CSV) for past close dates, deals stuck in a stage, no recent activity, missing required fields (also by stage), zero amounts, and close dates too far out. Writes a hygiene score and a fix list per rep you can send out.",
  7. 7 "category": "revops",
  8. 8 "license": "MIT",
  9. 9 "compat": [
  10. 10 "claude-code"
  11. 11 ],
  12. 12 "permissions": {
  13. 13 "shell": [
  14. 14 "node scripts/hygiene.mjs"
  15. 15 ],
  16. 16 "files": {
  17. 17 "read": [
  18. 18 "./data/**"
  19. 19 ],
  20. 20 "write": [
  21. 21 "./data/**",
  22. 22 "./out/**"
  23. 23 ]
  24. 24 }
  25. 25 },
  26. 26 "tests": {
  27. 27 "cases": [
  28. 28 {
  29. 29 "name": "flags each issue type with a config and stage-specific required fields",
  30. 30 "inputs": {
  31. 31 "data/opportunities.csv": "Opportunity ID,Opportunity Name,Opportunity Owner,Stage,Amount,Close Date,Next Step,Stage Entered Date,Last Activity Date,Decision Maker\nP1,Northwind Traders: expansion,Rep A,Negotiation,84000,2026-11-21,Send revised order form,2026-10-20,2026-11-03,CFO\nP2,Contoso Robotics: new logo,Rep B,Proposal,120000,2026-10-31,,2026-08-15,2026-10-12,\nP3,Fabrikam Health: renewal,Rep A,Discovery,0,2026-12-31,Discovery call 2,2026-10-28,2026-11-01,\nP4,Tailspin Toys: pilot,Rep C,Qualification,15000,2028-03-01,Intro call,2026-09-01,2026-09-02,\nP5,Adventure Works: upsell,,Proposal,30000,,Pricing review,2026-10-30,2026-11-02,\nP6,Litware: starter,Rep C,Closed Won,15000,2026-10-15,,2026-10-15,2026-10-15,\n",
  32. 32 "data/hygiene.json": "{\n \"stale_days\": 30,\n \"activity_days\": 14,\n \"far_future_days\": 365,\n \"required\": [\"amount\", \"close_date\", \"owner\", \"next_step\"],\n \"required_by_stage\": {\n \"Proposal\": [\"Decision Maker\"],\n \"Negotiation\": [\"Decision Maker\"]\n },\n \"closed_stages\": [\"Closed Won\", \"Closed Lost\"]\n}\n"
  33. 33 },
  34. 34 "checks": [
  35. 35 {
  36. 36 "type": "command_exits_zero",
  37. 37 "command": "node scripts/hygiene.mjs data/opportunities.csv --config data/hygiene.json --today 2026-11-04 --out out"
  38. 38 },
  39. 39 {
  40. 40 "type": "file_exists",
  41. 41 "path": "out/hygiene-fix-list.csv"
  42. 42 },
  43. 43 {
  44. 44 "type": "file_contains",
  45. 45 "path": "out/hygiene.md",
  46. 46 "text": "**Hygiene score 20%**"
  47. 47 },
  48. 48 {
  49. 49 "type": "output_matches_schema",
  50. 50 "path": "out/hygiene.json",
  51. 51 "schema": {
  52. 52 "type": "object",
  53. 53 "required": [
  54. 54 "open_deals",
  55. 55 "issue_counts",
  56. 56 "by_owner",
  57. 57 "deals"
  58. 58 ],
  59. 59 "properties": {
  60. 60 "open_deals": {
  61. 61 "const": 5
  62. 62 },
  63. 63 "closed_skipped": {
  64. 64 "const": 1
  65. 65 },
  66. 66 "clean_deals": {
  67. 67 "const": 1
  68. 68 },
  69. 69 "issue_counts": {
  70. 70 "type": "object",
  71. 71 "properties": {
  72. 72 "past_close_date": {
  73. 73 "const": 1
  74. 74 },
  75. 75 "stale_stage": {
  76. 76 "const": 2
  77. 77 },
  78. 78 "no_recent_activity": {
  79. 79 "const": 2
  80. 80 },
  81. 81 "missing_fields": {
  82. 82 "const": 2
  83. 83 },
  84. 84 "zero_amount": {
  85. 85 "const": 1
  86. 86 },
  87. 87 "far_future_close": {
  88. 88 "const": 1
  89. 89 }
  90. 90 }
  91. 91 },
  92. 92 "deals": {
  93. 93 "type": "array",
  94. 94 "minItems": 4,
  95. 95 "maxItems": 4
  96. 96 }
  97. 97 }
  98. 98 }
  99. 99 }
  100. 100 ]
  101. 101 },
  102. 102 {
  103. 103 "name": "HubSpot-style export with defaults, skipping checks it has no columns for",
  104. 104 "inputs": {
  105. 105 "data/deals.csv": "Record ID,Deal Name,Deal owner,Deal Stage,Amount,Close Date\n1,Alpha,Rep D,Contract sent,10000,2026-10-01\n2,Beta,Rep D,Qualified,5000,2026-12-01\n"
  106. 106 },
  107. 107 "checks": [
  108. 108 {
  109. 109 "type": "command_exits_zero",
  110. 110 "command": "node scripts/hygiene.mjs data/deals.csv --today 2026-11-04 --out out"
  111. 111 },
  112. 112 {
  113. 113 "type": "output_matches_schema",
  114. 114 "path": "out/hygiene.json",
  115. 115 "schema": {
  116. 116 "type": "object",
  117. 117 "properties": {
  118. 118 "open_deals": {
  119. 119 "const": 2
  120. 120 },
  121. 121 "issue_counts": {
  122. 122 "type": "object",
  123. 123 "properties": {
  124. 124 "past_close_date": {
  125. 125 "const": 1
  126. 126 },
  127. 127 "missing_fields": {
  128. 128 "const": 2
  129. 129 }
  130. 130 }
  131. 131 },
  132. 132 "checks_skipped": {
  133. 133 "type": "array",
  134. 134 "minItems": 2,
  135. 135 "maxItems": 2
  136. 136 }
  137. 137 }
  138. 138 }
  139. 139 }
  140. 140 ]
  141. 141 }
  142. 142 ]
  143. 143 }