lynkeus 0.2.0 → 0.4.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.
Files changed (134) hide show
  1. package/lib/cases/ahead.d.ts +31 -0
  2. package/lib/cases/ahead.js +90 -0
  3. package/lib/cases/fixtures.d.ts +12 -0
  4. package/lib/cases/fixtures.js +32 -0
  5. package/lib/cases/flakes.d.ts +28 -0
  6. package/lib/cases/flakes.js +61 -0
  7. package/lib/cases/format.d.ts +5 -0
  8. package/lib/cases/format.js +30 -4
  9. package/lib/cases/portClaim.d.ts +10 -0
  10. package/lib/cases/portClaim.js +55 -0
  11. package/lib/cases/runfile.d.ts +24 -0
  12. package/lib/cases/runfile.js +108 -0
  13. package/lib/cases/runner.d.ts +82 -3
  14. package/lib/cases/runner.js +394 -40
  15. package/lib/cases/templates.d.ts +2 -2
  16. package/lib/cases/templates.js +14 -4
  17. package/lib/cases/traces.d.ts +58 -0
  18. package/lib/cases/traces.js +250 -0
  19. package/lib/cli.js +28 -7
  20. package/lib/commands/cases.js +411 -42
  21. package/lib/commands/check.d.ts +6 -0
  22. package/lib/commands/check.js +8 -3
  23. package/lib/commands/doctor.js +8 -2
  24. package/lib/commands/drive.js +32 -8
  25. package/lib/commands/headless.js +132 -8
  26. package/lib/commands/init.d.ts +29 -0
  27. package/lib/commands/init.js +295 -33
  28. package/lib/commands/report.d.ts +97 -0
  29. package/lib/commands/report.js +228 -0
  30. package/lib/config.d.ts +26 -1
  31. package/lib/config.js +30 -0
  32. package/lib/device/agentVersion.d.ts +7 -0
  33. package/lib/device/agentVersion.js +12 -0
  34. package/lib/device/devices.d.ts +5 -0
  35. package/lib/device/devices.js +27 -0
  36. package/lib/device/driver.js +2 -2
  37. package/lib/flow/runner.js +33 -1
  38. package/lib/flow/types.d.ts +2 -1
  39. package/lib/knowledge/contrast.d.ts +45 -0
  40. package/lib/knowledge/contrast.js +114 -0
  41. package/lib/knowledge/errors.js +1 -1
  42. package/lib/knowledge/lint.d.ts +2 -0
  43. package/lib/knowledge/lint.js +13 -3
  44. package/lib/mcp/server.js +31 -2
  45. package/lib/registry.d.ts +5 -0
  46. package/lib/targets.d.ts +10 -1
  47. package/lib/targets.js +16 -3
  48. package/package.json +10 -6
  49. package/src/cases/ahead.ts +111 -0
  50. package/src/cases/fixtures.ts +37 -0
  51. package/src/cases/flakes.ts +67 -0
  52. package/src/cases/format.ts +31 -6
  53. package/src/cases/portClaim.ts +52 -0
  54. package/src/cases/runfile.ts +119 -0
  55. package/src/cases/runner.ts +454 -46
  56. package/src/cases/templates.ts +14 -4
  57. package/src/cases/traces.ts +298 -0
  58. package/src/cli.ts +29 -7
  59. package/src/commands/cases.ts +428 -41
  60. package/src/commands/check.ts +11 -4
  61. package/src/commands/doctor.ts +9 -2
  62. package/src/commands/drive.ts +31 -8
  63. package/src/commands/headless.ts +143 -8
  64. package/src/commands/init.ts +338 -30
  65. package/src/commands/report.ts +272 -0
  66. package/src/config.ts +39 -2
  67. package/src/device/agentVersion.ts +15 -0
  68. package/src/device/devices.ts +28 -0
  69. package/src/device/driver.ts +2 -2
  70. package/src/flow/runner.ts +35 -1
  71. package/src/flow/types.ts +2 -2
  72. package/src/knowledge/contrast.ts +135 -0
  73. package/src/knowledge/errors.ts +1 -1
  74. package/src/knowledge/lint.ts +15 -4
  75. package/src/mcp/server.ts +31 -2
  76. package/src/registry.ts +2 -0
  77. package/src/targets.ts +17 -3
  78. package/lib/__tests__/args.test.d.ts +0 -1
  79. package/lib/__tests__/args.test.js +0 -69
  80. package/lib/__tests__/check.test.d.ts +0 -1
  81. package/lib/__tests__/check.test.js +0 -60
  82. package/lib/__tests__/init.test.d.ts +0 -1
  83. package/lib/__tests__/init.test.js +0 -42
  84. package/lib/__tests__/record.test.d.ts +0 -1
  85. package/lib/__tests__/record.test.js +0 -44
  86. package/lib/__tests__/snapshot.test.d.ts +0 -1
  87. package/lib/__tests__/snapshot.test.js +0 -47
  88. package/lib/__tests__/targets.test.d.ts +0 -1
  89. package/lib/__tests__/targets.test.js +0 -127
  90. package/lib/cases/__tests__/format.test.d.ts +0 -1
  91. package/lib/cases/__tests__/format.test.js +0 -61
  92. package/lib/cases/__tests__/runner.test.d.ts +0 -1
  93. package/lib/cases/__tests__/runner.test.js +0 -188
  94. package/lib/knowledge/__tests__/edges.test.d.ts +0 -1
  95. package/lib/knowledge/__tests__/edges.test.js +0 -25
  96. package/lib/knowledge/__tests__/events.test.d.ts +0 -1
  97. package/lib/knowledge/__tests__/events.test.js +0 -39
  98. package/lib/knowledge/__tests__/extract.test.d.ts +0 -1
  99. package/lib/knowledge/__tests__/extract.test.js +0 -69
  100. package/lib/knowledge/__tests__/frontier.test.d.ts +0 -1
  101. package/lib/knowledge/__tests__/frontier.test.js +0 -57
  102. package/lib/knowledge/__tests__/funnels.test.d.ts +0 -1
  103. package/lib/knowledge/__tests__/funnels.test.js +0 -40
  104. package/lib/knowledge/__tests__/lint.test.d.ts +0 -1
  105. package/lib/knowledge/__tests__/lint.test.js +0 -53
  106. package/lib/knowledge/__tests__/perf.test.d.ts +0 -1
  107. package/lib/knowledge/__tests__/perf.test.js +0 -34
  108. package/lib/knowledge/__tests__/plan.test.d.ts +0 -1
  109. package/lib/knowledge/__tests__/plan.test.js +0 -35
  110. package/lib/knowledge/__tests__/query.test.d.ts +0 -1
  111. package/lib/knowledge/__tests__/query.test.js +0 -55
  112. package/lib/knowledge/__tests__/screens.test.d.ts +0 -1
  113. package/lib/knowledge/__tests__/screens.test.js +0 -30
  114. package/lib/knowledge/__tests__/why.test.d.ts +0 -1
  115. package/lib/knowledge/__tests__/why.test.js +0 -28
  116. package/src/__tests__/args.test.ts +0 -82
  117. package/src/__tests__/check.test.ts +0 -71
  118. package/src/__tests__/init.test.ts +0 -52
  119. package/src/__tests__/record.test.ts +0 -49
  120. package/src/__tests__/snapshot.test.ts +0 -51
  121. package/src/__tests__/targets.test.ts +0 -132
  122. package/src/cases/__tests__/format.test.ts +0 -76
  123. package/src/cases/__tests__/runner.test.ts +0 -230
  124. package/src/knowledge/__tests__/edges.test.ts +0 -34
  125. package/src/knowledge/__tests__/events.test.ts +0 -45
  126. package/src/knowledge/__tests__/extract.test.ts +0 -88
  127. package/src/knowledge/__tests__/frontier.test.ts +0 -77
  128. package/src/knowledge/__tests__/funnels.test.ts +0 -58
  129. package/src/knowledge/__tests__/lint.test.ts +0 -66
  130. package/src/knowledge/__tests__/perf.test.ts +0 -41
  131. package/src/knowledge/__tests__/plan.test.ts +0 -52
  132. package/src/knowledge/__tests__/query.test.ts +0 -74
  133. package/src/knowledge/__tests__/screens.test.ts +0 -37
  134. package/src/knowledge/__tests__/why.test.ts +0 -40
@@ -1,10 +1,28 @@
1
1
  import { type AppEvent, type RunEvent } from '../knowledge/events.js';
2
2
  import { type Base, type Command } from '../registry.js';
3
3
  import type { Fixtures, FixturesConfig } from './fixtures.js';
4
- import { type Case, type StepValue } from './format.js';
4
+ import { type BackendSpan, type TraceSink } from './traces.js';
5
+ import { type Case, type Scope, type StepValue } from './format.js';
6
+ export type NativeMock = {
7
+ result?: unknown;
8
+ screen?: {
9
+ title?: string;
10
+ subtitle?: string;
11
+ image?: string;
12
+ buttons?: Record<string, unknown>;
13
+ };
14
+ };
5
15
  export type CasesConfig = {
6
16
  /** The folder of the file that declared this, set when the configuration is read. */
7
17
  base?: string;
18
+ /**
19
+ * What native SDKs a headless host cannot run answer, keyed `Module.method` (the native module's name, as
20
+ * `NativeModules` has it): `result` is what the call resolves with; `screen` puts up a stand-in page with a
21
+ * `title`, an optional `subtitle` and `image` (a URI), and `buttons`, label to result, each pressable as
22
+ * `#native-mock-<label>`. Sent to the app at the start of every case; a step changes it with
23
+ * `app.call: { command: nativeMocks, params: { set: { … } } }`, and `null` takes a key's mock away.
24
+ */
25
+ nativeMocks?: Record<string, NativeMock | null>;
8
26
  /** Where cases live (default `cases`). */
9
27
  dir?: string;
10
28
  /** Where the flows a case runs live (default `flows`). */
@@ -24,17 +42,33 @@ export type CasesConfig = {
24
42
  unless?: string;
25
43
  }[];
26
44
  };
45
+ /** What a host's analytics capture saw a step send: the SDK it went to and the event. */
46
+ export type SentEvent = {
47
+ provider: string;
48
+ name: string;
49
+ props?: Record<string, unknown>;
50
+ };
51
+ /** `unsupported`: the host the case ran on has no such thing to do (a real device has no mocked responses), which says nothing about the app. */
27
52
  export type StepReport = {
28
53
  step: string;
29
- status: 'passed' | 'failed' | 'skipped';
54
+ status: 'passed' | 'failed' | 'skipped' | 'unsupported';
30
55
  ms: number;
31
56
  error?: string;
57
+ /** A frame of the screen once the step was done, an absolute path. */
58
+ screenshot?: string;
59
+ /** The second of the case's film at which the step began. */
60
+ videoS?: number;
61
+ /** What the step made the app send its analytics SDKs, where the host captures them. */
62
+ sent?: SentEvent[];
63
+ /** What the backend did for it, from the traces it exported to the run. */
64
+ backend?: BackendSpan[];
32
65
  };
33
66
  export type CaseReport = {
34
67
  id: string;
35
68
  title?: string;
36
69
  file: string;
37
- result: 'passed' | 'failed';
70
+ /** `unsupported`: a step could not be done on this host, so the case proved nothing here; it did not fail. */
71
+ result: 'passed' | 'failed' | 'unsupported';
38
72
  ms: number;
39
73
  steps: StepReport[];
40
74
  /** When a step failed: the screen, the requests since the mark, and why. */
@@ -45,17 +79,62 @@ export type CaseReport = {
45
79
  };
46
80
  /** What the app told its analytics, each with the step that caused it, when the run asked for it. */
47
81
  events?: RunEvent[];
82
+ /** The case's film, an absolute path, where the host films. */
83
+ video?: string;
84
+ /** Every screen the app went through while the case ran, when the run asked for them (`routes`). */
85
+ routes?: string[];
86
+ /** Why it failed, read as rules from the screen, the requests and the trace (`lynkeus why`). */
87
+ diagnosis?: string[];
88
+ };
89
+ /** Where a case keeps what it can show of itself: a frame per step, a film. Each is taken only where the host can. */
90
+ export type Evidence = {
91
+ dir: string;
92
+ screenshots?: boolean;
93
+ settleMs?: number;
94
+ video?: {
95
+ fps: number;
96
+ scale?: number;
97
+ };
48
98
  };
49
99
  export type RunOptions = {
50
100
  base: Base;
101
+ /** Where the backend's traces arrive during the run: each app step's requests carry its id. */
102
+ traces?: TraceSink;
51
103
  config: CasesConfig;
52
104
  fixtures?: Fixtures;
53
105
  dry?: boolean;
54
106
  events?: boolean;
107
+ evidence?: Evidence;
55
108
  log?: (line: string) => void;
109
+ /** The case's setup, already run by `case prepare`: the case starts from here. */
110
+ prepared?: Prepared;
111
+ /** Run only the setup and hand what it left to `keep`, for a case that will run later. */
112
+ setupOnly?: {
113
+ keep: (prepared: Prepared) => void;
114
+ };
115
+ /** Keep running a case's steps after one fails, to see everything that is wrong in one pass. */
116
+ continue?: boolean;
117
+ /** Collect the screens the app went through, for a coverage map. `fresh`: the app was started for this case. */
118
+ routes?: boolean | 'fresh';
119
+ };
120
+ /** What a case's setup leaves for its steps: the aliases and what they answered, and what ran. */
121
+ export type Prepared = {
122
+ scope: Scope;
123
+ latest: Record<string, unknown>;
124
+ ran: string[];
125
+ steps: StepReport[];
56
126
  };
127
+ /** A setup made only of the project's fixtures can run before the case, with no app attached. */
128
+ export declare const preparable: (c: Case, config: CasesConfig) => boolean;
57
129
  /** What a buffer holds that it did not before, whichever end it grows from. */
58
130
  export declare const newSince: (before: AppEvent[], now: AppEvent[]) => AppEvent[];
59
131
  /** A step's value as the argv of the command it names: what matches a positional by name goes in place, the rest are flags. */
60
132
  export declare const argvFor: (command: Command, value: StepValue) => string[];
133
+ /**
134
+ * The fixtures a case names that the project's server did not list. A macro's
135
+ * own steps are the project's to keep right; these are the ones written in the case.
136
+ */
137
+ export declare const missingFixtures: (c: Case, config: CasesConfig, known: string[]) => string[];
138
+ /** What the app or its host answers to a method it does not have; the name is what it lacks. */
139
+ export declare const lacking: (message: string) => string | undefined;
61
140
  export declare const runCase: (c: Case, options: RunOptions) => Promise<CaseReport>;