executable-stories-formatters 1.13.0 → 1.15.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/dist/index.d.cts CHANGED
@@ -1655,6 +1655,20 @@ interface ScenarioIndex {
1655
1655
  summary: StoryReport["summary"];
1656
1656
  scenarios: ScenarioIndexItem[];
1657
1657
  }
1658
+ /**
1659
+ * One scenario as this formatter emits it.
1660
+ *
1661
+ * This is an OUTPUT type: it describes what `toScenarioIndex` produces, which
1662
+ * is why `hash` and `assertionState` are required here while
1663
+ * `scenario-index-v1.json` marks both optional. The schema is deliberately the
1664
+ * laxer of the two so artifacts written before either field existed still
1665
+ * validate; every artifact written since carries them.
1666
+ *
1667
+ * The consequence, and it is intended: parsing an arbitrary v1 file and casting
1668
+ * it to this type is not sound for those two fields. Validate against the
1669
+ * schema and treat them as optional if you are reading files you did not just
1670
+ * write.
1671
+ */
1658
1672
  interface ScenarioIndexItem {
1659
1673
  id: string;
1660
1674
  title: string;
@@ -1681,6 +1695,12 @@ interface ScenarioIndexItem {
1681
1695
  message: string;
1682
1696
  stack?: string;
1683
1697
  };
1698
+ /**
1699
+ * Whether the scenario's claim was checked: `asserted`, `unasserted`, or
1700
+ * `unobserved` where the adapter cannot count. A passing scenario that is
1701
+ * `unasserted` ran and proved nothing.
1702
+ */
1703
+ assertionState: "asserted" | "unasserted" | "unobserved";
1684
1704
  }
1685
1705
  interface ScenarioIndexStep {
1686
1706
  id: string;
@@ -1691,6 +1711,11 @@ interface ScenarioIndexStep {
1691
1711
  durationMs: number;
1692
1712
  errorMessage?: string;
1693
1713
  docKinds: string[];
1714
+ /**
1715
+ * Assertions the framework observed. Absent means the adapter has no counter;
1716
+ * `0` means it counted none. Never defaulted — the difference is the point.
1717
+ */
1718
+ assertions?: number;
1694
1719
  }
1695
1720
  interface ScenarioIndexFilters {
1696
1721
  statuses?: TestStatus$1[];
@@ -2776,6 +2801,8 @@ interface CheckArgs {
2776
2801
  testCases: TestCaseResult[];
2777
2802
  /** Baseline scenario statuses keyed by scenario id, for regressed/fixed deltas. */
2778
2803
  baseline?: Map<string, TestStatus>;
2804
+ /** Per-scenario time budget. Scenarios above it are named (see {@link CheckSlow}). */
2805
+ maxDurationMs?: number;
2779
2806
  format: "text" | "json";
2780
2807
  }
2781
2808
  type CheckDeps = Record<string, never>;
@@ -2814,6 +2841,17 @@ interface CheckTurnedOff {
2814
2841
  status: "skipped" | "pending";
2815
2842
  tickets: string[];
2816
2843
  }
2844
+ /**
2845
+ * A scenario that took longer than the budget. A slow suite is usually two or
2846
+ * three scenarios, and nobody knows which until something names them.
2847
+ */
2848
+ interface CheckSlow {
2849
+ id: string;
2850
+ scenario: string;
2851
+ /** `sourceFile:sourceLine` */
2852
+ location: string;
2853
+ durationMs: number;
2854
+ }
2817
2855
  interface CheckReport {
2818
2856
  summary: {
2819
2857
  total: number;
@@ -2825,6 +2863,10 @@ interface CheckReport {
2825
2863
  failures: CheckFailure[];
2826
2864
  /** Scenarios switched off — named, not just counted (see {@link CheckTurnedOff}). */
2827
2865
  turnedOff: CheckTurnedOff[];
2866
+ /** Scenarios over `--max-duration`, longest first. Empty without a budget. */
2867
+ overBudget: CheckSlow[];
2868
+ /** The budget those scenarios broke, for the message that names it. */
2869
+ maxDurationMs?: number;
2828
2870
  /** Count of scenarios that went passed → failed vs. the baseline. */
2829
2871
  regressed: number;
2830
2872
  /** Count of scenarios that went failed → passed vs. the baseline. */
@@ -2900,6 +2942,22 @@ type GoalDeps = Record<string, never>;
2900
2942
  declare function buildGoal(args: GoalArgs, _deps?: GoalDeps): GoalReport;
2901
2943
  declare function renderGoal(report: GoalReport, format: "text" | "json"): string;
2902
2944
 
2945
+ /**
2946
+ * CODEOWNERS parsing, so a failing scenario can name the team that fixes it.
2947
+ *
2948
+ * A red run that belongs to everyone belongs to nobody until someone
2949
+ * volunteers. `triage --by-owner` groups the worklist the way the repo already
2950
+ * divides responsibility, using the file every GitHub repo already has.
2951
+ *
2952
+ * Supports the common CODEOWNERS subset — leading `/`, trailing `/`,
2953
+ * `*`, `**`, and bare extension globs. Character classes, `?`, and negation are
2954
+ * not implemented; swap in a gitignore-grade matcher if a repo needs them.
2955
+ */
2956
+ interface CodeownersRule {
2957
+ pattern: string;
2958
+ owners: string[];
2959
+ }
2960
+
2903
2961
  /**
2904
2962
  * `triage` — the discovery-phase worklist for an agent loop.
2905
2963
  *
@@ -2920,6 +2978,8 @@ interface TriageItem {
2920
2978
  /** Product-code paths to fix. Empty when the scenario declared no `covers`. */
2921
2979
  covers: string[];
2922
2980
  tickets: string[];
2981
+ /** CODEOWNERS entries for the code this scenario covers. Empty = unclaimed. */
2982
+ owners: string[];
2923
2983
  errorMessage?: string;
2924
2984
  /** Passed in the baseline, failing now. Ranked first. */
2925
2985
  regressed: boolean;
@@ -2938,10 +2998,16 @@ interface TriageArgs {
2938
2998
  /** Baseline statuses by scenario id, to flag regressions and rank them first. */
2939
2999
  baseline?: Map<string, TestStatus>;
2940
3000
  format: "text" | "json";
3001
+ /** Parsed CODEOWNERS. Without it every item is unowned. */
3002
+ codeowners?: readonly CodeownersRule[];
2941
3003
  }
2942
3004
  type TriageDeps = Record<string, never>;
2943
3005
  declare function buildTriage(args: TriageArgs, _deps?: TriageDeps): TriageReport;
2944
- declare function renderTriage(report: TriageReport, format: "text" | "json"): string;
3006
+ interface RenderTriageOptions {
3007
+ /** Group the text worklist under each CODEOWNERS owner. */
3008
+ byOwner?: boolean;
3009
+ }
3010
+ declare function renderTriage(report: TriageReport, format: "text" | "json", options?: RenderTriageOptions): string;
2945
3011
 
2946
3012
  /**
2947
3013
  * ReportGenerator — turns a canonical TestRunResult into report files.
package/dist/index.d.ts CHANGED
@@ -1655,6 +1655,20 @@ interface ScenarioIndex {
1655
1655
  summary: StoryReport["summary"];
1656
1656
  scenarios: ScenarioIndexItem[];
1657
1657
  }
1658
+ /**
1659
+ * One scenario as this formatter emits it.
1660
+ *
1661
+ * This is an OUTPUT type: it describes what `toScenarioIndex` produces, which
1662
+ * is why `hash` and `assertionState` are required here while
1663
+ * `scenario-index-v1.json` marks both optional. The schema is deliberately the
1664
+ * laxer of the two so artifacts written before either field existed still
1665
+ * validate; every artifact written since carries them.
1666
+ *
1667
+ * The consequence, and it is intended: parsing an arbitrary v1 file and casting
1668
+ * it to this type is not sound for those two fields. Validate against the
1669
+ * schema and treat them as optional if you are reading files you did not just
1670
+ * write.
1671
+ */
1658
1672
  interface ScenarioIndexItem {
1659
1673
  id: string;
1660
1674
  title: string;
@@ -1681,6 +1695,12 @@ interface ScenarioIndexItem {
1681
1695
  message: string;
1682
1696
  stack?: string;
1683
1697
  };
1698
+ /**
1699
+ * Whether the scenario's claim was checked: `asserted`, `unasserted`, or
1700
+ * `unobserved` where the adapter cannot count. A passing scenario that is
1701
+ * `unasserted` ran and proved nothing.
1702
+ */
1703
+ assertionState: "asserted" | "unasserted" | "unobserved";
1684
1704
  }
1685
1705
  interface ScenarioIndexStep {
1686
1706
  id: string;
@@ -1691,6 +1711,11 @@ interface ScenarioIndexStep {
1691
1711
  durationMs: number;
1692
1712
  errorMessage?: string;
1693
1713
  docKinds: string[];
1714
+ /**
1715
+ * Assertions the framework observed. Absent means the adapter has no counter;
1716
+ * `0` means it counted none. Never defaulted — the difference is the point.
1717
+ */
1718
+ assertions?: number;
1694
1719
  }
1695
1720
  interface ScenarioIndexFilters {
1696
1721
  statuses?: TestStatus$1[];
@@ -2776,6 +2801,8 @@ interface CheckArgs {
2776
2801
  testCases: TestCaseResult[];
2777
2802
  /** Baseline scenario statuses keyed by scenario id, for regressed/fixed deltas. */
2778
2803
  baseline?: Map<string, TestStatus>;
2804
+ /** Per-scenario time budget. Scenarios above it are named (see {@link CheckSlow}). */
2805
+ maxDurationMs?: number;
2779
2806
  format: "text" | "json";
2780
2807
  }
2781
2808
  type CheckDeps = Record<string, never>;
@@ -2814,6 +2841,17 @@ interface CheckTurnedOff {
2814
2841
  status: "skipped" | "pending";
2815
2842
  tickets: string[];
2816
2843
  }
2844
+ /**
2845
+ * A scenario that took longer than the budget. A slow suite is usually two or
2846
+ * three scenarios, and nobody knows which until something names them.
2847
+ */
2848
+ interface CheckSlow {
2849
+ id: string;
2850
+ scenario: string;
2851
+ /** `sourceFile:sourceLine` */
2852
+ location: string;
2853
+ durationMs: number;
2854
+ }
2817
2855
  interface CheckReport {
2818
2856
  summary: {
2819
2857
  total: number;
@@ -2825,6 +2863,10 @@ interface CheckReport {
2825
2863
  failures: CheckFailure[];
2826
2864
  /** Scenarios switched off — named, not just counted (see {@link CheckTurnedOff}). */
2827
2865
  turnedOff: CheckTurnedOff[];
2866
+ /** Scenarios over `--max-duration`, longest first. Empty without a budget. */
2867
+ overBudget: CheckSlow[];
2868
+ /** The budget those scenarios broke, for the message that names it. */
2869
+ maxDurationMs?: number;
2828
2870
  /** Count of scenarios that went passed → failed vs. the baseline. */
2829
2871
  regressed: number;
2830
2872
  /** Count of scenarios that went failed → passed vs. the baseline. */
@@ -2900,6 +2942,22 @@ type GoalDeps = Record<string, never>;
2900
2942
  declare function buildGoal(args: GoalArgs, _deps?: GoalDeps): GoalReport;
2901
2943
  declare function renderGoal(report: GoalReport, format: "text" | "json"): string;
2902
2944
 
2945
+ /**
2946
+ * CODEOWNERS parsing, so a failing scenario can name the team that fixes it.
2947
+ *
2948
+ * A red run that belongs to everyone belongs to nobody until someone
2949
+ * volunteers. `triage --by-owner` groups the worklist the way the repo already
2950
+ * divides responsibility, using the file every GitHub repo already has.
2951
+ *
2952
+ * Supports the common CODEOWNERS subset — leading `/`, trailing `/`,
2953
+ * `*`, `**`, and bare extension globs. Character classes, `?`, and negation are
2954
+ * not implemented; swap in a gitignore-grade matcher if a repo needs them.
2955
+ */
2956
+ interface CodeownersRule {
2957
+ pattern: string;
2958
+ owners: string[];
2959
+ }
2960
+
2903
2961
  /**
2904
2962
  * `triage` — the discovery-phase worklist for an agent loop.
2905
2963
  *
@@ -2920,6 +2978,8 @@ interface TriageItem {
2920
2978
  /** Product-code paths to fix. Empty when the scenario declared no `covers`. */
2921
2979
  covers: string[];
2922
2980
  tickets: string[];
2981
+ /** CODEOWNERS entries for the code this scenario covers. Empty = unclaimed. */
2982
+ owners: string[];
2923
2983
  errorMessage?: string;
2924
2984
  /** Passed in the baseline, failing now. Ranked first. */
2925
2985
  regressed: boolean;
@@ -2938,10 +2998,16 @@ interface TriageArgs {
2938
2998
  /** Baseline statuses by scenario id, to flag regressions and rank them first. */
2939
2999
  baseline?: Map<string, TestStatus>;
2940
3000
  format: "text" | "json";
3001
+ /** Parsed CODEOWNERS. Without it every item is unowned. */
3002
+ codeowners?: readonly CodeownersRule[];
2941
3003
  }
2942
3004
  type TriageDeps = Record<string, never>;
2943
3005
  declare function buildTriage(args: TriageArgs, _deps?: TriageDeps): TriageReport;
2944
- declare function renderTriage(report: TriageReport, format: "text" | "json"): string;
3006
+ interface RenderTriageOptions {
3007
+ /** Group the text worklist under each CODEOWNERS owner. */
3008
+ byOwner?: boolean;
3009
+ }
3010
+ declare function renderTriage(report: TriageReport, format: "text" | "json", options?: RenderTriageOptions): string;
2945
3011
 
2946
3012
  /**
2947
3013
  * ReportGenerator — turns a canonical TestRunResult into report files.