diff --git a/business-growth/skills/customer-success-manager/scripts/health_score_calculator.py b/business-growth/skills/customer-success-manager/scripts/health_score_calculator.py index 62aeba3d..f2b83e9e 100644 --- a/business-growth/skills/customer-success-manager/scripts/health_score_calculator.py +++ b/business-growth/skills/customer-success-manager/scripts/health_score_calculator.py @@ -397,11 +397,38 @@ def format_json(results: List[Dict[str, Any]]) -> str: # --------------------------------------------------------------------------- +# Embedded synthetic fixture for --sample (two customers across segments). +SAMPLE_DATA = { + "customers": [ + { + "customer_id": "C-001", + "name": "Acme Corp", + "segment": "enterprise", + "arr": 240000, + "usage": {"dau_mau_ratio": 0.55, "license_utilization": 0.82}, + "engagement": {"qbr_attendance": 1.0, "champion_engaged": True}, + "support": {"open_tickets": 2, "csat": 4.6}, + "relationship": {"nps": 9, "exec_sponsor": True}, + }, + { + "customer_id": "C-002", + "name": "Globex Ltd", + "segment": "smb", + "arr": 18000, + "usage": {"dau_mau_ratio": 0.12, "license_utilization": 0.35}, + "engagement": {"qbr_attendance": 0.0, "champion_engaged": False}, + "support": {"open_tickets": 7, "csat": 3.1}, + "relationship": {"nps": 4, "exec_sponsor": False}, + }, + ] +} + + def main() -> None: parser = argparse.ArgumentParser( description="Calculate multi-dimensional customer health scores with trend analysis." ) - parser.add_argument("input_file", help="Path to JSON file containing customer data") + parser.add_argument("input_file", nargs="?", help="Path to JSON file containing customer data") parser.add_argument( "--format", choices=["text", "json"], @@ -409,17 +436,27 @@ def main() -> None: dest="output_format", help="Output format (default: text)", ) + parser.add_argument( + "--sample", + action="store_true", + help="Run with an embedded synthetic customer fixture (no input file needed)", + ) args = parser.parse_args() - try: - with open(args.input_file, "r") as f: - data = json.load(f) - except FileNotFoundError: - print(f"Error: File not found: {args.input_file}", file=sys.stderr) - sys.exit(1) - except json.JSONDecodeError as e: - print(f"Error: Invalid JSON in {args.input_file}: {e}", file=sys.stderr) - sys.exit(1) + if args.sample: + data = SAMPLE_DATA + else: + if not args.input_file: + parser.error("input_file is required (or use --sample)") + try: + with open(args.input_file, "r") as f: + data = json.load(f) + except FileNotFoundError: + print(f"Error: File not found: {args.input_file}", file=sys.stderr) + sys.exit(1) + except json.JSONDecodeError as e: + print(f"Error: Invalid JSON in {args.input_file}: {e}", file=sys.stderr) + sys.exit(1) customers = data.get("customers", []) if not customers: diff --git a/business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py b/business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py index 23a56d43..f482a7e6 100644 --- a/business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py +++ b/business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py @@ -448,6 +448,24 @@ def format_text_report(results: dict) -> str: return "\n".join(lines) +# Embedded synthetic pipeline fixture for --sample. +SAMPLE_DATA = { + "quota": 1000000, + "average_cycle_days": 45, + "stages": ["discovery", "demo", "proposal", "negotiation", "closed_won"], + "deals": [ + {"id": "D-1", "name": "Acme renewal", "stage": "proposal", + "value": 120000, "age_days": 30, "close_date": "2026-07-15"}, + {"id": "D-2", "name": "Globex new logo", "stage": "discovery", + "value": 80000, "age_days": 10, "close_date": "2026-08-01"}, + {"id": "D-3", "name": "Initech expansion", "stage": "negotiation", + "value": 200000, "age_days": 70, "close_date": "2026-06-30"}, + {"id": "D-4", "name": "Umbrella upsell", "stage": "closed_won", + "value": 60000, "age_days": 50, "close_date": "2026-05-20"}, + ], +} + + def main() -> None: """Main entry point for pipeline analyzer CLI.""" parser = argparse.ArgumentParser( @@ -455,7 +473,6 @@ def main() -> None: ) parser.add_argument( "--input", - required=True, help="Path to JSON file containing pipeline data", ) parser.add_argument( @@ -464,18 +481,28 @@ def main() -> None: default="text", help="Output format: json or text (default: text)", ) + parser.add_argument( + "--sample", + action="store_true", + help="Analyze an embedded synthetic pipeline (no input file needed)", + ) args = parser.parse_args() - try: - with open(args.input, "r") as f: - data = json.load(f) - except FileNotFoundError: - print(f"Error: File not found: {args.input}", file=sys.stderr) - sys.exit(1) - except json.JSONDecodeError as e: - print(f"Error: Invalid JSON in {args.input}: {e}", file=sys.stderr) - sys.exit(1) + if args.sample: + data = SAMPLE_DATA + else: + if not args.input: + parser.error("--input is required (or use --sample)") + try: + with open(args.input, "r") as f: + data = json.load(f) + except FileNotFoundError: + print(f"Error: File not found: {args.input}", file=sys.stderr) + sys.exit(1) + except json.JSONDecodeError as e: + print(f"Error: Invalid JSON in {args.input}: {e}", file=sys.stderr) + sys.exit(1) # Validate required fields required_fields = ["deals", "quota", "stages"] diff --git a/c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py b/c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py index 5fd1a4f0..99885986 100644 --- a/c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py +++ b/c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py @@ -556,6 +556,11 @@ def main(): action="store_true", help="Output raw JSON instead of formatted report", ) + parser.add_argument( + "--sample", + action="store_true", + help="Run with the built-in sample data (no notice line — safe for JSON piping)", + ) args = parser.parse_args() if args.input: @@ -568,6 +573,8 @@ def main(): except json.JSONDecodeError as e: print(f"Error: invalid JSON: {e}", file=sys.stderr) sys.exit(1) + elif args.sample: + data = sample_data() else: print("No input file provided — running with sample data.\n") data = sample_data() diff --git a/c-level-advisor/skills/cto-advisor/scripts/team_scaling_calculator.py b/c-level-advisor/skills/cto-advisor/scripts/team_scaling_calculator.py index 66842259..ff53c738 100644 --- a/c-level-advisor/skills/cto-advisor/scripts/team_scaling_calculator.py +++ b/c-level-advisor/skills/cto-advisor/scripts/team_scaling_calculator.py @@ -528,9 +528,13 @@ if __name__ == "__main__": "--json", action="store_true", help="Output raw JSON instead of formatted report" ) + parser.add_argument( + "--sample", action="store_true", + help="Run with the embedded sample data (ignores input_file)" + ) args = parser.parse_args() - if args.input_file: + if args.input_file and not args.sample: with open(args.input_file) as f: data = json.load(f) current_state = data["current_state"] diff --git a/engineering-team/a11y-audit/skills/a11y-audit/scripts/contrast_checker.py b/engineering-team/a11y-audit/skills/a11y-audit/scripts/contrast_checker.py index 75ba84f1..edfe2999 100644 --- a/engineering-team/a11y-audit/skills/a11y-audit/scripts/contrast_checker.py +++ b/engineering-team/a11y-audit/skills/a11y-audit/scripts/contrast_checker.py @@ -353,6 +353,11 @@ def build_parser() -> argparse.ArgumentParser: action="store_true", help="Show example output with sample color pairs", ) + parser.add_argument( + "--sample", + action="store_true", + help="Alias for --demo (repo-wide embedded-sample convention)", + ) return parser @@ -360,8 +365,8 @@ def main() -> int: parser = build_parser() args = parser.parse_args() - # --demo mode - if args.demo: + # --demo / --sample mode + if args.demo or args.sample: run_demo(args.json_output) return 0 diff --git a/engineering-team/skills/incident-response/scripts/incident_triage.py b/engineering-team/skills/incident-response/scripts/incident_triage.py index 3a3e8e79..936d118e 100644 --- a/engineering-team/skills/incident-response/scripts/incident_triage.py +++ b/engineering-team/skills/incident-response/scripts/incident_triage.py @@ -584,6 +584,19 @@ def _print_text_report(result: dict) -> None: # Main Entry Point # --------------------------------------------------------------------------- +# Embedded synthetic security event for --sample (no file/stdin needed). +SAMPLE_EVENT = { + "event_type": "ransomware", + "source_ip": "203.0.113.50", + "destination_ip": "10.0.4.21", + "user_account": "svc-backup", + "hostname": "fileserver-02", + "process_name": "encryptor.exe", + "first_seen": "2026-06-10T01:30:00Z", + "detected_at": "2026-06-10T09:30:00Z", +} + + def main() -> None: parser = argparse.ArgumentParser( description="Incident Classification, Triage, and Escalation", @@ -627,12 +640,19 @@ Exit codes: choices=["sev1", "sev2", "sev3", "sev4"], help="Explicit severity override (skips taxonomy-derived severity)", ) + parser.add_argument( + "--sample", + action="store_true", + help="Triage an embedded synthetic ransomware event (no file/stdin needed)", + ) args = parser.parse_args() # --- Load input --- try: - if args.input: + if args.sample: + raw_event = SAMPLE_EVENT + elif args.input: with open(args.input, "r", encoding="utf-8") as fh: raw_event = json.load(fh) else: