executable-stories-formatters 1.9.2 → 1.11.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.ts CHANGED
@@ -718,6 +718,503 @@ interface IJsonFeature {
718
718
  uri: string;
719
719
  }
720
720
 
721
+ /**
722
+ * The test-management port.
723
+ *
724
+ * One interface, one engine, adapters per provider. Everything the engine does
725
+ * — matching, planning, drift detection, lockfile bookkeeping, reporting — is
726
+ * written once against these types. An adapter's only job is to translate
727
+ * between them and a vendor API.
728
+ *
729
+ * Adding a provider is one file in `adapters/` plus one line in
730
+ * `adapters/index.ts`, with no edits to `engine.ts`. If a new adapter forces an
731
+ * engine change, this port is wrong and gets fixed then, on evidence.
732
+ *
733
+ * Every method except `listCases` is optional. A read-only provider implements
734
+ * `listCases` alone and still produces a full coverage report; the engine
735
+ * reports the missing capabilities in the plan instead of failing.
736
+ */
737
+ /** A test case as it exists in the provider, normalized. */
738
+ interface RemoteCase {
739
+ /** Provider-native id, e.g. TestRail "1234" or Xray "PROJ-42". */
740
+ id: string;
741
+ /** Canonical URL a human can open. */
742
+ url: string;
743
+ title: string;
744
+ /** Suite, folder, or component — whatever the provider groups by. */
745
+ section?: string;
746
+ /**
747
+ * The content the provider currently holds, when it can supply it.
748
+ *
749
+ * Drift detection hashes this, not what we sent: providers normalize markup
750
+ * on write, so hashing the request would flag every case as human-edited on
751
+ * the very next run.
752
+ */
753
+ body?: CaseBody;
754
+ }
755
+ /** A story projected into provider-neutral case content. */
756
+ interface CaseBody {
757
+ title: string;
758
+ steps: ReadonlyArray<{
759
+ keyword: string;
760
+ text: string;
761
+ }>;
762
+ /** Story docs rendered to plain text/markdown; adapters convert as needed. */
763
+ description: string;
764
+ links: ReadonlyArray<{
765
+ label: string;
766
+ url: string;
767
+ }>;
768
+ }
769
+ /** Evidence uploaded alongside a result. */
770
+ interface ResultAttachment {
771
+ filename: string;
772
+ mediaType: string;
773
+ body: Uint8Array;
774
+ role?: "screenshot" | "video" | "trace" | "log";
775
+ }
776
+ /** One execution record to push. */
777
+ interface CaseResult {
778
+ caseId: string;
779
+ status: "passed" | "failed" | "skipped";
780
+ durationMs: number;
781
+ message?: string;
782
+ /** Deep link into the generated HTML report for this scenario. */
783
+ url?: string;
784
+ attachments?: ResultAttachment[];
785
+ }
786
+ /** What a provider did with a batch of results. */
787
+ interface RecordResultsSummary {
788
+ /** Provider-native run/execution id, when one was created. */
789
+ runId?: string;
790
+ /** URL of the created run/execution, when the provider exposes one. */
791
+ runUrl?: string;
792
+ recorded: number;
793
+ /** Results the provider declined (e.g. no status mapping configured). */
794
+ skipped: Array<{
795
+ caseId: string;
796
+ reason: string;
797
+ }>;
798
+ attachmentsUploaded: number;
799
+ }
800
+ /**
801
+ * A test-management system, reduced to what the engine needs.
802
+ *
803
+ * `createCase`/`updateCase` return the resulting {@link RemoteCase} rather than
804
+ * just an id so the engine can hash the provider's own normalized copy.
805
+ */
806
+ interface SyncProvider {
807
+ /** Stable key used in config, CLI args, and the lockfile. */
808
+ name: string;
809
+ listCases(): Promise<RemoteCase[]>;
810
+ createCase?(body: CaseBody): Promise<RemoteCase>;
811
+ updateCase?(id: string, body: CaseBody): Promise<RemoteCase>;
812
+ recordResults?(results: CaseResult[]): Promise<RecordResultsSummary>;
813
+ /**
814
+ * Per-file limit. The engine skips oversized attachments and reports them in
815
+ * the plan, rather than letting an adapter die mid-upload with half a run
816
+ * already pushed.
817
+ */
818
+ maxAttachmentBytes?: number;
819
+ /** Human-readable target, shown in the plan header (e.g. "ACME / Regression"). */
820
+ describeTarget?(): string;
821
+ }
822
+ /** Injectable dependencies shared by every adapter. */
823
+ interface AdapterDeps {
824
+ fetch: typeof globalThis.fetch;
825
+ logger: {
826
+ warn(msg: string): void;
827
+ };
828
+ }
829
+
830
+ /**
831
+ * The sync lockfile: the binding between a behaviour in the codebase and a case
832
+ * in someone else's system.
833
+ *
834
+ * Committed to the repo on purpose. When CI creates a case, the lockfile diff
835
+ * shows up in the pull request that caused it, so a reviewer sees the new case
836
+ * and its link before it lands anywhere else.
837
+ *
838
+ * Keyed on `behaviourFingerprint` (content-derived) rather than the canonical
839
+ * test-case id (`sha1(sourceFile::scenario)`), which changes the moment someone
840
+ * renames a test or moves a file. Keying on the volatile id would orphan every
841
+ * case on the first rename, which is exactly how these integrations lose trust.
842
+ */
843
+
844
+ declare const DEFAULT_LOCKFILE_PATH = ".executable-stories/sync.lock.json";
845
+ /** One behaviour-to-case binding. */
846
+ interface LockEntry {
847
+ /** Provider-native case id. */
848
+ caseId: string;
849
+ url: string;
850
+ /**
851
+ * Hash of the provider's normalized copy as of our last write. A mismatch on
852
+ * the next run means a human edited the case in the provider's UI.
853
+ */
854
+ hash: string;
855
+ /** Last known title, so orphan reports are readable without a remote lookup. */
856
+ title: string;
857
+ /**
858
+ * True only for cases this tool created.
859
+ *
860
+ * A case reached through a `story.tickets` id was authored by a human, so we
861
+ * push executions against it and never touch its body. Without this flag the
862
+ * first sync would silently overwrite hand-written cases, which is the single
863
+ * fastest way to lose a QA team.
864
+ */
865
+ owned: boolean;
866
+ }
867
+ interface Lockfile {
868
+ version: number;
869
+ /** provider name -> behaviour fingerprint -> entry */
870
+ providers: Record<string, Record<string, LockEntry>>;
871
+ }
872
+ declare function emptyLockfile(): Lockfile;
873
+ /**
874
+ * Hash provider-normalized case content.
875
+ *
876
+ * Deliberately excludes `links`: those embed report URLs that change with every
877
+ * CI run (build number, artifact host), and treating that churn as a human edit
878
+ * would make the drift guard fire constantly and get switched off.
879
+ */
880
+ declare function hashCaseBody(body: CaseBody): string;
881
+ /**
882
+ * Parse lockfile text. `label` names the source in errors, so the caller decides
883
+ * whether that is a path, a URL, or something else entirely.
884
+ *
885
+ * Split from {@link readLockfile} so the CLI can route every read and write
886
+ * through its injected file dependencies and still share these error messages.
887
+ */
888
+ declare function parseLockfile(contents: string, label: string): Lockfile;
889
+ /** Serialize with sorted keys so the diff a reviewer sees is minimal and stable. */
890
+ declare function serializeLockfile(lock: Lockfile): string;
891
+ declare function readLockfile(file: string): Lockfile;
892
+ declare function writeLockfile(file: string, lock: Lockfile): void;
893
+
894
+ /**
895
+ * Provider-agnostic sync engine.
896
+ *
897
+ * Everything that is not a vendor API call lives here: projecting stories into
898
+ * case bodies, binding them to remote cases, classifying what the provider
899
+ * holds, building the plan, and applying it. Adapters stay thin.
900
+ *
901
+ * Two phases, deliberately separate so `--dry-run` and a real run share one code
902
+ * path: {@link analyzeSync} reads and decides, {@link applySync} writes.
903
+ *
904
+ * fn(args, deps) throughout.
905
+ */
906
+
907
+ /** Which executions get their evidence uploaded. */
908
+ type AttachPolicy = "failed" | "all" | "none";
909
+ interface SyncEngineConfig {
910
+ /**
911
+ * Ticket-id prefix that marks a `story.tickets` entry as this provider's case
912
+ * id (TestRail's "C1234"). Without it, only the lockfile binds.
913
+ */
914
+ ticketPrefix?: string;
915
+ /**
916
+ * Whether the prefix is decoration to strip ("C1234" -> "1234", TestRail) or
917
+ * part of the id itself ("PROJ-42" stays whole, Xray/Jira). Default true.
918
+ */
919
+ ticketPrefixStrip?: boolean;
920
+ /** Base URL of the published HTML report, used for links back from cases. */
921
+ reportUrl?: string;
922
+ /**
923
+ * Turns a scenario into the fragment appended to `reportUrl`, for a link that
924
+ * lands on the scenario rather than the top of the page.
925
+ *
926
+ * Caller-supplied for the same reason the markdown formatter's option is
927
+ * (`types/options.ts`): the correct slug depends on how the docs site routes,
928
+ * and guessing it produces links that 404. Without it, cases link to the
929
+ * report page itself.
930
+ */
931
+ scenarioAnchor?: (tc: TestCaseResult) => string | undefined;
932
+ /** Default "failed": nobody watches a passing test's video, and quotas are real. */
933
+ attach?: AttachPolicy;
934
+ /** Similarity at or above which an unlinked case is flagged as a possible duplicate. */
935
+ duplicateThreshold?: number;
936
+ }
937
+ /** A story, ready to be a case. */
938
+ interface LocalBehaviour {
939
+ fingerprint: string;
940
+ testCase: TestCaseResult;
941
+ body: CaseBody;
942
+ }
943
+ type CoverageClass = "automated" | "duplicated" | "possible-duplicate" | "manual-only";
944
+ interface ClassifiedCase {
945
+ case: RemoteCase;
946
+ classification: CoverageClass;
947
+ /** Scenario title this case resembles or duplicates, when one was found. */
948
+ resembles?: string;
949
+ /** 0..1, present for "possible-duplicate". */
950
+ similarity?: number;
951
+ }
952
+ interface PlanCreate {
953
+ fingerprint: string;
954
+ scenario: string;
955
+ body: CaseBody;
956
+ }
957
+ interface PlanUpdate {
958
+ fingerprint: string;
959
+ caseId: string;
960
+ url: string;
961
+ scenario: string;
962
+ body: CaseBody;
963
+ }
964
+ interface PlanSkip {
965
+ fingerprint: string;
966
+ caseId: string;
967
+ url: string;
968
+ title: string;
969
+ reason: "remote-edited" | "case-missing";
970
+ }
971
+ interface PlanOrphan {
972
+ fingerprint: string;
973
+ caseId: string;
974
+ url: string;
975
+ title: string;
976
+ }
977
+ interface AttachmentSummary {
978
+ files: number;
979
+ bytes: number;
980
+ oversized: Array<{
981
+ filename: string;
982
+ bytes: number;
983
+ limit: number;
984
+ }>;
985
+ byRole: Record<string, number>;
986
+ }
987
+ interface SyncAnalysis {
988
+ provider: string;
989
+ target?: string;
990
+ local: LocalBehaviour[];
991
+ remote: ClassifiedCase[];
992
+ create: PlanCreate[];
993
+ update: PlanUpdate[];
994
+ unchanged: PlanUpdate[];
995
+ /** Human-authored cases bound via `story.tickets`. Executions only, body untouched. */
996
+ adopted: PlanUpdate[];
997
+ skipped: PlanSkip[];
998
+ orphaned: PlanOrphan[];
999
+ /** Results for behaviours already bound. Newly created cases add theirs at apply time. */
1000
+ results: CaseResult[];
1001
+ attachments: AttachmentSummary;
1002
+ /** Capabilities this provider lacks that the plan would otherwise use. */
1003
+ unsupported: string[];
1004
+ /**
1005
+ * Bound cases the provider would not hand back a body for, so a human edit to
1006
+ * them cannot be detected. Reported rather than assumed safe.
1007
+ */
1008
+ driftUncheckable: number;
1009
+ /** Set when the orphan count suggests the run was filtered rather than complete. */
1010
+ partialRunWarning?: string;
1011
+ }
1012
+ interface SyncApplyResult {
1013
+ created: Array<{
1014
+ scenario: string;
1015
+ caseId: string;
1016
+ url: string;
1017
+ }>;
1018
+ updated: Array<{
1019
+ scenario: string;
1020
+ caseId: string;
1021
+ url: string;
1022
+ }>;
1023
+ resultsRecorded: number;
1024
+ resultsSkipped: Array<{
1025
+ caseId: string;
1026
+ reason: string;
1027
+ }>;
1028
+ attachmentsUploaded: number;
1029
+ runUrl?: string;
1030
+ errors: string[];
1031
+ }
1032
+ /** Project one canonical test case into provider-neutral case content. */
1033
+ declare function toCaseBody(tc: TestCaseResult, config: SyncEngineConfig): CaseBody;
1034
+ /**
1035
+ * Project a run into fingerprinted behaviours.
1036
+ *
1037
+ * `behaviourFingerprint` returns "" for a scenario with no steps and no
1038
+ * `covers`, and two scenarios with identical steps collide. Both fall back to
1039
+ * the canonical test-case id, which is unique within a run — less
1040
+ * rename-resilient, but a stable binding beats a shared one.
1041
+ */
1042
+ declare function projectBehaviours(run: TestRunResult, config: SyncEngineConfig): LocalBehaviour[];
1043
+ /** Attachments for one test, filtered by policy and the provider's size limit. */
1044
+ declare function collectAttachments(args: {
1045
+ testCase: TestCaseResult;
1046
+ policy: AttachPolicy;
1047
+ maxBytes?: number;
1048
+ }): {
1049
+ attachments: ResultAttachment[];
1050
+ oversized: Array<{
1051
+ filename: string;
1052
+ bytes: number;
1053
+ limit: number;
1054
+ }>;
1055
+ };
1056
+ interface AnalyzeSyncArgs {
1057
+ run: TestRunResult;
1058
+ provider: SyncProvider;
1059
+ lockfile: Lockfile;
1060
+ config: SyncEngineConfig;
1061
+ }
1062
+ declare function analyzeSync(args: AnalyzeSyncArgs): Promise<SyncAnalysis>;
1063
+ interface ApplySyncArgs {
1064
+ analysis: SyncAnalysis;
1065
+ provider: SyncProvider;
1066
+ lockfile: Lockfile;
1067
+ config: SyncEngineConfig;
1068
+ }
1069
+ interface ApplySyncDeps {
1070
+ logger: {
1071
+ warn(msg: string): void;
1072
+ };
1073
+ }
1074
+ /**
1075
+ * Execute the plan. Mutates the passed lockfile so the caller can persist it
1076
+ * even when a later stage fails — a created case whose binding was lost would
1077
+ * be re-created on the next run, which is the one duplicate we can actually
1078
+ * cause.
1079
+ */
1080
+ declare function applySync(args: ApplySyncArgs, deps: ApplySyncDeps): Promise<SyncApplyResult>;
1081
+
1082
+ /**
1083
+ * TestRail adapter.
1084
+ *
1085
+ * Translates between the sync port and TestRail's API v2. All decisions about
1086
+ * what to write live in the engine; this file only knows how TestRail spells
1087
+ * things.
1088
+ *
1089
+ * Case templates differ per instance, which is why the step and description
1090
+ * field names are configurable. The defaults match TestRail's stock
1091
+ * "Test Case (Steps)" template.
1092
+ *
1093
+ * Auth: basic, with an API key rather than a password. Generate one under
1094
+ * My Settings -> API Keys.
1095
+ */
1096
+
1097
+ interface TestRailConfig {
1098
+ /** Instance URL, e.g. https://acme.testrail.io */
1099
+ url: string;
1100
+ projectId: number | string;
1101
+ /** Required on multi-suite projects. */
1102
+ suiteId?: number | string;
1103
+ /** Target section for created cases. Without it, creation is refused. */
1104
+ sectionId?: number | string;
1105
+ /** Reuse an existing run instead of creating one per sync. */
1106
+ runId?: number | string;
1107
+ /** Name for created runs. A UTC timestamp is appended. */
1108
+ runName?: string;
1109
+ /** Close the run after recording results. */
1110
+ closeRun?: boolean;
1111
+ /** Case template to create against, when the project uses a non-default one. */
1112
+ templateId?: number;
1113
+ /**
1114
+ * Result status ids. TestRail ships 1=Passed and 5=Failed; there is no stock
1115
+ * "skipped", so skipped results are dropped unless an id is configured.
1116
+ */
1117
+ statusIds?: {
1118
+ passed?: number;
1119
+ failed?: number;
1120
+ skipped?: number;
1121
+ };
1122
+ /** Field names, for instances with customised case templates. */
1123
+ fields?: {
1124
+ steps?: string;
1125
+ description?: string;
1126
+ };
1127
+ /**
1128
+ * Per-file attachment limit. Conservative by default: instances have storage
1129
+ * quotas, and a surprise 200 MB of video is a support ticket.
1130
+ */
1131
+ maxAttachmentBytes?: number;
1132
+ }
1133
+ interface TestRailAuth {
1134
+ username: string;
1135
+ apiKey: string;
1136
+ }
1137
+ declare function createTestRailProvider(config: TestRailConfig, auth: TestRailAuth, deps: AdapterDeps): SyncProvider;
1138
+
1139
+ /**
1140
+ * Xray (Jira Cloud) adapter.
1141
+ *
1142
+ * Xray splits its API in two and this adapter has to speak both: a GraphQL API
1143
+ * for test definitions, and a REST endpoint for importing execution results.
1144
+ * Evidence rides along with the results as base64, so screenshots and video
1145
+ * land on the execution without a separate upload call.
1146
+ *
1147
+ * A case id here is a Jira issue key ("PROJ-42"), not a number, which is why
1148
+ * `ticketPrefixStrip: false` is the right engine setting for this provider.
1149
+ *
1150
+ * Auth: an Xray API key pair (client id + secret) from Jira Settings -> Apps ->
1151
+ * Xray -> API Keys. Updating an existing test's summary or description also
1152
+ * needs Jira credentials, because those are Jira fields Xray does not own.
1153
+ */
1154
+
1155
+ interface XrayConfig {
1156
+ /** Jira site URL, e.g. https://acme.atlassian.net */
1157
+ jiraBaseUrl: string;
1158
+ projectKey: string;
1159
+ /** Xray Cloud API base. */
1160
+ xrayBaseUrl?: string;
1161
+ /** Selects the existing tests to reconcile against. */
1162
+ jql?: string;
1163
+ /** Xray test type for created tests. */
1164
+ testType?: string;
1165
+ /** Link created executions to this test plan. */
1166
+ testPlanKey?: string;
1167
+ /** Push results into an existing execution instead of creating one. */
1168
+ testExecutionKey?: string;
1169
+ /** Summary for created executions. A UTC timestamp is appended. */
1170
+ executionSummary?: string;
1171
+ statuses?: {
1172
+ passed?: string;
1173
+ failed?: string;
1174
+ skipped?: string;
1175
+ };
1176
+ maxAttachmentBytes?: number;
1177
+ }
1178
+ interface XrayAuth {
1179
+ clientId: string;
1180
+ clientSecret: string;
1181
+ /** Atlassian account email, needed only to update Jira summary/description. */
1182
+ jiraEmail?: string;
1183
+ /** Atlassian API token, needed only to update Jira summary/description. */
1184
+ jiraToken?: string;
1185
+ }
1186
+ declare function createXrayProvider(config: XrayConfig, auth: XrayAuth, deps: AdapterDeps): SyncProvider;
1187
+
1188
+ /**
1189
+ * Provider registry.
1190
+ *
1191
+ * Adding a provider is one file next to this one plus one entry in the map
1192
+ * below. No dynamic import: the CLI ships as a Bun single binary, which cannot
1193
+ * see modules resolved at runtime, so adapters are in-tree by design.
1194
+ *
1195
+ * Credentials come from the environment only, never from the config file, so a
1196
+ * config can be committed without leaking anything.
1197
+ */
1198
+
1199
+ type ProviderName = "testrail" | "xray";
1200
+ /** Per-provider config as it appears under `sync` in executable-stories.config.mjs. */
1201
+ interface SyncTargets {
1202
+ testrail?: TestRailConfig & Partial<SyncEngineConfig>;
1203
+ xray?: XrayConfig & Partial<SyncEngineConfig>;
1204
+ }
1205
+ interface BuiltProvider {
1206
+ provider: SyncProvider;
1207
+ /** Engine defaults this provider implies, overridable per target in config. */
1208
+ engineDefaults: SyncEngineConfig;
1209
+ }
1210
+ declare const PROVIDER_NAMES: ProviderName[];
1211
+ declare function isProviderName(value: string): value is ProviderName;
1212
+ declare function buildProvider(args: {
1213
+ name: ProviderName;
1214
+ targets: SyncTargets;
1215
+ env: Record<string, string | undefined>;
1216
+ }, deps: AdapterDeps): BuiltProvider;
1217
+
721
1218
  interface Formatter {
722
1219
  name: string;
723
1220
  fileExtension?: string;
@@ -725,7 +1222,72 @@ interface Formatter {
725
1222
  }
726
1223
  interface ExecutableStoriesConfig {
727
1224
  formatters?: Record<string, Formatter>;
1225
+ /**
1226
+ * Test-management targets for `coverage` and `sync`. Shape only — credentials
1227
+ * are read from the environment so this file stays committable.
1228
+ */
1229
+ sync?: SyncTargets;
1230
+ }
1231
+
1232
+ /**
1233
+ * Rendering for the two things a human reads: the coverage report and the plan.
1234
+ *
1235
+ * Coverage answers "what does my test-management system hold that my tests
1236
+ * already cover?", which needs no write access and is the whole reason to try
1237
+ * this. The plan borrows `terraform plan` deliberately: the idiom is already in
1238
+ * everyone's head, and it is what makes pointing this at a company's TestRail
1239
+ * feel safe.
1240
+ *
1241
+ * Pure functions of a {@link SyncAnalysis}. No IO here.
1242
+ */
1243
+
1244
+ interface CoverageSummary {
1245
+ provider: string;
1246
+ target?: string;
1247
+ totalCases: number;
1248
+ automated: number;
1249
+ duplicated: number;
1250
+ possibleDuplicate: number;
1251
+ manualOnly: number;
1252
+ /** Stories with no case in the provider. */
1253
+ untracked: number;
1254
+ /** Stories whose case was reached through a human-authored ticket id. */
1255
+ adopted: number;
1256
+ }
1257
+ interface CoverageJson extends CoverageSummary {
1258
+ schema: "executable-stories/sync-coverage/v1";
1259
+ cases: Array<{
1260
+ id: string;
1261
+ url: string;
1262
+ title: string;
1263
+ section?: string;
1264
+ classification: ClassifiedCase["classification"];
1265
+ resembles?: string;
1266
+ similarity?: number;
1267
+ }>;
1268
+ untrackedScenarios: string[];
1269
+ orphaned: Array<{
1270
+ caseId: string;
1271
+ url: string;
1272
+ title: string;
1273
+ }>;
1274
+ sections: Array<{
1275
+ name: string;
1276
+ total: number;
1277
+ automated: number;
1278
+ }>;
728
1279
  }
1280
+ /** Human-readable coverage, the first thing anyone sees. */
1281
+ declare function renderCoverageText(analysis: SyncAnalysis): string;
1282
+ /** The same content as Markdown, so it can be pasted, published, or PR-commented. */
1283
+ declare function renderCoverageMarkdown(analysis: SyncAnalysis): string;
1284
+ declare function buildCoverageJson(analysis: SyncAnalysis): CoverageJson;
1285
+ /** terraform-plan-shaped output. Read before anything is written. */
1286
+ declare function renderPlan(analysis: SyncAnalysis, opts: {
1287
+ dryRun: boolean;
1288
+ }): string;
1289
+ /** What actually happened, printed after a real run. */
1290
+ declare function renderApplyResult(result: SyncApplyResult): string;
729
1291
 
730
1292
  /**
731
1293
  * Diff types — parsed unified patches and content-anchored annotation targets.
@@ -2793,4 +3355,4 @@ declare function normalizeVitestResults(testModules: Parameters<typeof adaptVite
2793
3355
  */
2794
3356
  declare function normalizePlaywrightResults(testResults: Parameters<typeof adaptPlaywrightRun>[0], adapterOptions?: Parameters<typeof adaptPlaywrightRun>[1], canonicalizeOptions?: CanonicalizeOptions): TestRunResult;
2795
3357
 
2796
- export { AgentTextFormatter, type AnchorResolution, type AnchorState, type AstroAssetResult, AstroFormatter, type AstroFormatterOptions as AstroFormatterOpts, type BehaviorDebuggerIssue, type BehaviorDiff, type BehaviorDiffEntry, type BehaviorManifest, BehaviorManifestJsonFormatter, type BehaviorManifestJsonOptions, type BehaviorSourceFile, type BehaviorTag, type BundleOptions, type BundleResult, type ChangeType, type ChangedFile, type ChangedFileReview, type CheckArgs, type CheckDeps, type CheckFailure, type CheckReport, type CheckStep, type CodeDiffAnnotation, type CodeDiffAnnotationInput, type CodeDiffEvidence, type CodeDiffInput, type CodeDiffScenarioRef, type CodeDiffSidecar, type CodeDiffSidecarAnnotation, type ColocatedStyle, type CompareFormat, type CompareFormatterOptions, type ConfluenceAuth, ConfluenceFormatter, type ConfluenceFormatterOptions as ConfluenceFormatterOpts, type CopyMarkdownAssetsOptions, CucumberHtmlFormatter, type CucumberHtmlOptions, CucumberJsonFormatter, type CucumberJsonOptions, CucumberMessagesFormatter, type CucumberMessagesOptions, type DeploymentEntry, type DeploymentLedger, type DeploymentStatus, type DiffAnchor, type DiffHunk, type DiffLine, type DiffRunsOptions, type EnvironmentDrift, type EvidenceStrength, type ExecutableStoriesConfig, type FetchFn, type FileChangeKind, type FileDiff, type FlakinessLevel, type Formatter, type FormatterOptions, type GenerateArgs, type GenerateCompareResult, type GenerateDeps, type GenerateResult, type GenericWebhookNotifierOptions, type GoalArgs, type GoalDeps, type GoalReport, type GoalRequirementResult, type HistoryEntry, type HistoryStore, type IJsonDataTable, type IJsonDocString, type IJsonEmbedding, type IJsonFeature, type IJsonScenario, type IJsonStep, type IJsonStepArgument, type IJsonStepResult, type IJsonTableRow, type IJsonTag, JUnitFormatter, type JUnitOptions, type JiraAuth, type JiraPublishMode, type ListScenariosArgs, type ListScenariosDeps, type Logger, MIN_FLAKINESS_SAMPLES, MIN_METRIC_SAMPLES, MIN_PERF_SAMPLES, MarkdownFormatter, type MarkdownFormatterOptions, type MarkdownOptions, type MarkdownRenderers, type NotificationSummary, type NotifyCondition, type OutputConfig, type OutputFormat, type OutputMode, type OutputRule, type PerformanceTrend, type PublishConfluenceArgs, type PublishConfluenceDeps, type PublishConfluenceResult, type PublishJiraArgs, type PublishJiraDeps, type PublishJiraResult, type RatchetViolation, type RecordDeploymentArgs, type RecordDeploymentResult, type ReleaseManifest, ReleaseManifestFormatter, ReportGenerator, type ResolvedFormatterOptions, type ReviewAudience, type ReviewBand, type ReviewClaim, type ReviewContext, ReviewHtmlFormatter, type ReviewHtmlOptions, ReviewMarkdownFormatter, type ReviewMarkdownOptions, type ReviewResult, type ReviewSummary, RunDiffChangelogFormatter, type RunDiffChangelogOptions, RunDiffHtmlFormatter, type RunDiffHtmlOptions, RunDiffMarkdownFormatter, type RunDiffMarkdownOptions, type RunDiffResult, type RunDiffSummary, type ScenarioChangeFlags, type ScenarioChangeKind, type ScenarioDiff, type ScenarioIndex, type ScenarioIndexFilters, type ScenarioIndexItem, ScenarioIndexJsonFormatter, type ScenarioIndexJsonOptions, type ScenarioIndexStep, type ScenarioSnapshot, type SortTestCasesMode, type StabilityGrade, type StarlightBadge, StoryReportJsonFormatter, type StoryReportJsonOptions, type TestHistory, type TestMetrics, TraceabilityCsvFormatter, type TraceabilityMatrix, TraceabilityMatrixFormatter, type TraceabilityRequirement, type TriageArgs, type TriageDeps, type TriageItem, type TriageReport, type WatchDeps, type WatchHandle, type WatchOptions, type WebhookPayload, type WebhookSignerHmac, type WriteFile, adaptJestRun, adaptPlaywrightRun, adaptVitestRun, assembleCodeDiff, buildCheck, buildGoal, buildReview, buildTriage, bundleAssets, calculateFlakiness, calculateStability, classifyStatusChange, clearVersionCache, codeDiffDiagnostics, computeTestMetrics, copyMarkdownAssets, createAnchor, createPrCommentSummary, createReportGenerator, deriveAudience, deriveChangeType, detectCI, detectPerformanceTrend, diffRuns, diffStoryReports, findGitDir, generateRunComparison, getDeploymentStatus, getEnvironmentDrift, gradeEvidence, hasSufficientHistory, isReviewableSource, isTestFile, joinNameAndExt, listScenarios, loadHistory, normalizeFormats, normalizeJestResults, normalizePlaywrightResults, normalizeVitestResults, parseUnifiedDiff, publishConfluencePage, publishJiraIssue, readBranchName, readGitSha, readPackageVersion, recordDeployment, regenerateArtifacts, regenerateRun, relocateAnchor, renderCheck, renderGoal, renderTriage, rewriteAssetPaths, saveHistory, scenariosCoveringPaths, sendNotifications, sendSlackNotification, sendTeamsNotification, sendWebhookNotification, signBody, startWatch, stripAnsi, toAgentText, toBehaviorManifest, toReleaseManifest, toScenarioIndex, toTraceabilityMatrix, updateHistory };
3358
+ export { type AdapterDeps, AgentTextFormatter, type AnchorResolution, type AnchorState, type AstroAssetResult, AstroFormatter, type AstroFormatterOptions as AstroFormatterOpts, type AttachPolicy, type BehaviorDebuggerIssue, type BehaviorDiff, type BehaviorDiffEntry, type BehaviorManifest, BehaviorManifestJsonFormatter, type BehaviorManifestJsonOptions, type BehaviorSourceFile, type BehaviorTag, type BundleOptions, type BundleResult, type CaseBody, type CaseResult, type ChangeType, type ChangedFile, type ChangedFileReview, type CheckArgs, type CheckDeps, type CheckFailure, type CheckReport, type CheckStep, type CodeDiffAnnotation, type CodeDiffAnnotationInput, type CodeDiffEvidence, type CodeDiffInput, type CodeDiffScenarioRef, type CodeDiffSidecar, type CodeDiffSidecarAnnotation, type ColocatedStyle, type CompareFormat, type CompareFormatterOptions, type ConfluenceAuth, ConfluenceFormatter, type ConfluenceFormatterOptions as ConfluenceFormatterOpts, type CopyMarkdownAssetsOptions, type CoverageClass, type CoverageJson, CucumberHtmlFormatter, type CucumberHtmlOptions, CucumberJsonFormatter, type CucumberJsonOptions, CucumberMessagesFormatter, type CucumberMessagesOptions, DEFAULT_LOCKFILE_PATH, type DeploymentEntry, type DeploymentLedger, type DeploymentStatus, type DiffAnchor, type DiffHunk, type DiffLine, type DiffRunsOptions, type EnvironmentDrift, type EvidenceStrength, type ExecutableStoriesConfig, type FetchFn, type FileChangeKind, type FileDiff, type FlakinessLevel, type Formatter, type FormatterOptions, type GenerateArgs, type GenerateCompareResult, type GenerateDeps, type GenerateResult, type GenericWebhookNotifierOptions, type GoalArgs, type GoalDeps, type GoalReport, type GoalRequirementResult, type HistoryEntry, type HistoryStore, type IJsonDataTable, type IJsonDocString, type IJsonEmbedding, type IJsonFeature, type IJsonScenario, type IJsonStep, type IJsonStepArgument, type IJsonStepResult, type IJsonTableRow, type IJsonTag, JUnitFormatter, type JUnitOptions, type JiraAuth, type JiraPublishMode, type ListScenariosArgs, type ListScenariosDeps, type LockEntry, type Lockfile, type Logger, MIN_FLAKINESS_SAMPLES, MIN_METRIC_SAMPLES, MIN_PERF_SAMPLES, MarkdownFormatter, type MarkdownFormatterOptions, type MarkdownOptions, type MarkdownRenderers, type NotificationSummary, type NotifyCondition, type OutputConfig, type OutputFormat, type OutputMode, type OutputRule, PROVIDER_NAMES, type PerformanceTrend, type ProviderName, type PublishConfluenceArgs, type PublishConfluenceDeps, type PublishConfluenceResult, type PublishJiraArgs, type PublishJiraDeps, type PublishJiraResult, type RatchetViolation, type RecordDeploymentArgs, type RecordDeploymentResult, type RecordResultsSummary, type ReleaseManifest, ReleaseManifestFormatter, type RemoteCase, ReportGenerator, type ResolvedFormatterOptions, type ResultAttachment, type ReviewAudience, type ReviewBand, type ReviewClaim, type ReviewContext, ReviewHtmlFormatter, type ReviewHtmlOptions, ReviewMarkdownFormatter, type ReviewMarkdownOptions, type ReviewResult, type ReviewSummary, RunDiffChangelogFormatter, type RunDiffChangelogOptions, RunDiffHtmlFormatter, type RunDiffHtmlOptions, RunDiffMarkdownFormatter, type RunDiffMarkdownOptions, type RunDiffResult, type RunDiffSummary, type ScenarioChangeFlags, type ScenarioChangeKind, type ScenarioDiff, type ScenarioIndex, type ScenarioIndexFilters, type ScenarioIndexItem, ScenarioIndexJsonFormatter, type ScenarioIndexJsonOptions, type ScenarioIndexStep, type ScenarioSnapshot, type SortTestCasesMode, type StabilityGrade, type StarlightBadge, StoryReportJsonFormatter, type StoryReportJsonOptions, type SyncAnalysis, type SyncApplyResult, type SyncEngineConfig, type SyncProvider, type SyncTargets, type TestHistory, type TestMetrics, type TestRailConfig, TraceabilityCsvFormatter, type TraceabilityMatrix, TraceabilityMatrixFormatter, type TraceabilityRequirement, type TriageArgs, type TriageDeps, type TriageItem, type TriageReport, type WatchDeps, type WatchHandle, type WatchOptions, type WebhookPayload, type WebhookSignerHmac, type WriteFile, type XrayConfig, adaptJestRun, adaptPlaywrightRun, adaptVitestRun, analyzeSync, applySync, assembleCodeDiff, buildCheck, buildCoverageJson, buildGoal, buildProvider, buildReview, buildTriage, bundleAssets, calculateFlakiness, calculateStability, classifyStatusChange, clearVersionCache, codeDiffDiagnostics, collectAttachments, computeTestMetrics, copyMarkdownAssets, createAnchor, createPrCommentSummary, createReportGenerator, createTestRailProvider, createXrayProvider, deriveAudience, deriveChangeType, detectCI, detectPerformanceTrend, diffRuns, diffStoryReports, emptyLockfile, findGitDir, generateRunComparison, getDeploymentStatus, getEnvironmentDrift, gradeEvidence, hasSufficientHistory, hashCaseBody, isProviderName, isReviewableSource, isTestFile, joinNameAndExt, listScenarios, loadHistory, normalizeFormats, normalizeJestResults, normalizePlaywrightResults, normalizeVitestResults, parseLockfile, parseUnifiedDiff, projectBehaviours, publishConfluencePage, publishJiraIssue, readBranchName, readGitSha, readLockfile, readPackageVersion, recordDeployment, regenerateArtifacts, regenerateRun, relocateAnchor, renderApplyResult, renderCheck, renderCoverageMarkdown, renderCoverageText, renderGoal, renderPlan, renderTriage, rewriteAssetPaths, saveHistory, scenariosCoveringPaths, sendNotifications, sendSlackNotification, sendTeamsNotification, sendWebhookNotification, serializeLockfile, signBody, startWatch, stripAnsi, toAgentText, toBehaviorManifest, toCaseBody, toReleaseManifest, toScenarioIndex, toTraceabilityMatrix, updateHistory, writeLockfile };