jev-devtools 0.4.1 → 0.5.1
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/README.md +22 -12
- package/lib/flow/compare.d.ts +61 -0
- package/lib/flow/compare.js +336 -0
- package/lib/flow/index.d.ts +6 -1
- package/lib/flow/index.js +87 -21
- package/lib/flow/replay.d.ts +5 -0
- package/lib/flow/replay.js +55 -0
- package/lib/flow/runtime.d.ts +4 -0
- package/lib/flow/runtime.js +74 -0
- package/lib/flow/step-context.d.ts +7 -0
- package/lib/flow/step-context.js +3 -0
- package/lib/server/flows.d.ts +2 -2
- package/lib/server/flows.js +4 -6
- package/lib/server/index.js +16 -4
- package/lib/server/recorder.js +42 -6
- package/lib/src/ConnectedInspector.d.ts +1 -1
- package/lib/src/ConnectedInspector.js +14 -3
- package/lib/src/CopyFixture.d.ts +22 -0
- package/lib/src/CopyFixture.js +67 -0
- package/lib/src/FlowOverview.js +4 -2
- package/lib/src/JevDevtools.js +1 -1
- package/lib/src/display-redaction.d.ts +9 -0
- package/lib/src/display-redaction.js +116 -0
- package/lib/src/flow-fixture.d.ts +19 -0
- package/lib/src/flow-fixture.js +40 -0
- package/lib/src/flow-stream.js +9 -0
- package/lib/src/index.d.ts +5 -0
- package/lib/src/index.js +1 -0
- package/lib/src/inspector-styles.js +1 -1
- package/lib/src/inspector.css +76 -2
- package/package.json +2 -2
- package/skills/setup-jev-devtools/SKILL.md +21 -4
- package/skills/setup-jev-devtools/references/flows.md +17 -4
- package/skills/setup-jev-devtools/references/verify.md +1 -3
package/lib/src/inspector.css
CHANGED
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
}
|
|
44
44
|
.jev-devtools button,
|
|
45
45
|
.jev-devtools input,
|
|
46
|
-
.jev-devtools select
|
|
46
|
+
.jev-devtools select,
|
|
47
|
+
.jev-devtools textarea {
|
|
47
48
|
font: inherit;
|
|
48
49
|
color: inherit;
|
|
49
50
|
border: 1px solid #3b303d;
|
|
@@ -66,7 +67,7 @@
|
|
|
66
67
|
.jev-devtools button:hover:not(:disabled) {
|
|
67
68
|
border-color: #e551ba;
|
|
68
69
|
}
|
|
69
|
-
.jev-devtools :is(button, input, select, summary):focus-visible {
|
|
70
|
+
.jev-devtools :is(button, input, select, textarea, summary):focus-visible {
|
|
70
71
|
outline: 2px solid #e551ba;
|
|
71
72
|
outline-offset: 3px;
|
|
72
73
|
}
|
|
@@ -1868,3 +1869,76 @@
|
|
|
1868
1869
|
:where(.jev-devtools) .flow-item-next {
|
|
1869
1870
|
right: -76px;
|
|
1870
1871
|
}
|
|
1872
|
+
.jev-devtools .flow-run-summary {
|
|
1873
|
+
text-align: right;
|
|
1874
|
+
}
|
|
1875
|
+
.jev-devtools .flow-fixture-button {
|
|
1876
|
+
display: block;
|
|
1877
|
+
margin: 6px 0 0 auto;
|
|
1878
|
+
/* Keep the header still when the shorter confirmation replaces the label. */
|
|
1879
|
+
min-width: 96px;
|
|
1880
|
+
font-size: 11px;
|
|
1881
|
+
transition: background-color 160ms ease, border-color 160ms ease;
|
|
1882
|
+
}
|
|
1883
|
+
.jev-devtools .flow-fixture-button[data-copied] {
|
|
1884
|
+
border-color: #e551ba;
|
|
1885
|
+
background: #382035;
|
|
1886
|
+
animation: jev-fixture-copied 200ms ease-out;
|
|
1887
|
+
}
|
|
1888
|
+
@keyframes jev-fixture-copied {
|
|
1889
|
+
from {
|
|
1890
|
+
transform: scale(0.96);
|
|
1891
|
+
}
|
|
1892
|
+
to {
|
|
1893
|
+
transform: scale(1);
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1897
|
+
.jev-devtools .flow-fixture-button {
|
|
1898
|
+
transition: none;
|
|
1899
|
+
}
|
|
1900
|
+
.jev-devtools .flow-fixture-button[data-copied] {
|
|
1901
|
+
animation: none;
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
.jev-devtools .flow-fixture {
|
|
1905
|
+
display: flex;
|
|
1906
|
+
flex-direction: column;
|
|
1907
|
+
align-items: flex-end;
|
|
1908
|
+
flex-shrink: 0;
|
|
1909
|
+
gap: 4px;
|
|
1910
|
+
padding: 0 24px;
|
|
1911
|
+
text-align: right;
|
|
1912
|
+
}
|
|
1913
|
+
.jev-devtools .flow-fixture p {
|
|
1914
|
+
margin: 0;
|
|
1915
|
+
max-width: 360px;
|
|
1916
|
+
font-size: 11px;
|
|
1917
|
+
}
|
|
1918
|
+
.jev-devtools .flow-fixture details {
|
|
1919
|
+
max-width: 360px;
|
|
1920
|
+
font-size: 11px;
|
|
1921
|
+
}
|
|
1922
|
+
.jev-devtools .flow-fixture details ul {
|
|
1923
|
+
max-height: 120px;
|
|
1924
|
+
margin: 4px 0 0;
|
|
1925
|
+
padding: 0;
|
|
1926
|
+
overflow: auto;
|
|
1927
|
+
list-style: none;
|
|
1928
|
+
font-family: "JetBrains Mono", monospace;
|
|
1929
|
+
overflow-wrap: anywhere;
|
|
1930
|
+
}
|
|
1931
|
+
.jev-devtools .flow-fixture details ul:focus-visible {
|
|
1932
|
+
outline: 2px solid #e551ba;
|
|
1933
|
+
outline-offset: 2px;
|
|
1934
|
+
}
|
|
1935
|
+
.jev-devtools .flow-fixture textarea {
|
|
1936
|
+
width: 360px;
|
|
1937
|
+
max-width: 100%;
|
|
1938
|
+
height: 120px;
|
|
1939
|
+
padding: 8px;
|
|
1940
|
+
font:
|
|
1941
|
+
11px "JetBrains Mono",
|
|
1942
|
+
monospace;
|
|
1943
|
+
text-align: left;
|
|
1944
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jev-devtools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.12"
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"url": "git+https://github.com/diegoag64/jev-devtools.git",
|
|
49
49
|
"directory": "packages/jev-devtools"
|
|
50
50
|
},
|
|
51
|
-
"homepage": "https://
|
|
51
|
+
"homepage": "https://jevtools.dev",
|
|
52
52
|
"bugs": "https://github.com/diegoag64/jev-devtools/issues",
|
|
53
53
|
"scripts": {
|
|
54
54
|
"check": "tsc --noEmit",
|
|
@@ -7,6 +7,8 @@ description: Install and verify Jev DevTools in an existing React application wi
|
|
|
7
7
|
|
|
8
8
|
Complete the integration in the user's application: one React drawer, one shared Node adapter, and application calls through that adapter's TypeSafe client. Installing or mounting the drawer alone does not capture requests.
|
|
9
9
|
|
|
10
|
+
The human guides live at [docs.jevtools.dev](https://docs.jevtools.dev/), and [jevtools.dev](https://jevtools.dev/) introduces the project. Prefer the installed package’s bundled recipe and declarations when online documentation targets a different version.
|
|
11
|
+
|
|
10
12
|
## Choose the integration
|
|
11
13
|
|
|
12
14
|
Inspect the app's package manager/lockfile, React and Node versions, root component, server entry point, existing TypeSafe client construction, and development URL. Preserve existing configuration, authentication, routes, providers, and client options. Follow the host project's instructions; this package's contributor workflow does not apply to consumer apps.
|
|
@@ -15,19 +17,34 @@ Inspect the app's package manager/lockfile, React and Node versions, root compon
|
|
|
15
17
|
- **React with a Node backend, including Vite:** read [references/react-node.md](references/react-node.md). A browser-only app needs a Node server for Jev; the Vite development-server option is local only.
|
|
16
18
|
- **Other Node frameworks:** use the Web Request/Response or middleware API described in the React/Node reference and verify that framework's routing. Do not assume the Next.js recipe applies to Pages Router. Edge runtimes and cross-process/serverless history aggregation are unsupported.
|
|
17
19
|
|
|
18
|
-
Install `jev-devtools` using the app's existing package manager (npm: `npm install jev-devtools @typesafe-ai/sdk`; pnpm: `pnpm add jev-devtools @typesafe-ai/sdk`; Yarn: `yarn add jev-devtools @typesafe-ai/sdk`). `@typesafe-ai/sdk` is a peer dependency: keep the app's existing SDK version when it satisfies the peer range. Install in the workspace(s) that actually import it. It is a regular dependency when application modules import it, even though capture/display are development-only.
|
|
20
|
+
Install `jev-devtools` using the app's existing package manager (npm: `npm install jev-devtools @typesafe-ai/sdk`; pnpm: `pnpm add jev-devtools @typesafe-ai/sdk`; Yarn: `yarn add jev-devtools @typesafe-ai/sdk`; Bun: `bun add jev-devtools @typesafe-ai/sdk`). `@typesafe-ai/sdk` is a peer dependency: keep the app's existing SDK version when it satisfies the peer range. Install in the workspace(s) that actually import it. It is a regular dependency when application modules import it, even though capture/display are development-only. Do not replace the app's framework or upgrade unrelated dependencies to force compatibility.
|
|
21
|
+
|
|
22
|
+
### Consumer compatibility (0.5.1)
|
|
23
|
+
|
|
24
|
+
| Requirement | Contract |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| Node.js | 22.12+ for the adapter and flow execution; Edge runtimes are unsupported. |
|
|
27
|
+
| React / React DOM | Matching 18.x or 19.x versions; both remain required peers even for server-only installations. |
|
|
28
|
+
| TypeSafe SDK | `>=0.7.0 <0.8.0`; verified with 0.7.0. |
|
|
29
|
+
| TypeScript | 5.4+ for the public declarations; verified with 5.4.5. The flow API uses built-in `NoInfer`, which 5.3.3 cannot resolve. |
|
|
30
|
+
| Modules | ESM imports with export-aware `Bundler` or `NodeNext` resolution and a matching module setting. There is no CommonJS `require` entry. |
|
|
31
|
+
|
|
32
|
+
Use React types matching the app's React major, Node types compatible with its runtime/compiler, and DOM types for Web `Request`/`Response` APIs. The packed declarations passed strict checks without `skipLibCheck` using TypeScript 5.4.5, SDK 0.7.0, React 19.3.1, `@types/react` 19.3.0, and `@types/node` 22.10.2. Frameworks and newer type packages can require a newer compiler; preserve compatible app dependencies rather than downgrading to this verification baseline.
|
|
33
|
+
|
|
34
|
+
Import application APIs from `jev-devtools` (React and browser-safe capture helpers/types), or the Node-only `jev-devtools/server` and `jev-devtools/flow` entries. Internal paths and `jev-devtools/package.json` are not exported. Inspect the installed version through the package manager, and read declaration/skill files from disk rather than importing internal package paths. Always supply the browser `origin` to the server adapter, including when `enabled: false`.
|
|
19
35
|
|
|
20
|
-
## Optional connected flow API
|
|
36
|
+
## Optional connected flow API
|
|
21
37
|
|
|
22
|
-
When asked to build or inspect connected calls, read [references/flows.md](references/flows.md) after the framework recipe.
|
|
38
|
+
When asked to build or inspect connected calls, read [references/flows.md](references/flows.md) after the framework recipe. For 0.5.1 it covers requests, server function tasks, runtime request factories, parallel checks, terminal branches, returning conditionals, bounded collections, stateful loops, captured-answer replay, and fixture comparison. It includes sample verification, scope/execution rules, and privacy limits. For an older installation, use its bundled recipe and declarations rather than assuming these operations exist. Preserve existing application policies; do not convert unrelated calls just to install the drawer. Flow execution is server-only and continues even with the inspector disabled.
|
|
23
39
|
|
|
24
40
|
## Integration invariants
|
|
25
41
|
|
|
26
42
|
- Use only public imports: `jev-devtools` and server-only `jev-devtools/server` and `jev-devtools/flow`. No provider, TanStack DevTools shell, Tailwind, or shadcn setup is needed; TanStack Virtual is an internal dependency.
|
|
27
|
-
- Mount `<JevDevtools />` once with an explicit development flag. The drawer injects its own stylesheet into a Shadow DOM host under `document.body`;
|
|
43
|
+
- Mount `<JevDevtools />` once with an explicit development flag. The drawer injects its own stylesheet into a Shadow DOM host under `document.body`; no CSS import is needed. Do not add global `section`/`main` padding overrides to repair the drawer. Keep document-level transforms/filters on an app wrapper rather than `html`/`body`, which can affect fixed overlays. Server capture must also be explicitly enabled for development; both default to off.
|
|
28
44
|
- Create a shared adapter; the inspector routes and application client must use it in the same Node realm/process. Replace existing `new TypeSafeClient(options)` construction with `inspector.createClient(options)` while preserving keys, transport options, retries, and call semantics. Keep existing `systemOne(...)` inputs and application behavior.
|
|
29
45
|
- Browser and server `endpoint` paths must agree (default `/api/jev-devtools`). Route the base path and its subpaths. The server `origin` must exactly match the browser scheme, hostname, and port. A browser endpoint is a same-origin path, not an absolute backend URL.
|
|
30
46
|
- Keep keys in server environment variables, never `VITE_*` or `NEXT_PUBLIC_*`. Use the host's environment loader and an ignored local env file. If a key is unavailable, complete setup and use the clearly labeled sample verification in [references/verify.md](references/verify.md); report that live inference remains unverified.
|
|
47
|
+
- In 0.5.0, `redactAdditionalSensitiveData` defaults to true and masks supported personal fields in the drawer only; those values still exist in capture/stream/browser memory. Known credentials and custom server redactions cannot be revealed by disabling display masking. Keep application-specific server redaction for data that must not reach the browser.
|
|
31
48
|
- Preserve authentication and project redaction. Shared/non-loopback access requires a real `authorize(request)` check; do not bypass it with `() => true`. Keep local defaults unless shared access is requested. Without `authorize`, Node middleware accepts only loopback connections; Web Request routes can't check the connection, so their dev server must listen on `127.0.0.1` or set a real `authorize`. Separate processes require a different architecture, not extra adapter instances.
|
|
32
49
|
|
|
33
50
|
## Finish and verify
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Build and inspect a Jev flow
|
|
2
2
|
|
|
3
|
-
For `jev-devtools` **0.
|
|
3
|
+
For `jev-devtools` **0.5.1**. Check the repository changelog for publication status when installing from source. Read the installed package version and `lib/flow/index.d.ts` first; online `main` may describe newer APIs. Use this recipe when the user asks to connect multiple Jev requests, inspect branches, run server function steps, or visualize parallel checks, collections, and loops. Adding the inspector alone does not require converting existing calls to flows.
|
|
4
4
|
|
|
5
5
|
## Plan the integration
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ For `jev-devtools` **0.4.1**. Read the installed package version and `lib/flow/i
|
|
|
9
9
|
3. Import `defineJevFlow` (and `all`, `any`, `not` when needed) from **server-only** `jev-devtools/flow`. Define the graph once at module scope and call `run()` from the existing Node handler/action. In Next.js, mark the module `server-only` and keep the executing route/segment on the Node runtime. No new client provider or root component is needed.
|
|
10
10
|
4. A named output returns data and does not execute an action. Existing business actions can remain in the application after the returned outcome; use `task()` when the user wants application-owned server work included in the flow. Preserve authorization, idempotency, input validation, and error handling. Cancellation cannot undo side effects.
|
|
11
11
|
|
|
12
|
-
If importing question helpers as below, install `@typesafe-ai/sdk` as a direct dependency in the server workspace using its package manager. Version 0.
|
|
12
|
+
If importing question helpers as below, install `@typesafe-ai/sdk` as a direct dependency in the server workspace using its package manager. Version 0.5.1 requires SDK `>=0.7.0 <0.8.0` and is verified with 0.7.0; preserve a compatible existing version rather than silently changing SDK semantics. The flow also accepts ordinary SDK question objects.
|
|
13
13
|
|
|
14
14
|
## Complete example: parallel checks, one decision, two outcomes
|
|
15
15
|
|
|
@@ -94,7 +94,7 @@ For custom server-derived sessions, use `await inspector.run(request, () => revi
|
|
|
94
94
|
| `flow.if(id, { when, then, else }, display?)` | Only the selected path executes. Each arm returns an expression; the merged result can feed shared downstream steps. |
|
|
95
95
|
| `flow.map(id, { items, input, concurrency?, maxItems }, buildItem, display?)` | Run a bounded item program over an array; preserve result order. Pass outer values through `input`; return an expression from the item builder. |
|
|
96
96
|
| `flow.loop(id, { initial, input, while, maxIterations }, buildIteration, display?)` | Check a state expression before each iteration; return a same-type state expression from the body. Reject unfinished limit exhaustion with `FlowLoopLimitError`. |
|
|
97
|
-
| `flow.input.get('field')` |
|
|
97
|
+
| `flow.input.get('field')` | Select an own object field, array index, or array `length` as a typed reference resolved during execution. Primitive properties (string length/indexes included) are unsupported; compute them in a task callback. |
|
|
98
98
|
| `result.answer('name')` | Typed answer fields: `.choice`, `.probabilities.get('label')`, `.confidence`, `.noul`, `.score`, `.legend`, or `.box` as supported by that question's SDK result. Select nested fields with `.get(key)`. |
|
|
99
99
|
| `value.eq(other)`, `.lt(number)`, `.gt(number)`, `.gte(number)` | Matching scalar equality or finite numeric comparisons. Noul values are in 0–1; use `0.9`, not `90`. There is no `.lte()` method. |
|
|
100
100
|
| `all(...)`, `any(...)`, `not(...)` | Compose Boolean expressions. Every operand evaluates; missing values are errors even in an otherwise short-circuited expression. Do not use JavaScript `if`, `&&`, or `>=` on expression objects. |
|
|
@@ -160,13 +160,17 @@ Check these observable results:
|
|
|
160
160
|
|
|
161
161
|
If the flow executes but details are absent, check: `devtools` passed to `run`, `client` from that same adapter, same process/session, capture enabled, `/flows/events` forwarded, and histories not cleared/evicted. A plain SDK client can produce flow states but cannot link request details. See [verify.md](verify.md) for general endpoint checks.
|
|
162
162
|
|
|
163
|
+
To check routing without a key, copy the run's fixture with **Copy fixture** in the Flows run header. Replay it in a test with `flow.run(input, { client: replayClient(fixture) })` from `jev-devtools/flow`. Steps in map items and loop iterations are keyed `parent-id/index/step-id` (map item or loop iteration); tasks run again on replay. A missing-step error names the composed id of the step the fixture lacks; see the [flow guide](https://github.com/diegoag64/jev-devtools/blob/main/docs/flows.md#replay-a-run-in-tests) for limits.
|
|
164
|
+
|
|
165
|
+
To check a prompt or model change against saved cases, use `compareWithFixture(flow, input, fixture, { client })` from `jev-devtools/flow` and print `formatComparison` for each case where `comparison.changed || comparison.answers.some((a) => a.changed)`. Item steps are reported under their composed ids, and tasks run on both sides.
|
|
166
|
+
|
|
163
167
|
Remove temporary verification routes unless requested as a demo. Report the installed version, integration location, outcomes observed, whether browser checks were performed, and that responses were samples. Never equate sample verification with live-model correctness.
|
|
164
168
|
|
|
165
169
|
## Function steps and runtime requests (0.4.0)
|
|
166
170
|
|
|
167
171
|
Use `task()` for application-owned server work and the request-factory overload of `jev()` when later questions depend on earlier results. Both are part of 0.4.0.
|
|
168
172
|
|
|
169
|
-
- `flow.task(id, { input, run, timeoutMs? }, display?)`: resolve nested input references, run server code, and return a typed reference. `run(input, { signal, runId, stepId, executionId })` may return a value or Promise. Inputs/outputs must be plain JSON-compatible values; return null rather than undefined. No implicit retry.
|
|
173
|
+
- `flow.task(id, { input, run, timeoutMs? }, display?)`: resolve nested input references, run server code, and return a typed reference. `run(input, { signal, runId, stepId, executionId })` may return a value or Promise. Inputs/outputs must be plain JSON-compatible values; return null rather than undefined. Task input literals with own symbol keys (including nested objects and arrays) fail during definition; referenced values are checked before the callback runs. No implicit retry.
|
|
170
174
|
- `flow.jev(id, { input, request: resolved => ({ state, questions, ...sdkOptions }) }, display?)`: construct a synchronous SDK request at execution time. Do asynchronous work in a preceding task. Keep Jev calls here to retain full linked diagrams. Never return unresolved flow references or a Promise from the factory.
|
|
171
175
|
- Every Jev step also has `.answers`, a typed reference to the complete answer map. Pass it to a task when a request factory generates question names dynamically; do not create new `.answer()` references inside a runtime callback.
|
|
172
176
|
- Neither callback executes at definition time. Runtime input snapshots protect previous values from mutation. Task timeouts/cancellation stop downstream work and signal the callback, but cannot undo side effects or forcibly interrupt synchronous code.
|
|
@@ -225,3 +229,12 @@ Require `maxIterations` (1–64). If the condition is still true at the limit, `
|
|
|
225
229
|
Loops may contain one level of map, plus tasks, requests, conditions and parallel lanes. Nested loops, loops in maps and nested maps remain unsupported. All template nodes count toward the 256-node definition cap; the root execution shares a 1,024-expanded-step budget across iterations and collections. A fresh per-iteration budget would bypass that guarantee. Use a matching server and drawer. Loop cards reuse inline expansion/navigation: select an iteration → View Flow → select a nested frontier item if present. Input/latest state and child outcomes use normal redaction and capture limits.
|
|
226
230
|
|
|
227
231
|
`cookbooks/hierarchical-classification` is an executable sample at `/?cookbook=hierarchical-classification`. It follows the official executable algorithm’s **separate concurrent requests per frontier node**, despite introductory prose describing batching. Preserve geometric-mean decision-edge scores, epsilon 1e-9, single-child inference bypass, completed-leaf retention and top-k pruning. Samples are a small authored taxonomy and synthetic probabilities, not a replay of official benchmark data. Verify recovery, no-request paths, an initial leaf and intentional depth exhaustion before considering live execution.
|
|
232
|
+
|
|
233
|
+
## Replay captures and compare runs (new in 0.5.0)
|
|
234
|
+
|
|
235
|
+
For human examples, see [the flow reference](https://docs.jevtools.dev/api/flow/) and [API glossary](https://docs.jevtools.dev/api/reference/#fixtures-and-comparison). These operations require 0.5.0 or later; inspect the installed declarations before using them with older packages.
|
|
236
|
+
|
|
237
|
+
1. Capture a complete run and use **Copy fixture** in the drawer. The browser-safe root export `flowFixture(definition, run, traces)` also builds a `BuiltFlowFixture` with the fixture and capture/missing-response warnings. A fixture stores captured response bodies and step IDs, not the original input or executable recipe.
|
|
238
|
+
2. On Node, import `replayClient` from `jev-devtools/flow` and call `await program.run(originalInput, { client: replayClient(fixture) })`. Use the same recipe, input, and stable step IDs. Jev steps use stored answers without a key/network call; tasks and runtime request factories still execute. Avoid uncontrolled effects in test tasks.
|
|
239
|
+
3. For an explicitly requested live comparison, import `compareWithFixture` and `formatComparison` from `jev-devtools/flow`. Call `await compareWithFixture(program, originalInput, fixture, { client: liveClient, devtools: inspector, tolerance: 0.01 })`, then use `formatComparison(result)` for text. Do not run live comparison merely to verify installation; use stored SDK responses for ordinary verification.
|
|
240
|
+
4. Tasks execute on both sides. `changed` tracks outcomes, values, decisions, and executed Jev steps; answer drift alone does not set it. Inspect `answers` separately, and apply numeric tolerance only to answer fields. The result's `liveFixture` contains unredacted live responses: review it before saving or sharing. Replay is not rollback, and incomplete captures cannot recreate missing inference results.
|
|
@@ -78,6 +78,4 @@ Report HTTP/capture checks separately from visual browser checks, and sample ver
|
|
|
78
78
|
| Server import/build errors | Keep `/server` outside client modules. In Next externalize the SDK only. Use a supported Node runtime. |
|
|
79
79
|
| Production 404 | Expected when disabled; app inference remains independent. |
|
|
80
80
|
|
|
81
|
-
Capture is bounded to 50 calls in memory by default.
|
|
82
|
-
|
|
83
|
-
The current browser requests `/events?protocol=2`: the first event is a full version 2 `snapshot`, followed by `delta` events containing changed traces and the retained ID order. The unqualified `/events` check above intentionally remains compatible with legacy clients. Reconnecting always supplies a fresh snapshot.
|
|
81
|
+
Capture is bounded to 50 calls in memory by default. Known credential fields are always redacted, including common API-key, client-secret and session-token aliases (case, hyphens and underscores are ignored). HTTP headers/options are not captured. The `redactAdditionalSensitiveData` component prop defaults to `true` and masks supported email, phone, postal address, SSN and card-number fields **only in DevTools views**. Set it to `false` to inspect those fields; changes apply immediately to existing captures, independently in each viewer, without server requests. These personal values remain in server/stream/browser memory even while masked. Custom server redaction always remains active, and neither credentials nor custom-redacted values can be recovered through the prop. See the [exact policy](https://github.com/diegoag64/jev-devtools/blob/main/docs/integration.md#redaction-policy). Arbitrary secrets in prose and unusual field names still need custom redaction. Verify both modes with synthetic sentinels and confirm SDK/runtime values remain unchanged. Diagrams show captured inputs/outputs, not hidden model reasoning. Routing decisions are recorded only for explicitly defined flows; see [flows.md](flows.md) for flow verification.
|