jev-devtools 0.5.0 → 0.5.2

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.
@@ -64,6 +64,21 @@
64
64
  padding: 8px;
65
65
  width: 100%;
66
66
  }
67
+ .jev-devtools select {
68
+ appearance: none;
69
+ padding-right: 34px;
70
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='m4 6 4 4 4-4' stroke='%23bcadbf' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
71
+ background-repeat: no-repeat;
72
+ background-position: right 10px center;
73
+ background-size: 16px 16px;
74
+ }
75
+ @media (forced-colors: active) {
76
+ .jev-devtools select {
77
+ /* Let the system draw a visible arrow in high-contrast themes. */
78
+ appearance: auto;
79
+ background-image: none;
80
+ }
81
+ }
67
82
  .jev-devtools button:hover:not(:disabled) {
68
83
  border-color: #e551ba;
69
84
  }
@@ -149,13 +164,17 @@
149
164
  min-width: 0;
150
165
  }
151
166
  .jev-devtools .list-filters select {
152
- width: 86px;
167
+ width: 100px;
168
+ flex-shrink: 0;
153
169
  font-size: 11px;
154
170
  }
155
171
  .jev-devtools .request-items {
156
172
  overflow: auto;
157
173
  flex: 1;
158
174
  }
175
+ .jev-devtools .request-navigation {
176
+ display: none;
177
+ }
159
178
  .jev-devtools .request-row {
160
179
  display: flex;
161
180
  align-items: center;
@@ -495,6 +514,63 @@
495
514
  min-width: 240px;
496
515
  padding: 8px 12px;
497
516
  }
517
+ /* Requests use separate list/detail screens so history cannot collapse into
518
+ the fixed-height strip used by flow runs. CSS keeps desktop split panes. */
519
+ .jev-devtools .jev-inspector[data-mobile-view="list"] > .request-list {
520
+ flex: 1;
521
+ }
522
+ .jev-devtools .jev-inspector[data-mobile-view="list"] > .request-detail,
523
+ .jev-devtools .jev-inspector[data-mobile-view="detail"] .list-filters,
524
+ .jev-devtools .jev-inspector[data-mobile-view="detail"] .request-items {
525
+ display: none;
526
+ }
527
+ .jev-devtools .jev-inspector[data-mobile-view="detail"] > .request-list {
528
+ flex: none;
529
+ }
530
+ .jev-devtools .jev-inspector[data-mobile-view="detail"] .request-navigation {
531
+ display: flex;
532
+ align-items: center;
533
+ justify-content: space-between;
534
+ min-height: 44px;
535
+ margin: 6px 12px;
536
+ text-align: left;
537
+ }
538
+ .jev-devtools .jev-inspector[data-mobile-view] .request-items {
539
+ flex-direction: column;
540
+ }
541
+ .jev-devtools .jev-inspector[data-mobile-view] .request-row {
542
+ flex: none;
543
+ min-width: 0;
544
+ min-height: 60px;
545
+ padding: 12px;
546
+ }
547
+ .jev-devtools
548
+ .jev-inspector[data-mobile-view]
549
+ .request-row
550
+ > span:nth-child(2) {
551
+ min-width: 0;
552
+ overflow-wrap: anywhere;
553
+ }
554
+ .jev-devtools .jev-inspector[data-mobile-view] > .request-detail {
555
+ overflow: auto;
556
+ }
557
+ .jev-devtools
558
+ .jev-inspector[data-mobile-view]
559
+ > .request-detail
560
+ > :is(.detail-header, .detail-meta, .detail-tabs) {
561
+ flex: none;
562
+ }
563
+ .jev-devtools
564
+ .jev-inspector[data-mobile-view]
565
+ > .request-detail
566
+ > .detail-body-flow {
567
+ /* Let metadata scroll above the diagram instead of clipping its toolbar. */
568
+ flex: 1 0 auto;
569
+ min-height: min-content;
570
+ }
571
+ .jev-devtools .flow-details-bar > span {
572
+ display: none;
573
+ }
498
574
  .jev-devtools .detail-header {
499
575
  padding: 12px;
500
576
  }
@@ -503,6 +579,10 @@
503
579
  padding-left: 12px;
504
580
  padding-right: 12px;
505
581
  }
582
+ .jev-devtools .detail-tabs {
583
+ overflow-x: auto;
584
+ flex-shrink: 0;
585
+ }
506
586
  .jev-devtools .detail-body {
507
587
  padding: 12px;
508
588
  }
@@ -668,14 +748,16 @@
668
748
  padding: 12px 16px;
669
749
  flex-wrap: wrap;
670
750
  }
671
- .jev-devtools .lab-flow-toolbar label {
751
+ .jev-devtools .lab-flow-toolbar label,
752
+ .jev-devtools .flow-step-select {
672
753
  display: flex;
673
754
  gap: 10px;
674
755
  align-items: center;
675
756
  font-size: 11px;
676
757
  min-width: 0;
677
758
  }
678
- .jev-devtools .lab-flow-toolbar select {
759
+ .jev-devtools .lab-flow-toolbar select,
760
+ .jev-devtools .flow-step-select select {
679
761
  width: auto;
680
762
  max-width: 240px;
681
763
  font-size: 11px;
@@ -685,10 +767,12 @@
685
767
  gap: 8px;
686
768
  align-items: center;
687
769
  }
688
- .jev-devtools .lab-flow-toolbar button {
770
+ .jev-devtools .lab-flow-toolbar button,
771
+ .jev-devtools .flow-canvas-controls button {
689
772
  font-size: 11px;
690
773
  }
691
- .jev-devtools .lab-flow-toolbar output {
774
+ .jev-devtools .lab-flow-toolbar output,
775
+ .jev-devtools .flow-canvas-controls output {
692
776
  font-size: 11px;
693
777
  min-width: 35px;
694
778
  text-align: center;
@@ -722,10 +806,9 @@
722
806
  flex-shrink: 0;
723
807
  padding: 8px 16px;
724
808
  margin: 0;
725
- }
726
- .jev-devtools .lab-gesture-hint {
727
- display: block;
728
809
  color: #c6a7bd;
810
+ font-size: 11px;
811
+ line-height: 1.6;
729
812
  }
730
813
  .jev-devtools .lab-flow-canvas {
731
814
  position: absolute;
@@ -1144,14 +1227,20 @@
1144
1227
  min-width: 0;
1145
1228
  overflow: hidden;
1146
1229
  }
1147
- :where(.jev-devtools) .whole-flow > .detail-header,
1148
- :where(.jev-devtools) .whole-flow > .lab-flow-toolbar {
1230
+ :where(.jev-devtools)
1231
+ .flow-overview-stack:not(.flow-inline-overview)
1232
+ > .whole-flow {
1233
+ /* Short drawers must scroll metadata instead of clipping the canvas controls. */
1234
+ overflow: auto;
1235
+ }
1236
+ :where(.jev-devtools) .whole-flow > .detail-header {
1237
+ flex-wrap: wrap;
1149
1238
  flex-shrink: 0;
1150
1239
  }
1151
1240
  :where(.jev-devtools) .flow-workspace {
1152
1241
  display: flex;
1153
1242
  flex-direction: column;
1154
- flex: 1;
1243
+ flex: 1 0 auto;
1155
1244
  min-height: 0;
1156
1245
  overflow: hidden;
1157
1246
  }
@@ -1207,8 +1296,11 @@
1207
1296
  outline-offset: -1px;
1208
1297
  }
1209
1298
  :where(.jev-devtools) .flow-overview-viewport {
1299
+ background-color: #08060a;
1210
1300
  position: relative;
1211
- min-height: 0;
1301
+ /* The panel's grid row reserves its actual height, including wrapped buttons. */
1302
+ display: grid;
1303
+ min-height: min-content;
1212
1304
  flex: 1 1 0;
1213
1305
  overflow: hidden;
1214
1306
  touch-action: none;
@@ -1220,11 +1312,31 @@
1220
1312
  );
1221
1313
  background-size: 20px 20px;
1222
1314
  }
1315
+ .jev-devtools .flow-canvas-controls {
1316
+ align-self: start;
1317
+ justify-self: end;
1318
+ margin: 12px;
1319
+ z-index: 1;
1320
+ display: flex;
1321
+ flex-wrap: wrap;
1322
+ align-items: center;
1323
+ gap: 8px;
1324
+ max-width: calc(100% - 24px);
1325
+ padding: 8px;
1326
+ border: 1px solid #3b303d;
1327
+ border-radius: 10px;
1328
+ background: #17121b;
1329
+ box-shadow: 0 4px 16px #0006;
1330
+ cursor: default;
1331
+ }
1223
1332
  :where(.jev-devtools) .flow-overview-viewport[data-panning] {
1224
1333
  cursor: grabbing;
1225
1334
  }
1226
1335
  :where(.jev-devtools) .flow-overview-canvas {
1227
1336
  position: absolute;
1337
+ /* Keep camera coordinates at the viewport origin when the overlay uses grid. */
1338
+ top: 0;
1339
+ left: 0;
1228
1340
  transform-origin: 0 0;
1229
1341
  }
1230
1342
  :where(.jev-devtools) .flow-connections {
@@ -1658,14 +1770,22 @@
1658
1770
  margin-bottom: 5px;
1659
1771
  }
1660
1772
  :where(.jev-devtools) .flow-condition-rule code {
1661
- display: block;
1662
1773
  white-space: pre-wrap;
1663
- overflow-wrap: anywhere;
1664
1774
  font:
1665
1775
  12px/1.6 ui-monospace,
1666
1776
  monospace;
1667
1777
  color: #f2d7eb;
1668
1778
  }
1779
+ /* Bound card previews so long captured literals cannot push warnings off-canvas.
1780
+ The complete captured rule remains available in selected-step details. */
1781
+ :where(.jev-devtools) .flow-condition-rule code,
1782
+ :where(.jev-devtools) .flow-map-progress > code {
1783
+ display: -webkit-box;
1784
+ -webkit-box-orient: vertical;
1785
+ -webkit-line-clamp: 4;
1786
+ overflow: hidden;
1787
+ overflow-wrap: anywhere;
1788
+ }
1669
1789
 
1670
1790
  :where(.jev-devtools) .flow-condition-incoming {
1671
1791
  display: block;
@@ -1870,15 +1990,32 @@
1870
1990
  right: -76px;
1871
1991
  }
1872
1992
  .jev-devtools .flow-run-summary {
1993
+ max-width: 100%;
1994
+ margin-left: auto;
1873
1995
  text-align: right;
1874
1996
  }
1997
+ .jev-devtools .flow-run-controls {
1998
+ display: flex;
1999
+ flex-wrap: wrap;
2000
+ align-items: center;
2001
+ justify-content: flex-end;
2002
+ gap: 10px;
2003
+ margin-top: 6px;
2004
+ }
2005
+ .jev-devtools .flow-run-controls .flow-step-select {
2006
+ max-width: 100%;
2007
+ }
2008
+ .jev-devtools .flow-step-select select {
2009
+ min-width: 0;
2010
+ }
1875
2011
  .jev-devtools .flow-fixture-button {
1876
- display: block;
1877
- margin: 6px 0 0 auto;
2012
+ flex-shrink: 0;
1878
2013
  /* Keep the header still when the shorter confirmation replaces the label. */
1879
2014
  min-width: 96px;
1880
2015
  font-size: 11px;
1881
- transition: background-color 160ms ease, border-color 160ms ease;
2016
+ transition:
2017
+ background-color 160ms ease,
2018
+ border-color 160ms ease;
1882
2019
  }
1883
2020
  .jev-devtools .flow-fixture-button[data-copied] {
1884
2021
  border-color: #e551ba;
@@ -96,7 +96,7 @@ export function useDiagramViewport(width, height, scene, origin = { x: 0, y: 0 }
96
96
  const down = (event) => {
97
97
  if (event.button !== 0 ||
98
98
  pointers.size >= 2 ||
99
- event.target.closest("button, input, select, textarea, a, summary, [data-diagram-scroll]"))
99
+ event.target.closest("button, input, select, textarea, a, summary, [data-diagram-scroll], [data-diagram-controls]"))
100
100
  return;
101
101
  event.preventDefault();
102
102
  el.focus({ preventScroll: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jev-devtools",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22.12"
@@ -17,16 +17,30 @@ Inspect the app's package manager/lockfile, React and Node versions, root compon
17
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.
18
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.
19
19
 
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. React 18/19 and Node 22.12+ are required. Do not replace the app's framework or upgrade unrelated dependencies to force compatibility.
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.2)
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`.
21
35
 
22
36
  ## Optional connected flow API
23
37
 
24
- When asked to build or inspect connected calls, read [references/flows.md](references/flows.md) after the framework recipe. For 0.5.0 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.
38
+ When asked to build or inspect connected calls, read [references/flows.md](references/flows.md) after the framework recipe. For 0.5.2 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.
25
39
 
26
40
  ## Integration invariants
27
41
 
28
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.
29
- - Mount `<JevDevtools />` once with an explicit development flag. The drawer injects its own stylesheet into a Shadow DOM host under `document.body`; do not add a `jev-devtools/styles.css` import during setup. The CSS export remains supported for existing integrations. 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.
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.
30
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.
31
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.
32
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.